001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.geronimo.transform;
006:
007: import com.tc.asm.ClassAdapter;
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.MethodAdapter;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.asm.Type;
013: import com.tc.object.bytecode.ByteCodeUtil;
014: import com.tc.object.bytecode.ClassAdapterFactory;
015:
016: public class TomcatClassLoaderAdapter extends ClassAdapter implements
017: Opcodes, ClassAdapterFactory {
018:
019: public TomcatClassLoaderAdapter() {
020: super (null);
021: }
022:
023: private TomcatClassLoaderAdapter(ClassVisitor cv, ClassLoader caller) {
024: super (cv);
025: }
026:
027: public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) {
028: return new TomcatClassLoaderAdapter(visitor, loader);
029: }
030:
031: public void visit(int version, int access, String name,
032: String signature, String super Name, String[] interfaces) {
033: interfaces = ByteCodeUtil.addInterfaces(interfaces,
034: new String[] { ByteCodeUtil.NAMEDCLASSLOADER_CLASS });
035: super .visit(version, access, name, signature, super Name,
036: interfaces);
037: }
038:
039: public MethodVisitor visitMethod(int access, String name,
040: String desc, String signature, String[] exceptions) {
041: MethodVisitor mv = super .visitMethod(access, name, desc,
042: signature, exceptions);
043: if ("<init>".equals(name)
044: && Type.getArgumentTypes(desc).length > 0) {
045: mv = new CstrAdapter(mv);
046: }
047:
048: return mv;
049: }
050:
051: public void visitEnd() {
052: MethodVisitor mv = super .visitMethod(ACC_PUBLIC | ACC_FINAL
053: | ACC_SYNTHETIC, "__tc_getClassLoaderName",
054: "()Ljava/lang/String;", null, null);
055: mv.visitCode();
056: mv.visitFieldInsn(GETSTATIC, "com/tc/object/loaders/Namespace",
057: "GERONIMO_NAMESPACE", "Ljava/lang/String;");
058: mv.visitVarInsn(ALOAD, 0);
059: mv.visitMethodInsn(INVOKEVIRTUAL, "java/net/URLClassLoader",
060: "getParent", "()Ljava/lang/ClassLoader;");
061: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
062: "toString", "()Ljava/lang/String;");
063: mv
064: .visitMethodInsn(INVOKESTATIC,
065: "com/tc/object/loaders/Namespace",
066: "createLoaderName",
067: "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
068: mv.visitMethodInsn(INVOKESTATIC,
069: "com/tc/geronimo/GeronimoLoaderNaming", "adjustName",
070: "(Ljava/lang/String;)Ljava/lang/String;");
071: mv.visitInsn(ARETURN);
072: mv.visitMaxs(0, 0);
073: mv.visitEnd();
074:
075: mv = super .visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC,
076: "__tc_setClassLoaderName", "(Ljava/lang/String;)V",
077: null, null);
078: mv.visitCode();
079: mv.visitTypeInsn(NEW, "java/lang/AssertionError");
080: mv.visitInsn(DUP);
081: mv.visitMethodInsn(INVOKESPECIAL, "java/lang/AssertionError",
082: "<init>", "()V");
083: mv.visitInsn(ATHROW);
084: mv.visitMaxs(0, 0);
085: mv.visitEnd();
086:
087: super .visitEnd();
088: }
089:
090: private static class CstrAdapter extends MethodAdapter implements
091: Opcodes {
092:
093: public CstrAdapter(MethodVisitor mv) {
094: super (mv);
095: }
096:
097: public void visitInsn(int opcode) {
098: if (opcode == RETURN) {
099: mv.visitVarInsn(ALOAD, 0);
100: mv
101: .visitMethodInsn(
102: INVOKESTATIC,
103: "com/tc/object/bytecode/hook/impl/ClassProcessorHelper",
104: "registerGlobalLoader",
105: "("
106: + ByteCodeUtil.NAMEDCLASSLOADER_TYPE
107: + ")V");
108: }
109: super.visitInsn(opcode);
110: }
111:
112: }
113:
114: }
|