1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.jdo.impl.enhancer.util;
19
20 import java.util.Iterator;
21 import java.util.Enumeration;
22 import java.util.List;
23 import java.util.ArrayList;
24 import java.util.Map;
25 import java.util.HashMap;
26 import java.util.Set;
27 import java.util.HashSet;
28 import java.util.Stack;
29
30 import java.io.PrintWriter;
31 import java.io.StringWriter;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.FileInputStream;
35 import java.io.BufferedInputStream;
36 import java.io.DataInputStream;
37 import java.io.FileNotFoundException;
38 import java.io.ByteArrayOutputStream;
39 import java.io.PrintStream;
40
41 import org.apache.jdo.impl.enhancer.ClassArgMain;
42 import org.apache.jdo.impl.enhancer.EnhancerFatalError;
43 import org.apache.jdo.impl.enhancer.classfile.ClassFile;
44
45
46
47
48 /***
49 * Utility class for testing two class files for equal augmentation.
50 *
51 * @author Martin Zaun
52 */
53 public class Disassembler
54 extends ClassArgMain
55 {
56
57 static public final int AFFIRMATIVE = 1;
58 static public final int NEGATIVE = 0;
59 static public final int ERROR = -1;
60
61
62
63 private boolean verbose;
64
65 public Disassembler(PrintWriter out,
66 PrintWriter err)
67 {
68 super(out, err);
69 }
70
71 private int disassemble(PrintWriter out,
72 String className,
73 String classFileName)
74 {
75 affirm(className == null ^ classFileName == null);
76 final String name = (className != null ? className : classFileName);
77
78 DataInputStream dis = null;
79 try {
80 if (className != null) {
81 dis = new DataInputStream(openClassInputStream(className));
82 } else {
83 dis = new DataInputStream(openFileInputStream(classFileName));
84 }
85 final boolean allowJDK12ClassFiles = true;
86 final ClassFile classFile
87 = new ClassFile(dis, allowJDK12ClassFiles);
88 out.println(" +++ parsed class");
89
90 final ByteArrayOutputStream b = new ByteArrayOutputStream();
91 if (verbose) {
92 classFile.print(new PrintStream(b), 0);
93 out.println(b.toString());
94 }
95 out.println("Statistics:");
96 classFile.summarize(new PrintStream(b), 4);
97 out.println(b.toString());
98 } catch (ClassFormatError ex) {
99 out.println(" !!! ERROR: format error when parsing class: "
100 + name);
101 out.println(" error: " + err);
102 return ERROR;
103 } catch (IOException ex) {
104 out.println(" !!! ERROR: exception while reading class: "
105 + name);
106 out.println(" exception: " + ex);
107 return ERROR;
108 } finally {
109 closeInputStream(dis);
110 }
111
112 return AFFIRMATIVE;
113 }
114
115 protected int disassemble(PrintWriter out,
116 boolean verbose,
117 List classNames,
118 List classFileNames)
119 {
120 affirm(classNames);
121 affirm(classFileNames);
122 this.verbose = verbose;
123
124 out.println();
125 out.println("Disassembler: Dumps out the java byte-code for classes.");
126
127 int nofFailed = 0;
128 final int all = classNames.size() + classFileNames.size();
129 for (int i = 0; i < classNames.size(); i++) {
130 out.println("-------------------------------------------------------------------------------");
131 out.println();
132
133
134 final String className = (String)classNames.get(i);
135 final StringWriter s = new StringWriter();
136 if (disassemble(new PrintWriter(s), className, null) < NEGATIVE) {
137 out.println();
138 out.println("!!! ERROR: failed disassembling class: "
139 + className);
140 out.println(s.toString());
141 nofFailed++;
142 }
143
144 out.println("+++ disassembled class: " + className);
145 out.println();
146 out.println(s.toString());
147 }
148 for (int i = 0; i < classFileNames.size(); i++) {
149 out.println("-------------------------------------------------------------------------------");
150 out.println();
151
152
153 final String classFileName = (String)classFileNames.get(i);
154 final StringWriter s = new StringWriter();
155 if (disassemble(new PrintWriter(s), null, classFileName) < NEGATIVE) {
156 out.println();
157 out.println("!!! ERROR: failed disassembling class: "
158 + classFileName);
159 out.println(s.toString());
160 nofFailed++;
161 }
162
163 out.println("+++ disassembled class: " + classFileName);
164 out.println();
165 out.println(s.toString());
166 }
167 final int nofPassed = all - nofFailed;
168
169 out.println();
170 out.println("Disassembler: Summary: PROCESSED: " + all
171 + " PASSED: " + nofPassed
172 + " FAILED: " + nofFailed);
173 return nofFailed;
174 }
175
176
177
178 /***
179 * Run the disassembler.
180 */
181 protected int process()
182 {
183
184 return disassemble(out, options.verbose.value,
185 options.classNames, options.classFileNames);
186 }
187
188 static public void main(String[] args)
189 {
190 final PrintWriter out = new PrintWriter(System.out, true);
191 out.println("--> Disassembler.main()");
192 final Disassembler main = new Disassembler(out, out);
193 int res = main.run(args);
194 out.println("<-- Disassembler.main(): exit = " + res);
195 System.exit(res);
196 }
197 }