KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > asm > util > TraceClassVisitor


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000,2002,2003 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Contact: Eric.Bruneton@rd.francetelecom.com
31  *
32  * Author: Eric Bruneton
33  */

34
35 package org.logicalcobwebs.asm.util;
36
37 import org.logicalcobwebs.asm.ClassVisitor;
38 import org.logicalcobwebs.asm.CodeVisitor;
39 import org.logicalcobwebs.asm.Constants;
40 import org.logicalcobwebs.asm.ClassReader;
41 import org.logicalcobwebs.asm.Attribute;
42
43 import java.io.PrintWriter JavaDoc;
44
45 /**
46  * A {@link PrintClassVisitor PrintClassVisitor} that prints a disassembled
47  * view of the classes it visits. This class visitor can be used alone (see the
48  * {@link #main main} method) to disassemble a class. It can also be used in
49  * the middle of class visitor chain to trace the class that is visited at a
50  * given point in this chain. This may be uselful for debugging purposes.
51  * <p>
52  * The trace printed when visiting the <tt>Hello</tt> class is the following:
53  * <p>
54  * <blockquote>
55  * <pre>
56  * // compiled from Hello.java
57  * public class Hello {
58  *
59  * public static main ([Ljava/lang/String;)V
60  * GETSTATIC java/lang/System out Ljava/io/PrintStream;
61  * LDC "hello"
62  * INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
63  * RETURN
64  * MAXSTACK = 2
65  * MAXLOCALS = 1
66  *
67  * public &lt;init&gt; ()V
68  * ALOAD 0
69  * INVOKESPECIAL java/lang/Object &lt;init&gt; ()V
70  * RETURN
71  * MAXSTACK = 1
72  * MAXLOCALS = 1
73  *
74  * }
75  * </pre>
76  * </blockquote>
77  * where <tt>Hello</tt> is defined by:
78  * <p>
79  * <blockquote>
80  * <pre>
81  * public class Hello {
82  *
83  * public static void main (String[] args) {
84  * System.out.println("hello");
85  * }
86  * }
87  * </pre>
88  * </blockquote>
89  */

