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 }