langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/AnnoConstruct.java
changeset 28341 8f015bb3a75f
parent 26266 2d24bda701dc
child 34752 9c262a013456
equal deleted inserted replaced
28340:6869ff192a0e 28341:8f015bb3a75f
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 package com.sun.tools.javac.code;
    25 package com.sun.tools.javac.code;
    26 
    26 
    27 import java.lang.annotation.Annotation;
    27 import java.lang.annotation.Annotation;
    28 import java.lang.annotation.Inherited;
    28 import java.lang.annotation.Inherited;
       
    29 import java.lang.annotation.Repeatable;
    29 import java.lang.reflect.InvocationTargetException;
    30 import java.lang.reflect.InvocationTargetException;
    30 import java.lang.reflect.Method;
    31 import java.lang.reflect.Method;
    31 
    32 
    32 import javax.lang.model.AnnotatedConstruct;
    33 import javax.lang.model.AnnotatedConstruct;
    33 
    34 
   181 
   182 
   182         Attribute.Compound c = getAttribute(annoType);
   183         Attribute.Compound c = getAttribute(annoType);
   183         return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
   184         return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
   184     }
   185     }
   185 
   186 
   186     // Needed to unpack the runtime view of containing annotations
       
   187     private static final Class<? extends Annotation> REPEATABLE_CLASS = initRepeatable();
       
   188     private static final Method VALUE_ELEMENT_METHOD = initValueElementMethod();
       
   189 
       
   190     private static Class<? extends Annotation> initRepeatable() {
       
   191         try {
       
   192             // Repeatable will not be available when bootstrapping on
       
   193             // JDK 7 so use a reflective lookup instead of a class
       
   194             // literal for Repeatable.class.
       
   195             return Class.forName("java.lang.annotation.Repeatable").asSubclass(Annotation.class);
       
   196         } catch (ClassNotFoundException | SecurityException e) {
       
   197             return null;
       
   198         }
       
   199     }
       
   200 
       
   201     private static Method initValueElementMethod() {
       
   202         if (REPEATABLE_CLASS == null)
       
   203             return null;
       
   204 
       
   205         Method m = null;
       
   206         try {
       
   207             m = REPEATABLE_CLASS.getMethod("value");
       
   208             if (m != null)
       
   209                 m.setAccessible(true);
       
   210             return m;
       
   211         } catch (NoSuchMethodException e) {
       
   212             return null;
       
   213         }
       
   214     }
       
   215 
       
   216 
       
   217     // Helper to getAnnotationsByType
   187     // Helper to getAnnotationsByType
   218     private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
   188     private static Class<? extends Annotation> getContainer(Class<? extends Annotation> annoType) {
   219         // Since we can not refer to java.lang.annotation.Repeatable until we are
   189         Repeatable repeatable = annoType.getAnnotation(Repeatable.class);
   220         // bootstrapping with java 8 we need to get the Repeatable annotation using
   190         return (repeatable == null) ? null : repeatable.value();
   221         // reflective invocations instead of just using its type and element method.
   191     }
   222         if (REPEATABLE_CLASS != null &&
       
   223             VALUE_ELEMENT_METHOD != null) {
       
   224             // Get the Repeatable instance on the annotations declaration
       
   225             Annotation repeatable = (Annotation)annoType.getAnnotation(REPEATABLE_CLASS);
       
   226             if (repeatable != null) {
       
   227                 try {
       
   228                     // Get the value element, it should be a class
       
   229                     // indicating the containing annotation type
       
   230                     @SuppressWarnings("unchecked")
       
   231                     Class<? extends Annotation> containerType = (Class)VALUE_ELEMENT_METHOD.invoke(repeatable);
       
   232                     if (containerType == null)
       
   233                         return null;
       
   234 
       
   235                     return containerType;
       
   236                 } catch (ClassCastException | IllegalAccessException | InvocationTargetException e) {
       
   237                     return null;
       
   238                 }
       
   239             }
       
   240         }
       
   241         return null;
       
   242     }
       
   243 
       
   244 
   192 
   245     // Helper to getAnnotationsByType
   193     // Helper to getAnnotationsByType
   246     private static Attribute[] unpackAttributes(Attribute.Compound container) {
   194     private static Attribute[] unpackAttributes(Attribute.Compound container) {
   247         // We now have an instance of the container,
   195         // We now have an instance of the container,
   248         // unpack it returning an instance of the
   196         // unpack it returning an instance of the