001 package edu.rice.cs.cunit.classFile;
002
003 import edu.rice.cs.cunit.classFile.attributes.AAttributeInfo;
004 import edu.rice.cs.cunit.classFile.attributes.SourceFileAttributeInfo;
005 import edu.rice.cs.cunit.classFile.constantPool.APoolInfo;
006 import edu.rice.cs.cunit.classFile.constantPool.AUTFPoolInfo;
007 import edu.rice.cs.cunit.classFile.constantPool.ConstantPool;
008 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckUTFVisitor;
009
010 import java.io.DataInputStream;
011 import java.io.DataOutputStream;
012 import java.io.IOException;
013 import java.util.ArrayList;
014
015 /**
016 * Represents a field in a class file.
017 *
018 * @author Mathias Ricken
019 */
020
021 public final class FieldInfo {
022 /**
023 * Field access flags
024 */
025 private short _accessFlags;
026
027 /**
028 * Name information.
029 */
030 private AUTFPoolInfo _name;
031
032 /**
033 * Type descriptor information.
034 */
035 private AUTFPoolInfo _descriptor;
036
037 /**
038 * Attributes.
039 */
040 private ArrayList<AAttributeInfo> _attributes = new ArrayList<AAttributeInfo>();
041
042 /**
043 * Constructor.
044 *
045 * @param accessFlags field access flags
046 * @param name field name
047 * @param descriptor field descriptor
048 * @param attributes array of attributes
049 */
050 public FieldInfo(short accessFlags,
051 AUTFPoolInfo name,
052 AUTFPoolInfo descriptor,
053 SourceFileAttributeInfo[] attributes) {
054 _accessFlags = accessFlags;
055 _name = name;
056 _descriptor = descriptor;
057 if (attributes != null) {
058 for(AAttributeInfo attr : attributes) {
059 _attributes.add(attr);
060 }
061 }
062 }
063
064 /**
065 * Constructor.
066 *
067 * @param di input stream
068 * @param pool constant pool
069 *
070 * @throws IOException
071 * @throws ClassFormatError
072 */
073 public FieldInfo(DataInputStream di, ConstantPool pool) throws IOException, ClassFormatError {
074 _accessFlags = di.readShort();
075 _name = pool.get(di.readShort()).execute(CheckUTFVisitor.singleton(), null);
076 _descriptor = pool.get(di.readShort()).execute(CheckUTFVisitor.singleton(), null);
077
078 int count = di.readShort();
079 for(int i = 0; i < count; i++) {
080 _attributes.add(AAttributeInfo.read(di, pool));
081 }
082 }
083
084 /**
085 * Write this field into a stream.
086 *
087 * @param dos output stream
088 * @param pool constant pool
089 *
090 * @throws IOException
091 */
092 public void write(DataOutputStream dos, ConstantPool pool) throws IOException {
093 dos.writeShort(_accessFlags);
094 dos.writeShort(pool.indexOf(_name));
095 dos.writeShort(pool.indexOf(_descriptor));
096 dos.writeShort(_attributes.size());
097 for(AAttributeInfo attr : _attributes) {
098 attr.write(dos);
099 }
100 }
101
102 /**
103 * Return a human-readable version of this field.
104 *
105 * @return string
106 */
107 public String toString() {
108 StringBuilder x = new StringBuilder();
109
110 x.append(ClassFileTools.getAccessString(_accessFlags));
111 x.append(ClassFileTools.getTypeString(_descriptor.toStringVerbose(), _name.toStringVerbose()));
112 if (_attributes.size() != 0) {
113 x.append(" = " + _attributes.get(0).toString());
114 }
115 return x.toString();
116 }
117
118 /**
119 * Return a human-readable version of this field and correctly handle booleans and strings.
120 *
121 * @param pool constant pool
122 *
123 * @return string
124 */
125 public final String toString(ConstantPool pool) {
126 StringBuilder x = new StringBuilder();
127
128 x.append(ClassFileTools.getAccessString(_accessFlags));
129 String t = ClassFileTools.getTypeString(_descriptor.toString(), _name.toString());
130 x.append(t);
131 for(AAttributeInfo attr : _attributes) {
132 x.append(", " + attr);
133 }
134 return x.toString();
135 }
136
137 /**
138 * Accessor for access flags.
139 *
140 * @return access flags
141 */
142 public short getAccessFlags() {
143 return _accessFlags;
144 }
145
146 /**
147 * Mutator for access flags.
148 *
149 * @param accessFlags new access flags
150 */
151 public void setAccessFlags(short accessFlags) {
152 _accessFlags = accessFlags;
153 }
154
155 /**
156 * Accessor for field name.
157 *
158 * @return field name
159 */
160 public AUTFPoolInfo getName() {
161 return _name;
162 }
163
164 /**
165 * Mutator for field name.
166 *
167 * @param name new field name
168 */
169 public void setName(AUTFPoolInfo name) {
170 _name = name;
171 }
172
173 /**
174 * Accessor for descriptor.
175 *
176 * @return descriptor
177 */
178 public AUTFPoolInfo getDescriptor() {
179 return _descriptor;
180 }
181
182 /**
183 * Mutator for descriptor.
184 *
185 * @param descriptor new descriptor
186 */
187 public void setDescriptor(AUTFPoolInfo descriptor) {
188 _descriptor = descriptor;
189 }
190
191 /**
192 * Accessor for attributes.
193 *
194 * @return attributes
195 */
196 public ArrayList<AAttributeInfo> getAttributes() {
197 return _attributes;
198 }
199
200 /**
201 * Return the attribute with the specified name.
202 *
203 * @param name attribute name
204 *
205 * @return attribute or null if not found
206 */
207 public AAttributeInfo getAttribute(String name) {
208 if (0 == _attributes.size()) {
209 return null;
210 }
211 for(AAttributeInfo attr : _attributes) {
212 if (0 == name.compareTo(attr.getName().toString())) {
213 return attr;
214 }
215 }
216 return null;
217 }
218
219 /**
220 * Mutator for attributes.
221 *
222 * @param attributes new attributes
223 */
224 public void setAttributes(ArrayList<AAttributeInfo> attributes) {
225 _attributes = attributes;
226 }
227 }