KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > geronimo > transform > MultiParentClassLoaderAdapter


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

4 package com.tc.geronimo.transform;
5
6 import com.tc.asm.ClassAdapter;
7 import com.tc.asm.ClassVisitor;
8 import com.tc.asm.FieldVisitor;
9 import com.tc.asm.MethodAdapter;
10 import com.tc.asm.MethodVisitor;
11 import com.tc.asm.Opcodes;
12 import com.tc.object.bytecode.ByteCodeUtil;
13 import com.tc.object.bytecode.ClassAdapterFactory;
14 import com.tc.object.loaders.NamedClassLoader;
15
16 /**
17  * Adds NamedClassLoader interface to Geronimo loader, and register it with DSO
18  */

19 public class MultiParentClassLoaderAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory {
20
21   private String JavaDoc idDesc;
22
23   public MultiParentClassLoaderAdapter() {
24     super(null);
25   }
26   
27   private MultiParentClassLoaderAdapter(ClassVisitor cv, ClassLoader JavaDoc caller) {
28     super(cv);
29   }
30   
31   public ClassAdapter create(ClassVisitor visitor, ClassLoader JavaDoc loader) {
32     return new MultiParentClassLoaderAdapter(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
40   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
41     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
42     if ("<init>".equals(name)) { return new CstrVisitor(mv); }
43     return mv;
44   }
45
46   public void visitEnd() {
47     addNamedClassLoaderMethods();
48     super.visitEnd();
49   }
50
51   public FieldVisitor visitField(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, Object JavaDoc value) {
52     if ("id".equals(name)) {
53       // the type of the "id" field is different between 1.0 and 1.1
54
idDesc = desc;
55     }
56
57     return super.visitField(access, name, desc, signature, value);
58   }
59
60   private void addNamedClassLoaderMethods() {
61     MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_getClassLoaderName",
62                                          "()Ljava/lang/String;", null, null);
63     mv.visitCode();
64     mv.visitFieldInsn(GETSTATIC, "com/tc/object/loaders/Namespace", "GERONIMO_NAMESPACE", "Ljava/lang/String;");
65     mv.visitVarInsn(ALOAD, 0);
66     mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/geronimo/kernel/config/MultiParentClassLoader", "getId", "()"
67                                                                                                            + idDesc);
68     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
69     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/loaders/Namespace", "createLoaderName",
70                        "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
71     mv.visitMethodInsn(INVOKESTATIC, "com/tc/geronimo/GeronimoLoaderNaming", "adjustName",
72                        "(Ljava/lang/String;)Ljava/lang/String;");
73
74     mv.visitInsn(ARETURN);
75     mv.visitMaxs(0, 0);
76     mv.visitEnd();
77
78     mv = super.visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, "__tc_setClassLoaderName", "(Ljava/lang/String;)V",
79                            null, null);
80     mv.visitCode();
81     mv.visitTypeInsn(NEW, "java/lang/AssertionError");
82     mv.visitInsn(DUP);
83     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/AssertionError", "<init>", "()V");
84     mv.visitInsn(ATHROW);
85     mv.visitMaxs(0, 0);
86     mv.visitEnd();
87   }
88
89   private static class CstrVisitor extends MethodAdapter implements Opcodes {
90
91     public CstrVisitor(MethodVisitor mv) {
92       super(mv);
93     }
94
95     public void visitInsn(int opcode) {
96       if (opcode == RETURN) {
97         mv.visitVarInsn(ALOAD, 0);
98         mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/hook/impl/ClassProcessorHelper",
99                            "registerGlobalLoader", "(" + NamedClassLoader.TYPE + ")V");
100       }
101       super.visitInsn(opcode);
102     }
103
104   }
105
106 }
107
Popular Tags