001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.aspectwerkz.reflect.impl.asm;
005:
006: import com.tc.backport175.bytecode.AnnotationElement;
007: import com.tc.asm.Type;
008:
009: import com.tc.aspectwerkz.transform.inlining.AsmHelper;
010: import com.tc.aspectwerkz.reflect.ClassInfo;
011: import com.tc.aspectwerkz.reflect.ConstructorInfo;
012:
013: /**
014: * ASM implementation of the ConstructorInfo interface.
015: *
016: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
017: */
018: public class AsmConstructorInfo extends AsmMemberInfo implements
019: ConstructorInfo {
020:
021: /**
022: * A list with the parameter type names.
023: */
024: private String[] m_parameterTypeNames = null;
025:
026: /**
027: * A list with the exception type names.
028: */
029: private String[] m_exceptionTypeNames = null;
030:
031: /**
032: * A list with the parameter types.
033: */
034: private ClassInfo[] m_parameterTypes = null;
035:
036: /**
037: * A list with the exception types.
038: */
039: private ClassInfo[] m_exceptionTypes = null;
040:
041: /**
042: * Creates a new method meta data instance.
043: *
044: * @param method
045: * @param declaringType
046: * @param loader
047: */
048: AsmConstructorInfo(final MethodStruct method,
049: final String declaringType, final ClassLoader loader) {
050: super (method, declaringType, loader);
051: Type[] argTypes = Type.getArgumentTypes(method.desc);
052: m_parameterTypeNames = new String[argTypes.length];
053: for (int i = 0; i < argTypes.length; i++) {
054: m_parameterTypeNames[i] = argTypes[i].getClassName();
055: }
056: // TODO how to do exceptions?
057: m_exceptionTypeNames = new String[] {};
058: }
059:
060: /**
061: * Returns the constructor info for the constructor specified.
062: *
063: * @param constructorDesc
064: * @param bytecode
065: * @param loader
066: * @return the constructor info
067: */
068: public static ConstructorInfo getConstructorInfo(
069: final String constructorDesc, final byte[] bytecode,
070: final ClassLoader loader) {
071: String className = AsmClassInfo
072: .retrieveClassNameFromBytecode(bytecode);
073: AsmClassInfoRepository repository = AsmClassInfoRepository
074: .getRepository(loader);
075: ClassInfo classInfo = repository.getClassInfo(className);
076: if (classInfo == null) {
077: classInfo = AsmClassInfo.getClassInfo(bytecode, loader);
078: }
079: return classInfo.getConstructor(AsmHelper
080: .calculateConstructorHash(constructorDesc));
081: }
082:
083: /**
084: * Returns the signature for the element.
085: *
086: * @return the signature for the element
087: */
088: public String getSignature() {
089: return AsmHelper.getConstructorDescriptor(this );
090: }
091:
092: public String getGenericsSignature() {
093: return m_member.signature;
094: }
095:
096: /**
097: * Returns the parameter types.
098: *
099: * @return the parameter types
100: */
101: public synchronized ClassInfo[] getParameterTypes() {
102: if (m_parameterTypes == null) {
103: m_parameterTypes = new ClassInfo[m_parameterTypeNames.length];
104: for (int i = 0; i < m_parameterTypeNames.length; i++) {
105: m_parameterTypes[i] = AsmClassInfo.getClassInfo(
106: m_parameterTypeNames[i],
107: (ClassLoader) m_loaderRef.get());
108: }
109: }
110: return m_parameterTypes;
111: }
112:
113: /**
114: * Returns the exception types.
115: *
116: * @return the exception types
117: */
118: public synchronized ClassInfo[] getExceptionTypes() {
119: if (m_exceptionTypes == null) {
120: m_exceptionTypes = new ClassInfo[m_exceptionTypeNames.length];
121: for (int i = 0; i < m_exceptionTypeNames.length; i++) {
122: m_exceptionTypes[i] = AsmClassInfo.getClassInfo(
123: m_exceptionTypeNames[i],
124: (ClassLoader) m_loaderRef.get());
125: }
126: }
127: return m_exceptionTypes;
128: }
129:
130: /**
131: * Returns the annotations.
132: *
133: * @return the annotations
134: */
135: public AnnotationElement.Annotation[] getAnnotations() {
136: return getDeclaringType().getAnnotationReader()
137: .getConstructorAnnotationElements(m_member.desc);
138: }
139:
140: public boolean equals(Object o) {
141: if (this == o) {
142: return true;
143: }
144: if (!(o instanceof ConstructorInfo)) {
145: return false;
146: }
147: ConstructorInfo constructorInfo = (ConstructorInfo) o;
148: if (!m_declaringTypeName.equals(constructorInfo
149: .getDeclaringType().getName())) {
150: return false;
151: }
152: if (!m_member.name.equals(constructorInfo.getName())) {
153: return false;
154: }
155: ClassInfo[] parameterTypes = constructorInfo
156: .getParameterTypes();
157: if (m_parameterTypeNames.length != parameterTypes.length) {//check on names length for lazyness optim
158: return false;
159: }
160: for (int i = 0; i < m_parameterTypeNames.length; i++) {
161: if (!m_parameterTypeNames[i].equals(parameterTypes[i]
162: .getName())) {
163: return false;
164: }
165: }
166: return true;
167: }
168:
169: public int hashCode() {
170: int result = 29;
171: result = (29 * result) + m_declaringTypeName.hashCode();
172: result = (29 * result) + m_member.name.hashCode();
173: for (int i = 0; i < m_parameterTypeNames.length; i++) {
174: result = (29 * result) + m_parameterTypeNames[i].hashCode();
175: }
176: return result;
177: }
178:
179: public String toString() {
180: StringBuffer sb = new StringBuffer(m_declaringTypeName);
181: sb.append('.').append(m_member.name);
182: sb.append(m_member.desc);
183: return sb.toString();
184: }
185: }
|