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 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 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 toString() {
102            StringBuffer s;
103    
104            s = new StringBuffer();
105            s.append("CONSTANT_Class: Name = #");
106            s.append(_nameIndex);
107    
108            return s.toString();
109        }
110    
111        /**
112         * Return a human-readable version of this constant pool object.
113         *
114         * @return string
115         */
116        public String toStringVerbose() {
117            return toString();
118        }
119    
120        /**
121         * Return a hash code.
122         *
123         * @return hash code
124         */
125        public int hashCode() {
126            return _nameIndex;
127        }
128    
129        /**
130         * Compare this object and another one.
131         *
132         * @param obj other object
133         *
134         * @return true if the same
135         */
136        public boolean equals(Object obj) {
137            return (obj instanceof ClassPoolInfo) && (
138                (((ClassPoolInfo)obj)._nameIndex == _nameIndex) ||
139                (((ClassPoolInfo)obj)._name == _name)
140                );
141        }
142    
143        /**
144         * Execute a visitor.
145         *
146         * @param visitor visitor
147         * @param data    visitor-specific parameter
148         *
149         * @return visitor-specific return value
150         */
151        public <R, D> R execute(IPoolInfoVisitor<R, D> visitor, D data) {
152            return visitor.classCase(this, data);
153        }
154    }