1 5 package com.tc.tomcat.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 16 public class CatalinaAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory { 17 18 private static final String INJECT_CLASSES = ByteCodeUtil.TC_METHOD_PREFIX + "injectClasses"; 19 20 public CatalinaAdapter() { 21 super(null); 22 } 23 24 private CatalinaAdapter(ClassVisitor cv, ClassLoader caller) { 25 super(cv); 26 } 27 28 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 29 return new CatalinaAdapter(visitor, loader); 30 } 31 32 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 33 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 34 35 if ("start".equals(name) && "()V".equals(desc)) { 36 return new StartAdapter(mv); 37 } else if ("<clinit>".equals(name)) { return new CLInitMethodAdapter(mv); } 38 39 return mv; 40 } 41 42 public void visitEnd() { 43 addInjectClassesMethod(); 44 } 45 46 private void addInjectClassesMethod() { 47 MethodVisitor mv = visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, INJECT_CLASSES, "()V", null, null); 48 mv.visitCode(); 49 Label l0 = new Label(); 50 Label l1 = new Label(); 51 Label l2 = new Label(); 52 mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); 53 mv.visitLabel(l0); 54 mv.visitLdcInsn("org.apache.catalina.startup.Catalina"); 55 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); 56 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;"); 57 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/hook/impl/SessionsHelper", "injectClasses", 58 "(Ljava/lang/ClassLoader;)V"); 59 mv.visitLabel(l1); 60 Label l3 = new Label(); 61 mv.visitJumpInsn(GOTO, l3); 62 mv.visitLabel(l2); 63 mv.visitVarInsn(ASTORE, 0); 64 mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); 65 mv.visitInsn(DUP); 66 mv.visitVarInsn(ALOAD, 0); 67 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V"); 68 mv.visitInsn(ATHROW); 69 mv.visitLabel(l3); 70 mv.visitInsn(RETURN); 71 mv.visitMaxs(0, 0); 72 mv.visitEnd(); 73 } 74 75 private static class CLInitMethodAdapter extends MethodAdapter implements Opcodes { 76 77 public CLInitMethodAdapter(MethodVisitor mv) { 78 super(mv); 79 } 80 81 public void visitInsn(int opcode) { 82 if (opcode == Opcodes.RETURN) { 83 super.visitMethodInsn(INVOKESTATIC, "org/apache/catalina/startup/Catalina", INJECT_CLASSES, "()V"); 84 } 85 super.visitInsn(opcode); 86 } 87 } 88 89 private static class StartAdapter extends MethodAdapter implements Opcodes { 90 91 public StartAdapter(MethodVisitor mv) { 92 super(mv); 93 } 94 95 public void visitInsn(int opcode) { 96 if (opcode == RETURN) { 97 super.visitVarInsn(ALOAD, 0); 98 super.visitFieldInsn(GETFIELD, "org/apache/catalina/startup/Catalina", "await", "Z"); 99 Label notAwait = new Label(); 100 super.visitJumpInsn(IFEQ, notAwait); 101 super.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/hook/impl/ClassProcessorHelper", "shutdown", "()V"); 102 super.visitLabel(notAwait); 103 } 104 super.visitInsn(opcode); 105 } 106 } 107 108 } 109 | Popular Tags |