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.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              // swallow, since ok
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             // swallow, since ok
150         }
151     }
152 }