1 5 package com.tc.weblogic.transform; 6 7 import com.tc.asm.ClassAdapter; 8 import com.tc.asm.ClassVisitor; 9 import com.tc.asm.MethodVisitor; 10 import com.tc.asm.Opcodes; 11 import com.tc.asm.Type; 12 import com.tc.object.bytecode.ClassAdapterFactory; 13 14 import java.lang.reflect.Method ; 15 import java.lang.reflect.Modifier ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.Map ; 19 20 public class TerracottaServletResponseImplAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory { 21 22 private static final String CLASS_NAME = "weblogic.servlet.internal.ServletResponseImpl"; 23 24 private final Map nativeMethods; 25 private String thisClassname; 26 27 public TerracottaServletResponseImplAdapter() { 28 super(null); 29 this.nativeMethods = null; 30 } 31 32 private TerracottaServletResponseImplAdapter(ClassVisitor cv, ClassLoader caller) { 33 super(cv); 34 this.nativeMethods = getNativeMethods(caller); 35 } 36 37 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 38 return new TerracottaServletResponseImplAdapter(visitor, loader); 39 } 40 41 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 42 super.visit(version, access, name, signature, superName, interfaces); 43 this.thisClassname = name; 44 } 45 46 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 47 String sig = name + Type.getMethodDescriptor(Type.getReturnType(desc), Type.getArgumentTypes(desc)); 48 nativeMethods.remove(sig); 49 return super.visitMethod(access, name, desc, signature, exceptions); 50 } 51 52 public void visitEnd() { 53 for (Iterator iter = nativeMethods.values().iterator(); iter.hasNext();) { 54 Method m = (Method ) iter.next(); 55 56 Class [] exceptionTypes = m.getExceptionTypes(); 57 String [] exceptions = new String [exceptionTypes.length]; 58 for (int i = 0; i < exceptions.length; i++) { 59 exceptions[i] = exceptionTypes[i].getName().replace('.', '/'); 60 } 61 62 Type[] argumentTypes = Type.getArgumentTypes(m); 63 64 MethodVisitor mv = super 65 .visitMethod(m.getModifiers(), m.getName(), Type.getMethodDescriptor(m), null, exceptions); 66 mv.visitCode(); 67 68 mv.visitVarInsn(ALOAD, 0); 69 mv.visitFieldInsn(GETFIELD, thisClassname, "nativeResponse", "Lweblogic/servlet/internal/ServletResponseImpl;"); 70 71 int slot = 1; 72 for (int i = 0; i < argumentTypes.length; i++) { 73 Type arg = argumentTypes[i]; 74 mv.visitVarInsn(arg.getOpcode(ILOAD), slot); 75 slot += arg.getSize(); 76 } 77 78 mv.visitMethodInsn(INVOKEVIRTUAL, "weblogic/servlet/internal/ServletResponseImpl", m.getName(), Type 79 .getMethodDescriptor(m)); 80 81 Type returnType = Type.getReturnType(m); 82 if (returnType == Type.VOID_TYPE) { 83 mv.visitInsn(RETURN); 84 } else { 85 mv.visitInsn(returnType.getOpcode(IRETURN)); 86 } 87 88 mv.visitMaxs(0, 0); 89 mv.visitEnd(); 90 } 91 } 92 93 private static Map getNativeMethods(ClassLoader caller) { 94 Class c; 95 try { 96 c = Class.forName(CLASS_NAME, false, caller); 97 } catch (ClassNotFoundException e) { 98 throw new RuntimeException ("Unable to load class " + CLASS_NAME); 99 } 100 101 Map rv = new HashMap (); 102 Method [] methods = c.getDeclaredMethods(); 103 for (int i = 0; i < methods.length; i++) { 104 Method m = methods[i]; 105 106 int access = m.getModifiers(); 107 108 if (Modifier.isStatic(access) || Modifier.isPrivate(access)) { 109 continue; 110 } 111 112 if (Modifier.isFinal(access)) { throw new RuntimeException ("Final modifier found (should have been removed): " 113 + m.toString()); } 114 115 String sig = m.getName() + Type.getMethodDescriptor(m); 116 Object prev = rv.put(sig, m); 117 if (prev != null) { throw new AssertionError ("replaced mapping for " + sig); } 118 } 119 return rv; 120 } 121 } 122 | Popular Tags |