001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.bytecode;
017:
018: import java.io.PrintWriter;
019: import javassist.Modifier;
020: import java.util.List;
021:
022: /**
023: * A utility class for priting the contents of a class file.
024: * It prints a constant pool table, fields, and methods in a
025: * human readable representation.
026: */
027: public class ClassFileWriter {
028: /**
029: * Prints the contents of a class file to the standard output stream.
030: */
031: public static void print(ClassFile cf) {
032: print(cf, new PrintWriter(System.out, true));
033: }
034:
035: /**
036: * Prints the contents of a class file.
037: */
038: public static void print(ClassFile cf, PrintWriter out) {
039: List list;
040: int n;
041:
042: /* 0x0020 (SYNCHRONIZED) means ACC_SUPER if the modifiers
043: * are of a class.
044: */
045: int mod = AccessFlag.toModifier(cf.getAccessFlags()
046: & ~AccessFlag.SYNCHRONIZED);
047: out.println("major: " + cf.major + ", minor: " + cf.minor);
048: out.println(Modifier.toString(mod) + " class " + cf.getName()
049: + " extends " + cf.getSuperclass());
050:
051: String[] infs = cf.getInterfaces();
052: if (infs != null && infs.length > 0) {
053: out.print(" implements ");
054: out.print(infs[0]);
055: for (int i = 1; i < infs.length; ++i)
056: out.print(", " + infs[i]);
057:
058: out.println();
059: }
060:
061: out.println();
062: list = cf.getFields();
063: n = list.size();
064: for (int i = 0; i < n; ++i) {
065: FieldInfo finfo = (FieldInfo) list.get(i);
066: int acc = finfo.getAccessFlags();
067: out.println(Modifier.toString(AccessFlag.toModifier(acc))
068: + " " + finfo.getName() + "\t"
069: + finfo.getDescriptor());
070: printAttributes(finfo.getAttributes(), out);
071: }
072:
073: out.println();
074: list = cf.getMethods();
075: n = list.size();
076: for (int i = 0; i < n; ++i) {
077: MethodInfo minfo = (MethodInfo) list.get(i);
078: int acc = minfo.getAccessFlags();
079: out.println(Modifier.toString(AccessFlag.toModifier(acc))
080: + " " + minfo.getName() + "\t"
081: + minfo.getDescriptor());
082: printAttributes(minfo.getAttributes(), out);
083: out.println();
084: }
085:
086: out.println();
087: printAttributes(cf.getAttributes(), out);
088: }
089:
090: static void printAttributes(List list, PrintWriter out) {
091: if (list == null)
092: return;
093:
094: int n = list.size();
095: for (int i = 0; i < n; ++i) {
096: AttributeInfo ai = (AttributeInfo) list.get(i);
097: if (ai instanceof CodeAttribute) {
098: CodeAttribute ca = (CodeAttribute) ai;
099: out.println("attribute: " + ai.getName() + ": "
100: + ai.getClass().getName());
101: out.println("max stack " + ca.getMaxStack()
102: + ", max locals " + ca.getMaxLocals() + ", "
103: + ca.getExceptionTable().size()
104: + " catch blocks");
105: out.println("<code attribute begin>");
106: printAttributes(ca.getAttributes(), out);
107: out.println("<code attribute end>");
108: } else
109: out.println("attribute: " + ai.getName() + " ("
110: + ai.get().length + " byte): "
111: + ai.getClass().getName());
112: }
113: }
114: }
|