1 32 package net.sf.retrotranslator.runtime.impl; 33 34 import java.lang.reflect.*; 35 import java.util.*; 36 import net.sf.retrotranslator.runtime.asm.*; 37 import net.sf.retrotranslator.runtime.asm.Type; 38 import net.sf.retrotranslator.runtime.java.lang.Enum_; 39 import net.sf.retrotranslator.runtime.java.lang.annotation.*; 40 41 44 public abstract class AnnotatedElementDescriptor extends EmptyVisitor { 45 46 private static final Annotation_[] EMPTY = new Annotation_[0]; 47 protected static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor(); 48 49 protected int access; 50 51 private LazyList<AnnotationValue, Annotation_> declaredAnnotations = new LazyList<AnnotationValue, Annotation_>() { 52 protected Annotation_ resolve(AnnotationValue input) { 53 return createAnnotation(input); 54 } 55 56 protected Annotation_[] newArray(int size) { 57 return new Annotation_[size]; 58 } 59 }; 60 61 private LazyValue<LazyList<AnnotationValue, Annotation_>, Annotation_[]> annotations 62 = new LazyValue<LazyList<AnnotationValue, Annotation_>, Annotation_[]>(declaredAnnotations) { 63 protected Annotation_[] resolve(LazyList<AnnotationValue, Annotation_> input) { 64 return createAnnotations(input.getLive()); 65 } 66 }; 67 68 public boolean isAccess(int mask) { 69 return (access & mask) != 0; 70 } 71 72 public boolean isAnnotationPresent(Class annotationType) { 73 for (Annotation_ annotation : annotations.get()) { 74 if (annotationType.isInstance(annotation)) return true; 75 } 76 return false; 77 } 78 79 public Annotation_ getAnnotation(Class annotationType) { 80 for (Annotation_ annotation : annotations.get()) { 81 if (annotationType.isInstance(annotation)) return annotation; 82 } 83 return null; 84 } 85 86 public Annotation_[] getAnnotations() { 87 Annotation_[] result = annotations.get(); 88 return result.length == 0 ? result : result.clone(); 89 } 90 91 public Annotation_[] getDeclaredAnnotations() { 92 return declaredAnnotations.getClone(); 93 } 94 95 public abstract ClassDescriptor getClassDescriptor(); 96 97 protected abstract TypeVariable findTypeVariable(String name); 98 99 protected abstract Annotation_[] createAnnotations(Annotation_[] declaredAnnotations); 100 101 protected Annotation_[] createAnnotations(List<AnnotationValue> values) { 102 if (values == null) return EMPTY; 103 Annotation_[] result = new Annotation_[values.size()]; 104 for (int i = 0; i < result.length; i++) { 105 result[i] = createAnnotation(values.get(i)); 106 } 107 return result; 108 } 109 110 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 111 if (!visible) return EMPTY_VISITOR; 112 AnnotationValue value = new AnnotationValue(desc); 113 declaredAnnotations.add(value); 114 return value; 115 } 116 117 private ClassLoader getClassLoader() { 118 return getClassDescriptor().getTarget().getClassLoader(); 119 } 120 121 protected Class getClassByInternalName(String name) { 122 name = name.replace('/', '.'); 123 try { 124 return Class.forName(name, false, getClassLoader()); 125 } catch (ClassNotFoundException e) { 126 throw new TypeNotPresentException (name, e); 127 } 128 } 129 130 protected Class getClassByType(net.sf.retrotranslator.runtime.asm.Type type) { 131 Class baseClass = RuntimeTools.getBaseClass(type); 132 if (baseClass != null) return baseClass; 133 return getClassByInternalName(type.getSort() == Type.ARRAY ? type.getDescriptor() : type.getInternalName()); 134 } 135 136 private Class getClassByDesc(String desc) { 137 return getClassByType(net.sf.retrotranslator.runtime.asm.Type.getType(desc)); 138 } 139 140 public java.lang.reflect.Type [] createTypes(List<TypeDescriptor> descriptors) { 141 if (descriptors == null) return null; 142 java.lang.reflect.Type [] result = new java.lang.reflect.Type [descriptors.size()]; 143 Iterator<TypeDescriptor> iterator = descriptors.iterator(); 144 for (int i = 0; i < result.length; i++) { 145 result[i] = createType(iterator.next()); 146 } 147 return result; 148 } 149 150 public java.lang.reflect.Type createType(TypeDescriptor descriptor) { 151 if (descriptor == null) return null; 152 if (descriptor.arrayType != null) { 153 return new GenericArrayTypeImpl(createType(descriptor.arrayType)); 154 } 155 if (descriptor.typeVariable != null) { 156 return findTypeVariable(descriptor.typeVariable); 157 } 158 LinkedList<ClassTypeElement> elements = descriptor.elements; 159 if (elements != null) { 160 return createClassType(elements.toArray(new ClassTypeElement[elements.size()])); 161 } 162 return RuntimeTools.getBaseClass(descriptor.baseType); 163 } 164 165 private java.lang.reflect.Type createClassType(ClassTypeElement[] typeElements) { 166 class Element { 167 Class rawType; 168 List<TypeArgument> arguments; 169 170 public Element(Class rawType, List<TypeArgument> arguments) { 171 this.rawType = rawType; 172 this.arguments = arguments; 173 } 174 } 175 String className = null; 176 for (ClassTypeElement typeElement : typeElements) { 177 className = (className == null ? "" : className + "$") + typeElement.getName(); 178 } 179 LinkedList<Element> elements = new LinkedList<Element>(); 180 Class currentClass = getClassByInternalName(className); 181 for (int i = typeElements.length - 1; i >= 0; i--) { 182 elements.addFirst(new Element(currentClass, typeElements[i].getArguments())); 183 currentClass = currentClass.getDeclaringClass(); 184 if (currentClass == null) break; 185 } 186 java.lang.reflect.Type result = elements.getFirst().arguments.isEmpty() ? null : currentClass; 187 for (Element element : elements) { 188 result = (result == null && element.arguments.isEmpty()) ? element.rawType 189 : new ParameterizedTypeImpl(createArguments(element.arguments), element.rawType, result); 190 } 191 return result; 192 } 193 194 private java.lang.reflect.Type [] createArguments(List<TypeArgument> arguments) { 195 java.lang.reflect.Type [] result = new java.lang.reflect.Type [arguments.size()]; 196 Iterator<TypeArgument> iterator = arguments.iterator(); 197 for (int i = 0; i < result.length; i++) { 198 TypeArgument argument = iterator.next(); 199 result[i] = argument.wildcard == INSTANCEOF ? createType(argument.descriptor) 200 : new WildcardTypeImpl(argument.wildcard == EXTENDS, getLazyType(argument.descriptor)); 201 } 202 return result; 203 } 204 205 protected Annotation_ createAnnotation(AnnotationValue annotationValue) { 206 Class annotationType = getClassByDesc(annotationValue.getDesc()); 207 StringBuffer buffer = new StringBuffer ("@").append(annotationType.getName()).append('('); 208 Map<String , Object > values = new HashMap<String , Object >(); 209 boolean isFirst = true; 210 for (MethodDescriptor descriptor : ClassDescriptor.getInstance(annotationType).getMethodDescriptors()) { 211 if (isFirst) { 212 isFirst = false; 213 } else { 214 buffer.append(", "); 215 } 216 String elementName = descriptor.getName(); 217 Object elementValue = annotationValue.getElement(elementName); 218 Object resolvedValue = elementValue == null ? descriptor.getDefaultValue() 219 : resolveValue(elementValue, descriptor.getReturnType(), descriptor); 220 if (resolvedValue == null) throw new IncompleteAnnotationException_(annotationType, elementName); 221 values.put(elementName, resolvedValue); 222 buffer.append(elementName).append('='); 223 append(buffer, resolvedValue); 224 } 225 buffer.append(")"); 226 Class [] interfaces = Annotation_.class.isAssignableFrom(annotationType) ? 227 new Class []{annotationType} : new Class []{annotationType, Annotation_.class}; 228 return (Annotation_) Proxy.newProxyInstance(getClassLoader(), 229 interfaces, new AnnotationHandler(annotationType, buffer.toString(), values)); 230 } 231 232 protected Object resolveValue(Object value, Class type, MethodDescriptor descriptor) { 233 if (value == null) return null; 234 if (value instanceof net.sf.retrotranslator.runtime.asm.Type) { 235 value = getClassByType((net.sf.retrotranslator.runtime.asm.Type) value); 236 } else if (value instanceof EnumValue) { 237 EnumValue enumValue = (EnumValue) value; 238 value = Enum.valueOf(getClassByDesc(enumValue.getDescriptor()), enumValue.getValue()); 239 } else if (value instanceof AnnotationValue) { 240 value = createAnnotation((AnnotationValue) value); 241 } else if (value instanceof AnnotationArray) { 242 AnnotationArray array = (AnnotationArray) value; 243 Class componentType = type.getComponentType(); 244 List<Object > values = array.getValues(); 245 value = Array.newInstance(componentType, values.size()); 246 for (int i = Array.getLength(value) - 1; i >= 0; i--) { 247 Array.set(value, i, resolveValue(values.get(i), componentType, descriptor)); 248 } 249 } 250 if (!type.isPrimitive() && !type.isInstance(value)) { 251 throw new AnnotationTypeMismatchException_(descriptor.getMethod(), type.getName()); 252 } 253 return value; 254 } 255 256 257 private static void append(StringBuffer buffer, Object value) { 258 if (value.getClass().isArray()) { 259 buffer.append('['); 260 int length = Array.getLength(value); 261 for (int i = 0; i < length; i++) { 262 if (i > 0) buffer.append(", "); 263 append(buffer, Array.get(value, i)); 264 } 265 buffer.append(']'); 266 } else { 267 buffer.append(value); 268 } 269 } 270 271 protected LazyValue<TypeDescriptor, java.lang.reflect.Type > getLazyType(TypeDescriptor descriptor) { 272 if (descriptor == null) return null; 273 return new LazyValue<TypeDescriptor, java.lang.reflect.Type >(descriptor) { 274 protected java.lang.reflect.Type resolve(TypeDescriptor input) { 275 return createType(input); 276 } 277 }; 278 } 279 280 protected LazyList<TypeDescriptor, java.lang.reflect.Type > getLazyList() { 281 return new LazyList<TypeDescriptor, java.lang.reflect.Type >() { 282 283 protected java.lang.reflect.Type resolve(TypeDescriptor descriptor) { 284 return createType(descriptor); 285 } 286 287 protected java.lang.reflect.Type [] newArray(int size) { 288 return new java.lang.reflect.Type [size]; 289 } 290 }; 291 } 292 293 } 294 | Popular Tags |