1 package serp.bytecode;
2
3 import java.io.*;
4
5 import serp.bytecode.lowlevel.*;
6 import serp.bytecode.visitor.*;
7
8 /***
9 * A constant value for a member field.
10 *
11 * @author Abe White
12 */
13 public class ConstantValue extends Attribute {
14 int _valueIndex = 0;
15
16 ConstantValue(int nameIndex, Attributes owner) {
17 super(nameIndex, owner);
18 }
19
20 int getLength() {
21 return 2;
22 }
23
24 /***
25 * Return the owning field.
26 */
27 public BCField getField() {
28 return (BCField) getOwner();
29 }
30
31 /***
32 * Return the {@link ConstantPool} index of the {@link ConstantEntry}
33 * holding the value of this constant. Defaults to 0.
34 */
35 public int getValueIndex() {
36 return _valueIndex;
37 }
38
39 /***
40 * Set the {@link ConstantPool} of the {@link ConstantEntry}
41 * holding the value of this constant.
42 */
43 public void setValueIndex(int valueIndex) {
44 _valueIndex = valueIndex;
45 }
46
47 /***
48 * Return the type of constant this attribute represents, or null if
49 * not set.
50 */
51 public String getTypeName() {
52 Class type = getType();
53 if (type == null)
54 return null;
55 return type.getName();
56 }
57
58 /***
59 * Return the type of constant this attribute represents (String.class,
60 * int.class, etc), or null if not set.
61 */
62 public Class getType() {
63 Object value = getValue();
64 if (value == null)
65 return null;
66
67 Class type = value.getClass();
68 if (type == Integer.class)
69 return int.class;
70 if (type == Float.class)
71 return float.class;
72 if (type == Double.class)
73 return double.class;
74 if (type == Long.class)
75 return long.class;
76 return String.class;
77 }
78
79 /***
80 * Return the bytecode for the type of constant this attribute represents.
81 */
82 public BCClass getTypeBC() {
83 return getProject().loadClass(getType());
84 }
85
86 /***
87 * Return the value of this constant as an Object of the appropriate
88 * type (String, Integer, Double, etc), or null if not set.
89 */
90 public Object getValue() {
91 if (_valueIndex <= 0)
92 return null;
93 return ((ConstantEntry) getPool().getEntry(_valueIndex)).getConstant();
94 }
95
96 /***
97 * Set the value of this constant using the appropriate wrapper Object
98 * type (String, Integer, Double, etc). Types that are not directly
99 * supported will be converted accordingly if possible.
100 */
101 public void setValue(Object value) {
102 Class type = value.getClass();
103 if (type == Boolean.class)
104 setIntValue((((Boolean) value).booleanValue()) ? 1 : 0);
105 else if (type == Character.class)
106 setIntValue((int) ((Character) value).charValue());
107 else if (type == Byte.class || type == Integer.class
108 || type == Short.class)
109 setIntValue(((Number) value).intValue());
110 else if (type == Float.class)
111 setFloatValue(((Number) value).floatValue());
112 else if (type == Double.class)
113 setDoubleValue(((Number) value).doubleValue());
114 else if (type == Long.class)
115 setLongValue(((Number) value).longValue());
116 else
117 setStringValue(value.toString());
118 }
119
120 /***
121 * Get the value of this int constant, or 0 if not set.
122 */
123 public int getIntValue() {
124 if (getValueIndex() <= 0)
125 return 0;
126 return ((IntEntry) getPool().getEntry(getValueIndex())).getValue();
127 }
128
129 /***
130 * Set the value of this int constant.
131 */
132 public void setIntValue(int value) {
133 setValueIndex(getPool().findIntEntry(value, true));
134 }
135
136 /***
137 * Get the value of this float constant.
138 */
139 public float getFloatValue() {
140 if (getValueIndex() <= 0)
141 return 0F;
142 return ((FloatEntry) getPool().getEntry(getValueIndex())).getValue();
143 }
144
145 /***
146 * Set the value of this float constant.
147 */
148 public void setFloatValue(float value) {
149 setValueIndex(getPool().findFloatEntry(value, true));
150 }
151
152 /***
153 * Get the value of this double constant.
154 */
155 public double getDoubleValue() {
156 if (getValueIndex() <= 0)
157 return 0D;
158 return ((DoubleEntry) getPool().getEntry(getValueIndex())).getValue();
159 }
160
161 /***
162 * Set the value of this double constant.
163 */
164 public void setDoubleValue(double value) {
165 setValueIndex(getPool().findDoubleEntry(value, true));
166 }
167
168 /***
169 * Get the value of this long constant.
170 */
171 public long getLongValue() {
172 if (getValueIndex() <= 0)
173 return 0L;
174 return ((LongEntry) getPool().getEntry(getValueIndex())).getValue();
175 }
176
177 /***
178 * Set the value of this long constant.
179 */
180 public void setLongValue(long value) {
181 setValueIndex(getPool().findLongEntry(value, true));
182 }
183
184 /***
185 * Get the value of this string constant.
186 */
187 public String getStringValue() {
188 if (getValueIndex() <= 0)
189 return null;
190 return ((StringEntry) getPool().getEntry(getValueIndex())).
191 getStringEntry().getValue();
192 }
193
194 /***
195 * Set the value of this string constant.
196 */
197 public void setStringValue(String value) {
198 setValueIndex(getPool().findStringEntry(value, true));
199 }
200
201 public void acceptVisit(BCVisitor visit) {
202 visit.enterConstantValue(this);
203 visit.exitConstantValue(this);
204 }
205
206 void read(Attribute other) {
207 setValue(((ConstantValue) other).getValue());
208 }
209
210 void read(DataInput in, int length) throws IOException {
211 setValueIndex(in.readUnsignedShort());
212 }
213
214 void write(DataOutput out, int length) throws IOException {
215 out.writeShort(getValueIndex());
216 }
217 }