001: /***
002: * ASM Guide
003: * Copyright (c) 2007 Eric Bruneton
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */package util;
030:
031: import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
032: import static org.objectweb.asm.Opcodes.ALOAD;
033: import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
034: import static org.objectweb.asm.Opcodes.INVOKESTATIC;
035: import static org.objectweb.asm.Opcodes.RETURN;
036: import static org.objectweb.asm.Opcodes.V1_1;
037:
038: import java.io.InputStream;
039: import java.util.Enumeration;
040: import java.util.zip.ZipEntry;
041: import java.util.zip.ZipFile;
042:
043: import junit.framework.TestCase;
044:
045: import org.objectweb.asm.ClassReader;
046: import org.objectweb.asm.ClassVisitor;
047: import org.objectweb.asm.ClassWriter;
048: import org.objectweb.asm.FieldVisitor;
049: import org.objectweb.asm.MethodVisitor;
050: import org.objectweb.asm.Opcodes;
051: import org.objectweb.asm.tree.ClassNode;
052: import org.objectweb.asm.util.TraceMethodVisitor;
053:
054: /**
055: * ASM Guide example test class.
056: *
057: * @author Eric Bruneton
058: */
059: public class AbstractTestCase extends TestCase {
060:
061: private TestClassLoader LOADER = new TestClassLoader();
062:
063: public void tests() throws Exception {
064: if (getClassAdapter(null) != null) {
065: String file = System.getProperty("java.home")
066: + "/lib/rt.jar";
067: ZipFile zip = new ZipFile(file);
068: Enumeration entries = zip.entries();
069: while (entries.hasMoreElements()) {
070: ZipEntry e = (ZipEntry) entries.nextElement();
071: String n = e.getName();
072: if (n.endsWith(".class")) {
073: n = n.substring(0, n.length() - 6)
074: .replace('/', '.');
075: InputStream is = zip.getInputStream(e);
076: ClassReader cr = new ClassReader(is);
077: if (cr.readInt(4) != Opcodes.V1_6) {
078: try {
079: ClassWriter cw = new ClassWriter(
080: ClassWriter.COMPUTE_FRAMES);
081: cr.accept(cw, 0);
082: cr = new ClassReader(cw.toByteArray());
083: } catch (Throwable ignored) {
084: continue;
085: }
086: }
087: ClassWriter cw = new ClassWriter(0);
088: ClassVisitor cv = getClassAdapter(cw);
089: try {
090: cr.accept(cv, ClassReader.EXPAND_FRAMES);
091: } catch (UnsatisfiedLinkError ignored) {
092: } catch (NoClassDefFoundError ignored) {
093: }
094: byte[] b = cw.toByteArray();
095: try {
096: new TestClassLoader().defineClass(n, b);
097: } catch (ClassFormatError cfe) {
098: cfe.printStackTrace();
099: fail();
100: } catch (Throwable t) {
101: }
102: }
103: }
104: }
105: }
106:
107: protected ClassVisitor getClassAdapter(ClassVisitor cv) {
108: return null;
109: }
110:
111: protected void generateBasicClass(ClassVisitor cv) {
112: FieldVisitor fv;
113: MethodVisitor mv;
114: cv.visit(V1_1, ACC_PUBLIC, "C", null, "java/lang/Object", null);
115: cv.visitSource("C.java", null);
116: fv = cv.visitField(ACC_PUBLIC, "f", "I", null, null);
117: if (fv != null) {
118: fv.visitEnd();
119: }
120: mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
121: if (mv != null) {
122: mv.visitCode();
123: mv.visitVarInsn(ALOAD, 0);
124: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object",
125: "<init>", "()V");
126: mv.visitInsn(RETURN);
127: mv.visitMaxs(1, 1);
128: mv.visitEnd();
129: }
130: mv = cv.visitMethod(ACC_PUBLIC, "m", "()V", null, null);
131: if (mv != null) {
132: mv.visitCode();
133: mv.visitLdcInsn(new Long(100));
134: mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread",
135: "sleep", "(J)V");
136: mv.visitInsn(RETURN);
137: mv.visitMaxs(3, 1);
138: mv.visitEnd();
139: }
140: cv.visitEnd();
141: }
142:
143: protected ClassNode generateBasicClass() {
144: ClassNode cn = new ClassNode();
145: generateBasicClass(cn);
146: return cn;
147: }
148:
149: protected Class defineClass(String name, byte[] b) {
150: return LOADER.defineClass(name, b);
151: }
152:
153: protected void assertEquals(TraceMethodVisitor expected,
154: TraceMethodVisitor actual) {
155: assertEquals(getText(expected), getText(actual));
156: }
157:
158: private static String getText(TraceMethodVisitor mv) {
159: StringBuffer sb = new StringBuffer();
160: for (int i = 0; i < mv.text.size(); i++) {
161: sb.append(mv.text.get(i));
162: }
163: return sb.toString();
164: }
165:
166: static class TestClassLoader extends ClassLoader {
167:
168: public Class defineClass(String name, byte[] b) {
169: return defineClass(name, b, 0, b.length);
170: }
171: }
172: }
|