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.javassist;
9   
10  import org.codehaus.aspectwerkz.annotation.AnnotationInfo;
11  import org.codehaus.aspectwerkz.annotation.instrumentation.AttributeExtractor;
12  import org.codehaus.aspectwerkz.reflect.ClassInfo;
13  import org.codehaus.aspectwerkz.reflect.FieldInfo;
14  
15  import java.util.List;
16  
17  import javassist.CtClass;
18  import javassist.CtField;
19  import javassist.NotFoundException;
20  
21  /***
22   * Implementation of the FieldInfo interface for Javassist.
23   * 
24   * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
25   */
26  public class JavassistFieldInfo extends JavassistMemberInfo implements FieldInfo {
27      /***
28       * The field type.
29       */
30      private ClassInfo m_type = null;
31  
32      /***
33       * Creates a new field java instance.
34       * 
35       * @param field
36       * @param declaringType
37       * @param loader
38       * @param attributeExtractor
39       */
40      JavassistFieldInfo(final CtField field,
41                         final JavassistClassInfo declaringType,
42                         final ClassLoader loader,
43                         final AttributeExtractor attributeExtractor) {
44          super(field, declaringType, loader, attributeExtractor);
45          addAnnotations();
46      }
47  
48      /***
49       * Returns the field info for the field specified.
50       * 
51       * @param field the field
52       * @param loader the class loader
53       * @return the field info
54       */
55      public static FieldInfo getFieldInfo(final CtField field, final ClassLoader loader) {
56          CtClass declaringClass = field.getDeclaringClass();
57          JavassistClassInfoRepository repository = JavassistClassInfoRepository.getRepository(loader);
58          ClassInfo classInfo = repository.getClassInfo(declaringClass.getName());
59          if (classInfo == null) {
60              classInfo = JavassistClassInfo.getClassInfo(declaringClass, loader);
61          }
62          return classInfo.getField(calculateHash(field));
63      }
64  
65      /***
66       * Calculates the field hash.
67       * 
68       * @param field
69       * @return the hash
70       */
71      public static int calculateHash(final CtField field) {
72          return field.getName().hashCode();
73      }
74  
75      /***
76       * Returns the attributes.
77       * 
78       * @return the attributes
79       */
80      public List getAnnotations() {
81          return m_annotations;
82      }
83  
84      /***
85       * Returns the field type.
86       * 
87       * @return the field type
88       */
89      public ClassInfo getType() {
90          if (m_type == null) {
91              try {
92                  CtClass type = ((CtField) m_member).getType();
93                  if (m_classInfoRepository.hasClassInfo(type.getName())) {
94                      m_type = m_classInfoRepository.getClassInfo(type.getName());
95                  } else {
96                      m_type = JavassistClassInfo.getClassInfo(type, (ClassLoader) m_loaderRef.get());
97                      m_classInfoRepository.addClassInfo(m_type);
98                  }
99              } catch (NotFoundException e) {
100                 // swallow, since ok
101             }
102         }
103         return m_type;
104     }
105 
106     public boolean equals(Object o) {
107         if (this == o) {
108             return true;
109         }
110         if (!(o instanceof FieldInfo)) {
111             return false;
112         }
113         FieldInfo fieldInfo = (FieldInfo) o;
114         if (!m_declaringType.getName().toString().equals(fieldInfo.getDeclaringType().getName().toString())) {
115             return false;
116         }
117         if (!m_member.getName().equals(fieldInfo.getName())) {
118             return false;
119         }
120         ClassInfo fieldType = fieldInfo.getType();
121         if (!m_type.getName().toString().equals(fieldType.getName().toString())) {
122             return false;
123         }
124         return true;
125     }
126 
127     public int hashCode() {
128         int result = 29;
129         if (m_type == null) {
130             getType();
131         }
132         result = (29 * result) + m_declaringType.getName().toString().hashCode();
133         result = (29 * result) + m_member.getName().toString().hashCode();
134         result = (29 * result) + m_type.getName().toString().hashCode();
135         return result;
136     }
137 
138     /***
139      * Adds annotations to the field info.
140      */
141     private void addAnnotations() {
142         if (m_attributeExtractor == null) {
143             return;
144         }
145         Object[] attributes = m_attributeExtractor.getFieldAttributes(m_member.getName());
146         for (int i = 0; i < attributes.length; i++) {
147             Object attribute = attributes[i];
148             if (attribute instanceof AnnotationInfo) {
149                 m_annotations.add(attribute);
150             }
151         }
152     }
153 }