001    package sysModel.classFile.constantPool;
002    
003    import sysModel.classFile.constantPool.visitors.CheckUTFVisitor;
004    import sysModel.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 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 toString() {
135            StringBuffer s;
136    
137            s = new StringBuffer();
138            s.append("NAME-AND-TYPE: Name = #");
139            s.append(_nameIndex);
140            s.append(", Descriptor = #");
141            s.append(_descriptorIndex);
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 toStringVerbose() {
152            return toString();
153        }
154    
155        /**
156         * Return a hash code.
157         *
158         * @return hash code
159         */
160        public int hashCode() {
161            return _nameIndex + 6101 * _descriptorIndex;
162        }
163    
164        /**
165         * Compare this object and another one.
166         *
167         * @param obj other object
168         *
169         * @return true if the same
170         */
171        public boolean equals(Object obj) {
172            return (obj instanceof NameAndTypePoolInfo) && (
173                (((NameAndTypePoolInfo)obj)._nameIndex == _nameIndex) ||
174                (((NameAndTypePoolInfo)obj)._name == _name)
175                ) && (
176                (((NameAndTypePoolInfo)obj)._descriptorIndex == _descriptorIndex) ||
177                (((NameAndTypePoolInfo)obj)._descriptor == _descriptor)
178                );
179        }
180    
181        /**
182         * Execute a visitor.
183         *
184         * @param visitor visitor
185         * @param data    visitor-specific parameter
186         *
187         * @return visitor-specific return value
188         */
189        public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
190            return visitor.nameAndTypeCase(this, data);
191        }
192    }