KickJava   Java API By Example, From Geeks To Geeks.

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


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.MethodVisitor;
10 import com.tc.asm.Opcodes;
11 import com.tc.asm.Type;
12 import com.tc.util.FieldUtils;
13
14 import java.util.HashSet JavaDoc;
15 import java.util.Set JavaDoc;
16
17 public class JavaLangReflectFieldAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory {
18
19   private static final Set JavaDoc setters = new HashSet JavaDoc();
20   private static final Set JavaDoc getters = new HashSet JavaDoc();
21
22   static {
23     getters.add("get(Ljava/lang/Object;)Ljava/lang/Object;");
24
25     setters.add("set(Ljava/lang/Object;Ljava/lang/Object;)V");
26     setters.add("setByte(Ljava/lang/Object;B)V");
27     setters.add("setBoolean(Ljava/lang/Object;Z)V");
28     setters.add("setChar(Ljava/lang/Object;C)V");
29     setters.add("setDouble(Ljava/lang/Object;D)V");
30     setters.add("setFloat(Ljava/lang/Object;F)V");
31     setters.add("setInt(Ljava/lang/Object;I)V");
32     setters.add("setLong(Ljava/lang/Object;J)V");
33     setters.add("setShort(Ljava/lang/Object;S)V");
34   }
35
36   public JavaLangReflectFieldAdapter() {
37     super(null);
38   }
39   
40   private JavaLangReflectFieldAdapter(ClassVisitor cv, ClassLoader JavaDoc caller) {
41     super(cv);
42   }
43
44   public ClassAdapter create(ClassVisitor visitor, ClassLoader JavaDoc loader) {
45     return new JavaLangReflectFieldAdapter(visitor, loader);
46   }
47   
48   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
49     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
50
51     String JavaDoc method = name + desc;
52
53     if (setters.contains(method)) {
54       callFieldUtilSetter(mv, name, desc);
55     } else if (getters.contains(method)) {
56       rewriteGetter(mv, name, desc);
57       return null;
58     }
59
60     return mv;
61   }
62
63   private String JavaDoc getFieldUtilsSetterDesc(String JavaDoc desc) {
64     int index = desc.indexOf(")");
65     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(desc.substring(0, index));
66     sb.append("Ljava/lang/reflect/Field;)Z");
67     return sb.toString();
68   }
69
70   private void callFieldUtilSetter(MethodVisitor mv, String JavaDoc name, String JavaDoc desc) {
71     Type type = Type.getArgumentTypes(desc)[1];
72     Label notSet = new Label();
73     mv.visitVarInsn(ALOAD, 1);
74     mv.visitVarInsn(type.getOpcode(ILOAD), 2);
75     mv.visitVarInsn(ALOAD, 0);
76     mv.visitMethodInsn(INVOKESTATIC, FieldUtils.CLASS, name, getFieldUtilsSetterDesc(desc));
77     mv.visitJumpInsn(IFEQ, notSet);
78     mv.visitInsn(RETURN);
79     mv.visitLabel(notSet);
80   }
81
82   private void rewriteGetter(MethodVisitor mv, String JavaDoc name, String JavaDoc desc) {
83     Type returnType = Type.getReturnType(desc);
84
85     mv.visitCode();
86     mv.visitVarInsn(ALOAD, 1);
87     mv.visitVarInsn(ALOAD, 0);
88     mv.visitVarInsn(ALOAD, 0);
89     mv.visitVarInsn(ALOAD, 1);
90     mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/Field", "getFieldAccessor",
91                        "(Ljava/lang/Object;)Lsun/reflect/FieldAccessor;");
92     mv.visitMethodInsn(INVOKESTATIC, FieldUtils.CLASS, name, FieldUtils.GET_DESC + returnType.getDescriptor());
93     mv.visitInsn(returnType.getOpcode(IRETURN));
94     mv.visitMaxs(0, 0);
95     mv.visitEnd();
96   }
97
98 }
Popular Tags