1 19 20 package asm1; 21 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.List ; 25 26 import org.objectweb.asm.Attribute; 27 import org.objectweb.asm.ClassAdapter; 28 import org.objectweb.asm.ClassVisitor; 29 import org.objectweb.asm.CodeVisitor; 30 import org.objectweb.asm.Constants; 31 import org.objectweb.asm.Label; 32 import org.objectweb.asm.Type; 33 34 35 public class NotifierClassVisitor extends ClassAdapter implements Constants { 36 private static final String NOTIFIER = Type.getType(Notifier.class).getInternalName(); 37 private static final String LISTENER = Type.getType(Listener.class).getInternalName(); 38 39 private String className; 40 41 public NotifierClassVisitor( ClassVisitor cv) { 42 super( cv); 43 } 44 45 public void visit( int version, int access, 46 String name, String superName, 47 String [] interfaces, String sourceFile) { 48 this.className = name; 49 List c = interfaces==null ? 50 new ArrayList () : new ArrayList ( Arrays.asList( interfaces)); 51 c.add( NOTIFIER); 52 cv.visit( version, access, name, superName, 53 (String [])c.toArray(new String [c.size()]), 54 sourceFile); 55 } 56 57 public void visitEnd() { 58 cv.visitField(ACC_PRIVATE, "__lst", 60 "Ljava/util/ArrayList;", null, null); 61 62 CodeVisitor cd; 64 { 65 cd = cv.visitMethod(ACC_PUBLIC, "notify", 66 "(Ljava/lang/String;)V", null, null); 67 cd.visitInsn(ICONST_0); 68 cd.visitVarInsn(ISTORE, 2); 69 Label l0 = new Label(); 70 cd.visitLabel(l0); 71 cd.visitVarInsn(ILOAD, 2); 72 cd.visitVarInsn(ALOAD, 0); 73 cd.visitFieldInsn(GETFIELD, className, 74 "__lst", "Ljava/util/ArrayList;"); 75 cd.visitMethodInsn(INVOKEVIRTUAL, 76 "java/util/ArrayList", "size", "()I"); 77 Label l1 = new Label(); 78 cd.visitJumpInsn(IF_ICMPGE, l1); 79 cd.visitVarInsn(ALOAD, 0); 80 cd.visitFieldInsn(GETFIELD, className, 81 "__lst", "Ljava/util/ArrayList;"); 82 cd.visitVarInsn(ILOAD, 2); 83 cd.visitMethodInsn(INVOKEVIRTUAL, 84 "java/util/ArrayList", "get", 85 "(I)Ljava/lang/Object;"); 86 cd.visitTypeInsn(CHECKCAST, LISTENER); 87 cd.visitVarInsn(ALOAD, 0); 88 cd.visitVarInsn(ALOAD, 1); 89 cd.visitMethodInsn(INVOKEINTERFACE, 90 LISTENER, "notify", 91 "(Ljava/lang/Object;Ljava/lang/Object;)V"); 92 cd.visitIincInsn(2, 1); 93 cd.visitJumpInsn(GOTO, l0); 94 cd.visitLabel(l1); 95 cd.visitInsn(RETURN); 96 cd.visitMaxs(1, 1); 97 } 98 { 99 cd = cv.visitMethod(ACC_PUBLIC, "addListener", 100 "(Lasm1/Listener;)V", null, null); 101 cd.visitVarInsn(ALOAD, 0); 102 cd.visitFieldInsn(GETFIELD, className, 103 "__lst", "Ljava/util/ArrayList;"); 104 cd.visitVarInsn(ALOAD, 1); 105 cd.visitMethodInsn(INVOKEVIRTUAL, 106 "java/util/ArrayList", "add", 107 "(Ljava/lang/Object;)Z"); 108 cd.visitInsn(POP); 109 cd.visitInsn(RETURN); 110 cd.visitMaxs(1, 1); 111 } 112 113 cv.visitEnd(); 114 } 115 116 public CodeVisitor visitMethod( int access, 117 String name, String desc, 118 String [] exceptions, Attribute attrs) { 119 CodeVisitor cd = cv.visitMethod( access, 120 name, desc, exceptions, attrs); 121 if( cd==null) return null; 122 123 if( "<init>".equals( name)) { 124 return new NotifierCodeAdapter( cd, className); 125 } 126 if((access & Constants.ACC_STATIC)==0) { 127 cd.visitVarInsn(ALOAD, 0); 129 cd.visitLdcInsn(name+desc); 130 cd.visitMethodInsn(INVOKEVIRTUAL, className, 131 "notify", "(Ljava/lang/String;)V"); 132 } 133 return cd; 134 } 135 136 } 137 138 | Popular Tags |