KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hansel > Transformer


1 package org.hansel;
2
3 import java.io.ByteArrayInputStream JavaDoc;
4 import java.io.FileOutputStream JavaDoc;
5 import java.lang.instrument.ClassDefinition JavaDoc;
6 import java.lang.instrument.ClassFileTransformer JavaDoc;
7 import java.lang.instrument.IllegalClassFormatException JavaDoc;
8 import java.lang.instrument.Instrumentation JavaDoc;
9 import java.lang.instrument.UnmodifiableClassException JavaDoc;
10 import java.security.ProtectionDomain JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.Set JavaDoc;
13 import java.util.Vector JavaDoc;
14
15 import org.objectweb.asm.ClassReader;
16 import org.objectweb.asm.ClassWriter;
17 import org.objectweb.asm.tree.ClassNode;
18
19 public class Transformer implements ClassFileTransformer JavaDoc {
20     private Set JavaDoc<String JavaDoc> classNames;
21     private List JavaDoc<ClassEntry> redefinedClasses = new Vector JavaDoc<ClassEntry>();
22
23     public Transformer(Set JavaDoc<String JavaDoc> classNames) {
24         this.classNames = classNames;
25     }
26
27     public byte[] transform(ClassLoader JavaDoc loader,
28                             String JavaDoc className,
29                             Class JavaDoc<?> classBeingRedefined,
30                             ProtectionDomain JavaDoc protectionDomain,
31                             byte[] classfileBuffer)
32         throws IllegalClassFormatException JavaDoc {
33
34         if (!classNames.contains(className.replace('/', '.'))) {
35             return null;
36         }
37
38         try {
39             ClassReader cr = new ClassReader(new ByteArrayInputStream JavaDoc(classfileBuffer));
40             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS);
41          
42             ClassNode cn = new ClassNode();
43             cr.accept(cn, 0);
44
45             TransformingAdapter ta = new TransformingAdapter(cw, cn, loader);
46
47             cn.accept(ta);
48
49         //System.out.println("Redefining class: " + className + " " + loader);
50
redefinedClasses.add(new ClassEntry(className, loader,
51                                                 classfileBuffer));
52             byte[] result = cw.toByteArray();
53
54             if (cn.name.endsWith("Example")) {
55         FileOutputStream JavaDoc out = new FileOutputStream JavaDoc("test.class");
56         out.write(result);
57         out.close();
58              }
59         //System.out.println("Success: " + className);
60

61             return result;
62         } catch (Throwable JavaDoc e) {
63             e.printStackTrace();
64             throw new IllegalClassFormatException JavaDoc(e.getMessage());
65         }
66     }
67
68     public void undo(Instrumentation JavaDoc instrumentation)
69         throws ClassNotFoundException JavaDoc, UnmodifiableClassException JavaDoc {
70         
71         ClassDefinition JavaDoc[] oldClasses =
72         new ClassDefinition JavaDoc[redefinedClasses.size()];
73      
74         for (int i=0; i<oldClasses.length; i++) {
75             oldClasses[i] =
76                 redefinedClasses.get(i).toClassDefinition();
77         }
78
79         instrumentation.redefineClasses(oldClasses);
80     }
81
82     private static class ClassEntry {
83         private ClassLoader JavaDoc cl;
84         private byte[] classBuffer;
85         private String JavaDoc classname;
86         
87         public ClassEntry(String JavaDoc classname, ClassLoader JavaDoc cl,
88                           byte[] classBuffer) {
89             this.cl = cl;
90             this.classname = classname;
91             this.classBuffer = classBuffer;
92
93         /*try {
94         if (classname.endsWith("EventQueue")) {
95         FileOutputStream out = new FileOutputStream("testHansel.class");
96         out.write(classBuffer);
97         out.close();
98         }} catch (Exception e) {
99         e.printStackTrace();
100         } */

101         }
102
103         public ClassDefinition JavaDoc toClassDefinition() throws ClassNotFoundException JavaDoc {
104             return new ClassDefinition JavaDoc(cl.loadClass(classname.replace('/', '.')),
105                                        classBuffer);
106         }
107     }
108 }
109
Popular Tags