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.ConstructorInfo;
12 import org.codehaus.aspectwerkz.reflect.MethodInfo;
13 import org.codehaus.aspectwerkz.transform.AsmHelper;
14 import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper;
15 import org.codehaus.aspectwerkz.ContextClassLoader;
16 import org.objectweb.asm.Type;
17 import org.objectweb.asm.ClassReader;
18
19 import java.util.List;
20 import java.util.ArrayList;
21 import java.io.IOException;
22
23 /***
24 * ASM implementation of the ConstructorInfo interface.
25 *
26 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
27 */
28 public class AsmConstructorInfo extends AsmMemberInfo implements ConstructorInfo {
29
30 /***
31 * A list with the parameter type names.
32 */
33 private String[] m_parameterTypeNames = null;
34
35 /***
36 * A list with the exception type names.
37 */
38 private String[] m_exceptionTypeNames = null;
39
40 /***
41 * A list with the parameter types.
42 */
43 private ClassInfo[] m_parameterTypes = null;
44
45 /***
46 * A list with the exception types.
47 */
48 private ClassInfo[] m_exceptionTypes = null;
49
50 /***
51 * Creates a new method meta data instance.
52 *
53 * @param method
54 * @param declaringType
55 * @param loader
56 */
57 AsmConstructorInfo(final MethodStruct method, final String declaringType, final ClassLoader loader) {
58 super(method, declaringType, loader);
59 Type[] argTypes = Type.getArgumentTypes(method.desc);
60 m_parameterTypeNames = new String[argTypes.length];
61 for (int i = 0; i < argTypes.length; i++) {
62 m_parameterTypeNames[i] = argTypes[i].getClassName();
63 }
64
65 m_exceptionTypeNames = new String[] {};
66 }
67
68 /***
69 * Returns the constructor info for the constructor specified.
70 *
71 * @param constructorDesc
72 * @param bytecode
73 * @param loader
74 * @return the constructor info
75 */
76 public static MethodInfo getConstructorInfo(
77 final String constructorDesc,
78 final byte[] bytecode,
79 final ClassLoader loader) {
80 String className = AsmClassInfo.retrieveClassNameFromBytecode(bytecode);
81 AsmClassInfoRepository repository = AsmClassInfoRepository.getRepository(loader);
82 ClassInfo classInfo = repository.getClassInfo(className);
83 if (classInfo == null) {
84 classInfo = AsmClassInfo.getClassInfo(bytecode, loader);
85 }
86 return classInfo.getMethod(AsmHelper.calculateConstructorHash(constructorDesc));
87 }
88
89 /***
90 * Returns the parameter types.
91 *
92 * @return the parameter types
93 */
94 public ClassInfo[] getParameterTypes() {
95 if (m_parameterTypes == null) {
96 m_parameterTypes = new ClassInfo[m_parameterTypeNames.length];
97 for (int i = 0; i < m_parameterTypeNames.length; i++) {
98 m_parameterTypes[i] = AsmClassInfo.getClassInfo(
99 m_parameterTypeNames[i],
100 (ClassLoader) m_loaderRef.get()
101 );
102 }
103 }
104 return m_parameterTypes;
105 }
106
107 /***
108 * Returns the exception types.
109 *
110 * @return the exception types
111 */
112 public ClassInfo[] getExceptionTypes() {
113 if (m_exceptionTypes == null) {
114 m_exceptionTypes = new ClassInfo[m_exceptionTypeNames.length];
115 for (int i = 0; i < m_exceptionTypeNames.length; i++) {
116 m_exceptionTypes[i] = AsmClassInfo.getClassInfo(
117 m_exceptionTypeNames[i],
118 (ClassLoader) m_loaderRef.get()
119 );
120 }
121 }
122 return m_exceptionTypes;
123 }
124
125 /***
126 * Returns the annotations.
127 *
128 * @return the annotations
129 */
130 public List getAnnotations() {
131 if (m_annotations == null) {
132 try {
133 ClassReader cr = new ClassReader(
134 ContextClassLoader.getResourceAsStream(
135 m_declaringTypeName.replace('.','/')+".class",
136 (ClassLoader)m_loaderRef.get()
137 )
138 );
139 List annotations = new ArrayList();
140 cr.accept(
141 new AsmAnnotationHelper.ConstructorAnnotationExtractor(annotations, m_member.desc, (ClassLoader)m_loaderRef.get()),
142 AsmAnnotationHelper.ANNOTATIONS_ATTRIBUTES,
143 true
144 );
145 m_annotations = annotations;
146 } catch (IOException e) {
147
148 System.err.println("WARN - could not load " + m_declaringTypeName + " as a resource to retrieve annotations");
149 m_annotations = AsmClassInfo.EMPTY_LIST;
150 }
151 }
152 return m_annotations;
153 }
154
155 public boolean equals(Object o) {
156 if (this == o) {
157 return true;
158 }
159 if (!(o instanceof ConstructorInfo)) {
160 return false;
161 }
162 ConstructorInfo constructorInfo = (ConstructorInfo) o;
163 if (!m_declaringTypeName.equals(constructorInfo.getDeclaringType().getName())) {
164 return false;
165 }
166 if (!m_member.name.equals(constructorInfo.getName())) {
167 return false;
168 }
169 ClassInfo[] parameterTypes = constructorInfo.getParameterTypes();
170 if (m_parameterTypeNames.length != parameterTypes.length) {
171 return false;
172 }
173 for (int i = 0; i < m_parameterTypeNames.length; i++) {
174 if (!m_parameterTypeNames[i].equals(parameterTypes[i].getName())) {
175 return false;
176 }
177 }
178 return true;
179 }
180
181 public int hashCode() {
182 int result = 29;
183 result = (29 * result) + m_declaringTypeName.hashCode();
184 result = (29 * result) + m_member.name.hashCode();
185 for (int i = 0; i < m_parameterTypeNames.length; i++) {
186 result = (29 * result) + m_parameterTypeNames[i].hashCode();
187 }
188 return result;
189 }
190
191 public String toString() {
192 StringBuffer sb = new StringBuffer(m_declaringTypeName);
193 sb.append('.').append(m_member.name);
194 sb.append(m_member.desc);
195 return sb.toString();
196 }
197 }