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