KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > tool > ClassDiff


1 package alt.jiapi.tool;
2
3 import java.lang.reflect.Modifier JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.util.List JavaDoc;
6 import java.util.Iterator JavaDoc;
7
8 import alt.jiapi.file.*;
9 import alt.jiapi.reflect.*;
10 import alt.jiapi.reflect.instruction.*;
11
12 /**
13  * This class examines two class files, and reports differences
14  * between them
15  *
16  * @author Mika Riekkinen
17  */

18 public class ClassDiff {
19     private ClassFile f1;
20     private ClassFile f2;
21
22     public static void main(String JavaDoc[] args) throws IOException JavaDoc {
23         if (args.length != 2) {
24             System.out.println("Usage: ClassDiff <file1.class> <file2.class>");
25             System.exit(0);
26         }
27
28         ClassDiff cd = new ClassDiff(args[0], args[1]);
29         cd.runDiff();
30     }
31
32
33     public ClassDiff(String JavaDoc file1, String JavaDoc file2) throws IOException JavaDoc {
34         this.f1 = ClassFile.parse(file1);
35         this.f2 = ClassFile.parse(file2);
36     }
37
38     public void runDiff() {
39         diff("magic-number", f1.getMagicNumber(), f2.getMagicNumber());
40         diff("major-version", f1.getMajorVersion(), f2.getMajorVersion());
41         diff("minor-version", f1.getMinorVersion(), f2.getMinorVersion());
42         
43         //diffConstantPool();
44

45         diff("access-flags", f1.getAccessFlags(), f2.getAccessFlags());
46         ConstantPool cp1 = f1.getConstantPool();
47         ConstantPool cp2 = f2.getConstantPool();
48         
49         diffCPEntry("this_class",
50              cp1.get(f1.getThisClassIndex()),
51              cp2.get(f2.getThisClassIndex()));
52
53         diffCPEntry("super_class",
54              cp1.get(f1.getSuperClassIndex()),
55              cp2.get(f2.getSuperClassIndex()));
56
57         diffInterfaces("interface", f1.getInterfaces(), f2.getInterfaces());
58         diffFields("field", f1.getFields(), f2.getFields());
59         diffMethods("method", f1.getMethods(), f2.getMethods());
60     }
61
62     public void diff(String JavaDoc dName, int i1, int i2) {
63         if (i1 != i2) {
64             System.out.println("< " + dName + ": " + i1);
65             System.out.println("> " + dName + ": " + i2);
66         }
67     }
68
69
70     private void diffInstructions(Instruction i1, Instruction i2) {
71         if (i1.getOpcode() != i2.getOpcode()) {
72             System.out.println("< instruction: " + i1);
73             System.out.println("> instruction: " + i2);
74             return;
75         }
76
77         if (i1 instanceof CPInstruction) {
78             CPInstruction cpIns1 = (CPInstruction)i1;
79             CPInstruction cpIns2 = (CPInstruction)i2;
80
81             diffCPEntry("instruction, constant-pool entry",
82                         cpIns1.getEntry(), cpIns2.getEntry());
83         }
84     }
85
86     public void diffCPEntry(String JavaDoc name, ConstantPool.Entry e1,
87                             ConstantPool.Entry e2) {
88         if (e1.getClass().getName() != e2.getClass().getName()) {
89             System.out.println("< " + name + ": " + e1);
90             System.out.println("> " + name + ": " + e2);
91             return;
92         }
93
94         if (e1 instanceof ConstantPool.ClassInfo) {
95             ConstantPool.ClassInfo ci1 = (ConstantPool.ClassInfo)e1;
96             ConstantPool.ClassInfo ci2 = (ConstantPool.ClassInfo)e2;
97             String JavaDoc cn1 = ci1.getName();
98             String JavaDoc cn2 = ci2.getName();
99             if (!cn1.equals(cn2)) {
100                 System.out.println("< " + name + ": " + cn1);
101                 System.out.println("> " + name + ": " + cn2);
102                 return;
103             }
104         }
105         else if (e1 instanceof ConstantPool.FieldRefInfo) {
106             ConstantPool.FieldRefInfo fri1 = (ConstantPool.FieldRefInfo)e1;
107             ConstantPool.FieldRefInfo fri2 = (ConstantPool.FieldRefInfo)e2;
108             if (!(fri1.getFieldName().equals(fri2.getFieldName()) &&
109                   fri2.getDescriptor().equals(fri2.getDescriptor()))) {
110                 System.out.println("< " + name + ": " + e1);
111                 System.out.println("> " + name + ": " + e2);
112                 return;
113             }
114         }
115         else if (e1 instanceof ConstantPool.MethodRefInfo) {
116             ConstantPool.MethodRefInfo mri1 = (ConstantPool.MethodRefInfo)e1;
117             ConstantPool.MethodRefInfo mri2 = (ConstantPool.MethodRefInfo)e2;
118             if (!(mri1.getMethodName().equals(mri2.getMethodName()) &&
119                   mri2.getDescriptor().equals(mri2.getDescriptor()))) {
120                 System.out.println("< " + name + ": " + e1);
121                 System.out.println("> " + name + ": " + e2);
122                 return;
123             }
124         }
125         else if (e1 instanceof ConstantPool.StringInfo) {
126             ConstantPool.StringInfo si1 = (ConstantPool.StringInfo)e1;
127             ConstantPool.StringInfo si2 = (ConstantPool.StringInfo)e2;
128             if (!si1.stringValue().equals(si2.stringValue())) {
129                 System.out.println("< " + name + ": " + si1.stringValue());
130                 System.out.println("> " + name + ": " + si2.stringValue());
131                 return;
132             }
133         }
134         else {
135             System.out.println("ERROR: comparison not defined: " + e1 + ", " +
136                                e2);
137         }
138     }
139
140
141     private void diffInterfaces(String JavaDoc name, List JavaDoc il1, List JavaDoc il2) {
142         Iterator JavaDoc i1 = il1.iterator();
143         Iterator JavaDoc i2 = il2.iterator();
144
145         Interface if1 = null;
146         Interface if2 = null;
147         while(i1.hasNext()) {
148             if1 = (Interface)i1.next();
149             String JavaDoc n1 = if1.getName();
150             String JavaDoc n2 = null;
151             if (i2.hasNext()) {
152                 if2 = (Interface)i2.next();
153                 n2 = if2.getName();
154             }
155
156             if (n2 != null) {
157                 if (!(n1.equals(n2))) {
158                     System.out.println("< " + name + ": " + n1);
159                     System.out.println("> " + name + ": " + n2);
160                 }
161             }
162             else {
163                 System.out.println("< only here, " + name + ": " + n1);
164             }
165         }
166
167         while(i2.hasNext()) {
168             if2 = (Interface)i2.next();
169             System.out.println("> only here, " + name + ": " + if2.getName());
170         }
171     }
172
173
174     private void diffFields(String JavaDoc name, List JavaDoc il1, List JavaDoc il2) {
175         Iterator JavaDoc i = il1.iterator();
176         while(i.hasNext()) {
177             Field f1 = (Field)i.next();
178             Field f2 = findField(f1.getName(), f1.getDescriptor(), il2);
179
180             if (f2 != null) {
181                 if (f1.getAccessFlags() != f2.getAccessFlags()) {
182                     System.out.println("< " + name + ": " +
183                                        Modifier.toString(f1.getAccessFlags()) +
184                                        " " + f1.getName() + " " +
185                                        f1.getDescriptor());
186                     System.out.println("> " + name + ": " +
187                                        Modifier.toString(f2.getAccessFlags()) +
188                                        " " + f2.getName() + " " +
189                                        f2.getDescriptor());
190                 }
191
192                 diffAttributes("field", f1.getName(), f2.getName(),
193                                f1.getAttributes(), f2.getAttributes());
194             }
195             else {
196                 System.out.println("< only here, " + name + ": " +
197                                    Modifier.toString(f1.getAccessFlags()) +" "+
198                                    f1.getName()+ f1.getDescriptor());
199             }
200         }
201
202
203         i = il2.iterator();
204         while(i.hasNext()) {
205             Field f1 = (Field)i.next();
206             Field f2 = findField(f1.getName(), f1.getDescriptor(), il1);
207
208             if (f2 == null) {
209                 System.out.println("> only here, " + name + ": " +
210                                    Modifier.toString(f1.getAccessFlags()) +" "+
211                                    f1.getName()+ f1.getDescriptor());
212             }
213         }
214     }
215
216
217     private void diffMethods(String JavaDoc name, List JavaDoc il1, List JavaDoc il2) {
218         Iterator JavaDoc i = il1.iterator();
219         while(i.hasNext()) {
220             Method m1 = (Method)i.next();
221             Method m2 = findMethod(m1.getName(), m1.getDescriptor(), il2);
222
223             if (m2 != null) {
224                 if (m1.getAccessFlags() != m2.getAccessFlags()) {
225                     System.out.println("< " + name + ": " +
226                                        Modifier.toString(m1.getAccessFlags()) +
227                                        " " + m1.getName() +m1.getDescriptor());
228                     System.out.println("> " + name + ": " +
229                                        Modifier.toString(m2.getAccessFlags()) +
230                                        " " + m2.getName() +m2.getDescriptor());
231                 }
232
233                 diffAttributes("method", m1.getName(), m2.getName(),
234                                m1.getAttributes(), m2.getAttributes());
235             }
236             else {
237                 System.out.println("< only here, " + name + ": " +
238                                    Modifier.toString(m1.getAccessFlags()) +" "+
239                                    m1.getName()+ m1.getDescriptor());
240             }
241
242             JiapiMethod jm1 = new JiapiMethod(m1);
243             JiapiMethod jm2 = new JiapiMethod(m2);
244             diffInstructions(jm1, jm2);
245         }
246
247
248         i = il2.iterator();
249         while(i.hasNext()) {
250             Method m1 = (Method)i.next();
251             Method m2 = findMethod(m1.getName(), m1.getDescriptor(), il1);
252
253             if (m2 == null) {
254                 System.out.println("> only here, " + name + ": " +
255                                    Modifier.toString(m1.getAccessFlags()) +" "+
256                                    m1.getName()+ m1.getDescriptor());
257             }
258         }
259     }
260
261
262
263     private void diffAttributes(String JavaDoc name, String JavaDoc n1, String JavaDoc n2,
264                                 List JavaDoc al1, List JavaDoc al2) {
265         Iterator JavaDoc i = al1.iterator();
266         while(i.hasNext()) {
267             Attribute a1 = (Attribute)i.next();
268             Attribute a2 = findAttribute(a1.getName(), al2);
269
270             if (a2 != null) {
271                 if (a1 instanceof CodeAttribute) {
272                     diffCodeAttributes((CodeAttribute)a1, (CodeAttribute)a2);
273                 }
274                 else if (a1 instanceof LineNumberTableAttribute) {
275                     diffLNTableAttributes((LineNumberTableAttribute)a1,
276                                           (LineNumberTableAttribute)a2);
277                 }
278                 else if (a1 instanceof LocalVariableTableAttribute) {
279                     diffLVTableAttributes((LocalVariableTableAttribute)a1,
280                                           (LocalVariableTableAttribute)a2);
281                 }
282                 else {
283                     System.out.println("diff: " + a1.getName() +
284                                        " not implemented");
285                 }
286             }
287             else {
288                 System.out.println("< only here, " + name + "(" + n1 +
289                                    ") attribute: '" + a1.getName() + "'");
290                 if (a1 instanceof LocalVariableTableAttribute) {
291                     printLVTable((LocalVariableTableAttribute)a1);
292                 }
293             }
294         }
295
296
297         i = al2.iterator();
298         while(i.hasNext()) {
299             Attribute a1 = (Attribute)i.next();
300             Attribute a2 = findAttribute(a1.getName(), al1);
301
302             if (a2 == null) {
303                 System.out.println("> only here, " + name + "(" + n2 +
304                                    ") attribute: '" + a1.getName() + "'");
305                 if (a1 instanceof LocalVariableTableAttribute) {
306                     printLVTable((LocalVariableTableAttribute)a1);
307                 }
308             }
309         }
310     }
311
312     private void diffInstructions(JiapiMethod jm1, JiapiMethod jm2){
313         InstructionList il1 = jm1.getInstructionList();
314         InstructionList il2 = jm2.getInstructionList();
315
316         diff("instruction-list size", il1.size(), il2.size());
317
318         for (int i = 0; (i < il1.size()) && (i < il2.size()); i++) {
319             diffInstructions(il1.get(i), il2.get(i));
320         }
321     }
322
323
324     private void diffCodeAttributes(CodeAttribute a1, CodeAttribute a2) {
325         diff("max-locals", a1.getMaxLocals(), a2.getMaxLocals());
326         diff("max-stack", a1.getMaxStack(), a2.getMaxStack());
327
328         diffAttributes("attribute", "c1", "c2",
329                        a1.getAttributes(), a2.getAttributes());
330     }
331
332     private void diffLNTableAttributes(LineNumberTableAttribute a1,
333                                        LineNumberTableAttribute a2) {
334     }
335
336     private void diffLVTableAttributes(LocalVariableTableAttribute a1,
337                                        LocalVariableTableAttribute a2) {
338     }
339
340
341     private Method findMethod(String JavaDoc name, String JavaDoc descriptor, List JavaDoc il) {
342         Iterator JavaDoc i = il.iterator();
343         while(i.hasNext()) {
344             Method m = (Method)i.next();
345             if (name.equals(m.getName()) &&
346                 descriptor.equals(m.getDescriptor())) {
347                 return m;
348             }
349         }
350
351         return null;
352     }
353
354     private Field findField(String JavaDoc name, String JavaDoc descriptor, List JavaDoc il) {
355         Iterator JavaDoc i = il.iterator();
356         while(i.hasNext()) {
357             Field f = (Field)i.next();
358             if (name.equals(f.getName()) &&
359                 descriptor.equals(f.getDescriptor())) {
360                 return f;
361             }
362         }
363
364         return null;
365     }
366
367     private Attribute findAttribute(String JavaDoc name, List JavaDoc il) {
368         Iterator JavaDoc i = il.iterator();
369         while(i.hasNext()) {
370             Attribute a = (Attribute)i.next();
371             if (name.equals(a.getName())) {
372                 return a;
373             }
374         }
375
376         return null;
377     }
378
379     private void printLVTable(LocalVariableTableAttribute lvta) {
380         List JavaDoc lvt = lvta.getLocalVariables();
381         System.out.println(lvt.size() + " local variables");
382         Iterator JavaDoc i = lvt.iterator();
383         System.out.println(" start_pc length name descriptor index");
384         while(i.hasNext()) {
385             LocalVariableTableAttribute.LocalVariable lv =
386                 (LocalVariableTableAttribute.LocalVariable)i.next();
387             
388             System.out.println(" " + lv.getStartPc() + " " + lv.getLength() +
389                                " " + lv.getName() + " " + lv.getDescriptor() +
390                                " " + lv.getIndex());
391         }
392     }
393 }
394
Popular Tags