001 package edu.rice.cs.cunit.classFile.constantPool;
002
003 import edu.rice.cs.cunit.classFile.constantPool.visitors.ADefaultPoolInfoVisitor;
004 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckClassVisitor;
005
006 import java.io.DataInputStream;
007 import java.io.DataOutputStream;
008 import java.io.IOException;
009
010 /**
011 * Represents an object in the constant pool described by class and name-and-type.
012 *
013 * @author Mathias Ricken
014 */
015 public abstract class AClassNameTypePoolInfo extends APoolInfo {
016 /**
017 * Class information.
018 */
019 protected ClassPoolInfo _classInfo;
020
021 /**
022 * NameAndType information.
023 */
024 protected NameAndTypePoolInfo _nameAndType;
025
026 /**
027 * Class index.
028 */
029 protected int _classInfoIndex;
030
031 /**
032 * NameAndType index.
033 */
034 protected int _nameAndTypeIndex;
035
036 /**
037 * Create a new object.
038 *
039 * @param type type, either FIELD, METHOD or CONSTANT_InterfaceMethodref
040 * @param clas class information
041 * @param nameAndType NameAndType information
042 * @param cp constant pool
043 */
044 public AClassNameTypePoolInfo(int type,
045 ClassPoolInfo clas,
046 NameAndTypePoolInfo nameAndType,
047 ConstantPool cp) {
048 super(type, cp);
049 _classInfo = clas;
050 _nameAndType = nameAndType;
051 reindex();
052 }
053
054 /**
055 * Constructor reading from a stream.
056 *
057 * @param type type, either FIELD, METHOD or CONSTANT_InterfaceMethodref
058 * @param dis input stream
059 * @param cp constant pool
060 *
061 * @throws IOException
062 */
063 public AClassNameTypePoolInfo(int type, DataInputStream dis, ConstantPool cp) throws IOException {
064 super(type, cp);
065 _classInfoIndex = dis.readShort();
066 _nameAndTypeIndex = dis.readShort();
067 }
068
069 /**
070 * Accessor for the class information.
071 *
072 * @return class information
073 */
074 public ClassPoolInfo getClassInfo() {
075 return _classInfo;
076 }
077
078 /**
079 * Mutator for the class information.
080 *
081 * @param classInfo new class information
082 */
083 public void setClassInfo(ClassPoolInfo classInfo) {
084 _classInfo = classInfo;
085 }
086
087 /**
088 * Accessor for the NameAndType information.
089 *
090 * @return NameAndType information
091 */
092 public NameAndTypePoolInfo getNameAndType() {
093 return _nameAndType;
094 }
095
096 /**
097 * Mutator for the NameAndType information.
098 *
099 * @param nameAndType new NameAndTypeInformation
100 */
101 public void setNameAndType(NameAndTypePoolInfo nameAndType) {
102 _nameAndType = nameAndType;
103 }
104
105 /**
106 * Write this constant pool object into the stream, including the type byte.
107 *
108 * @param dos stream
109 *
110 * @throws java.io.IOException
111 */
112 public void write(DataOutputStream dos) throws IOException {
113 reindex();
114 dos.writeByte(_type);
115 dos.writeShort(_classInfoIndex);
116 dos.writeShort(_nameAndTypeIndex);
117 }
118
119 /**
120 * Resolve constant pool objects. This makes sure that the object links match the index links.
121 */
122 public void resolve() {
123 _classInfo = _constantPool.get(_classInfoIndex).execute(CheckClassVisitor.singleton(), null);
124 _nameAndType = _constantPool.get(_nameAndTypeIndex).execute(new ADefaultPoolInfoVisitor<NameAndTypePoolInfo, Object>() {
125 public NameAndTypePoolInfo defaultCase(APoolInfo host, Object o) {
126 throw new ClassFormatError(
127 "Info is of type " + host.getClass().getName() + ", needs to be NameAndTypePoolInfo");
128 }
129
130 public NameAndTypePoolInfo nameAndTypeCase(NameAndTypePoolInfo host, Object o) {
131 return host;
132 }
133 }, null);
134 }
135
136 /**
137 * Reindex constant pool indices. This makes sure the index links match the object links.
138 */
139 public void reindex() {
140 _classInfoIndex = _constantPool.indexOf(_classInfo);
141 _nameAndTypeIndex = _constantPool.indexOf(_nameAndType);
142 }
143
144 /**
145 * Return a human-readable version of this constant pool object.
146 *
147 * @return string
148 */
149 public String toString() {
150 StringBuilder s = new StringBuilder();
151 s.append(_classInfo.getName().toString());
152 s.append('.');
153 s.append(_nameAndType.getName().toString());
154 s.append(_nameAndType.getDescriptor().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 _classInfoIndex + 6101 * _nameAndTypeIndex;
165 }
166 }