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