View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.annotation;
    9
    10  import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
    11
    12  import java.io.Serializable;
    13  import java.lang.reflect.Array;
    14
    15  /***
    16   * A structure for an Annotation element
    17   * It wraps value behind an holder. The holder is the object itself (boxed) excepted
    18   * for Class, for which it is a LazyClass.
    19   *
    20   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    21   */
    22  public class AnnotationElement implements Serializable {
    23
    24      //TODO calculate
    25      private static final long serialVersionUID = 1L;
    26
    27      /***
    28       * element name
    29       */
    30      String name;
    31
    32      /***
    33       * element value holder
    34       */
    35      private Object valueHolder;
    36
    37      /***
    38       * true if we have a lasy class (optimization to avoid instance of at each get)
    39       */
    40      protected boolean isLazyClass = false;
    41
    42      /***
    43       * true if we have a lasy class array (N-dim) (optimization to avoid instance of at each get)
    44       */
    45      protected boolean isLazyClassArray = false;
    46
    47      /***
    48       * Build a new annotation element
    49       * @param name
    50       * @param valueHolder
    51       */
    52      public AnnotationElement(String name, Object valueHolder) {
    53          this.name = name;
    54          this.valueHolder = valueHolder;
    55          if (valueHolder instanceof LazyClass) {
    56              isLazyClass = true;
    57          } else if (valueHolder instanceof LazyClass[]) {
    58              isLazyClassArray = true;
    59          }
    60      }
    61
    62      /***
    63       * Returns the actual holded element value
    64       *
    65       * @param loader from which to resolve LazyClass. It should be the annotated element class loader
    66       * @return
    67       */
    68      public Object resolveValueHolderFrom(ClassLoader loader) {
    69          if (isLazyClass) {
    70              return ((LazyClass) valueHolder).resolveFrom(loader);
    71          } else if (isLazyClassArray) {
    72              Object[] annotationValueHolderArray = (Object[]) valueHolder;
    73              Class[] resolved = new Class[annotationValueHolderArray.length];
    74              for (int i = 0; i < annotationValueHolderArray.length; i++) {
    75                  resolved[i] = ((LazyClass)annotationValueHolderArray[i]).resolveFrom(loader);
    76              }
    77              return resolved;
    78              //TODO support N dimension array needed ?
    79          } else {
    80              return valueHolder;
    81          }
    82      }
    83
    84      /***
    85       * Returns a string representation of the annotation element value
    86       *
    87       * Note that such a represention won't look like source code.
    88       * (f.e. element String s() will not have quotes and escapes etc).
    89       * @return
    90       */
    91      public String toString() {
    92          if (isLazyClass) {
    93              StringBuffer sb = new StringBuffer("class ");
    94              sb.append(((LazyClass) valueHolder).className);
    95              return sb.toString();
    96          } else {
    97              if (valueHolder == null) {
    98                  return "null";
    99              } else {
    100                 return valueHolder.toString();
    101             }
    102         }
    103     }
    104
    105     /***
    106      * A wrapper for a className, that will allow late loading of the actual Class object of an annotation value
    107      * For array type, className is componentClassName([])*
    108      *
    109      * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    110      */
    111     public static class LazyClass implements Serializable {
    112
    113         //TODO calculate
    114         private static final long serialVersionUID = 1L;
    115
    116         public String className;
    117         private String componentClassName = null;
    118         private int dimemsion = 0;
    119
    120         public LazyClass(String className) {
    121             this.className = className;
    122
    123             componentClassName = className;
    124             while (componentClassName.endsWith("[]")) {
    125                 dimemsion++;
    126                 componentClassName = componentClassName.substring(0, componentClassName.length()-2);
    127             }
    128         }
    129
    130         public String toString() {
    131             return className;
    132         }
    133
    134         public Class resolveFrom(ClassLoader loader) {
    135             try {
    136                 if (dimemsion <= 0) {
    137                     return Class.forName(className, false, loader);
    138                 } else {
    139                     Class componentClass = Class.forName(componentClassName, false, loader);
    140                     return (Array.newInstance(componentClass, dimemsion)).getClass();
    141                 }
    142             } catch (ClassNotFoundException e) {
    143                 throw new WrappedRuntimeException(e);
    144             }
    145         }
    146     }
    147
    148 }