/Users/lyon/j4p/src/javassist/convert/TransformReadField.java

1    /* 
2     * Javassist, a Java-bytecode translator toolkit. 
3     * Copyright (C) 1999-2003 Shigeru Chiba. All Rights Reserved. 
4     * 
5     * The contents of this file are subject to the Mozilla Public License Version 
6     * 1.1 (the "License"); you may not use this file except in compliance with 
7     * the License.  Alternatively, the contents of this file may be used under 
8     * the terms of the GNU Lesser General Public License Version 2.1 or later. 
9     * 
10    * Software distributed under the License is distributed on an "AS IS" basis, 
11    * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
12    * for the specific language governing rights and limitations under the 
13    * License. 
14    */ 
15    
16   package javassist.convert; 
17    
18   import javassist.bytecode.*; 
19   import javassist.ClassPool; 
20   import javassist.CtClass; 
21   import javassist.CtField; 
22   import javassist.CannotCompileException; 
23   import javassist.NotFoundException; 
24   import javassist.Modifier; 
25    
26   public class TransformReadField extends Transformer { 
27       protected String fieldname; 
28       protected CtClass fieldClass; 
29       protected boolean isPrivate; 
30       protected String methodClassname, methodName; 
31    
32       public TransformReadField(Transformer next, CtField field, 
33                                 String methodClassname, String methodName) { 
34           super(next); 
35           this.fieldClass = field.getDeclaringClass(); 
36           this.fieldname = field.getName(); 
37           this.methodClassname = methodClassname; 
38           this.methodName = methodName; 
39           this.isPrivate = Modifier.isPrivate(field.getModifiers()); 
40       } 
41    
42       static String isField(ClassPool pool, ConstPool cp, CtClass fclass, 
43                             String fname, boolean is_private, int index) { 
44           if (!cp.getFieldrefName(index).equals(fname)) 
45               return null; 
46    
47           try { 
48               CtClass c = pool.get(cp.getFieldrefClassName(index)); 
49               if (is_private ? c == fclass : c.subclassOf(fclass)) 
50                   return cp.getFieldrefType(index); 
51           } catch (NotFoundException e) { 
52           } 
53           return null; 
54       } 
55    
56       public int transform(CtClass tclazz, int pos, CodeIterator iterator, 
57                            ConstPool cp) throws BadBytecode { 
58           int c = iterator.byteAt(pos); 
59           if (c == GETFIELD || c == GETSTATIC) { 
60               int index = iterator.u16bitAt(pos + 1); 
61               String typedesc = isField(tclazz.getClassPool(), cp, 
62                       fieldClass, fieldname, isPrivate, index); 
63               if (typedesc != null) { 
64                   if (c == GETSTATIC) { 
65                       iterator.move(pos); 
66                       iterator.insertGap(1); // insertGap() may insert 4 bytes. 
67                       iterator.writeByte(ACONST_NULL, pos); 
68                       pos = iterator.next(); 
69                   } 
70    
71                   String type = "(Ljava/lang/Object;)" + typedesc; 
72                   int mi = cp.addClassInfo(methodClassname); 
73                   int methodref = cp.addMethodrefInfo(mi, methodName, type); 
74                   iterator.writeByte(INVOKESTATIC, pos); 
75                   iterator.write16bit(methodref, pos + 1); 
76                   return pos; 
77               } 
78           } 
79    
80           return pos; 
81       } 
82   } 
83