# HG changeset patch # User jfranck # Date 1354123297 28800 # Node ID 985410ec95e3d908cb79c60f43a6ac2f4e3364b1 # Parent 17224d0282f1dfefa425a609acf66c7afaa24998 7154390: Add support for repeating annotations in j.l.r.AnnotatedElement Reviewed-by: darcy diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/Class.java --- a/jdk/src/share/classes/java/lang/Class.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/Class.java Wed Nov 28 09:21:37 2012 -0800 @@ -48,6 +48,7 @@ import java.util.Set; import java.util.Map; import java.util.HashMap; +import java.util.Objects; import sun.misc.Unsafe; import sun.reflect.ConstantPool; import sun.reflect.Reflection; @@ -3044,34 +3045,62 @@ * @throws NullPointerException {@inheritDoc} * @since 1.5 */ - @SuppressWarnings("unchecked") public A getAnnotation(Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); + Objects.requireNonNull(annotationClass); initAnnotationsIfNecessary(); - return (A) annotations.get(annotationClass); + return AnnotationSupport.getOneAnnotation(annotations, annotationClass); } /** * @throws NullPointerException {@inheritDoc} * @since 1.5 */ - public boolean isAnnotationPresent( - Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); + public boolean isAnnotationPresent(Class annotationClass) { + Objects.requireNonNull(annotationClass); return getAnnotation(annotationClass) != null; } + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A[] getAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + initAnnotationsIfNecessary(); + return AnnotationSupport.getMultipleAnnotations(annotations, annotationClass); + } /** * @since 1.5 */ public Annotation[] getAnnotations() { initAnnotationsIfNecessary(); - return AnnotationParser.toArray(annotations); + return AnnotationSupport.unpackToArray(annotations); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A getDeclaredAnnotation(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + initAnnotationsIfNecessary(); + return AnnotationSupport.getOneAnnotation(declaredAnnotations, annotationClass); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A[] getDeclaredAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + initAnnotationsIfNecessary(); + return AnnotationSupport.getMultipleAnnotations(declaredAnnotations, annotationClass); } /** @@ -3079,7 +3108,17 @@ */ public Annotation[] getDeclaredAnnotations() { initAnnotationsIfNecessary(); - return AnnotationParser.toArray(declaredAnnotations); + return AnnotationSupport.unpackToArray(declaredAnnotations); + } + + /** Returns one "directly" present annotation or null */ + A getDirectDeclaredAnnotation(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + initAnnotationsIfNecessary(); + @SuppressWarnings("unchecked") // TODO check safe + A ret = (A)declaredAnnotations.get(annotationClass); + return ret; } // Annotations cache diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/Package.java --- a/jdk/src/share/classes/java/lang/Package.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/Package.java Wed Nov 28 09:21:37 2012 -0800 @@ -395,6 +395,14 @@ } /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A[] getAnnotations(Class annotationClass) { + return getPackageInfo().getAnnotations(annotationClass); + } + + /** * @since 1.5 */ public Annotation[] getAnnotations() { @@ -402,6 +410,22 @@ } /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A getDeclaredAnnotation(Class annotationClass) { + return getPackageInfo().getDeclaredAnnotation(annotationClass); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public A[] getDeclaredAnnotations(Class annotationClass) { + return getPackageInfo().getDeclaredAnnotations(annotationClass); + } + + /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/System.java --- a/jdk/src/share/classes/java/lang/System.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/System.java Wed Nov 28 09:21:37 2012 -0800 @@ -25,6 +25,7 @@ package java.lang; import java.io.*; +import java.lang.annotation.Annotation; import java.util.Properties; import java.util.PropertyPermission; import java.util.StringTokenizer; @@ -1195,6 +1196,9 @@ public AnnotationType getAnnotationType(Class klass) { return klass.getAnnotationType(); } + public A getDirectDeclaredAnnotation(Class klass, Class anno) { + return klass.getDirectDeclaredAnnotation(anno); + } public > E[] getEnumConstantsShared(Class klass) { return klass.getEnumConstantsShared(); diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/annotation/ContainedBy.java --- a/jdk/src/share/classes/java/lang/annotation/ContainedBy.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/annotation/ContainedBy.java Wed Nov 28 09:21:37 2012 -0800 @@ -26,10 +26,35 @@ package java.lang.annotation; /** - * A meta-annotation to indicate which annotation type should be used - * as a container for repeated values of the annotation type modified - * by the {@code ContainedBy} annotation. + * The annotation type {@code java.lang.annotation.ContainedBy} is + * used to indicate that the annotation type whose declaration it + * (meta-)annotates is repeatable. The value of + * {@code @ContainedBy} indicates the containing annotation + * type for the repeatable annotation type. + * + *

