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
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 }