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 class in the constant pool.
012     *
013     * @author Mathias Ricken
014     */
015    public class ClassPoolInfo extends APoolInfo {
016        /**
017         * Class name information.
018         */
019        private AUTFPoolInfo _name;
020    
021        /**
022         * Class name index.
023         */
024        private short _nameIndex;
025    
026        /**
027         * Constructor.
028         *
029         * @param name class name information
030         * @param cp   constant pool
031         */
032        public ClassPoolInfo(AUTFPoolInfo name, ConstantPool cp) {
033            super(CONSTANT_Class, cp);
034            _name = name;
035            reindex();
036        }
037    
038        /**
039         * Constructor reading from a stream.
040         *
041         * @param dis input stream
042         * @param cp  constant pool
043         *
044         * @throws IOException
045         */
046        public ClassPoolInfo(DataInputStream dis, ConstantPool cp) throws IOException {
047            super(CONSTANT_Class, cp);
048            _nameIndex = dis.readShort();
049        }
050    
051        /**
052         * Accessor for the name information.
053         *
054         * @return name information
055         */
056        public AUTFPoolInfo getName() {
057            return _name;
058        }
059    
060        /**
061         * Mutator for the name information.
062         *
063         * @param name new name information
064         */
065        public void setName(AUTFPoolInfo name) {
066            _name = name;
067        }
068    
069        /**
070         * Write this constant pool object into the stream, including the type byte.
071         *
072         * @param dos stream
073         *
074         * @throws java.io.IOException
075         */
076        public void write(DataOutputStream dos) throws IOException {
077            reindex();
078            dos.writeByte(_type);
079            dos.writeShort(_nameIndex);
080        }
081    
082        /**
083         * Resolve constant pool objects. This makes sure that the object links match the index links.
084         */
085        public void resolve() {
086            _name = _constantPool.get(_nameIndex).execute(CheckUTFVisitor.singleton(), null);
087        }
088    
089        /**
090         * Reindex constant pool indices. This makes sure the index links match the object links.
091         */
092        public void reindex() {
093            _nameIndex = _constantPool.indexOf(_name);
094        }
095    
096        /**
097         * Return a human-readable version of this constant pool object.
098         *
099         * @return string
100         */
101        public String toStringVerbose() {
102            StringBuilder s = new StringBuilder();
103            s.append("CONSTANT_Class: Name = #");
104            s.append(_nameIndex);
105            s.append(' ');
106            s.append(toString());
107            return s.toString();
108        }
109    
110        /**
111         * Return a human-readable version of this constant pool object.
112         *
113         * @return string
114         */
115        public String toString() {
116            return _name.toString();
117        }
118    
119        /**
120         * Return a hash code.
121         *
122         * @return hash code
123         */
124        public int hashCode() {
125            return _nameIndex;
126        }
127    
128        /**
129         * Compare this object and another one.
130         *
131         * @param obj other object
132         *
133         * @return true if the same
134         */
135        public boolean equals(Object obj) {
136            return (obj instanceof ClassPoolInfo) && (
137                (((ClassPoolInfo)obj)._nameIndex == _nameIndex) ||
138                (((ClassPoolInfo)obj)._name == _name)
139                );
140        }
141    
142        /**
143         * Execute a visitor.
144         *
145         * @param visitor visitor
146         * @param data    visitor-specific parameter
147         *
148         * @return visitor-specific return value
149         */
150        public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
151            return visitor.classCase(this, data);
152        }
153    }