KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > asm > ClassWriterComputeFramesTest


1 /***
2  * ASM tests
3  * Copyright (c) 2002-2005 France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package org.objectweb.asm;
31
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.PrintWriter JavaDoc;
35 import java.io.StringWriter JavaDoc;
36 import java.lang.instrument.ClassFileTransformer JavaDoc;
37 import java.lang.instrument.IllegalClassFormatException JavaDoc;
38 import java.lang.instrument.Instrumentation JavaDoc;
39 import java.security.ProtectionDomain JavaDoc;
40
41 import org.objectweb.asm.util.TraceClassVisitor;
42
43 import junit.framework.TestSuite;
44
45 /**
46  * ClassWriter tests.
47  *
48  * @author Eric Bruneton
49  */

50 public class ClassWriterComputeFramesTest extends AbstractTest {
51
52     public static void premain(
53         final String JavaDoc agentArgs,
54         final Instrumentation JavaDoc inst)
55     {
56         inst.addTransformer(new ClassFileTransformer JavaDoc() {
57             public byte[] transform(
58                 final ClassLoader JavaDoc loader,
59                 final String JavaDoc className,
60                 final Class JavaDoc classBeingRedefined,
61                 final ProtectionDomain JavaDoc domain,
62                 final byte[] classFileBuffer)
63                     throws IllegalClassFormatException JavaDoc
64             {
65                 String JavaDoc n = className.replace('/', '.');
66                 if (n.indexOf("junit") != -1) {
67                     return null;
68                 }
69                 if (agentArgs.length() == 0 || n.indexOf(agentArgs) != -1) {
70                     return transformClass(n, classFileBuffer);
71                 } else {
72                     return null;
73                 }
74             }
75         });
76     }
77
78     private static byte[] transformClass(final String JavaDoc n, final byte[] clazz) {
79         ClassReader cr = new ClassReader(clazz);
80         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES) {
81             protected String JavaDoc getCommonSuperClass(
82                 final String JavaDoc type1,
83                 final String JavaDoc type2)
84             {
85                 if (n.equals("pkg.Frames")) {
86                     return super.getCommonSuperClass(type1, type2);
87                 }
88                 ClassInfo c, d;
89                 try {
90                     c = new ClassInfo(type1, getClass().getClassLoader());
91                     d = new ClassInfo(type2, getClass().getClassLoader());
92                 } catch (Throwable JavaDoc e) {
93                     throw new RuntimeException JavaDoc(e);
94                 }
95                 if (c.isAssignableFrom(d)) {
96                     return type1;
97                 }
98                 if (d.isAssignableFrom(c)) {
99                     return type2;
100                 }
101                 if (c.isInterface() || d.isInterface()) {
102                     return "java/lang/Object";
103                 } else {
104                     do {
105                         c = c.getSuperclass();
106                     } while (!c.isAssignableFrom(d));
107                     return c.getType().getInternalName();
108                 }
109             }
110         };
111         cr.accept(new ClassAdapter(cw) {
112
113             public void visit(
114                 final int version,
115                 final int access,
116                 final String JavaDoc name,
117                 final String JavaDoc signature,
118                 final String JavaDoc superName,
119                 final String JavaDoc[] interfaces)
120             {
121                 super.visit(Opcodes.V1_6,
122                         access,
123                         name,
124                         signature,
125                         superName,
126                         interfaces);
127             }
128
129         }, ClassReader.SKIP_FRAMES);
130         return cw.toByteArray();
131     }
132
133     public static TestSuite suite() throws Exception JavaDoc {
134         return new ClassWriterComputeFramesTest().getSuite();
135     }
136
137     public void test() throws Exception JavaDoc {
138         try {
139             Class.forName(n, true, getClass().getClassLoader());
140         } catch (NoClassDefFoundError JavaDoc ncdfe) {
141             // ignored
142
} catch (UnsatisfiedLinkError JavaDoc ule) {
143             // ignored
144
} catch (ClassFormatError JavaDoc cfe) {
145             fail(cfe.getMessage());
146         } catch (VerifyError JavaDoc ve) {
147             String JavaDoc s = n.replace('.', '/') + ".class";
148             InputStream JavaDoc is = getClass().getClassLoader().getResourceAsStream(s);
149             ClassReader cr = new ClassReader(is);
150             byte[] b = transformClass("", cr.b);
151             StringWriter JavaDoc sw1 = new StringWriter JavaDoc();
152             StringWriter JavaDoc sw2 = new StringWriter JavaDoc();
153             sw2.write(ve.toString() + "\n");
154             ClassVisitor cv1 = new TraceClassVisitor(new PrintWriter JavaDoc(sw1));
155             ClassVisitor cv2 = new TraceClassVisitor(new PrintWriter JavaDoc(sw2));
156             cr.accept(cv1, 0);
157             new ClassReader(b).accept(cv2, 0);
158             String JavaDoc s1 = sw1.toString();
159             String JavaDoc s2 = sw2.toString();
160             assertEquals("different data", s1, s2);
161         }
162     }
163 }
164
165 /**
166  * @author Eugene Kuleshov
167  */

