• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2007 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.bytecode;
17 
18 import java.io.DataInputStream;
19 import java.io.DataOutputStream;
20 import java.io.IOException;
21 import java.util.List;
22 import java.util.ArrayList;
23 
24 /**
25  * <code>field_info</code> structure.
26  *
27  * @see javassist.CtField#getFieldInfo()
28  */
29 public final class FieldInfo {
30     ConstPool constPool;
31     int accessFlags;
32     int name;
33     String cachedName;
34     String cachedType;
35     int descriptor;
36     ArrayList attribute;       // may be null.
37 
FieldInfo(ConstPool cp)38     private FieldInfo(ConstPool cp) {
39         constPool = cp;
40         accessFlags = 0;
41         attribute = null;
42     }
43 
44     /**
45      * Constructs a <code>field_info</code> structure.
46      *
47      * @param cp                a constant pool table
48      * @param fieldName         field name
49      * @param desc              field descriptor
50      *
51      * @see Descriptor
52      */
FieldInfo(ConstPool cp, String fieldName, String desc)53     public FieldInfo(ConstPool cp, String fieldName, String desc) {
54         this(cp);
55         name = cp.addUtf8Info(fieldName);
56         cachedName = fieldName;
57         descriptor = cp.addUtf8Info(desc);
58     }
59 
FieldInfo(ConstPool cp, DataInputStream in)60     FieldInfo(ConstPool cp, DataInputStream in) throws IOException {
61         this(cp);
62         read(in);
63     }
64 
65     /**
66      * Returns a string representation of the object.
67      */
toString()68     public String toString() {
69         return getName() + " " + getDescriptor();
70     }
71 
72     /**
73      * Copies all constant pool items to a given new constant pool
74      * and replaces the original items with the new ones.
75      * This is used for garbage collecting the items of removed fields
76      * and methods.
77      *
78      * @param cp    the destination
79      */
compact(ConstPool cp)80     void compact(ConstPool cp) {
81         name = cp.addUtf8Info(getName());
82         descriptor = cp.addUtf8Info(getDescriptor());
83         attribute = AttributeInfo.copyAll(attribute, cp);
84         constPool = cp;
85     }
86 
prune(ConstPool cp)87     void prune(ConstPool cp) {
88         ArrayList newAttributes = new ArrayList();
89         AttributeInfo invisibleAnnotations
90             = getAttribute(AnnotationsAttribute.invisibleTag);
91         if (invisibleAnnotations != null) {
92             invisibleAnnotations = invisibleAnnotations.copy(cp, null);
93             newAttributes.add(invisibleAnnotations);
94          }
95 
96         AttributeInfo visibleAnnotations
97             = getAttribute(AnnotationsAttribute.visibleTag);
98         if (visibleAnnotations != null) {
99             visibleAnnotations = visibleAnnotations.copy(cp, null);
100             newAttributes.add(visibleAnnotations);
101         }
102 
103         AttributeInfo signature
104             = getAttribute(SignatureAttribute.tag);
105         if (signature != null) {
106             signature = signature.copy(cp, null);
107             newAttributes.add(signature);
108         }
109 
110         int index = getConstantValue();
111         if (index != 0) {
112             index = constPool.copy(index, cp, null);
113             newAttributes.add(new ConstantAttribute(cp, index));
114         }
115 
116         attribute = newAttributes;
117         name = cp.addUtf8Info(getName());
118         descriptor = cp.addUtf8Info(getDescriptor());
119         constPool = cp;
120     }
121 
122     /**
123      * Returns the constant pool table used
124      * by this <code>field_info</code>.
125      */
getConstPool()126     public ConstPool getConstPool() {
127         return constPool;
128     }
129 
130     /**
131      * Returns the field name.
132      */
getName()133     public String getName() {
134        if (cachedName == null)
135            cachedName = constPool.getUtf8Info(name);
136 
137        return cachedName;
138     }
139 
140     /**
141      * Sets the field name.
142      */
setName(String newName)143     public void setName(String newName) {
144         name = constPool.addUtf8Info(newName);
145         cachedName = newName;
146     }
147 
148     /**
149      * Returns the access flags.
150      *
151      * @see AccessFlag
152      */
getAccessFlags()153     public int getAccessFlags() {
154         return accessFlags;
155     }
156 
157     /**
158      * Sets the access flags.
159      *
160      * @see AccessFlag
161      */
setAccessFlags(int acc)162     public void setAccessFlags(int acc) {
163         accessFlags = acc;
164     }
165 
166     /**
167      * Returns the field descriptor.
168      *
169      * @see Descriptor
170      */
getDescriptor()171     public String getDescriptor() {
172         return constPool.getUtf8Info(descriptor);
173     }
174 
175     /**
176      * Sets the field descriptor.
177      *
178      * @see Descriptor
179      */
setDescriptor(String desc)180     public void setDescriptor(String desc) {
181         if (!desc.equals(getDescriptor()))
182             descriptor = constPool.addUtf8Info(desc);
183     }
184 
185     /**
186      * Finds a ConstantValue attribute and returns the index into
187      * the <code>constant_pool</code> table.
188      *
189      * @return 0    if a ConstantValue attribute is not found.
190      */
getConstantValue()191     public int getConstantValue() {
192         if ((accessFlags & AccessFlag.STATIC) == 0)
193             return 0;
194 
195         ConstantAttribute attr
196             = (ConstantAttribute)getAttribute(ConstantAttribute.tag);
197         if (attr == null)
198             return 0;
199         else
200             return attr.getConstantValue();
201     }
202 
203     /**
204      * Returns all the attributes.    The returned <code>List</code> object
205      * is shared with this object.  If you add a new attribute to the list,
206      * the attribute is also added to the field represented by this
207      * object.  If you remove an attribute from the list, it is also removed
208      * from the field.
209      *
210      * @return a list of <code>AttributeInfo</code> objects.
211      * @see AttributeInfo
212      */
getAttributes()213     public List getAttributes() {
214         if (attribute == null)
215             attribute = new ArrayList();
216 
217         return attribute;
218     }
219 
220     /**
221      * Returns the attribute with the specified name.
222      * It returns null if the specified attribute is not found.
223      *
224      * @param name      attribute name
225      * @see #getAttributes()
226      */
getAttribute(String name)227     public AttributeInfo getAttribute(String name) {
228         return AttributeInfo.lookup(attribute, name);
229     }
230 
231     /**
232      * Appends an attribute.  If there is already an attribute with
233      * the same name, the new one substitutes for it.
234      *
235      * @see #getAttributes()
236      */
addAttribute(AttributeInfo info)237     public void addAttribute(AttributeInfo info) {
238         if (attribute == null)
239             attribute = new ArrayList();
240 
241         AttributeInfo.remove(attribute, info.getName());
242         attribute.add(info);
243     }
244 
read(DataInputStream in)245     private void read(DataInputStream in) throws IOException {
246         accessFlags = in.readUnsignedShort();
247         name = in.readUnsignedShort();
248         descriptor = in.readUnsignedShort();
249         int n = in.readUnsignedShort();
250         attribute = new ArrayList();
251         for (int i = 0; i < n; ++i)
252             attribute.add(AttributeInfo.read(constPool, in));
253     }
254 
write(DataOutputStream out)255     void write(DataOutputStream out) throws IOException {
256         out.writeShort(accessFlags);
257         out.writeShort(name);
258         out.writeShort(descriptor);
259         if (attribute == null)
260             out.writeShort(0);
261         else {
262             out.writeShort(attribute.size());
263             AttributeInfo.writeAll(attribute, out);
264         }
265     }
266 }
267