001 package serp.bytecode; 002 003 import java.io.*; 004 005 import serp.bytecode.lowlevel.*; 006 import serp.bytecode.visitor.*; 007 008 /** 009 * A constant value for a member field. 010 * 011 * @author Abe White 012 */ 013 public class ConstantValue extends Attribute { 014 int _valueIndex = 0; 015 016 ConstantValue(int nameIndex, Attributes owner) { 017 super(nameIndex, owner); 018 } 019 020 int getLength() { 021 return 2; 022 } 023 024 /** 025 * Return the owning field. 026 */ 027 public BCField getField() { 028 return (BCField) getOwner(); 029 } 030 031 /** 032 * Return the {@link ConstantPool} index of the {@link ConstantEntry} 033 * holding the value of this constant. Defaults to 0. 034 */ 035 public int getValueIndex() { 036 return _valueIndex; 037 } 038 039 /** 040 * Set the {@link ConstantPool} of the {@link ConstantEntry} 041 * holding the value of this constant. 042 */ 043 public void setValueIndex(int valueIndex) { 044 _valueIndex = valueIndex; 045 } 046 047 /** 048 * Return the type of constant this attribute represents, or null if 049 * not set. 050 */ 051 public String getTypeName() { 052 Class type = getType(); 053 if (type == null) 054 return null; 055 return type.getName(); 056 } 057 058 /** 059 * Return the type of constant this attribute represents (String.class, 060 * int.class, etc), or null if not set. 061 */ 062 public Class getType() { 063 Object value = getValue(); 064 if (value == null) 065 return null; 066 067 Class type = value.getClass(); 068 if (type == Integer.class) 069 return int.class; 070 if (type == Float.class) 071 return float.class; 072 if (type == Double.class) 073 return double.class; 074 if (type == Long.class) 075 return long.class; 076 return String.class; 077 } 078 079 /** 080 * Return the bytecode for the type of constant this attribute represents. 081 */ 082 public BCClass getTypeBC() { 083 return getProject().loadClass(getType()); 084 } 085 086 /** 087 * Return the value of this constant as an Object of the appropriate 088 * type (String, Integer, Double, etc), or null if not set. 089 */ 090 public Object getValue() { 091 if (_valueIndex <= 0) 092 return null; 093 return ((ConstantEntry) getPool().getEntry(_valueIndex)).getConstant(); 094 } 095 096 /** 097 * Set the value of this constant using the appropriate wrapper Object 098 * type (String, Integer, Double, etc). Types that are not directly 099 * 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 }