1 5 package org.terracotta.modules.cglib_2_1_3; 6 7 import org.osgi.framework.Bundle; 8 import org.terracotta.modules.cglib_2_1_3.util.FilterTCMethods; 9 10 import com.tc.asm.ClassAdapter; 11 import com.tc.asm.ClassReader; 12 import com.tc.asm.ClassVisitor; 13 import com.tc.asm.MethodAdapter; 14 import com.tc.asm.MethodVisitor; 15 import com.tc.asm.Opcodes; 16 import com.tc.asm.tree.ClassNode; 17 import com.tc.asm.tree.MethodNode; 18 import com.tc.exception.TCRuntimeException; 19 import com.tc.object.bytecode.ClassAdapterFactory; 20 import com.tc.plugins.ModulesLoader; 21 22 import java.io.ByteArrayOutputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.net.URL ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 29 public class CGLibProxyEnhancerAdapter extends ClassAdapter implements ClassAdapterFactory, Opcodes { 30 private final ClassLoader caller; 31 private final Bundle bundle; 32 33 public CGLibProxyEnhancerAdapter(Bundle bundle) { 34 super(null); 35 this.caller = null; 36 this.bundle = bundle; 37 } 38 39 private CGLibProxyEnhancerAdapter(ClassVisitor cv, ClassLoader caller, Bundle bundle) { 40 super(cv); 41 this.caller = caller; 42 this.bundle = bundle; 43 } 44 45 public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) { 46 return new CGLibProxyEnhancerAdapter(visitor, loader, bundle); 47 } 48 49 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 50 52 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 53 54 if ("getMethods".equals(name) 55 && "(Ljava/lang/Class;[Ljava/lang/Class;Ljava/util/List;Ljava/util/List;Ljava/util/Set;)V".equals(desc)) { return new InterceptAdapter( 56 mv); } 57 58 return mv; 59 60 } 61 62 public void visitEnd() { 63 addFilterMethod(); 64 super.visitEnd(); 65 } 66 67 private void addFilterMethod() { 68 try { 69 byte[] bytes = getBytesForClass(bundle, FilterTCMethods.class); 70 ClassReader tcCR = new ClassReader(bytes); 71 ClassNode tcCN = new ClassNode(); 72 tcCR.accept(tcCN, true); 73 74 List tcMethods = tcCN.methods; 75 for (Iterator i = tcMethods.iterator(); i.hasNext();) { 76 MethodNode mNode = (MethodNode) i.next(); 77 if (!"<init>".equals(mNode.name)) { 78 mNode.accept(cv); 79 } 80 } 81 } catch (ClassNotFoundException e) { 82 throw new TCRuntimeException(e); 83 } 84 } 85 86 public byte[] getBytesForClass(final Bundle bundle, Class clazz) throws ClassNotFoundException { 87 String className = clazz.getName().replace('.', '/') + ".class"; 88 InputStream is = null; 89 ByteArrayOutputStream baos = null; 90 try { 91 is = ModulesLoader.getJarResource(new URL (bundle.getLocation()), className); 92 if (is == null) { throw new ClassNotFoundException ("No resource found for class: " + className); } 93 final int size = 4096; 94 byte[] buffer = new byte[size]; 95 baos = new ByteArrayOutputStream (size); 96 97 int read; 98 99 while ((read = is.read(buffer, 0, size)) > 0) { 100 baos.write(buffer, 0, read); 101 } 102 } catch (IOException ioe) { 103 throw new ClassNotFoundException ("Error reading bytes for " + className, ioe); 104 } finally { 105 if (is != null) { 106 try { 107 is.close(); 108 } catch (IOException ioe) { 109 } 111 } 112 } 113 114 return baos.toByteArray(); 115 } 116 117 private static class InterceptAdapter extends MethodAdapter implements Opcodes { 118 119 public InterceptAdapter(MethodVisitor mv) { 120 super(mv); 121 } 122 123 public void visitInsn(int opcode) { 124 if (RETURN == opcode) { 125 mv.visitVarInsn(ALOAD, 2); 126 mv.visitMethodInsn(INVOKESTATIC, "net/sf/cglib/proxy/Enhancer", "filterTCMethods", "(Ljava/util/Collection;)V"); 127 } 128 super.visitInsn(opcode); 129 } 130 } 131 132 } 133 | Popular Tags |