KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > asm1 > NotifierClassVisitor


1 /*
2  * Java bytecode manipulation with ASM toolkit
3  * Copyright (c) 2004, Eugene Kuleshov
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package asm1;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.List JavaDoc;
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 JavaDoc NOTIFIER = Type.getType(Notifier.class).getInternalName();
37   private static final String JavaDoc LISTENER = Type.getType(Listener.class).getInternalName();
38
39   private String JavaDoc className;
40
41   public NotifierClassVisitor( ClassVisitor cv) {
42     super( cv);
43   }
44
45   public void visit( int version, int access,
46       String JavaDoc name, String JavaDoc superName,
47       String JavaDoc[] interfaces, String JavaDoc sourceFile) {
48     this.className = name;
49     List JavaDoc c = interfaces==null ?
50         new ArrayList JavaDoc() : new ArrayList JavaDoc( Arrays.asList( interfaces));
51     c.add( NOTIFIER);
52     cv.visit( version, access, name, superName,
53         (String JavaDoc[])c.toArray(new String JavaDoc[c.size()]),
54         sourceFile);
55   }
56   
57   public void visitEnd() {
58     // adding new field
59
cv.visitField(ACC_PRIVATE, "__lst",
60         "Ljava/util/ArrayList;", null, null);
61
62     // adding new methods
63
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 JavaDoc name, String JavaDoc desc,
118       String JavaDoc[] 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       // add instructions to call notify() method
128
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