001    package edu.rice.cs.cunit.classFile.constantPool;
002    
003    import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckUTFVisitor;
004    import edu.rice.cs.cunit.classFile.constantPool.visitors.IPoolInfoVisitor;
005    
006    import java.io.DataInputStream;
007    import java.io.DataOutputStream;
008    import java.io.IOException;
009    
010    /**
011     * Represents a name-and-type object in the constant pool.
012     *
013     * @author Mathias Ricken
014     */
015    public class NameAndTypePoolInfo extends APoolInfo {
016        /**
017         * Name information.
018         */
019        protected AUTFPoolInfo _name;
020    
021        /**
022         * Type descriptor information.
023         */
024        protected AUTFPoolInfo _descriptor;
025    
026        /**
027         * Name index.
028         */
029        protected short _nameIndex;
030    
031        /**
032         * Type descriptor index.
033         */
034        protected short _descriptorIndex;
035    
036        /**
037         * Constructor.
038         *
039         * @param name       name information
040         * @param descriptor type descriptor information
041         */
042        public NameAndTypePoolInfo(AUTFPoolInfo name, AUTFPoolInfo descriptor, ConstantPool cp) {
043            super(CONSTANT_NameAndType, cp);
044            _name = name;
045            _descriptor = descriptor;
046            reindex();
047        }
048    
049        /**
050         * Constructor reading from a stream.
051         *
052         * @param dis input stream
053         * @param cp  constant pool
054         *
055         * @throws IOException
056         */
057        public NameAndTypePoolInfo(DataInputStream dis, ConstantPool cp) throws IOException {
058            super(CONSTANT_NameAndType, cp);
059            _nameIndex = dis.readShort();
060            _descriptorIndex = dis.readShort();
061        }
062    
063        /**
064         * Accessor for the name information.
065         *
066         * @return name information
067         */
068        public AUTFPoolInfo getName() {
069            return _name;
070        }
071    
072        /**
073         * Mutator for the name information.
074         *
075         * @param name new name information
076         */
077        public void setName(AUTFPoolInfo name) {
078            _name = name;
079        }
080    
081        /**
082         * Accessor for the type descriptor information.
083         *
084         * @return type descriptor information
085         */
086        public AUTFPoolInfo getDescriptor() {
087            return _descriptor;
088        }
089    
090        /**
091         * Mutator for the type descriptor information.
092         *
093         * @param descriptor type descriptor information
094         */
095        public void setDescriptor(AUTFPoolInfo descriptor) {
096            _descriptor = descriptor;
097        }
098    
099        /**
100         * Write this constant pool object into the stream, including the type byte.
101         *
102         * @param dos stream
103         *
104         * @throws java.io.IOException
105         */
106        public void write(DataOutputStream dos) throws IOException {
107            reindex();
108            dos.writeByte(_type);
109            dos.writeShort(_nameIndex);
110            dos.writeShort(_descriptorIndex);
111        }
112    
113        /**
114         * Resolve constant pool objects. This makes sure that the object links match the index links.
115         */
116        public void resolve() {
117            _name = _constantPool.get(_nameIndex).execute(CheckUTFVisitor.singleton(), null);
118            _descriptor = _constantPool.get(_descriptorIndex).execute(CheckUTFVisitor.singleton(), null);
119        }
120    
121        /**
122         * Reindex constant pool indices. This makes sure the index links match the object links.
123         */
124        public void reindex() {
125            _nameIndex = _constantPool.indexOf(_name);
126            _descriptorIndex = _constantPool.indexOf(_descriptor);
127        }
128    
129        /**
130         * Return a human-readable version of this constant pool object.
131         *
132         * @return string
133         */
134        public String toStringVerbose() {
135            StringBuilder s = new StringBuilder();
136            s.append("NAME-AND-TYPE: Name = #");
137            s.append(_nameIndex);
138            s.append(", Descriptor = #");
139            s.append(_descriptorIndex);
140            s.append(' ');
141            s.append(toString());
142    
143            return s.toString();
144        }
145    
146        /**
147         * Return a human-readable version of this constant pool object.
148         *
149         * @return string
150         */
151        public String toString() {
152            StringBuilder s = new StringBuilder();
153            s.append(_name.toString());
154            s.append(_descriptor.toString());
155            return s.toString();
156        }
157    
158        /**
159         * Return a hash code.
160         *
161         * @return hash code
162         */
163        public int hashCode() {
164            return _nameIndex + 6101 * _descriptorIndex;
165        }
166    
167        /**
168         * Compare this object and another one.
169         *
170         * @param obj other object
171         *
172         * @return true if the same
173         */
174        public boolean equals(Object obj) {
175            return (obj instanceof NameAndTypePoolInfo) && (
176                (((NameAndTypePoolInfo)obj)._nameIndex == _nameIndex) ||
177                (((NameAndTypePoolInfo)obj)._name == _name)
178                ) && (
179                (((NameAndTypePoolInfo)obj)._descriptorIndex == _descriptorIndex) ||
180                (((NameAndTypePoolInfo)obj)._descriptor == _descriptor)
181                );
182        }
183    
184        /**
185         * Execute a visitor.
186         *
187         * @param visitor visitor
188         * @param data    visitor-specific parameter
189         *
190         * @return visitor-specific return value
191         */
192        public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
193            return visitor.nameAndTypeCase(this, data);
194        }
195    }