90
91 public class TraceClassVisitor extends PrintClassVisitor {
92
93   /**
94    * The {@link ClassVisitor ClassVisitor} to which this visitor delegates
95    * calls. May be <tt>null</tt>.
96    */

97
98   protected final ClassVisitor cv;
99
100   /**
101    * Prints a disassembled view of the given class to the standard output.
102    * <p>
103    * Usage: TraceClassVisitor &lt;fully qualified class name&gt;
104    *
105    * @param args the command line arguments.
106    *
107    * @throws Exception if the class cannot be found, or if an IO exception
108    * occurs.
109    */

110
111   public static void main (final String JavaDoc[] args) throws Exception JavaDoc {
112     if (args.length == 0) {
113       System.err.println("Prints a disassembled view of the given class.");
114       System.err.println("Usage: TraceClassVisitor <fully qualified class name>");
115       System.exit(-1);
116     }
117     ClassReader cr = new ClassReader(args[0]);
118     cr.accept(new TraceClassVisitor(null, new PrintWriter JavaDoc(System.out)), true);
119   }
120
121   /**
122    * Constructs a new {@link TraceClassVisitor TraceClassVisitor} object.
123    *
124    * @param cv the class visitor to which this adapter must delegate calls. May
125    * be <tt>null</tt>.
126    * @param pw the print writer to be used to print the class.
127    */

128
129   public TraceClassVisitor (final ClassVisitor cv, final PrintWriter JavaDoc pw) {
130     super(pw);
131     this.cv = cv;
132   }
133
134   public void visit (
135     final int access,
136     final String JavaDoc name,
137     final String JavaDoc superName,
138     final String JavaDoc[] interfaces,
139     final String JavaDoc sourceFile)
140   {
141     buf.setLength(0);
142     if ((access & Constants.ACC_DEPRECATED) != 0) {
143       buf.append("// DEPRECATED\n");
144     }
145     if (sourceFile != null) {
146       buf.append("// compiled from ").append(sourceFile).append("\n");
147     }
148     appendAccess(access & ~Constants.ACC_SUPER);
149     if ((access & Constants.ACC_INTERFACE) != 0) {
150       buf.append("interface ");
151     } else {
152       buf.append("class ");
153     }
154     buf.append(name).append(" ");
155     if (superName != null && !superName.equals("java/lang/Object")) {
156       buf.append("extends ").append(superName).append(" ");
157     }
158     if (interfaces != null && interfaces.length > 0) {
159       buf.append("implements ");
160       for (int i = 0; i < interfaces.length; ++i) {
161         buf.append(interfaces[i]).append(" ");
162       }
163     }
164     buf.append("{\n\n");
165     text.add(buf.toString());
166
167     if (cv != null) {
168       cv.visit(access, name, superName, interfaces, sourceFile);
169     }
170   }
171
172   public void visitInnerClass (
173     final String JavaDoc name,
174     final String JavaDoc outerName,
175     final String JavaDoc innerName,
176     final int access)
177   {
178     buf.setLength(0);
179     buf.append(" INNERCLASS ")
180       .append(name)
181       .append(" ")
182       .append(outerName)
183       .append(" ")
184       .append(innerName)
185       .append(" ")
186       .append(access)
187       .append("\n");
188     text.add(buf.toString());
189
190     if (cv != null) {
191       cv.visitInnerClass(name, outerName, innerName, access);
192     }
193   }
194
195   public void visitField (
196     final int access,
197     final String JavaDoc name,
198     final String JavaDoc desc,
199     final Object JavaDoc value,
200     final Attribute attrs)
201   {
202     buf.setLength(0);
203     if ((access & Constants.ACC_DEPRECATED) != 0) {
204       buf.append(" // DEPRECATED\n");
205     }
206     buf.append(" ");
207     appendAccess(access);
208     buf.append(desc)
209       .append(" ")
210       .append(name);
211     if (value != null) {
212       buf.append(" = ");
213       if (value instanceof String JavaDoc) {
214         buf.append("\"").append(value).append("\"");
215       } else {
216         buf.append(value);
217       }
218     }
219     Attribute attr = attrs;
220     while (attr != null) {
221       buf.append(" , FIELD ATTRIBUTE ").append(attr.type);
222       attr = attr.next;
223     }
224     buf.append("\n\n");
225     text.add(buf.toString());
226
227     if (cv != null) {
228       cv.visitField(access, name, desc, value, attrs);
229     }
230   }
231
232   public CodeVisitor visitMethod (
233     final int access,
234     final String JavaDoc name,
235     final String JavaDoc desc,
236     final String JavaDoc[] exceptions,
237     final Attribute attrs)
238   {
239     buf.setLength(0);
240     if ((access & Constants.ACC_DEPRECATED) != 0) {
241       buf.append(" // DEPRECATED\n");
242     }
243     buf.append(" ");
244     appendAccess(access);
245     buf.append(name).
246       append(" ").
247       append(desc);
248     if (exceptions != null && exceptions.length > 0) {
249       buf.append(" throws ");
250       for (int i = 0; i < exceptions.length; ++i) {
251         buf.append(exceptions[i]).append(" ");
252       }
253     }
254     buf.append("\n");
255     text.add(buf.toString());
256     Attribute attr = attrs;
257     while (attr != null) {
258       buf.setLength(0);
259       buf.append(" METHOD ATTRIBUTE ")
260         .append(attr.type)
261         .append("\n");
262       text.add(buf.toString());
263       attr = attr.next;
264     }
265
266     CodeVisitor cv;
267     if (this.cv != null) {
268       cv = this.cv.visitMethod(access, name, desc, exceptions, attrs);
269     } else {
270       cv = null;
271     }
272     PrintCodeVisitor pcv = new TraceCodeVisitor(cv);
273     text.add(pcv.getText());
274     return pcv;
275   }
276
277   public void visitAttribute (final Attribute attr) {
278     buf.setLength(0);
279     buf.append(" CLASS ATTRIBUTE ")
280       .append(attr.type)
281       .append("\n");
282     text.add(buf.toString());
283
284     if (cv != null) {
285       cv.visitAttribute(attr);
286     }
287   }
288
289   public void visitEnd () {
290     text.add("}\n");
291
292     if (cv != null) {
293       cv.visitEnd();
294     }
295
296     super.visitEnd();
297   }
298
299   /**
300    * Appends a string representation of the given access modifiers to {@link
301    * #buf buf}.
302    *
303    * @param access some access modifiers.
304    */

305
306   private void appendAccess (final int access) {
307     if ((access & Constants.ACC_PUBLIC) != 0) {
308       buf.append("public ");
309     }
310     if ((access & Constants.ACC_PRIVATE) != 0) {
311       buf.append("private ");
312     }
313     if ((access & Constants.ACC_PROTECTED) != 0) {
314       buf.append("protected ");
315     }
316     if ((access & Constants.ACC_FINAL) != 0) {
317       buf.append("final ");
318     }
319     if ((access & Constants.ACC_STATIC) != 0) {
320       buf.append("static ");
321     }
322     if ((access & Constants.ACC_SYNCHRONIZED) != 0) {
323       buf.append("synchronized ");
324     }
325     if ((access & Constants.ACC_VOLATILE) != 0) {
326       buf.append("volatile ");
327     }
328     if ((access & Constants.ACC_TRANSIENT) != 0) {
329       buf.append("transient ");
330     }
331     if ((access & Constants.ACC_NATIVE) != 0) {
332       buf.append("native ");
333     }
334     if ((access & Constants.ACC_ABSTRACT) != 0) {
335       buf.append("abstract ");
336     }
337     if ((access & Constants.ACC_STRICT) != 0) {
338       buf.append("strictfp ");
339     }
340   }
341 }
342
Popular Tags