Source code: com/techtrader/modules/tools/bytecode/BCField.java
1 package com.techtrader.modules.tools.bytecode;
2
3
4 import java.io.IOException;
5 import java.io.DataInput;
6 import java.io.DataOutput;
7
8 import com.techtrader.modules.tools.bytecode.lowlevel.ConstantPool;
9 import com.techtrader.modules.tools.bytecode.lowlevel.FieldEntry;
10 import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
11
12
13 /**
14 * Representation of a bytecode field of a class; a BCField can only
15 * be obtained from a BCClass.
16 *
17 * @author Abe White
18 */
19 public class BCField
20 extends BCEntity
21 implements Constants
22 {
23 private BCClass _owner = null;
24 private int _access = ACCESS_PRIVATE;
25 private int _nameIndex = 0;
26 private int _descriptorIndex = 0;
27
28
29 /**
30 * Protected constructor.
31 */
32 protected BCField (BCClass owner)
33 {
34 _owner = owner;
35 }
36
37
38 /**
39 * Used when this field is deleted from its class.
40 */
41 protected void invalidate ()
42 {
43 _owner = null;
44 }
45
46
47 /**
48 * Get the BCClass that owns this field.
49 */
50 public BCClass getOwner ()
51 {
52 return _owner;
53 }
54
55
56 /**
57 * Return the access flags for this class as a bit array of
58 * ACCESS_XXX constants. This can be used to transfer access flags
59 * between fields without getting/setting each possible access flag.
60 */
61 public int getAccessFlags ()
62 {
63 return _access;
64 }
65
66
67 /**
68 * Set the access flags for this class as a bit array of
69 * ACCESS_XXX constants. This can be used to transfer access flags
70 * between fields without getting/setting each possible access flag.
71 */
72 public void setAccessFlags (int access)
73 {
74 _access = access;
75 }
76
77
78 /**
79 * Manipulate the method access flags.
80 */
81 public boolean isPublic ()
82 {
83 return BCHelper.hasFlag (_access, ACCESS_PUBLIC);
84 }
85
86
87 /**
88 * Manipulate the method access flags.
89 */
90 public void makePublic ()
91 {
92 _access = BCHelper.setFlag (_access, ACCESS_PUBLIC, true);
93 _access = BCHelper.setFlag (_access, ACCESS_PRIVATE, false);
94 _access = BCHelper.setFlag (_access, ACCESS_PROTECTED, false);
95 }
96
97
98 /**
99 * Manipulate the method access flags.
100 */
101 public boolean isProtected ()
102 {
103 return BCHelper.hasFlag (_access, ACCESS_PROTECTED);
104 }
105
106
107 /**
108 * Manipulate the method access flags.
109 */
110 public void makeProtected ()
111 {
112 _access = BCHelper.setFlag (_access, ACCESS_PUBLIC, false);
113 _access = BCHelper.setFlag (_access, ACCESS_PRIVATE, false);
114 _access = BCHelper.setFlag (_access, ACCESS_PROTECTED, true);
115 }
116
117
118 /**
119 * Manipulate the method access flags.
120 */
121 public boolean isPrivate ()
122 {
123 return BCHelper.hasFlag (_access, ACCESS_PRIVATE);
124 }
125
126
127 /**
128 * Manipulate the method access flags.
129 */
130 public void makePrivate ()
131 {
132 _access = BCHelper.setFlag (_access, ACCESS_PUBLIC, false);
133 _access = BCHelper.setFlag (_access, ACCESS_PRIVATE, true);
134 _access = BCHelper.setFlag (_access, ACCESS_PROTECTED, false);
135 }
136
137
138 /**
139 * Manipulate the method access flags.
140 */
141 public boolean isPackage ()
142 {
143 boolean hasAccess = false;
144 hasAccess = hasAccess || BCHelper.hasFlag (_access, ACCESS_PRIVATE);
145 hasAccess = hasAccess || BCHelper.hasFlag (_access, ACCESS_PROTECTED);
146 hasAccess = hasAccess || BCHelper.hasFlag (_access, ACCESS_PUBLIC);
147
148 return !hasAccess;
149 }
150
151
152 /**
153 * Manipulate the method access flags.
154 */
155 public void makePackage ()
156 {
157 _access = BCHelper.setFlag (_access, ACCESS_PUBLIC, false);
158 _access = BCHelper.setFlag (_access, ACCESS_PRIVATE, false);
159 _access = BCHelper.setFlag (_access, ACCESS_PROTECTED, false);
160 }
161
162
163 /**
164 * Manipulate the method access flags.
165 */
166 public boolean isFinal ()
167 {
168 return BCHelper.hasFlag (_access, ACCESS_FINAL);
169 }
170
171
172 /**
173 * Manipulate the method access flags.
174 */
175 public void setFinal (boolean on)
176 {
177 _access = BCHelper.setFlag (_access, ACCESS_FINAL, on);
178 }
179
180
181 /**
182 * Manipulate the method access flags.
183 */
184 public boolean isStatic ()
185 {
186 return BCHelper.hasFlag (_access, ACCESS_STATIC);
187 }
188
189
190 /**
191 * Manipulate the method access flags.
192 */
193 public void setStatic (boolean on)
194 {
195 _access = BCHelper.setFlag (_access, ACCESS_STATIC, on);
196 }
197
198
199 /**
200 * Manipulate the method access flags.
201 */
202 public boolean isVolatile ()
203 {
204 return BCHelper.hasFlag (_access, ACCESS_VOLATILE);
205 }
206
207
208 /**
209 * Manipulate the method access flags.
210 */
211 public void setVolatile (boolean on)
212 {
213 _access = BCHelper.setFlag (_access, ACCESS_VOLATILE, on);
214 }
215
216
217 /**
218 * Manipulate the method access flags.
219 */
220 public boolean isTransient ()
221 {
222 return BCHelper.hasFlag (_access, ACCESS_TRANSIENT);
223 }
224
225
226 /**
227 * Manipulate the method access flags.
228 */
229 public void setTransient (boolean on)
230 {
231 _access = BCHelper.setFlag (_access, ACCESS_TRANSIENT, on);
232 }
233
234
235 /**
236 * Get the index in the constant pool of the UTF entry holding the name
237 * of this field.
238 */
239 public int getNameIndex ()
240 {
241 return _nameIndex;
242 }
243
244
245 /**
246 * Set the index in the constant pool of the UTF entry holding the name
247 * of this field.
248 */
249 public void setNameIndex (int index)
250 {
251 _nameIndex = index;
252 }
253
254
255 /**
256 * Get the index in the constant pool of the UTF entry holding the
257 * descriptor of this field.
258 */
259 public int getDescriptorIndex ()
260 {
261 return _descriptorIndex;
262 }
263
264
265 /**
266 * Set the index in the constant pool of the UTF entry holding the
267 * descriptor of this field.
268 */
269 public void setDescriptorIndex (int index)
270 {
271 _descriptorIndex = index;
272 }
273
274
275 /**
276 * Get the name of this field.
277 */
278 public String getName ()
279 {
280 return getPool ().getUTF (_nameIndex);
281 }
282
283
284 /**
285 * Set the name of this field.
286 */
287 public void setName (String name)
288 {
289 String origName = getName ();
290
291 // reset the name
292 _nameIndex = getPool ().setUTF (0, name);
293
294 // find the ComplexEntry matching this field, if any
295 String internalDesc = getPool ().getUTF (_descriptorIndex);
296 String internalOwner = getPool ().getClassName (_owner.getIndex ());
297
298 int index = getPool ().getComplexIndex
299 (origName, internalDesc, internalOwner, FieldEntry.class);
300
301 // change the ComplexEntry to match the new name; this is dones so
302 // that refs to the field in code will still be valid after the name
303 // change, without changing any other constants that happened to match
304 // the old field name
305 if (index != 0)
306 getPool ().setComplex
307 (index, name, internalDesc, internalOwner, FieldEntry.class);
308 }
309
310
311 /**
312 * Get the index in the constant pool of the UTF entry holding the
313 * descriptor of this field.
314 */
315 public int getTypeIndex ()
316 {
317 return _descriptorIndex;
318 }
319
320
321 /**
322 * Set the index in the constant pool of the UTF entry holding the
323 * descriptor of this field.
324 */
325 public void setTypeIndex (int index)
326 {
327 _descriptorIndex = index;
328 }
329
330
331 /**
332 * Get the name of the type of this field.
333 */
334 public String getTypeName ()
335 {
336 return BCHelper.getExternalForm
337 (getPool ().getUTF (_descriptorIndex), true);
338 }
339
340
341 /**
342 * Set the type name for this field.
343 */
344 public void setTypeName (String name)
345 {
346 String origDesc = getPool ().getUTF (_descriptorIndex);
347
348 // reset the desc
349 String internalDesc = BCHelper.getInternalForm (name, true);
350 _descriptorIndex = getPool ().setUTF (0, internalDesc);
351
352 // find the ComplexEntry matching this field, if any
353 String internalName = getName ();
354 String internalOwner = getPool ().getClassName (_owner.getIndex ());
355
356 int index = getPool ().getComplexIndex
357 (internalName, origDesc, internalOwner, FieldEntry.class);
358
359 // change the ComplexEntry to match the new desc; this is dones so
360 // that refs to the field in code will still be valid after the name
361 // change, without changing any other constants that happened to match
362 // the old field name
363 if (index != 0)
364 getPool ().setComplex (index, internalName, internalDesc,
365 internalOwner, FieldEntry.class);
366 }
367
368
369 /**
370 * Get the Class object for the type of this field.
371 */
372 public Class getType ()
373 throws ClassNotFoundException
374 {
375 return BCHelper.classForName (getPool ().getUTF (_descriptorIndex));
376 }
377
378
379 /**
380 * Set the type of this field.
381 */
382 public void setType (Class type)
383 {
384 setTypeName (type.getName ());
385 }
386
387
388 /**
389 * Get the class constant pool; this method delegates to the
390 * owning class.
391 */
392 public ConstantPool getPool ()
393 {
394 return getOwner ().getPool ();
395 }
396
397
398 protected void readData (DataInput in)
399 throws IOException
400 {
401 setAccessFlags (in.readUnsignedShort ());
402 setNameIndex (in.readUnsignedShort ());
403 setDescriptorIndex (in.readUnsignedShort ());
404
405 readAttributes (in);
406 }
407
408
409 protected void writeData (DataOutput out)
410 throws IOException
411 {
412 out.writeShort (getAccessFlags ());
413 out.writeShort (getNameIndex ());
414 out.writeShort (getDescriptorIndex ());
415
416 writeAttributes (out);
417 }
418
419
420 public void acceptVisit (BCVisitor visit)
421 {
422 visit.enterBCField (this);
423 visitAttributes (visit);
424 visit.exitBCField (this);
425 }
426 }