KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > bytecode > JavaLangReflectProxyClassAdapter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.object.bytecode;
5
6 import com.tc.asm.ClassAdapter;
7 import com.tc.asm.ClassVisitor;
8 import com.tc.asm.Label;
9 import com.tc.asm.MethodAdapter;
10 import com.tc.asm.MethodVisitor;
11 import com.tc.asm.Opcodes;
12
13 /**
14  *
15  * This custom adapter instrument java.lang.reflect.Proxy class so that all DSO interfaces
16  * added to the Proxy class will be filtered out in the getProxyClass method.
17  */

18 public class JavaLangReflectProxyClassAdapter extends ClassAdapter implements Opcodes {
19   private final static String JavaDoc FILTER_INTERFACES_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "filterInterfaces";
20   private final static String JavaDoc PROXY_INTERFACES_FIELD_NAME = ByteCodeUtil.TC_FIELD_PREFIX + "proxyInterfaces";
21   
22   public JavaLangReflectProxyClassAdapter(ClassVisitor cv) {
23     super(cv);
24   }
25   
26   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
27     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
28     if ("getProxyClass".equals(name) && "(Ljava/lang/ClassLoader;[Ljava/lang/Class;)Ljava/lang/Class;".equals(desc)) {
29       mv = new FilterInterfacesMethodAdapter(mv);
30     } else if ("<clinit>".equals(name)) {
31       mv = new StaticInitializerMethodAdapter(mv);
32     }
33     
34     return mv;
35   }
36   
37   public void visitEnd() {
38     addProxyInterfacesField();
39     addFilterInterfacesMethod();
40     super.visitEnd();
41   }
42   
43   private void addProxyInterfacesField() {
44     cv.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, PROXY_INTERFACES_FIELD_NAME, "[Ljava/lang/Class;", null, null);
45   }
46   
47   private void addFilterInterfacesMethod() {
48     MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, FILTER_INTERFACES_METHOD_NAME, "([Ljava/lang/Class;)[Ljava/lang/Class;", null, null);
49     mv.visitCode();
50     Label l0 = new Label();
51     mv.visitLabel(l0);
52     mv.visitTypeInsn(NEW, "java/util/ArrayList");
53     mv.visitInsn(DUP);
54     mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V");
55     mv.visitVarInsn(ASTORE, 1);
56     Label l1 = new Label();
57     mv.visitLabel(l1);
58     mv.visitInsn(ICONST_0);
59     mv.visitVarInsn(ISTORE, 2);
60     Label l2 = new Label();
61     mv.visitLabel(l2);
62     Label l3 = new Label();
63     mv.visitJumpInsn(GOTO, l3);
64     Label l4 = new Label();
65     mv.visitLabel(l4);
66     mv.visitVarInsn(ALOAD, 0);
67     mv.visitVarInsn(ILOAD, 2);
68     mv.visitInsn(AALOAD);
69     mv.visitVarInsn(ASTORE, 3);
70     Label l5 = new Label();
71     mv.visitLabel(l5);
72     mv.visitInsn(ICONST_0);
73     mv.visitVarInsn(ISTORE, 4);
74     Label l6 = new Label();
75     mv.visitLabel(l6);
76     mv.visitInsn(ICONST_0);
77     mv.visitVarInsn(ISTORE, 5);
78     Label l7 = new Label();
79     mv.visitLabel(l7);
80     Label l8 = new Label();
81     mv.visitJumpInsn(GOTO, l8);
82     Label l9 = new Label();
83     mv.visitLabel(l9);
84     mv.visitFieldInsn(GETSTATIC, "java/lang/reflect/Proxy", PROXY_INTERFACES_FIELD_NAME, "[Ljava/lang/Class;");
85     mv.visitVarInsn(ILOAD, 5);
86     mv.visitInsn(AALOAD);
87     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
88     mv.visitVarInsn(ALOAD, 3);
89     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
90     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
91     Label l10 = new Label();
92     mv.visitJumpInsn(IFEQ, l10);
93     Label l11 = new Label();
94     mv.visitLabel(l11);
95     mv.visitFieldInsn(GETSTATIC, "java/lang/reflect/Proxy", PROXY_INTERFACES_FIELD_NAME, "[Ljava/lang/Class;");
96     mv.visitVarInsn(ILOAD, 5);
97     mv.visitInsn(AALOAD);
98     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
99     mv.visitLdcInsn("com.tc");
100     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z");
101     mv.visitJumpInsn(IFEQ, l10);
102     Label l12 = new Label();
103     mv.visitLabel(l12);
104     mv.visitInsn(ICONST_1);
105     mv.visitVarInsn(ISTORE, 4);
106     Label l13 = new Label();
107     mv.visitLabel(l13);
108     Label l14 = new Label();
109     mv.visitJumpInsn(GOTO, l14);
110     mv.visitLabel(l10);
111     mv.visitIincInsn(5, 1);
112     mv.visitLabel(l8);
113     mv.visitVarInsn(ILOAD, 5);
114     mv.visitFieldInsn(GETSTATIC, "java/lang/reflect/Proxy", PROXY_INTERFACES_FIELD_NAME, "[Ljava/lang/Class;");
115     mv.visitInsn(ARRAYLENGTH);
116     mv.visitJumpInsn(IF_ICMPLT, l9);
117     mv.visitLabel(l14);
118     mv.visitVarInsn(ILOAD, 4);
119     Label l15 = new Label();
120     mv.visitJumpInsn(IFNE, l15);
121     Label l16 = new Label();
122     mv.visitLabel(l16);
123     mv.visitVarInsn(ALOAD, 1);
124     mv.visitVarInsn(ALOAD, 3);
125     mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z");
126     mv.visitInsn(POP);
127     mv.visitLabel(l15);
128     mv.visitIincInsn(2, 1);
129     mv.visitLabel(l3);
130     mv.visitVarInsn(ILOAD, 2);
131     mv.visitVarInsn(ALOAD, 0);
132     mv.visitInsn(ARRAYLENGTH);
133     mv.visitJumpInsn(IF_ICMPLT, l4);
134     Label l17 = new Label();
135     mv.visitLabel(l17);
136     mv.visitVarInsn(ALOAD, 1);
137     mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I");
138     mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
139     mv.visitVarInsn(ASTORE, 2);
140     Label l18 = new Label();
141     mv.visitLabel(l18);
142     mv.visitVarInsn(ALOAD, 1);
143     mv.visitVarInsn(ALOAD, 2);
144     mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;");
145     mv.visitInsn(POP);
146     Label l19 = new Label();
147     mv.visitLabel(l19);
148     mv.visitVarInsn(ALOAD, 2);
149     mv.visitInsn(ARETURN);
150     Label l20 = new Label();
151     mv.visitLabel(l20);
152     mv.visitMaxs(0, 0);
153     mv.visitEnd();
154   }
155
156   private static class FilterInterfacesMethodAdapter extends MethodAdapter implements Opcodes {
157     public FilterInterfacesMethodAdapter(MethodVisitor mv) {
158       super(mv);
159     }
160     
161     public void visitCode() {
162       super.visitCode();
163       mv.visitVarInsn(ALOAD, 1);
164       mv.visitMethodInsn(INVOKESTATIC, "java/lang/reflect/Proxy", FILTER_INTERFACES_METHOD_NAME, "([Ljava/lang/Class;)[Ljava/lang/Class;");
165       mv.visitVarInsn(ASTORE, 1);
166     }
167   }
168   
169   private static class StaticInitializerMethodAdapter extends MethodAdapter implements Opcodes {
170     public StaticInitializerMethodAdapter(MethodVisitor mv) {
171       super(mv);
172     }
173     
174     public void visitInsn(int opcode) {
175       if (RETURN == opcode) {
176         mv.visitTypeInsn(NEW, "java/lang/reflect/Proxy");
177         mv.visitInsn(DUP);
178         mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/Proxy", "<init>", "()V");
179         mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
180         mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getInterfaces", "()[Ljava/lang/Class;");
181         mv.visitFieldInsn(PUTSTATIC, "java/lang/reflect/Proxy", PROXY_INTERFACES_FIELD_NAME, "[Ljava/lang/Class;");
182       }
183       super.visitInsn(opcode);
184     }
185   }
186
187 }
188
Popular Tags