Home » openjdk-7 » sun » reflect » annotation » [javadoc | source]

    1   /*
    2    * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    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
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.reflect.annotation;
   27   
   28   import java.lang.annotation;
   29   import java.lang.reflect;
   30   import java.util;
   31   import java.security.AccessController;
   32   import java.security.PrivilegedAction;
   33   
   34   /**
   35    * Represents an annotation type at run time.  Used to type-check annotations
   36    * and apply member defaults.
   37    *
   38    * @author  Josh Bloch
   39    * @since   1.5
   40    */
   41   public class AnnotationType {
   42       /**
   43        * Member name -> type mapping. Note that primitive types
   44        * are represented by the class objects for the corresponding wrapper
   45        * types.  This matches the return value that must be used for a
   46        * dynamic proxy, allowing for a simple isInstance test.
   47        */
   48       private final Map<String, Class<?>> memberTypes = new HashMap<String,Class<?>>();
   49   
   50       /**
   51        * Member name -> default value mapping.
   52        */
   53       private final Map<String, Object> memberDefaults =
   54           new HashMap<String, Object>();
   55   
   56       /**
   57        * Member name -> Method object mapping. This (and its assoicated
   58        * accessor) are used only to generate AnnotationTypeMismatchExceptions.
   59        */
   60       private final Map<String, Method> members = new HashMap<String, Method>();
   61   
   62       /**
   63        * The retention policy for this annotation type.
   64        */
   65       private RetentionPolicy retention = RetentionPolicy.RUNTIME;;
   66   
   67       /**
   68        * Whether this annotation type is inherited.
   69        */
   70       private boolean inherited = false;
   71   
   72       /**
   73        * Returns an AnnotationType instance for the specified annotation type.
   74        *
   75        * @throw IllegalArgumentException if the specified class object for
   76        *     does not represent a valid annotation type
   77        */
   78       public static synchronized AnnotationType getInstance(
   79           Class<? extends Annotation> annotationClass)
   80       {
   81           AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess().
   82               getAnnotationType(annotationClass);
   83           if (result == null)
   84               result = new AnnotationType((Class<? extends Annotation>) annotationClass);
   85   
   86           return result;
   87       }
   88   
   89       /**
   90        * Sole constructor.
   91        *
   92        * @param annotationClass the class object for the annotation type
   93        * @throw IllegalArgumentException if the specified class object for
   94        *     does not represent a valid annotation type
   95        */
   96       private AnnotationType(final Class<? extends Annotation> annotationClass) {
   97           if (!annotationClass.isAnnotation())
   98               throw new IllegalArgumentException("Not an annotation type");
   99   
  100           Method[] methods =
  101               AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
  102                   public Method[] run() {
  103                       // Initialize memberTypes and defaultValues
  104                       return annotationClass.getDeclaredMethods();
  105                   }
  106               });
  107   
  108   
  109           for (Method method :  methods) {
  110               if (method.getParameterTypes().length != 0)
  111                   throw new IllegalArgumentException(method + " has params");
  112               String name = method.getName();
  113               Class<?> type = method.getReturnType();
  114               memberTypes.put(name, invocationHandlerReturnType(type));
  115               members.put(name, method);
  116   
  117               Object defaultValue = method.getDefaultValue();
  118               if (defaultValue != null)
  119                   memberDefaults.put(name, defaultValue);
  120   
  121               members.put(name, method);
  122           }
  123   
  124           sun.misc.SharedSecrets.getJavaLangAccess().
  125               setAnnotationType(annotationClass, this);
  126   
  127           // Initialize retention, & inherited fields.  Special treatment
  128           // of the corresponding annotation types breaks infinite recursion.
  129           if (annotationClass != Retention.class &&
  130               annotationClass != Inherited.class) {
  131               Retention ret = annotationClass.getAnnotation(Retention.class);
  132               retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
  133               inherited = annotationClass.isAnnotationPresent(Inherited.class);
  134           }
  135       }
  136   
  137       /**
  138        * Returns the type that must be returned by the invocation handler
  139        * of a dynamic proxy in order to have the dynamic proxy return
  140        * the specified type (which is assumed to be a legal member type
  141        * for an annotation).
  142        */
  143       public static Class<?> invocationHandlerReturnType(Class<?> type) {
  144           // Translate primitives to wrappers
  145           if (type == byte.class)
  146               return Byte.class;
  147           if (type == char.class)
  148               return Character.class;
  149           if (type == double.class)
  150               return Double.class;
  151           if (type == float.class)
  152               return Float.class;
  153           if (type == int.class)
  154               return Integer.class;
  155           if (type == long.class)
  156               return Long.class;
  157           if (type == short.class)
  158               return Short.class;
  159           if (type == boolean.class)
  160               return Boolean.class;
  161   
  162           // Otherwise, just return declared type
  163           return type;
  164       }
  165   
  166       /**
  167        * Returns member types for this annotation type
  168        * (member name -> type mapping).
  169        */
  170       public Map<String, Class<?>> memberTypes() {
  171           return memberTypes;
  172       }
  173   
  174       /**
  175        * Returns members of this annotation type
  176        * (member name -> associated Method object mapping).
  177        */
  178       public Map<String, Method> members() {
  179           return members;
  180       }
  181   
  182       /**
  183        * Returns the default values for this annotation type
  184        * (Member name -> default value mapping).
  185        */
  186       public Map<String, Object> memberDefaults() {
  187           return memberDefaults;
  188       }
  189   
  190       /**
  191        * Returns the retention policy for this annotation type.
  192        */
  193       public RetentionPolicy retention() {
  194           return retention;
  195       }
  196   
  197       /**
  198        * Returns true if this this annotation type is inherited.
  199        */
  200       public boolean isInherited() {
  201           return inherited;
  202       }
  203   
  204       /**
  205        * For debugging.
  206        */
  207       public String toString() {
  208           StringBuffer s = new StringBuffer("Annotation Type:" + "\n");
  209           s.append("   Member types: " + memberTypes + "\n");
  210           s.append("   Member defaults: " + memberDefaults + "\n");
  211           s.append("   Retention policy: " + retention + "\n");
  212           s.append("   Inherited: " + inherited);
  213           return s.toString();
  214       }
  215   }

Home » openjdk-7 » sun » reflect » annotation » [javadoc | source]