View Javadoc

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 }