168 class ClassInfo {
169
170     private Type type;
171
172     private ClassLoader JavaDoc loader;
173
174     int access;
175
176     String JavaDoc superClass;
177
178     String JavaDoc[] interfaces;
179
180     public ClassInfo(final String JavaDoc type, final ClassLoader JavaDoc loader) {
181         this.loader = loader;
182         this.type = Type.getObjectType(type);
183         String JavaDoc s = type.replace('.', '/') + ".class";
184         InputStream JavaDoc is = null;
185         ClassReader cr;
186         try {
187             is = loader.getResourceAsStream(s);
188             cr = new ClassReader(is);
189         } catch (IOException JavaDoc e) {
190             throw new RuntimeException JavaDoc(e);
191         } finally {
192             if (is != null) {
193                 try {
194                     is.close();
195                 } catch (Exception JavaDoc e) {
196                 }
197             }
198         }
199
200         // optimized version
201
int h = cr.header;
202         ClassInfo.this.access = cr.readUnsignedShort(h);
203         char[] buf = new char[2048];
204         // String name = cr.readClass( cr.header + 2, buf);
205

206         int v = cr.getItem(cr.readUnsignedShort(h + 4));
207         ClassInfo.this.superClass = v == 0 ? null : cr.readUTF8(v, buf);
208         ClassInfo.this.interfaces = new String JavaDoc[cr.readUnsignedShort(h + 6)];
209         h += 8;
210         for (int i = 0; i < interfaces.length; ++i) {
211             interfaces[i] = cr.readClass(h, buf);
212             h += 2;
213         }
214     }
215
216     String JavaDoc getName() {
217         return type.getInternalName();
218     }
219
220     Type getType() {
221         return type;
222     }
223
224     int getModifiers() {
225         return access;
226     }
227
228     ClassInfo getSuperclass() {
229         if (superClass == null) {
230             return null;
231         }
232         return new ClassInfo(superClass, loader);
233     }
234
235     ClassInfo[] getInterfaces() {
236         if (interfaces == null) {
237             return new ClassInfo[0];
238         }
239         ClassInfo[] result = new ClassInfo[interfaces.length];
240         for (int i = 0; i < result.length; ++i) {
241             result[i] = new ClassInfo(interfaces[i], loader);
242         }
243         return result;
244     }
245
246     boolean isInterface() {
247         return (getModifiers() & Opcodes.ACC_INTERFACE) > 0;
248     }
249
250     private boolean implementsInterface(final ClassInfo that) {
251         for (ClassInfo c = this; c != null; c = c.getSuperclass()) {
252             ClassInfo[] tis = c.getInterfaces();
253             for (int i = 0; i < tis.length; ++i) {
254                 ClassInfo ti = tis[i];
255                 if (ti.type.equals(that.type) || ti.implementsInterface(that)) {
256                     return true;
257                 }
258             }
259         }
260         return false;
261     }
262
263     private boolean isSubclassOf(final ClassInfo that) {
264         for (ClassInfo c = this; c != null; c = c.getSuperclass()) {
265             if (c.getSuperclass() != null
266                     && c.getSuperclass().type.equals(that.type))
267             {
268                 return true;
269             }
270         }
271         return false;
272     }
273
274     public boolean isAssignableFrom(final ClassInfo that) {
275         if (this == that) {
276             return true;
277         }
278
279         if (that.isSubclassOf(this)) {
280             return true;
281         }
282
283         if (that.implementsInterface(this)) {
284             return true;
285         }
286
287         if (that.isInterface()
288                 && getType().getDescriptor().equals("Ljava/lang/Object;"))
289         {
290             return true;
291         }
292
293         return false;
294     }
295 }
296
Popular Tags