1 8 package com.tc.backport175.bytecode; 9 10 import com.tc.backport175.ReaderException; 11 import com.tc.backport175.bytecode.AnnotationElement.Annotation; 12 13 import com.tc.asm.AnnotationVisitor; 14 import com.tc.asm.ClassAdapter; 15 import com.tc.asm.ClassReader; 16 import com.tc.asm.ClassVisitor; 17 import com.tc.asm.ClassWriter; 18 import com.tc.asm.MethodAdapter; 19 import com.tc.asm.MethodVisitor; 20 21 import java.util.Map ; 22 import java.util.WeakHashMap ; 23 24 31 class AnnotationDefaults { 32 33 37 private static Map s_annotationDefaults = new WeakHashMap (); 38 39 46 public static AnnotationElement.Annotation getDefaults(final String annotationClassName, final ClassLoader loader) { 47 AnnotationReader.ClassKey key = new AnnotationReader.ClassKey(annotationClassName, loader); 48 AnnotationElement.Annotation defaults = (AnnotationElement.Annotation) s_annotationDefaults.get(key); 49 if (defaults == null) { 50 final AnnotationElement.Annotation newDefaults = new AnnotationElement.Annotation(annotationClassName); 51 final byte[] bytes; 52 try { 53 bytes = AnnotationReader.getBytecodeFor(annotationClassName, loader); 54 } catch (Exception e) { 55 throw new ReaderException("could not retrieve the bytecode from the bytecode provider for class [" + annotationClassName+ "]", e); 56 } 57 ClassReader cr = new ClassReader(bytes); 58 ClassWriter cw = new ClassWriter(false, true); 59 cr.accept(new AnnotationDefaultsClassVisitor(cw, newDefaults, loader), true); 60 defaults = newDefaults; 61 s_annotationDefaults.put(key, newDefaults); 62 } 63 return defaults; 64 } 65 66 private static final class AnnotationDefaultsClassVisitor extends ClassAdapter { 67 68 private final AnnotationElement.Annotation defaults; 69 private final ClassLoader loader; 70 71 private AnnotationDefaultsClassVisitor(ClassVisitor cv, AnnotationElement.Annotation defaults, ClassLoader loader) { 72 super(cv); 73 this.defaults = defaults; 74 this.loader = loader; 75 } 76 77 public MethodVisitor visitMethod(int access, final String name, String desc, String signature, String [] exceptions) { 78 return new AnnotationDefaultsMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), name, defaults, loader); 79 } 80 } 81 82 private static final class AnnotationDefaultsMethodVisitor extends MethodAdapter { 83 private final String name; 84 private final Annotation defaults; 85 private final ClassLoader loader; 86 87 private AnnotationDefaultsMethodVisitor(MethodVisitor mv, String name, Annotation defaults, ClassLoader loader) { 88 super(mv); 89 this.name = name; 90 this.defaults = defaults; 91 this.loader = loader; 92 } 93 94 public AnnotationVisitor visitAnnotationDefault() { 95 return new DefaultAnnotationBuilderVisitor(defaults, name, loader); 96 } 97 } 98 99 105 static class DefaultAnnotationBuilderVisitor extends AnnotationReader.AnnotationBuilderVisitor { 106 107 private String m_methodName; 108 109 public DefaultAnnotationBuilderVisitor(final AnnotationElement.NestedAnnotationElement annotation, String methodName, ClassLoader loader) { 110 super(annotation, loader, null); 111 m_methodName = methodName; 112 } 113 114 public void visit(String name, Object value) { 115 super.visit(m_methodName, value); 116 } 117 118 public void visitEnum(String name, String desc, String value) { 119 super.visitEnum(m_methodName, desc, value); 120 } 121 122 public AnnotationVisitor visitAnnotation(String name, String desc) { 123 return super.visitAnnotation(m_methodName, desc); 124 } 125 126 public AnnotationVisitor visitArray(String name) { 127 return super.visitArray(m_methodName); 128 } 129 130 } 131 132 public static void refresh(AnnotationReader.ClassKey key) { 133 AnnotationElement.Annotation defaults = (AnnotationElement.Annotation) s_annotationDefaults.get(key); 134 if (defaults != null) { 135 s_annotationDefaults.remove(key); 136 } 137 } 138 } 139 | Popular Tags |