KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > loskutov > bco > asm > DecompilerClassVisitor


1 package de.loskutov.bco.asm;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.BitSet JavaDoc;
7 import java.util.List JavaDoc;
8
9 import org.objectweb.asm.AnnotationVisitor;
10 import org.objectweb.asm.Attribute;
11 import org.objectweb.asm.ClassAdapter;
12 import org.objectweb.asm.ClassReader;
13 import org.objectweb.asm.ClassVisitor;
14 import org.objectweb.asm.FieldVisitor;
15 import org.objectweb.asm.MethodVisitor;
16 import org.objectweb.asm.tree.ClassNode;
17 import org.objectweb.asm.tree.MethodNode;
18 import org.objectweb.asm.util.AbstractVisitor;
19
20 import de.loskutov.bco.asm.CommentedClassVisitor.CommentedAnnotationVisitor;
21 import de.loskutov.bco.asm.CommentedClassVisitor.CommentedFieldVisitor;
22 import de.loskutov.bco.preferences.BCOConstants;
23
24 /**
25  * @author Eric Bruneton
26  */

27
28 public class DecompilerClassVisitor extends ClassAdapter {
29
30     private final String JavaDoc fieldFilter;
31
32     private final String JavaDoc methodFilter;
33
34     private String JavaDoc name;
35
36     private final List JavaDoc methods;
37
38     private AnnotationVisitor dummyAnnVisitor;
39
40     private String JavaDoc javaVersion;
41
42     private final BitSet JavaDoc modes;
43
44     private int accessFlags;
45
46     private ClassNode classNode;
47
48     public DecompilerClassVisitor(final ClassVisitor cv, final String JavaDoc field,
49         final String JavaDoc method, final BitSet JavaDoc modes) {
50         super(cv);
51         this.classNode = new ClassNode();
52         this.fieldFilter = field;
53         this.methodFilter = method;
54         this.modes = modes;
55         this.methods = new ArrayList JavaDoc();
56     }
57
58     public static DecompiledClass getDecompiledClass(final InputStream JavaDoc is,
59         final String JavaDoc field, final String JavaDoc method, final BitSet JavaDoc modes, final ClassLoader JavaDoc cl)
60         throws IOException JavaDoc, UnsupportedClassVersionError JavaDoc {
61         ClassReader cr = new ClassReader(is);
62         int crFlags = 0;
63         if(modes.get(BCOConstants.F_EXPAND_STACKMAP)) {
64             crFlags |= ClassReader.EXPAND_FRAMES;
65         }
66         ClassVisitor cv;
67         if (modes.get(BCOConstants.F_SHOW_ASMIFIER_CODE)) {
68             cv = new CommentedASMifierClassVisitor(modes);
69         } else {
70             cv = new CommentedClassVisitor(modes);
71         }
72         DecompilerClassVisitor dcv = new DecompilerClassVisitor(
73             cv, field, method, modes);
74         cr.accept(dcv, crFlags);
75         return dcv.getResult(cl);
76     }
77
78     public DecompiledClass getResult(final ClassLoader JavaDoc cl) {
79         List JavaDoc text = new ArrayList JavaDoc();
80         formatText(((AbstractVisitor) cv).getText(), new StringBuffer JavaDoc(), text, cl);
81         while (text.size() > 0 && text.get(0).equals("\n")) {
82             text.remove(0);
83         }
84         DecompiledClass dc = new DecompiledClass(text);
85         dc.setAttribute(DecompiledClass.ATTR_JAVA_VERSION, javaVersion);
86         dc.setAttribute(DecompiledClass.ATTR_ACCESS_FLAGS, String.valueOf(accessFlags));
87         dc.setClassNode(classNode);
88         return dc;
89     }
90
91     private void formatText(final List JavaDoc input, StringBuffer JavaDoc line, final List JavaDoc result,
92         final ClassLoader JavaDoc cl) {
93         for (int i = 0; i < input.size(); ++i) {
94             Object JavaDoc o = input.get(i);
95             if (o instanceof List JavaDoc) {
96                 formatText((List JavaDoc) o, line, result, cl);
97             } else if (o instanceof DecompilerMethodVisitor) {
98                 result.add(((DecompilerMethodVisitor) o).getResult(cl));
99             } else {
100                 String JavaDoc s = o.toString();
101                 int p;
102                 do {
103                     p = s.indexOf('\n');
104                     if (p == -1) {
105                         line.append(s);
106                     } else {
107                         result.add(line.toString() + s.substring(0, p + 1));
108                         s = s.substring(p + 1);
109                         line.setLength(0);
110                     }
111                 } while (p != -1);
112             }
113         }
114     }
115
116     public void visit(final int version, final int access, final String JavaDoc name1,
117         final String JavaDoc signature, final String JavaDoc superName,
118         final String JavaDoc[] interfaces) {
119         if (methodFilter == null && fieldFilter == null) {
120             super
121                 .visit(version, access, name1, signature, superName, interfaces);
122             classNode.visit(version, access, name1, signature, superName, interfaces);
123         }
124         this.name = name1;
125         int major = version & 0xFFFF;
126         //int minor = version >>> 16;
127
// 1.1 is 45, 1.2 is 46 etc.
128
int javaV = major % 44;
129         if (javaV > 0 && javaV < 10) {
130             javaVersion = "1." + javaV; //$NON-NLS-1$
131
}
132
133         this.accessFlags = access;
134     }
135
136     public void visitSource(final String JavaDoc source, final String JavaDoc debug) {
137         if (methodFilter == null && fieldFilter == null) {
138             super.visitSource(source, debug);
139             classNode.visitSource(source, debug);
140         }
141     }
142
143     public void visitOuterClass(final String JavaDoc owner, final String JavaDoc name1,
144         final String JavaDoc desc) {
145         if (methodFilter == null && fieldFilter == null) {
146             super.visitOuterClass(owner, name1, desc);
147             classNode.visitOuterClass(owner, name1, desc);
148         }
149     }
150
151     public AnnotationVisitor visitAnnotation(final String JavaDoc desc,
152         final boolean visible) {
153         if (methodFilter == null && fieldFilter == null) {
154             AnnotationVisitor cav = classNode.visitAnnotation(desc, visible);
155             AnnotationVisitor av = super.visitAnnotation(desc, visible);
156             if(av instanceof CommentedAnnotationVisitor){
157                 CommentedAnnotationVisitor visitor = (CommentedAnnotationVisitor) av;
158                 visitor.setAnnotationVisitor(cav);
159             }
160             return av;
161         }
162         return getDummyAnnotationVisitor();
163     }
164
165     public void visitAttribute(final Attribute attr) {
166         if (methodFilter == null && fieldFilter == null) {
167             super.visitAttribute(attr);
168             classNode.visitAttribute(attr);
169         }
170     }
171
172     public void visitInnerClass(final String JavaDoc name1, final String JavaDoc outerName,
173         final String JavaDoc innerName, final int access) {
174         if (methodFilter == null && fieldFilter == null) {
175             super.visitInnerClass(name1, outerName, innerName, access);
176             classNode.visitInnerClass(name1, outerName, innerName, access);
177         }
178     }
179
180     public FieldVisitor visitField(final int access, final String JavaDoc name1,
181         final String JavaDoc desc, final String JavaDoc signature, final Object JavaDoc value) {
182         if (methodFilter != null) {
183             return null;
184         }
185         if (fieldFilter != null && !name1.equals(fieldFilter)) {
186             return null;
187         }
188         FieldVisitor cfv = classNode.visitField(access, name1, desc, signature, value);
189         FieldVisitor fieldVisitor = super.visitField(access, name1, desc, signature, value);
190         if(fieldVisitor instanceof CommentedFieldVisitor){
191             CommentedFieldVisitor visitor = (CommentedFieldVisitor) fieldVisitor;
192             visitor.setFieldVisitor(cfv);
193         }
194         return fieldVisitor;
195     }
196
197     public MethodVisitor visitMethod(final int access, final String JavaDoc name1,
198         final String JavaDoc desc, final String JavaDoc signature, final String JavaDoc[] exceptions) {
199         if (fieldFilter != null) {
200             return null;
201         }
202         if (methodFilter != null && !(name1 + desc).equals(methodFilter)) {
203             return null;
204         }
205         MethodNode meth = (MethodNode) classNode.visitMethod(
206             access, name1, desc, signature, exceptions);
207         List JavaDoc text = ((AbstractVisitor) cv).getText();
208         int size = text.size();
209         MethodVisitor mv = cv.visitMethod(
210             access, name1, desc, signature, exceptions);
211         mv = new DecompilerMethodVisitor(this.name, meth, mv, modes);
212         methods.add(mv);
213         for (int i = size; i < text.size(); ++i) {
214             if (text.get(i) instanceof List JavaDoc) {
215                 text.set(i, mv);
216             }
217         }
218         return mv;
219     }
220
221     public void visitEnd() {
222         if (methodFilter == null && fieldFilter == null) {
223             classNode.visitEnd();
224             super.visitEnd();
225         }
226     }
227
228     private AnnotationVisitor getDummyAnnotationVisitor(){
229         if (dummyAnnVisitor == null) {
230             dummyAnnVisitor = new AnnotationVisitor() {
231                 public void visit(String JavaDoc n, Object JavaDoc value) {
232                     /* empty */
233                 }
234                 public void visitEnum(String JavaDoc n, String JavaDoc desc, String JavaDoc value) {
235                     /* empty */
236                 }
237                 public AnnotationVisitor visitAnnotation(String JavaDoc n, String JavaDoc desc) {
238                     return this;
239                 }
240                 public AnnotationVisitor visitArray(String JavaDoc n) {
241                     return this;
242                 }
243                 public void visitEnd() {
244                     /* empty*/
245                 }
246             };
247         }
248         return dummyAnnVisitor;
249     }
250 }
251
Popular Tags