Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/techtrader/modules/tools/bytecode/FieldInstruction.java


1   package com.techtrader.modules.tools.bytecode;
2   
3   
4   import java.lang.reflect.Field;
5   import java.io.IOException;
6   import java.io.DataInput;
7   import java.io.DataOutput;
8   
9   import com.techtrader.modules.tools.bytecode.lowlevel.FieldEntry;
10  import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
11  
12  
13  /**
14   *  Represents an instruction that takes as an argument a field to operate on.
15   *  Examples include GETFIELD, GETSTATIC, SETFIELD, SETSTATIC.
16   *
17   *  @author    Abe White
18   */
19  public abstract class FieldInstruction
20    extends Instruction
21  {
22    private int _index = 0;
23  
24  
25    protected FieldInstruction (Code owner, int opcode)
26    {
27      super (owner);
28      _opcode = opcode;  
29    }
30  
31  
32    /**
33     *  Get the index of the ComplexEntry in the constant pool describing
34      *  the field to operate on.
35     */
36    public int getFieldIndex ()
37    {
38      return _index;
39    }
40  
41  
42    /**
43     *  Set the index of the ComplexEntry in the constant pool describing
44      *  the field to operate on.
45     */
46    public void setFieldIndex (int index)
47    {
48      _index = index;
49    }
50  
51  
52    /**
53      *  Set the field to operate on.
54     *  
55     *  @return    this Instruction, for method chaining
56     */
57    public FieldInstruction setField (BCField field)
58    {
59      BCClass ownerType = field.getOwner ();
60      return setField (field.getName (), field.getTypeName (), 
61        ownerType.getName ());
62    }
63  
64  
65    /**
66     *  Set the field to operate on.
67     *  
68     *  @return    this Instruction, for method chaining
69     */
70    public FieldInstruction setField (Field field)
71    {
72      return setField (field.getName (), field.getType ().getName (),
73        field.getDeclaringClass ().getName ());
74    }
75  
76  
77    /**
78     *  Set the field to operate on.
79     *  
80     *  @return    this Instruction, for method chaining
81     */
82    public FieldInstruction setField (String name, String type, 
83      String ownerType)
84    {
85      String internalType = BCHelper.getInternalForm (type, true);
86      String internalOwner = BCHelper.getInternalForm(ownerType, false);
87  
88      _index = _owner.getPool ().setComplex (0, name, internalType, 
89        internalOwner, FieldEntry.class);
90  
91      return this;
92    }
93  
94    
95    /**
96     *  Set the field to operate on.
97     *  
98     *  @return    this Instruction, for method chaining
99     */
100   public FieldInstruction setField (String name, Class type, String ownerType)
101   {
102     String typeName = (type == null) ? null : type.getName ();
103     return setField (name, typeName, ownerType);
104   }
105 
106 
107   /**
108    *  Set the field to operate on.
109    *  
110    *  @return    this Instruction, for method chaining
111    */
112   public FieldInstruction setField (String name, Class type, Class ownerType)
113   {
114     String typeName = (type == null) ? null : type.getName ();
115     String ownerName = (ownerType == null) ? null : ownerType.getName ();
116     return setField (name, typeName, ownerName);
117   }
118 
119 
120   /**
121    *  Change the field name.
122    *  
123    *  @return    this Instruction, for method chaining
124    */
125   public FieldInstruction setFieldName (String name)
126   {
127     return setField (name, getFieldTypeName (), getFieldOwnerTypeName ());
128   }
129 
130 
131   /**
132    *  Return true if the field is a member of the current class.
133    */
134   public boolean isFieldInCurrentClass ()
135   {
136     BCClass type = ((BCMethod) _owner.getOwner ()).getOwner ();
137     return type.getName ().equals (getFieldOwnerTypeName ());
138   }
139 
140 
141   /**
142    *  If the field is a member of the current class, then this method will
143    *  retrieve the BCField object for it; otherwise it will return null.
144    */
145   public BCField getField ()
146   {
147     if (!isFieldInCurrentClass ())
148       return null;
149 
150     return ((BCMethod) _owner.getOwner ()).getOwner ().
151       getField (getFieldName ());
152   }
153 
154 
155   /**
156     *  Get the nam of the field to operate on.
157    */
158   public String getFieldName ()
159   {
160     return _owner.getPool ().getComplexName (_index);
161   }  
162 
163 
164   /**
165    *  Get the type of the field.
166    */
167   public String getFieldTypeName ()
168   {
169     return BCHelper.getExternalForm 
170       (_owner.getPool ().getComplexTypeName (_index), true);
171   }
172 
173 
174   /**
175    *  Get the type of the field.
176    */
177   public Class getFieldType ()
178     throws ClassNotFoundException
179   {
180     return BCHelper.classForName 
181       (_owner.getPool ().getComplexTypeName (_index));
182   }
183 
184 
185   /**
186    *  Get the type of the field.
187    */
188   public String getFieldOwnerTypeName ()
189   {
190     return BCHelper.getExternalForm 
191       (_owner.getPool ().getComplexOwnerTypeName (_index), true);
192   }
193 
194 
195   /**
196    *  Get the type of the field.
197    */
198   public Class getFieldOwnerType ()
199     throws ClassNotFoundException
200   {
201     return BCHelper.classForName
202       (_owner.getPool ().getComplexOwnerTypeName (_index));
203   }
204 
205 
206   /**
207    *  FieldInstructions are equal if the field they reference is the same, 
208    *  or if the field of either is unset.
209    */
210   public boolean equals (Object other)
211   {
212     if (other == this)
213       return true;
214     if (!(other instanceof FieldInstruction))
215       return false;
216     if (!super.equals (other))
217       return false;
218 
219     FieldInstruction ins = (FieldInstruction) other;
220 
221     String s1 = getFieldName ();
222     String s2 = ins.getFieldName ();
223     if (!(s1.length () == 0 || s2.length () == 0 || s1.equals (s2)))
224       return false;
225 
226     s1 = getFieldTypeName ();
227     s2 = ins.getFieldTypeName ();
228     if (!(s1.length () == 0 || s2.length () == 0 || s1.equals (s2)))
229       return false;
230     
231     s1 = getFieldOwnerTypeName ();
232     s2 = ins.getFieldOwnerTypeName ();
233     if (!(s1.length () == 0 || s2.length () == 0 || s1.equals (s2)))
234       return false;
235 
236     return true;
237   }
238 
239 
240   public int getLength ()
241   {
242     return super.getLength () + 2;
243   }
244 
245 
246   protected void copy (Instruction orig)
247   {
248     super.copy (orig);
249     FieldInstruction origFI = (FieldInstruction) orig;
250 
251     setField (origFI.getFieldName (), origFI.getFieldTypeName (), 
252       origFI.getFieldOwnerTypeName ());
253   }
254 
255 
256   protected void readData (DataInput in)
257     throws IOException
258   {
259     _index = in.readUnsignedShort ();
260   }
261 
262 
263   protected void writeData (DataOutput out)
264     throws IOException
265   {
266     out.writeShort (_index);
267   }
268 }