KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hansel > TransformingAdapter


1 package org.hansel;
2
3 import org.objectweb.asm.ClassAdapter;
4 import org.objectweb.asm.ClassVisitor;
5 import org.objectweb.asm.MethodVisitor;
6 import org.objectweb.asm.Opcodes;
7 import org.objectweb.asm.tree.ClassNode;
8 import org.objectweb.asm.tree.InsnList;
9 import org.objectweb.asm.tree.MethodNode;
10 import org.objectweb.asm.tree.analysis.Analyzer;
11 import org.objectweb.asm.tree.analysis.AnalyzerException;
12 import org.objectweb.asm.tree.analysis.Frame;
13
14 public class TransformingAdapter extends ClassAdapter {
15     private ClassNode classNode;
16     private ClassLoader JavaDoc loader;
17
18     public TransformingAdapter(final ClassVisitor cv, final ClassNode classNode,
19             ClassLoader JavaDoc loader) {
20         super(cv);
21         this.classNode = classNode;
22         this.loader = loader;
23     }
24     
25     public void visit(int version, int access, String JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] interfaces) {
26         super.visit(version, access, name, signature, superName, interfaces);
27     }
28
29     private MethodNode getMethodNode(String JavaDoc name, String JavaDoc desc) {
30         for (int i=0; i<classNode.methods.size(); i++) {
31             MethodNode mn = (MethodNode) classNode.methods.get(i);
32             if (mn.name.equals(name) && mn.desc.equals(desc)) {
33                 return mn;
34             }
35         }
36         
37         throw new IllegalStateException JavaDoc("Method: " + name + " - " + desc
38         + " not found.");
39     }
40
41     public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
42         //System.err.println("-->" + name);
43
try {
44             MethodNode mn = getMethodNode(name, desc);
45             if ((mn.access & Opcodes.ACC_ABSTRACT) != 0) {
46                 return cv.visitMethod(access, name, desc, signature,
47                                       exceptions);
48             }
49
50             if (isPrivateEmptyConstructor(name, access, mn.instructions)
51                 || isSynthetic(access)) {
52                 return super.visitMethod(access, name, desc, signature, exceptions);
53             }
54
55             Analyzer analyzer =
56             new Analyzer(new HanselInterpreter(/*mn.instructions, */mn.localVariables)) {
57                 protected Frame newFrame (final int nLocals, final int nStack) {
58                     return new HanselFrame(nLocals, nStack);
59                 }
60                 
61                 protected Frame newFrame (final Frame src) {
62                     return new HanselFrame((HanselFrame) src);
63                 }
64             };
65
66             Frame[] frames = analyzer.analyze(classNode.name, mn);
67             HanselFrame[] hanselFrames = new HanselFrame[frames.length];
68             for (int i=0; i<frames.length; i++) {
69                 hanselFrames[i] = (HanselFrame) frames[i];
70             }
71             return new HanselCodeAdapter(access, classNode.name, mn.name,
72                                          mn.instructions, mn.tryCatchBlocks,
73                                          cv.visitMethod(access, name, desc, signature,
74                                                         exceptions),
75                                          hanselFrames, loader);
76         } catch (AnalyzerException e) {
77             e.printStackTrace();
78            throw new IllegalStateException JavaDoc(classNode.name + "." + name, e);
79         }
80     }
81
82     private boolean isSynthetic(int access) {
83         return (access & Opcodes.ACC_SYNTHETIC) != 0;
84     }
85     
86     private boolean isPrivateEmptyConstructor(String JavaDoc name,
87                                               int access, InsnList instructions) {
88         return ((access & Opcodes.ACC_PRIVATE) != 0)
89         && "<init>".equals(name) && (instructions.size() == 6);
90     }
91 }
92
Popular Tags