1 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 19 public class MultiParentClassLoaderAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory { 20 21 private String idDesc; 22 23 public MultiParentClassLoaderAdapter() { 24 super(null); 25 } 26 27 private MultiParentClassLoaderAdapter(ClassVisitor cv, ClassLoader caller) { 28 super(cv); 29 } 30 31 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 32 return new MultiParentClassLoaderAdapter(visitor, loader); 33 } 34 35 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 36 interfaces = ByteCodeUtil.addInterfaces(interfaces, new String [] { NamedClassLoader.CLASS }); 37 super.visit(version, access, name, signature, superName, interfaces); 38 } 39 40 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] 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 name, String desc, String signature, Object value) { 52 if ("id".equals(name)) { 53 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 |