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    }