The pair of annotation types {@code @ContainedBy} and + * {@link java.lang.annotation.ContainerFor @ContainerFor} are used to + * indicate that annotation types are repeatable. Specifically: + * + *

    + *
  • The annotation type {@code @ContainedBy} is used on the + * declaration of a repeatable annotation type (JLS 9.6) to indicate + * its containing annotation type. * + *
  • The annotation type {@code @ContainerFor} is used on the + * declaration of a containing annotation type (JLS 9.6) to indicate + * the repeatable annotation type for which it serves as the + * containing annotation type. + *
+ * + *

+ * An inconsistent pair of {@code @ContainedBy} and + * {@code @ContainerFor} annotations on a repeatable annotation type + * and its containing annotation type (JLS 9.6) will lead to + * compile-time errors and runtime exceptions when using reflection to + * read annotations of a repeatable type. + * + * @see java.lang.annotation.ContainerFor * @since 1.8 * @jls 9.6 Annotation Types * @jls 9.7 Annotations @@ -39,8 +64,8 @@ @Target(ElementType.ANNOTATION_TYPE) public @interface ContainedBy { /** - * The annotation type to use to store repeated values of another - * annotation. + * Indicates the containing annotation type for the + * repeatable annotation type. */ Class value(); } diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/annotation/ContainerFor.java --- a/jdk/src/share/classes/java/lang/annotation/ContainerFor.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/annotation/ContainerFor.java Wed Nov 28 09:21:37 2012 -0800 @@ -26,10 +26,36 @@ package java.lang.annotation; /** - * Indicates that an annotation type is a container for repeated - * instances of annotations of the type of the value of the - * {@code ContainerFor}'s value element. + * The annotation type {@code java.lang.annotation.ContainerFor} is + * used to indicate that the annotation type whose declaration it + * (meta-)annotates is a containing annotation type. The + * value of {@code @ContainerFor} indicates the repeatable + * annotation type for the containing annotation type. + * + *

The pair of annotation types {@link + * java.lang.annotation.ContainedBy @ContainedBy} and + * {@code @ContainerFor} are used to indicate that annotation types + * are repeatable. Specifically: * + *

    + *
  • The annotation type {@code @ContainedBy} is used on the + * declaration of a repeatable annotation type (JLS 9.6) to indicate + * its containing annotation type. + * + *
  • The annotation type {@code @ContainerFor} is used on the + * declaration of a containing annotation type (JLS 9.6) to indicate + * the repeatable annotation type for which it serves as the + * containing annotation type. + *
+ * + *

+ * An inconsistent pair of {@code @ContainedBy} and + * {@code @ContainerFor} annotations on a repeatable annotation type + * and its containing annotation type (JLS 9.6) will lead to + * compile-time errors and runtime exceptions when using reflection to + * read annotations of a repeatable type. + * + * @see java.lang.annotation.ContainedBy * @since 1.8 * @jls 9.6 Annotation Types * @jls 9.7 Annotations @@ -38,9 +64,10 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface ContainerFor { + /** - * The repeating annotation type that the annotation type - * annotated with this annotation is a container for. + * Indicates the repeatable annotation type for the containing + * annotation type. */ Class value(); } diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package java.lang.annotation; + +import java.util.Objects; + +/** + * Thrown to indicate that an annotation type whose declaration is + * (meta-)annotated with a {@link ContainerFor} annotation is not, in + * fact, the containing annotation type of the type named by {@link + * ContainerFor}. + * + * @see java.lang.reflect.AnnotatedElement + * @since 1.8 + * @jls 9.6 Annotation Types + * @jls 9.7 Annotations + */ +public class InvalidContainerAnnotationError extends AnnotationFormatError { + private static final long serialVersionUID = 5023L; + + /** + * The instance of the erroneous container. + */ + private transient Annotation container; + + /** + * The type of the annotation that should be contained in the + * container. + */ + private transient Class annotationType; + + /** + * Constructs a new InvalidContainerAnnotationError with the + * specified detail message. + * + * @param message the detail message. + */ + public InvalidContainerAnnotationError(String message) { + super(message); + } + + /** + * Constructs a new InvalidContainerAnnotationError with the specified + * detail message and cause. Note that the detail message associated + * with {@code cause} is not automatically incorporated in + * this error's detail message. + * + * @param message the detail message + * @param cause the cause, may be {@code null} + */ + public InvalidContainerAnnotationError(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidContainerAnnotationError with the + * specified cause and a detail message of {@code (cause == null ? + * null : cause.toString())} (which typically contains the class + * and detail message of {@code cause}). + * + * @param cause the cause, may be {@code null} + */ + public InvalidContainerAnnotationError(Throwable cause) { + super(cause); + } + + /** + * Constructs InvalidContainerAnnotationError for the specified + * container instance and contained annotation type. + * + * @param message the detail message + * @param cause the cause, may be {@code null} + * @param container the erroneous container instance, may be + * {@code null} + * @param annotationType the annotation type intended to be + * contained, may be {@code null} + */ + public InvalidContainerAnnotationError(String message, + Throwable cause, + Annotation container, + Class annotationType) { + super(message, cause); + this.container = container; + this.annotationType = annotationType; + } + + /** + * Returns the erroneous container. + * + * @return the erroneous container, may return {@code null} + */ + public Annotation getContainer() { + return container; + } + + /** + * Returns the annotation type intended to be contained. Returns + * {@code null} if the annotation type intended to be contained + * could not be determined. + * + * @return the annotation type intended to be contained, or {@code + * null} if unknown + */ + public Class getAnnotationType() { + return annotationType; + } +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/reflect/AccessibleObject.java --- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -184,12 +184,19 @@ * @throws NullPointerException {@inheritDoc} * @since 1.5 */ - public boolean isAnnotationPresent( - Class annotationClass) { + public boolean isAnnotationPresent(Class annotationClass) { return getAnnotation(annotationClass) != null; } /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public T[] getAnnotations(Class annotationClass) { + throw new AssertionError("All subclasses should override this method"); + } + + /** * @since 1.5 */ public Annotation[] getAnnotations() { @@ -197,6 +204,28 @@ } /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public T getDeclaredAnnotation(Class annotationClass) { + // Only annotations on classes are inherited, for all other + // objects getDeclaredAnnotation is the same as + // getAnnotation. + return getAnnotation(annotationClass); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public T[] getDeclaredAnnotations(Class annotationClass) { + // Only annotations on classes are inherited, for all other + // objects getDeclaredAnnotations is the same as + // getAnnotations. + return getAnnotations(annotationClass); + } + + /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedElement.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -45,6 +45,11 @@ * a {@link EnumConstantNotPresentException} if the enum constant in the * annotation is no longer present in the enum type. * + *

Attempting to read annotations of a repeatable annotation type T + * that are contained in an annotation whose type is not, in fact, the + * containing annotation type of T will result in an + * InvalidContainerAnnotationError. + * *

Finally, Attempting to read a member whose definition has evolved * incompatibly will result in a {@link * java.lang.annotation.AnnotationTypeMismatchException} or an @@ -55,6 +60,7 @@ * @see java.lang.annotation.AnnotationFormatError * @see java.lang.annotation.AnnotationTypeMismatchException * @see java.lang.annotation.IncompleteAnnotationException + * @see java.lang.annotation.InvalidContainerAnnotationError * @since 1.5 * @author Josh Bloch */ @@ -87,6 +93,23 @@ T getAnnotation(Class annotationClass); /** + * Returns an array of all this element's annotations for the + * specified type if one or more of such annotation is present, + * else an array of length zero. + * + * The caller of this method is free to modify the returned array; + * it will have no effect on the arrays returned to other callers. + * + * @param annotationClass the Class object corresponding to the + * annotation type + * @return all this element's annotations for the specified annotation type if + * present on this element, else an array of length zero + * @throws NullPointerException if the given annotation class is null + * @since 1.8 + */ + T[] getAnnotations(Class annotationClass); + + /** * Returns all annotations present on this element. (Returns an array * of length zero if this element has no annotations.) The caller of * this method is free to modify the returned array; it will have no @@ -98,12 +121,48 @@ Annotation[] getAnnotations(); /** + * Returns this element's annotation for the specified type if + * such an annotation is present, else null. + * + * This method ignores inherited annotations. (Returns null if no + * annotations are directly present on this element.) + * + * @param annotationClass the Class object corresponding to the + * annotation type + * @return this element's annotation for the specified annotation type if + * present on this element, else null + * @throws NullPointerException if the given annotation class is null + * @since 1.8 + */ + T getDeclaredAnnotation(Class annotationClass); + + /** + * Returns an array of all this element's annotations for the + * specified type if one or more of such annotation is directly + * present, else an array of length zero. + * + * This method ignores inherited annotations. (Returns + * an array of length zero if no annotations are directly present + * on this element.) The caller of this method is free to modify + * the returned array; it will have no effect on the arrays + * returned to other callers. + * + * @param annotationClass the Class object corresponding to the + * annotation type + * @return all this element's annotations for the specified annotation type if + * present on this element, else an array of length zero + * @throws NullPointerException if the given annotation class is null + * @since 1.8 + */ + T[] getDeclaredAnnotations(Class annotationClass); + + /** * Returns all annotations that are directly present on this - * element. Unlike the other methods in this interface, this method - * ignores inherited annotations. (Returns an array of length zero if - * no annotations are directly present on this element.) The caller of - * this method is free to modify the returned array; it will have no - * effect on the arrays returned to other callers. + * element. This method ignores inherited annotations. (Returns + * an array of length zero if no annotations are directly present + * on this element.) The caller of this method is free to modify + * the returned array; it will have no effect on the arrays + * returned to other callers. * * @return All annotations directly present on this element * @since 1.5 diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/reflect/Executable.java --- a/jdk/src/share/classes/java/lang/reflect/Executable.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,11 @@ package java.lang.reflect; import java.lang.annotation.*; +import java.util.Collections; import java.util.Map; +import java.util.Objects; import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.AnnotationSupport; import sun.reflect.generics.repository.ConstructorRepository; /** @@ -363,19 +366,28 @@ * {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ - @SuppressWarnings("unchecked") public T getAnnotation(Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); + Objects.requireNonNull(annotationClass); + + return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass); + } - return (T) declaredAnnotations().get(annotationClass); + /** + * {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public T[] getAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass); } /** * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); + return AnnotationSupport.unpackToArray(declaredAnnotations()); } private transient Map, Annotation> declaredAnnotations; diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/java/lang/reflect/Field.java --- a/jdk/src/share/classes/java/lang/reflect/Field.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/java/lang/reflect/Field.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -33,7 +33,9 @@ import sun.reflect.generics.scope.ClassScope; import java.lang.annotation.Annotation; import java.util.Map; +import java.util.Objects; import sun.reflect.annotation.AnnotationParser; +import sun.reflect.annotation.AnnotationSupport; /** @@ -1012,19 +1014,28 @@ * @throws NullPointerException {@inheritDoc} * @since 1.5 */ - @SuppressWarnings("unchecked") public T getAnnotation(Class annotationClass) { - if (annotationClass == null) - throw new NullPointerException(); + Objects.requireNonNull(annotationClass); - return (T) declaredAnnotations().get(annotationClass); + return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass); } /** - * @since 1.5 + * {@inheritDoc} + * @throws NullPointerException {@inheritDoc} + * @since 1.8 + */ + public T[] getAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + + return AnnotationSupport.getMultipleAnnotations(declaredAnnotations(), annotationClass); + } + + /** + * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); + return AnnotationSupport.unpackToArray(declaredAnnotations()); } private transient Map, Annotation> declaredAnnotations; diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/sun/misc/JavaLangAccess.java --- a/jdk/src/share/classes/sun/misc/JavaLangAccess.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/sun/misc/JavaLangAccess.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,6 +25,7 @@ package sun.misc; +import java.lang.annotation.Annotation; import sun.reflect.ConstantPool; import sun.reflect.annotation.AnnotationType; import sun.nio.ch.Interruptible; @@ -83,4 +84,9 @@ * Returns the ith StackTraceElement for the given throwable. */ StackTraceElement getStackTraceElement(Throwable t, int i); + + /** + * Returns a directly present annotation. + */ + public A getDirectDeclaredAnnotation(Class klass, Class anno); } diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationParser.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -806,4 +806,6 @@ public static Annotation[] toArray(Map, Annotation> annotations) { return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY); } + + static Annotation[] getEmptyAnnotationArray() { return EMPTY_ANNOTATION_ARRAY; } } diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationSupport.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.reflect.annotation; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import sun.reflect.Reflection; +import sun.misc.JavaLangAccess; + +public final class AnnotationSupport { + private static JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess(); + + /** + * Finds and returns _one_ annotation of the type indicated by + * {@code annotationClass} from the {@code Map} {@code + * annotationMap}. Looks into containers of the {@code + * annotationClass} (as specified by an the {@code + * annotationClass} type being meta-annotated with an {@code + * ContainedBy} annotation). + * + * @param annotationMap the {@code Map} used to store annotations and indexed by their type + * @param annotationClass the type of annotation to search for + * + * @return in instance of {@code annotationClass} or {@code null} if none were found + */ + public static A getOneAnnotation(final Map, Annotation> annotationMap, + final Class annotationClass) { + @SuppressWarnings("unchecked") + final A candidate = (A)annotationMap.get(annotationClass); + if (candidate != null) { + return candidate; + } + + final Class containerClass = getContainer(annotationClass); + if (containerClass != null) { + return unpackOne(annotationMap.get(containerClass), annotationClass); + } + + return null; // found none + } + + /** + * Finds and returns all annotation of the type indicated by + * {@code annotationClass} from the {@code Map} {@code + * annotationMap}. Looks into containers of the {@code + * annotationClass} (as specified by an the {@code + * annotationClass} type being meta-annotated with an {@code + * ContainedBy} annotation). + * + * @param annotationMap the {@code Map} used to store annotations indexed by their type + * @param annotationClass the type of annotation to search for + * + * @return an array of instances of {@code annotationClass} or an empty array if none were found + */ + public static A[] getMultipleAnnotations(final Map, Annotation> annotationMap, + final Class annotationClass) { + final ArrayList res = new ArrayList(); + + @SuppressWarnings("unchecked") + final A candidate = (A)annotationMap.get(annotationClass); + if (candidate != null) { + res.add(candidate); + } + + final Class containerClass = getContainer(annotationClass); + if (containerClass != null) { + res.addAll(unpackAll(annotationMap.get(containerClass), annotationClass)); + } + + @SuppressWarnings("unchecked") // should be safe annotationClass is a token for A + final A[] emptyTemplateArray = (A[])Array.newInstance(annotationClass, 0); + return res.isEmpty() ? emptyTemplateArray : res.toArray(emptyTemplateArray); + } + + /** + * Unpacks the {@code annotationMap} parameter into an array of + * {@code Annotation}s. This method will unpack all repeating + * annotaions containers (once). An annotation type is marked as a + * container by meta-annotating it the with the {@code + * ContainerFor} annotation. + * + * @param annotationMap the {@code Map} from where the annotations are unpacked + * + * @return an array of Annotation + */ + public static Annotation[] unpackToArray(Map, Annotation> annotationMap) { + List res = new ArrayList<>(); + for (Map.Entry, Annotation> e : annotationMap.entrySet()) { + Class annotationClass = e.getKey(); + Annotation annotationInstance = e.getValue(); + Class containee = getContainee(e.getKey()); + boolean isContainer = javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class) != null; + + if (isContainer) { + res.addAll(unpackAll(annotationInstance, containee)); + } else { + res.add(annotationInstance); + } + } + + return res.isEmpty() + ? AnnotationParser.getEmptyAnnotationArray() + : res.toArray(AnnotationParser.getEmptyAnnotationArray()); + } + + /** Helper to get the container, or null if none, of an annotation. */ + private static Class getContainer(Class annotationClass) { + ContainedBy containerAnnotation = + javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainedBy.class); + return (containerAnnotation == null) ? null : containerAnnotation.value(); + } + + /** Helper to get the containee, or null if this isn't a container, of a possible container annotation. */ + private static Class getContainee(Class annotationClass) { + ContainerFor containerAnnotation = + javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class); + return (containerAnnotation == null) ? null : containerAnnotation.value(); + } + + /** Reflectively look up and get the returned array from the the + * invocation of the value() element on an instance of an + * Annotation. + */ + private static A[] getValueArray(Annotation containerInstance) { + try { + // the spec tells us the container must have an array-valued + // value element. Get the AnnotationType, get the "value" element + // and invoke it to get the contents. + + Class containerClass = containerInstance.annotationType(); + AnnotationType annoType = javaLangAccess.getAnnotationType(containerClass); + if (annoType == null) + throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations"); + + Method m = annoType.members().get("value"); + if (m == null) + throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations"); + m.setAccessible(true); + + @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException + A[] a = (A[])m.invoke(containerInstance); // this will erase to (Annotation[]) but we + // do a runtime cast on the return-value + // in the methods that call this method + return a; + } catch (IllegalAccessException | // couldnt loosen security + IllegalArgumentException | // parameters doesn't match + InvocationTargetException | // the value method threw an exception + ClassCastException e) { // well, a cast failed ... + e.getCause().printStackTrace(); + throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations", + e, + containerInstance, + null); + } + } + + /* Sanity check type of and return the first annotation instance + * of type {@code annotationClass} from {@code + * containerInstance}. + */ + private static A unpackOne(Annotation containerInstance, Class annotationClass) { + if (containerInstance == null) { + return null; + } + + try { + return annotationClass.cast(getValueArray(containerInstance)[0]); + } catch (ArrayIndexOutOfBoundsException | // empty array + ClassCastException | // well, a cast failed ... + NullPointerException e) { // can this NP? for good meassure + throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s", + containerInstance, annotationClass), + e, + containerInstance, + annotationClass); + } + } + + /* Sanity check type of and return a list of all the annotation + * instances of type {@code annotationClass} from {@code + * containerInstance}. + */ + private static List unpackAll(Annotation containerInstance, Class annotationClass) { + if (containerInstance == null) { + return Collections.emptyList(); // container not present + } + + try { + A[] a = getValueArray(containerInstance); + ArrayList l = new ArrayList<>(a.length); + for (int i = 0; i < a.length; i++) + l.add(annotationClass.cast(a[i])); + return l; + } catch (ClassCastException | + NullPointerException e) { + throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s", + containerInstance, annotationClass), + e, + containerInstance, + annotationClass); + } + } +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java --- a/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Wed Nov 28 05:18:57 2012 -0800 +++ b/jdk/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java Wed Nov 28 09:21:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,6 +26,7 @@ package sun.reflect.generics.reflectiveObjects; import java.lang.annotation.Annotation; +import java.lang.reflect.Array; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; @@ -192,6 +193,25 @@ return null; } + public T getDeclaredAnnotation(Class annotationClass) { + Objects.requireNonNull(annotationClass); + return null; + } + + @SuppressWarnings("unchecked") + public T[] getAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + // safe because annotationClass is the class for T + return (T[])Array.newInstance(annotationClass, 0); + } + + @SuppressWarnings("unchecked") + public T[] getDeclaredAnnotations(Class annotationClass) { + Objects.requireNonNull(annotationClass); + // safe because annotationClass is the class for T + return (T[])Array.newInstance(annotationClass, 0); + } + public Annotation[] getAnnotations() { // Since zero-length, don't need defensive clone return EMPTY_ANNOTATION_ARRAY; diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7154390 + * @summary Unit test for repeated annotation reflection + * + * @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java + * @run main RepeatedUnitTest + */ + +import subpackage.*; + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; + +public class RepeatedUnitTest { + public static void main(String[] args) throws Exception { + // PACKAGE ANNOTATIONS + Class c = Class.forName("subpackage.NonRepeated"); // force package "subpackage" load + Package p = Package.getPackage("subpackage"); + packageNonRepeated(p); + packageRepeated(p); + packageContainer(p); + + // INHERITED/NON-INHERITED ON CLASS + inheritedMe1(); + inheritedMe2(); + inheritedMe3(); + inheritedMe4(); + + // CONSTRUCTOR + checkMultiplier(Me1.class.getConstructor(new Class[0]), 10); + + // FIELD + checkMultiplier(Me1.class.getField("foo"), 1); + + // METHOD + checkMultiplier(Me1.class.getDeclaredMethod("mee", null), 100); + + // INNER CLASS + checkMultiplier(Me1.MiniMee.class, 1000); + + // ENUM ELEMENT + checkMultiplier(Me1.E.class.getField("EE"), 10000); + + // ENUM + checkMultiplier(Me1.E.class, 100000); + } + + static void packageNonRepeated(AnnotatedElement e) { + NonRepeated nr = e.getAnnotation(NonRepeated.class); + check(nr.value() == 10); + + check(1 == countAnnotation(e, NonRepeated.class)); + + nr = e.getAnnotations(NonRepeated.class)[0]; + check(nr.value() == 10); + + check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class)); + } + + static void packageRepeated(AnnotatedElement e) { + Containee c = e.getAnnotation(Containee.class); + check(c.value() == 1); + + check(2 == countAnnotation(e, Containee.class)); + + c = e.getAnnotations(Containee.class)[0]; + check(c.value() == 1); + c = e.getAnnotations(Containee.class)[1]; + check(c.value() == 2); + + check(2 == containsAnnotationOfType(e.getAnnotations(), Containee.class)); + } + + static void packageContainer(AnnotatedElement e) { + Container cr = e.getAnnotation(Container.class); + check(null != cr); + check(1 == containsAnnotationOfType(e.getAnnotations(Container.class), Container.class)); + check(1 == countAnnotation(e, Container.class)); + } + + static void inheritedMe1() { + AnnotatedElement e = Me1.class; + check(null == e.getAnnotation(NonRepeated.class)); + check(e.getAnnotation(InheritedNonRepeated.class).value() == 20); + check(0 == countAnnotation(e, Containee.class)); + check(4 == countAnnotation(e, InheritedContainee.class)); + check(0 == countAnnotation(e, Container.class)); + check(1 == countAnnotation(e, InheritedContainer.class)); + } + + static void inheritedMe2() { + AnnotatedElement e = Me2.class; + check(e.getAnnotation(NonRepeated.class).value() == 100); + check(e.getAnnotation(InheritedNonRepeated.class).value() == 200); + check(4 == countAnnotation(e, Containee.class)); + check(4 == countAnnotation(e, InheritedContainee.class)); + check(1 == countAnnotation(e, Container.class)); + check(1 == countAnnotation(e, InheritedContainer.class)); + check(1 == countAnnotation(e, NonRepeated.class)); + check(1 == countAnnotation(e, InheritedNonRepeated.class)); + + check(e.getAnnotations(Containee.class)[2].value() == 300); + check(e.getAnnotations(InheritedContainee.class)[2].value() == 300); + check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 200); + check(e.getAnnotations(NonRepeated.class)[0].value() == 100); + } + + static void inheritedMe3() { + AnnotatedElement e = Me3.class; + check(null == e.getAnnotation(NonRepeated.class)); + + check(0 == countAnnotation(e, Containee.class)); + check(4 == countAnnotation(e, InheritedContainee.class)); + check(0 == countAnnotation(e, Container.class)); + check(1 == countAnnotation(e, InheritedContainer.class)); + + check(e.getAnnotations(InheritedContainee.class)[2].value() == 350); + check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 15); + } + + static void inheritedMe4() { + AnnotatedElement e = Me4.class; + check(e.getAnnotation(NonRepeated.class).value() == 1000); + check(e.getAnnotation(InheritedNonRepeated.class).value() == 2000); + check(4 == countAnnotation(e, Containee.class)); + check(4 == countAnnotation(e, InheritedContainee.class)); + check(1 == countAnnotation(e, Container.class)); + check(1 == countAnnotation(e, InheritedContainer.class)); + check(1 == countAnnotation(e, NonRepeated.class)); + check(1 == countAnnotation(e, InheritedNonRepeated.class)); + + check(e.getAnnotations(Containee.class)[2].value() == 3000); + check(e.getAnnotations(InheritedContainee.class)[2].value() == 3000); + check(e.getAnnotations(InheritedNonRepeated.class)[0].value() == 2000); + check(e.getAnnotations(NonRepeated.class)[0].value() == 1000); + } + + static void checkMultiplier(AnnotatedElement e, int m) { + check(e.getAnnotation(NonRepeated.class).value() == 5 * m); + + check(4 == countAnnotation(e, Containee.class)); + check(1 == countAnnotation(e, Container.class)); + check(1 == countAnnotation(e, NonRepeated.class)); + + check(e.getAnnotations(Containee.class)[2].value() == 3 * m); + check(e.getAnnotations(NonRepeated.class)[0].value() == 5 * m); + } + + static void check(Boolean b) { + if (!b) throw new RuntimeException(); + } + + static int countAnnotation(AnnotatedElement e, Class c) { + return containsAnnotationOfType(e.getAnnotations(c), c); + } + + static int containsAnnotationOfType(A[] l, Class a) { + int count = 0; + for (Annotation an : l) { + if (an.annotationType().equals(a)) + count++; + } + return count; + } +} + +@NonRepeated @InheritedNonRepeated +@InheritedContainee(1) @InheritedContainee(2) @InheritedContainee(3) @InheritedContainee(4) +@Containee(1) @Containee(2) @Containee(3) @Containee(4) +class Grandma {} + +class Mother extends Grandma {} + +@NonRepeated(5) @InheritedNonRepeated(15) +@InheritedContainee(150) @InheritedContainee(250) @InheritedContainee(350) @InheritedContainee(450) +@Containee(150) @Containee(250) @Containee(350) @Containee(450) +class Father extends Grandma {} + +class Me1 extends Mother { + + @NonRepeated(5) + @Containee(1) @Containee(2) @Containee(3) @Containee(4) + public String foo = ""; + + @NonRepeated(50) + @Containee(10) @Containee(20) @Containee(30) @Containee(40) + public Me1() { + } + + @NonRepeated(500) + @Containee(100) @Containee(200) @Containee(300) @Containee(400) + public void mee() { + } + + @NonRepeated(5000) + @Containee(1000) @Containee(2000) @Containee(3000) @Containee(4000) + public class MiniMee {} + + @NonRepeated(500000) + @Containee(100000) @Containee(200000) @Containee(300000) @Containee(400000) + public enum E { + @NonRepeated(50000) + @Containee(10000) @Containee(20000) @Containee(30000) @Containee(40000) + EE(), + } +} + +@NonRepeated(100) @InheritedNonRepeated(200) +@InheritedContainee(100) @InheritedContainee(200) @InheritedContainee(300) @InheritedContainee(400) +@Containee(100) @Containee(200) @Containee(300) @Containee(400) +class Me2 extends Mother {} + +class Me3 extends Father {} + +@NonRepeated(1000) @InheritedNonRepeated(2000) +@InheritedContainee(1000) @InheritedContainee(2000) @InheritedContainee(3000) @InheritedContainee(4000) +@Containee(1000) @Containee(2000) @Containee(3000) @Containee(4000) +class Me4 extends Father {} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package subpackage; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(Container.class) +public @interface Containee { + int value(); +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package subpackage; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@ContainerFor(Containee.class) +public @interface Container { + Containee[] value(); +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package subpackage; + +import java.lang.annotation.*; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@ContainedBy(InheritedContainer.class) +public @interface InheritedContainee { + int value(); +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package subpackage; + +import java.lang.annotation.*; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@ContainerFor(InheritedContainee.class) +public @interface InheritedContainer { + InheritedContainee[] value(); +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedNonRepeated.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedNonRepeated.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package subpackage; + +import java.lang.annotation.*; + +@Inherited +@Retention(RetentionPolicy.RUNTIME) +public @interface InheritedNonRepeated { + int value() default 20; +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/NonRepeated.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/NonRepeated.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package subpackage; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface NonRepeated { + int value() default 10; +} diff -r 17224d0282f1 -r 985410ec95e3 jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/annotation/repeatingAnnotations/subpackage/package-info.java Wed Nov 28 09:21:37 2012 -0800 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +@NonRepeated @Containee(1) @Containee(2) +package subpackage;