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.reflect.impl.asm;
    9
    10  import org.codehaus.aspectwerkz.reflect.ClassInfo;
    11  import org.codehaus.aspectwerkz.reflect.FieldInfo;
    12  import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
    13  import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper;
    14  import org.codehaus.aspectwerkz.proxy.ProxyCompiler;
    15
    16  import org.objectweb.asm.Type;
    17  import org.objectweb.asm.ClassReader;
    18  import org.objectweb.asm.attrs.Attributes;
    19
    20  import java.util.List;
    21  import java.util.ArrayList;
    22  import java.io.IOException;
    23  import java.io.InputStream;
    24
    25  /***
    26   * ASM implementation of the FieldInfo interface.
    27   *
    28   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    29   */
    30  public class AsmFieldInfo extends AsmMemberInfo implements FieldInfo {
    31
    32      /***
    33       * The field type name.
    34       */
    35      private String m_typeName;
    36
    37      /***
    38       * The field type.
    39       */
    40      private ClassInfo m_type = null;
    41
    42      /***
    43       * Creates a new field java instance.
    44       *
    45       * @param field
    46       * @param declaringType
    47       * @param loader
    48       */
    49      AsmFieldInfo(final FieldStruct field, final String declaringType, final ClassLoader loader) {
    50          super(field, declaringType, loader);
    51          m_typeName = Type.getType(field.desc).getClassName();
    52      }
    53
    54      /***
    55       * Returns the field info for the field specified.
    56       *
    57       * @param fieldName
    58       * @param fieldDesc
    59       * @param bytecode
    60       * @param loader
    61       * @return the field info
    62       */
    63      public static FieldInfo getFieldInfo(final String fieldName,
    64                                           final String fieldDesc,
    65                                           final byte[] bytecode,
    66                                           final ClassLoader loader) {
    67          String className = AsmClassInfo.retrieveClassNameFromBytecode(bytecode);
    68          AsmClassInfoRepository repository = AsmClassInfoRepository.getRepository(loader);
    69          ClassInfo classInfo = repository.getClassInfo(className);
    70          if (classInfo == null) {
    71              classInfo = AsmClassInfo.getClassInfo(bytecode, loader);
    72          }
    73          return classInfo.getField(AsmHelper.calculateFieldHash(fieldName, fieldDesc));
    74      }
    75
    76      /***
    77       * Returns the signature for the element.
    78       *
    79       * @return the signature for the element
    80       */
    81      public String getSignature() {
    82          return AsmHelper.getFieldDescriptor(this);
    83      }
    84
    85      /***
    86       * Returns the type.
    87       *
    88       * @return the type
    89       */
    90      public ClassInfo getType() {
    91          if (m_type == null) {
    92              m_type = AsmClassInfo.getClassInfo(m_typeName, (ClassLoader) m_loaderRef.get());
    93          }
    94          return m_type;
    95      }
    96
    97      /***
    98       * Returns the annotations.
    99       *
    100      * @return the annotations
    101      */
    102     public List getAnnotations() {
    103         if (m_annotations == null) {
    104             try {
    105                 InputStream in = null;
    106                 ClassReader cr = null;
    107                 try {
    108                     if ((ClassLoader) m_loaderRef.get() != null) {
    109                         in = ((ClassLoader) m_loaderRef.get()).getResourceAsStream(
    110                                 m_declaringTypeName.replace('.', '/') + ".class"
    111                         );
    112                     } else {
    113                         in = ClassLoader.getSystemClassLoader().getResourceAsStream(
    114                                 m_declaringTypeName.replace('.', '/') + ".class"
    115                         );
    116                     }
    117                     if (in == null) {
    118                         in = ProxyCompiler.getProxyResourceAsStream((ClassLoader) m_loaderRef.get(), m_declaringTypeName);
    119                     }
    120                     cr = new ClassReader(in);
    121                 } finally {
    122                     try {
    123                         in.close();
    124                     } catch (Exception e) {
    125                         ;
    126                     }
    127                 }
    128                 List annotations = new ArrayList();
    129                 cr.accept(
    130                         new AsmAnnotationHelper.FieldAnnotationExtractor(
    131                                 annotations, m_member.name, (ClassLoader) m_loaderRef.get()
    132                         ),
    133                         Attributes.getDefaultAttributes(),
    134                         true
    135                 );
    136                 m_annotations = annotations;
    137             } catch (IOException e) {
    138                 // unlikely to occur since ClassInfo relies on getResourceAsStream
    139                 System.err.println(
    140                         "WARN - could not load " + m_declaringTypeName + " as a resource to retrieve annotations"
    141                 );
    142                 m_annotations = AsmClassInfo.EMPTY_LIST;
    143             }
    144         }
    145         return m_annotations;
    146     }
    147
    148     public boolean equals(Object o) {
    149         if (this == o) {
    150             return true;
    151         }
    152         if (!(o instanceof FieldInfo)) {
    153             return false;
    154         }
    155         FieldInfo fieldInfo = (FieldInfo) o;
    156         if (!m_declaringTypeName.equals(fieldInfo.getDeclaringType().getName())) {
    157             return false;
    158         }
    159         if (!m_member.name.equals(fieldInfo.getName())) {
    160             return false;
    161         }
    162         if (!m_typeName.equals(fieldInfo.getType().getName())) {
    163             return false;
    164         }
    165         return true;
    166     }
    167
    168     public int hashCode() {
    169         int result = 29;
    170         result = (29 * result) + m_declaringTypeName.hashCode();
    171         result = (29 * result) + m_member.name.hashCode();
    172         result = (29 * result) + m_typeName.hashCode();
    173         return result;
    174     }
    175
    176     public String toString() {
    177         StringBuffer sb = new StringBuffer(m_declaringTypeName);
    178         sb.append('.').append(m_member.name).append(' ');
    179         sb.append(m_member.desc);
    180         return sb.toString();
    181     }
    182 }