1 8 package org.codehaus.aspectwerkz.annotation.instrumentation.asm; 9 10 import org.objectweb.asm.ClassVisitor; 11 import org.objectweb.asm.Attribute; 12 import org.objectweb.asm.CodeVisitor; 13 import org.objectweb.asm.Label; 14 import org.objectweb.asm.Type; 15 import org.objectweb.asm.attrs.RuntimeInvisibleAnnotations; 16 import org.objectweb.asm.attrs.Annotation; 17 import org.objectweb.asm.attrs.RuntimeVisibleAnnotations; 18 import org.objectweb.asm.attrs.AnnotationDefaultAttribute; 19 import org.objectweb.asm.attrs.Attributes; 20 import org.codehaus.aspectwerkz.annotation.AnnotationInfo; 21 import org.codehaus.aspectwerkz.annotation.AnnotationDefault; 22 import org.codehaus.aspectwerkz.annotation.Java5AnnotationInvocationHandler; 23 24 import java.util.List ; 25 import java.util.Iterator ; 26 27 33 public class AsmAnnotationHelper { 34 35 private final static String INIT_METHOD_NAME = "<init>"; 36 37 40 private static class AnnotationExtractor extends NullClassAdapter { 41 42 45 protected List m_annotations; 46 47 52 protected ClassLoader m_loader; 53 54 60 private AnnotationExtractor(List annotations, final ClassLoader loader) { 61 m_annotations = annotations; 62 m_loader = loader; 63 } 64 } 65 66 69 public static class ClassAnnotationExtractor extends AnnotationExtractor { 70 71 public ClassAnnotationExtractor(List annotations, final ClassLoader loader) { 72 super(annotations, loader); 73 } 74 75 public void visitAttribute(final Attribute attribute) { 76 m_annotations = extractAnnotations(m_annotations, attribute, m_loader); 77 super.visitAttribute(attribute); 78 } 79 } 80 81 84 private static class MemberAnnotationExtractor extends AnnotationExtractor { 85 86 89 protected String m_name; 90 91 94 protected String m_desc; 95 96 104 private MemberAnnotationExtractor(List annotations, String name, String desc, final ClassLoader loader) { 105 super(annotations, loader); 106 m_name = name; 107 m_desc = desc; 108 } 109 } 110 111 114 public static class MethodAnnotationExtractor extends MemberAnnotationExtractor { 115 116 public MethodAnnotationExtractor(List annotations, String name, String desc, final ClassLoader loader) { 117 super(annotations, name, desc, loader); 118 } 119 120 public CodeVisitor visitMethod(final int access, 121 final String name, 122 final String desc, 123 final String [] exceptions, 124 final Attribute attrs) { 125 if (name.equals(m_name) && desc.equals(m_desc)) { 126 m_annotations = extractAnnotations(m_annotations, attrs, m_loader); 127 } 128 return super.visitMethod(access, name, desc, exceptions, attrs); 129 } 130 } 131 132 135 public static class ConstructorAnnotationExtractor extends MethodAnnotationExtractor { 136 137 public ConstructorAnnotationExtractor(List annotations, String desc, final ClassLoader loader) { 138 super(annotations, INIT_METHOD_NAME, desc, loader); 139 } 140 } 141 142 145 public static class FieldAnnotationExtractor extends MemberAnnotationExtractor { 146 147 public FieldAnnotationExtractor(List annotations, String name, final ClassLoader loader) { 148 super(annotations, name, null, loader); 149 } 150 151 public void visitField(final int access, 152 final String name, 153 final String desc, 154 final Object value, 155 final Attribute attrs) { 156 if (name.equals(m_name)) { 158 m_annotations = extractAnnotations(m_annotations, attrs, m_loader); 159 } 160 super.visitField(access, name, desc, value, attrs); 161 } 162 } 163 164 169 public static class NullClassAdapter implements ClassVisitor { 170 171 public final static ClassVisitor NULL_CLASS_ADAPTER = new NullClassAdapter(); 172 173 public void visit(int i, int i1, String s, String s1, String [] strings, String s2) { 174 } 175 176 public void visitInnerClass(String s, String s1, String s2, int i) { 177 } 178 179 public void visitField(int i, String s, String s1, Object o, Attribute attribute) { 180 } 181 182 public CodeVisitor visitMethod(int i, String s, String s1, String [] strings, Attribute attribute) { 183 return NullCodeAdapter.NULL_CODE_ADAPTER; 184 } 185 186 public void visitAttribute(Attribute attribute) { 187 } 188 189 public void visitEnd() { 190 } 191 } 192 193 198 public static class NullCodeAdapter implements CodeVisitor { 199 200 public final static CodeVisitor NULL_CODE_ADAPTER = new NullCodeAdapter(); 201 202 public void visitInsn(int opcode) { 203 } 204 205 public void visitIntInsn(int opcode, int operand) { 206 } 207 208 public void visitVarInsn(int opcode, int var) { 209 } 210 211 public void visitTypeInsn(int opcode, String desc) { 212 } 213 214 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 215 } 216 217 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 218 } 219 220 public void visitJumpInsn(int opcode, Label label) { 221 } 222 223 public void visitLabel(Label label) { 224 } 225 226 public void visitLdcInsn(Object cst) { 227 } 228 229 public void visitIincInsn(int var, int increment) { 230 } 231 232 public void visitTableSwitchInsn(int min, int max, Label dflt, Label labels[]) { 233 } 234 235 public void visitLookupSwitchInsn(Label dflt, int keys[], Label labels[]) { 236 } 237 238 public void visitMultiANewArrayInsn(String desc, int dims) { 239 } 240 241 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 242 } 243 244 public void visitMaxs(int maxStack, int maxLocals) { 245 } 246 247 public void visitLocalVariable(String name, String desc, Label start, Label end, int index) { 248 } 249 250 public void visitLineNumber(int line, Label start) { 251 } 252 253 public void visitAttribute(Attribute attr) { 254 } 255 } 256 257 265 public static List extractAnnotations(List annotations, final Attribute attribute, final ClassLoader loader) { 266 for (Attribute current = attribute; current != null; current = current.next) { 267 if (current instanceof RuntimeInvisibleAnnotations) { 268 for (Iterator it = ((RuntimeInvisibleAnnotations) current).annotations.iterator(); it.hasNext();) { 269 Annotation annotation = (Annotation) it.next(); 270 if (CustomAttribute.TYPE.equals(annotation.type)) { 271 annotations.add(CustomAttributeHelper.extractCustomAnnotation(annotation)); 272 } else { 273 AnnotationInfo annotationInfo = getAnnotationInfo(annotation, loader); 274 annotations.add(annotationInfo); 275 } 276 } 277 } else if (current instanceof RuntimeVisibleAnnotations) { 278 for (Iterator it = ((RuntimeVisibleAnnotations) current).annotations.iterator(); it.hasNext();) { 279 Annotation annotation = (Annotation) it.next(); 280 AnnotationInfo annotationInfo = getAnnotationInfo(annotation, loader); 281 annotations.add(annotationInfo); 282 } 283 } else if (current instanceof AnnotationDefaultAttribute) { 284 AnnotationDefaultAttribute defaultAttribute = (AnnotationDefaultAttribute) current; 285 AnnotationInfo annotationInfo = new AnnotationInfo( 286 AnnotationDefault.NAME, 287 new AnnotationDefault.AnnotationDefaultImpl(defaultAttribute.defaultValue) 288 ); 289 annotations.add(annotationInfo); 290 } 291 } 292 return annotations; 293 } 294 295 302 public static AnnotationInfo getAnnotationInfo(final Annotation annotation, final ClassLoader loader) { 303 String annotationName = Type.getType(annotation.type).getClassName(); 304 return new AnnotationInfo(annotationName, 305 Java5AnnotationInvocationHandler.getAnnotationProxy(annotation, loader) 306 ); 307 } 308 } 309 | Popular Tags |