KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > weblogic > transform > GenericClassLoaderAdapter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.weblogic.transform;
6
7 import com.tc.asm.ClassAdapter;
8 import com.tc.asm.ClassVisitor;
9 import com.tc.asm.Label;
10 import com.tc.asm.MethodAdapter;
11 import com.tc.asm.MethodVisitor;
12 import com.tc.asm.Opcodes;
13 import com.tc.object.bytecode.ByteCodeUtil;
14 import com.tc.object.bytecode.ClassAdapterFactory;
15 import com.tc.object.bytecode.hook.impl.ClassProcessorHelper;
16 import com.tc.object.loaders.NamedClassLoader;
17 import com.tc.object.loaders.Namespace;
18
19 public class GenericClassLoaderAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory {
20
21   private static final String JavaDoc LOADER_DESC_FIELD = ByteCodeUtil.TC_FIELD_PREFIX + "loaderDesc";
22
23   public GenericClassLoaderAdapter() {
24     super(null);
25   }
26
27   private GenericClassLoaderAdapter(ClassVisitor cv, ClassLoader JavaDoc caller) {
28     super(cv);
29   }
30
31   public ClassAdapter create(ClassVisitor visitor, ClassLoader JavaDoc loader) {
32     return new GenericClassLoaderAdapter(visitor, loader);
33   }
34
35   public void visit(int version, int access, String JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] interfaces) {
36     interfaces = ByteCodeUtil.addInterfaces(interfaces, new String JavaDoc[] { NamedClassLoader.CLASS });
37     super.visit(version, access, name, signature, superName, interfaces);
38
39     // add field for loader description
40
super.visitField(ACC_PRIVATE | ACC_SYNTHETIC | ACC_TRANSIENT, LOADER_DESC_FIELD, "Ljava/lang/String;", null, null);
41   }
42
43   public void visitEnd() {
44     addNamedClassLoaderMethods();
45     super.visitEnd();
46   }
47
48   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
49     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
50     if ("setAnnotation".equals(name)) {
51       mv = new SetAnnotationAdatper(mv);
52     }
53
54     return mv;
55   }
56
57   private void addNamedClassLoaderMethods() {
58     MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_getClassLoaderName",
59                                          "()Ljava/lang/String;", null, null);
60     mv.visitCode();
61     mv.visitVarInsn(ALOAD, 0);
62     mv.visitFieldInsn(GETFIELD, "weblogic/utils/classloaders/GenericClassLoader", LOADER_DESC_FIELD,
63                       "Ljava/lang/String;");
64     Label loaderDescDefined = new Label();
65     mv.visitJumpInsn(IFNONNULL, loaderDescDefined);
66     mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
67     mv.visitInsn(DUP);
68     mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
69     mv.visitInsn(DUP);
70     mv.visitLdcInsn("No terracotta loader name defined for ");
71     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
72     mv.visitVarInsn(ALOAD, 0);
73     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append",
74                        "(Ljava/lang/Object;)Ljava/lang/StringBuffer;");
75     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
76     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V");
77     mv.visitInsn(ATHROW);
78     mv.visitLabel(loaderDescDefined);
79     mv.visitVarInsn(ALOAD, 0);
80     mv.visitFieldInsn(GETFIELD, "weblogic/utils/classloaders/GenericClassLoader", LOADER_DESC_FIELD,
81                       "Ljava/lang/String;");
82     mv.visitInsn(ARETURN);
83     mv.visitMaxs(0, 0);
84     mv.visitEnd();
85
86     mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_setClassLoaderName", "(Ljava/lang/String;)V",
87                            null, null);
88     mv.visitCode();
89     mv.visitTypeInsn(NEW, "java/lang/AssertionError");
90     mv.visitInsn(DUP);
91     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/AssertionError", "<init>", "()V");
92     mv.visitInsn(ATHROW);
93     mv.visitMaxs(0, 0);
94     mv.visitEnd();
95   }
96
97   private static class SetAnnotationAdatper extends MethodAdapter implements Opcodes {
98
99     public SetAnnotationAdatper(MethodVisitor mv) {
100       super(mv);
101     }
102
103     public void visitInsn(int opcode) {
104       if (RETURN == opcode) {
105         // update the terracotta loader desc for this loader
106
mv.visitVarInsn(ALOAD, 0);
107         mv.visitLdcInsn(Namespace.WEBLOGIC_NAMESPACE);
108         mv.visitVarInsn(ALOAD, 0);
109         mv.visitMethodInsn(INVOKEVIRTUAL, "weblogic/utils/classloaders/GenericClassLoader", "getAnnotation",
110                            "()Lweblogic/utils/classloaders/Annotation;");
111         mv.visitMethodInsn(INVOKEVIRTUAL, "weblogic/utils/classloaders/Annotation", "getAnnotationString",
112                            "()Ljava/lang/String;");
113         mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/loaders/Namespace", "createLoaderName",
114                            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
115         mv.visitFieldInsn(PUTFIELD, "weblogic/utils/classloaders/GenericClassLoader", LOADER_DESC_FIELD,
116                           "Ljava/lang/String;");
117         mv.visitVarInsn(ALOAD, 0);
118         mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/hook/impl/ClassProcessorHelper",
119                            "registerGlobalLoader", "(Lcom/tc/object/loaders/NamedClassLoader;)V");
120       }
121       super.visitInsn(opcode);
122     }
123
124   }
125
126   void foo() {
127     ClassProcessorHelper.registerGlobalLoader((NamedClassLoader) this);
128   }
129
130 }
131
Popular Tags