001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.reflect.impl.asm;
008:
009: import org.codehaus.aspectwerkz.reflect.ClassInfo;
010: import org.codehaus.aspectwerkz.reflect.FieldInfo;
011: import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
012: import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper;
013: import org.codehaus.aspectwerkz.proxy.ProxyCompiler;
014:
015: import org.objectweb.asm.Type;
016: import org.objectweb.asm.ClassReader;
017: import org.objectweb.asm.attrs.Attributes;
018:
019: import java.util.List;
020: import java.util.ArrayList;
021: import java.io.IOException;
022: import java.io.InputStream;
023:
024: /**
025: * ASM implementation of the FieldInfo interface.
026: *
027: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
028: */
029: public class AsmFieldInfo extends AsmMemberInfo implements FieldInfo {
030:
031: /**
032: * The field type name.
033: */
034: private String m_typeName;
035:
036: /**
037: * The field type.
038: */
039: private ClassInfo m_type = null;
040:
041: /**
042: * Creates a new field java instance.
043: *
044: * @param field
045: * @param declaringType
046: * @param loader
047: */
048: AsmFieldInfo(final FieldStruct field, final String declaringType,
049: final ClassLoader loader) {
050: super (field, declaringType, loader);
051: m_typeName = Type.getType(field.desc).getClassName();
052: }
053:
054: /**
055: * Returns the field info for the field specified.
056: *
057: * @param fieldName
058: * @param fieldDesc
059: * @param bytecode
060: * @param loader
061: * @return the field info
062: */
063: public static FieldInfo getFieldInfo(final String fieldName,
064: final String fieldDesc, final byte[] bytecode,
065: final ClassLoader loader) {
066: String className = AsmClassInfo
067: .retrieveClassNameFromBytecode(bytecode);
068: AsmClassInfoRepository repository = AsmClassInfoRepository
069: .getRepository(loader);
070: ClassInfo classInfo = repository.getClassInfo(className);
071: if (classInfo == null) {
072: classInfo = AsmClassInfo.getClassInfo(bytecode, loader);
073: }
074: return classInfo.getField(AsmHelper.calculateFieldHash(
075: fieldName, fieldDesc));
076: }
077:
078: /**
079: * Returns the signature for the element.
080: *
081: * @return the signature for the element
082: */
083: public String getSignature() {
084: return AsmHelper.getFieldDescriptor(this );
085: }
086:
087: /**
088: * Returns the type.
089: *
090: * @return the type
091: */
092: public ClassInfo getType() {
093: if (m_type == null) {
094: m_type = AsmClassInfo.getClassInfo(m_typeName,
095: (ClassLoader) m_loaderRef.get());
096: }
097: return m_type;
098: }
099:
100: /**
101: * Returns the annotations.
102: *
103: * @return the annotations
104: */
105: public List getAnnotations() {
106: if (m_annotations == null) {
107: try {
108: InputStream in = null;
109: ClassReader cr = null;
110: try {
111: if ((ClassLoader) m_loaderRef.get() != null) {
112: in = ((ClassLoader) m_loaderRef.get())
113: .getResourceAsStream(m_declaringTypeName
114: .replace('.', '/')
115: + ".class");
116: } else {
117: in = ClassLoader.getSystemClassLoader()
118: .getResourceAsStream(
119: m_declaringTypeName.replace(
120: '.', '/')
121: + ".class");
122: }
123: if (in == null) {
124: in = ProxyCompiler.getProxyResourceAsStream(
125: (ClassLoader) m_loaderRef.get(),
126: m_declaringTypeName);
127: }
128: cr = new ClassReader(in);
129: } finally {
130: try {
131: in.close();
132: } catch (Exception e) {
133: ;
134: }
135: }
136: List annotations = new ArrayList();
137: cr
138: .accept(
139: new AsmAnnotationHelper.FieldAnnotationExtractor(
140: annotations, m_member.name,
141: (ClassLoader) m_loaderRef.get()),
142: Attributes.getDefaultAttributes(), true);
143: m_annotations = annotations;
144: } catch (IOException e) {
145: // unlikely to occur since ClassInfo relies on getResourceAsStream
146: System.err.println("WARN - could not load "
147: + m_declaringTypeName
148: + " 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 FieldInfo)) {
160: return false;
161: }
162: FieldInfo fieldInfo = (FieldInfo) o;
163: if (!m_declaringTypeName.equals(fieldInfo.getDeclaringType()
164: .getName())) {
165: return false;
166: }
167: if (!m_member.name.equals(fieldInfo.getName())) {
168: return false;
169: }
170: if (!m_typeName.equals(fieldInfo.getType().getName())) {
171: return false;
172: }
173: return true;
174: }
175:
176: public int hashCode() {
177: int result = 29;
178: result = (29 * result) + m_declaringTypeName.hashCode();
179: result = (29 * result) + m_member.name.hashCode();
180: result = (29 * result) + m_typeName.hashCode();
181: return result;
182: }
183:
184: public String toString() {
185: StringBuffer sb = new StringBuffer(m_declaringTypeName);
186: sb.append('.').append(m_member.name).append(' ');
187: sb.append(m_member.desc);
188: return sb.toString();
189: }
190: }
|