001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tcspring;
005:
006: import org.jmock.Mock;
007: import org.jmock.MockObjectTestCase;
008:
009: import com.tc.asm.ClassWriter;
010: import com.tc.asm.FieldVisitor;
011: import com.tc.asm.MethodVisitor;
012: import com.tc.asm.Opcodes;
013: import com.tc.aspectwerkz.reflect.ClassInfo;
014: import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
015: import com.tc.object.bytecode.hook.DSOContext;
016:
017: public class ClassHierarchyWalkerTest extends MockObjectTestCase
018: implements Opcodes {
019:
020: private DSOContext dsoContext;
021: private Mock dsoContextMock;
022: private ClassHierarchyWalker walker;
023:
024: protected void setUp() {
025: dsoContextMock = mock(DSOContext.class);
026: dsoContext = (DSOContext) dsoContextMock.proxy();
027:
028: walker = new ClassHierarchyWalker("id", dsoContext);
029: }
030:
031: public void testWalkThroughClassHierarchy() {
032: String[] classNames = { "com.tcspring.beans.SimpleBean",
033: "com.tcspring.beans.SimpleBean1",
034: "com.tcspring.beans.SimpleBean2",
035: "com.tcspring.beans.SimpleParentBean",
036: "com.tcspring.beans.SimplePropertyBean" };
037:
038: for (int i = 0; i < classNames.length; i++) {
039: String className = classNames[i];
040: dsoContextMock.expects(once()).method("addInclude").with(
041: eq(className), ANYTHING,
042: eq("* " + className + ".*(..)"), ANYTHING);
043: }
044:
045: walker.walkClass(classNames[0], getClass().getClassLoader());
046: }
047:
048: public void testWalkWithGenerics() throws Exception {
049: String[] classNames = {
050: "com.tcspring.beans.SimpleBeanWithGenerics",
051: "com.tcspring.beans.SimpleBean1",
052: "com.tcspring.beans.SimpleBean2",
053: "java.util.ArrayList", "java.util.AbstractList",
054: "java.util.AbstractCollection",
055: "com.tcspring.beans.SimplePropertyBean",
056: "com.tcspring.beans.SimpleBean",
057: "com.tcspring.beans.SimpleParentBean" };
058:
059: for (int i = 0; i < classNames.length; i++) {
060: String className = classNames[i];
061: dsoContextMock.expects(once()).method("addInclude").with(
062: eq(className), ANYTHING,
063: eq("* " + className + ".*(..)"), ANYTHING);
064: }
065:
066: /*
067: * constructing ClassInfo from the generated bytecode to retain 1.4 compatibility
068: *
069: * public class SimpleBeanWithGenerics {
070: * public Map<SimpleBean1, SimpleBean2[]> map1;
071: * public Map<SimpleBean1, ArrayList<SimplePropertyBean>> map2;
072: * }
073: */
074: ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
075:
076: cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER,
077: "com/tcspring/beans/SimpleBeanWithGenerics", null,
078: "java/lang/Object", null);
079:
080: cw.visitSource("SimpleBeanWithGenerics.java", null);
081:
082: FieldVisitor fv1 = cw
083: .visitField(
084: ACC_PUBLIC,
085: "map1",
086: "Ljava/util/Map;", //
087: "Ljava/util/Map<Lcom/tcspring/beans/SimpleBean1;[Lcom/tcspring/beans/SimpleBean2;>;",
088: null);
089: fv1.visitEnd();
090:
091: FieldVisitor fv2 = cw
092: .visitField(
093: ACC_PUBLIC,
094: "map2",
095: "Ljava/util/Map;", //
096: "Ljava/util/Map<Lcom/tcspring/beans/SimpleBean1;Ljava/util/ArrayList<Lcom/tcspring/beans/SimplePropertyBean;>;>;",
097: null);
098: fv2.visitEnd();
099:
100: MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V",
101: null, null);
102: mv.visitCode();
103: mv.visitVarInsn(ALOAD, 0);
104: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>",
105: "()V");
106: mv.visitInsn(RETURN);
107: mv.visitMaxs(1, 1);
108: mv.visitEnd();
109:
110: cw.visitEnd();
111:
112: byte[] bytecode = cw.toByteArray();
113:
114: ClassInfo classInfo = AsmClassInfo.newClassInfo(bytecode,
115: getClass().getClassLoader());
116:
117: walker.walkClass(classInfo);
118: }
119: }
|