1 32 package net.sf.retrotranslator.runtime.impl; 33 34 import java.io.*; 35 import java.lang.annotation.Inherited ; 36 import java.lang.ref.SoftReference ; 37 import java.lang.reflect.*; 38 import java.lang.reflect.Type ; 39 import java.util.*; 40 import net.sf.retrotranslator.runtime.asm.*; 41 import net.sf.retrotranslator.runtime.asm.signature.*; 42 import net.sf.retrotranslator.runtime.java.lang.annotation.Annotation_; 43 44 47 public class ClassDescriptor extends GenericDeclarationDescriptor { 48 49 public static final String SIGNATURES_NAME = "signatures.properties"; 50 51 private static SoftReference <Map<Class , ClassDescriptor>> cache; 52 private static Properties signatures = getSignatures(); 53 private static BytecodeTransformer bytecodeTransformer; 54 55 private String name; 56 private Class target; 57 private String enclosingClass; 58 private String enclosingMethod; 59 private LazyList<TypeDescriptor, Type > genericInterfaces; 60 private LazyValue<TypeDescriptor, Type > genericSuperclass; 61 private Map<String , FieldDescriptor> fieldDescriptors = new HashMap<String , FieldDescriptor>(); 62 private Map<String , MethodDescriptor> methodDescriptors = new HashMap<String , MethodDescriptor>(); 63 64 private static Properties getSignatures() { 65 try { 66 Properties properties = new Properties(); 67 InputStream stream = ClassDescriptor.class.getResourceAsStream(SIGNATURES_NAME); 68 if (stream != null) { 69 properties.load(stream); 70 stream.close(); 71 } 72 return properties; 73 } catch (IOException e) { 74 throw new RuntimeException (e); 75 } 76 } 77 78 public ClassDescriptor(Class target, byte[] bytecode) { 79 this.target = target; 80 if (bytecode != null) { 81 if (bytecodeTransformer != null) { 82 bytecode = bytecodeTransformer.transform(bytecode, 0, bytecode.length); 83 } 84 new ClassReader(bytecode).accept(this, true); 85 } 86 } 87 88 public static void setBytecodeTransformer(BytecodeTransformer transformer) { 89 bytecodeTransformer = transformer; 90 } 91 92 public static ClassDescriptor getInstance(Class target) { 93 Map<Class , ClassDescriptor> map = getMap(); 94 ClassDescriptor descriptor = map.get(target); 95 if (descriptor != null) return descriptor; 96 descriptor = new ClassDescriptor(target, RuntimeTools.getBytecode(target)); 97 map.put(target, descriptor); 98 return descriptor; 99 } 100 101 private static synchronized Map<Class , ClassDescriptor> getMap() { 102 Map<Class , ClassDescriptor> map = cache == null ? null : cache.get(); 103 if (map == null) { 104 map = new Hashtable<Class , ClassDescriptor>(); 105 cache = new SoftReference <Map<Class , ClassDescriptor>>(map); 106 } 107 return map; 108 } 109 110 protected Annotation_[] createAnnotations(Annotation_[] declaredAnnotations) { 111 Class superclass = target.getSuperclass(); 112 if (superclass == null) return declaredAnnotations; 113 Annotation_[] superAnnotations = getInstance(superclass).getAnnotations(); 114 if (superAnnotations.length == 0) return declaredAnnotations; 115 Map<Class , Annotation_> result = new HashMap<Class , Annotation_>(); 116 for (Annotation_ annotation : superAnnotations) { 117 Class annotationClass = annotation.getClass().getInterfaces()[0]; 118 if (annotationClass.isAnnotationPresent(Inherited .class)) { 119 result.put(annotationClass, annotation); 120 } 121 } 122 for (Annotation_ annotation : declaredAnnotations) { 123 result.put(annotation.getClass().getInterfaces()[0], annotation); 124 } 125 return result.values().toArray(new Annotation_[result.size()]); 126 } 127 128 public String getName() { 129 return name; 130 } 131 132 public ClassDescriptor getClassDescriptor() { 133 return this; 134 } 135 136 public MethodDescriptor getEnclosingMethodDescriptor() { 137 return enclosingMethod == null ? null 138 : getInstance(getClassByInternalName(enclosingClass)).getMethodDescriptor(enclosingMethod); 139 } 140 141 public boolean isLocalOrAnonymous() { 142 return enclosingMethod != null; 143 } 144 145 public FieldDescriptor getFieldDescriptor(String name) { 146 return fieldDescriptors.get(name); 147 } 148 149 public Type [] getGenericInterfaces() { 150 return genericInterfaces == null ? null : genericInterfaces.getClone(); 151 } 152 153 public Type getGenericSuperclass() { 154 return genericSuperclass == null ? null : genericSuperclass.get(); 155 } 156 157 public MethodDescriptor getMethodDescriptor(String key) { 158 return methodDescriptors.get(key); 159 } 160 161 public Collection<MethodDescriptor> getMethodDescriptors() { 162 return methodDescriptors.values(); 163 } 164 165 public Collection<FieldDescriptor> getFieldDescriptors() { 166 return fieldDescriptors.values(); 167 } 168 169 public Class getTarget() { 170 return target; 171 } 172 173 protected TypeVariable findTypeVariable(String name) { 174 TypeVariable variable = getTypeVariable(name); 175 if (variable != null) return variable; 176 MethodDescriptor methodDescriptor = getEnclosingMethodDescriptor(); 177 if (methodDescriptor != null) return methodDescriptor.findTypeVariable(name); 178 Class declaringClass = target.getDeclaringClass(); 179 if (declaringClass != null) return getInstance(declaringClass).findTypeVariable(name); 180 throw new MalformedParameterizedTypeException(); 181 } 182 183 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 184 this.access = access; 185 this.name = name; 186 if (signature == null) signature = signatures.getProperty(name); 187 if (signature != null) new SignatureReader(signature).accept(this); 188 } 189 190 public void visitOuterClass(String owner, String name, String desc) { 191 if (name != null) { 192 enclosingClass = owner; 193 enclosingMethod = name + desc; 194 } 195 } 196 197 public void visitInnerClass(String name, String outerName, String innerName, int access) { 198 if (name.equals(this.name)) this.access |= access; 199 } 200 201 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { 202 FieldDescriptor fieldDescriptor = new FieldDescriptor(this, access, name, desc, signature); 203 fieldDescriptors.put(name, fieldDescriptor); 204 return fieldDescriptor; 205 } 206 207 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 208 MethodDescriptor methodDescriptor = new MethodDescriptor(this, access, name, desc, signature); 209 methodDescriptors.put(name + desc, methodDescriptor); 210 return methodDescriptor; 211 } 212 213 public SignatureVisitor visitSuperclass() { 214 TypeDescriptor descriptor = new TypeDescriptor(); 215 if (!isAccess(Opcodes.ACC_INTERFACE)) { 216 genericSuperclass = getLazyType(descriptor); 217 } 218 return descriptor; 219 } 220 221 public SignatureVisitor visitInterface() { 222 TypeDescriptor descriptor = new TypeDescriptor(); 223 if (genericInterfaces == null) genericInterfaces = getLazyList(); 224 genericInterfaces.add(descriptor); 225 return descriptor; 226 } 227 228 } 229 | Popular Tags |