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