1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.generic; 19 20 import java.io.DataOutputStream; 21 import java.io.IOException; 22 23 import org.apache.bcel.classfile.ConstantDouble; 24 import org.apache.bcel.classfile.ConstantFloat; 25 import org.apache.bcel.classfile.ConstantInteger; 26 import org.apache.bcel.classfile.ConstantLong; 27 import org.apache.bcel.classfile.ConstantUtf8; 28 import org.apache.bcel.classfile.ElementValue; 29 import org.apache.bcel.classfile.SimpleElementValue; 30 31 /** 32 * @since 6.0 33 */ 34 public class SimpleElementValueGen extends ElementValueGen 35 { 36 // For primitive types and string type, this points to the value entry in 37 // the cpGen 38 // For 'class' this points to the class entry in the cpGen 39 private int idx; 40 41 // ctors for each supported type... type could be inferred but for now lets 42 // force it to be passed 43 /** 44 * Protected ctor used for deserialization, doesn't *put* an entry in the 45 * constant pool, assumes the one at the supplied index is correct. 46 */ SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen)47 protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) 48 { 49 super(type, cpGen); 50 this.idx = idx; 51 } 52 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value)53 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) 54 { 55 super(type, cpGen); 56 idx = getConstantPool().addInteger(value); 57 } 58 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value)59 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) 60 { 61 super(type, cpGen); 62 idx = getConstantPool().addLong(value); 63 } 64 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value)65 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) 66 { 67 super(type, cpGen); 68 idx = getConstantPool().addDouble(value); 69 } 70 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value)71 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) 72 { 73 super(type, cpGen); 74 idx = getConstantPool().addFloat(value); 75 } 76 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value)77 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) 78 { 79 super(type, cpGen); 80 idx = getConstantPool().addInteger(value); 81 } 82 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value)83 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) 84 { 85 super(type, cpGen); 86 idx = getConstantPool().addInteger(value); 87 } 88 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value)89 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) 90 { 91 super(type, cpGen); 92 idx = getConstantPool().addInteger(value); 93 } 94 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value)95 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) 96 { 97 super(type, cpGen); 98 if (value) { 99 idx = getConstantPool().addInteger(1); 100 } else { 101 idx = getConstantPool().addInteger(0); 102 } 103 } 104 SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value)105 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) 106 { 107 super(type, cpGen); 108 idx = getConstantPool().addUtf8(value); 109 } 110 111 /** 112 * The boolean controls whether we copy info from the 'old' constant pool to 113 * the 'new'. You need to use this ctor if the annotation is being copied 114 * from one file to another. 115 */ SimpleElementValueGen(final SimpleElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries)116 public SimpleElementValueGen(final SimpleElementValue value, 117 final ConstantPoolGen cpool, final boolean copyPoolEntries) 118 { 119 super(value.getElementValueType(), cpool); 120 if (!copyPoolEntries) 121 { 122 // J5ASSERT: Could assert value.stringifyValue() is the same as 123 // cpool.getConstant(SimpleElementValuevalue.getIndex()) 124 idx = value.getIndex(); 125 } 126 else 127 { 128 switch (value.getElementValueType()) 129 { 130 case STRING: 131 idx = cpool.addUtf8(value.getValueString()); 132 break; 133 case PRIMITIVE_INT: 134 idx = cpool.addInteger(value.getValueInt()); 135 break; 136 case PRIMITIVE_BYTE: 137 idx = cpool.addInteger(value.getValueByte()); 138 break; 139 case PRIMITIVE_CHAR: 140 idx = cpool.addInteger(value.getValueChar()); 141 break; 142 case PRIMITIVE_LONG: 143 idx = cpool.addLong(value.getValueLong()); 144 break; 145 case PRIMITIVE_FLOAT: 146 idx = cpool.addFloat(value.getValueFloat()); 147 break; 148 case PRIMITIVE_DOUBLE: 149 idx = cpool.addDouble(value.getValueDouble()); 150 break; 151 case PRIMITIVE_BOOLEAN: 152 if (value.getValueBoolean()) 153 { 154 idx = cpool.addInteger(1); 155 } 156 else 157 { 158 idx = cpool.addInteger(0); 159 } 160 break; 161 case PRIMITIVE_SHORT: 162 idx = cpool.addInteger(value.getValueShort()); 163 break; 164 default: 165 throw new RuntimeException( 166 "SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); 167 } 168 } 169 } 170 171 /** 172 * Return immutable variant 173 */ 174 @Override getElementValue()175 public ElementValue getElementValue() 176 { 177 return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); 178 } 179 getIndex()180 public int getIndex() 181 { 182 return idx; 183 } 184 getValueString()185 public String getValueString() 186 { 187 if (super.getElementValueType() != STRING) { 188 throw new RuntimeException( 189 "Dont call getValueString() on a non STRING ElementValue"); 190 } 191 final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); 192 return c.getBytes(); 193 } 194 getValueInt()195 public int getValueInt() 196 { 197 if (super.getElementValueType() != PRIMITIVE_INT) { 198 throw new RuntimeException( 199 "Dont call getValueString() on a non STRING ElementValue"); 200 } 201 final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); 202 return c.getBytes(); 203 } 204 205 // Whatever kind of value it is, return it as a string 206 @Override stringifyValue()207 public String stringifyValue() 208 { 209 switch (super.getElementValueType()) 210 { 211 case PRIMITIVE_INT: 212 final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); 213 return Integer.toString(c.getBytes()); 214 case PRIMITIVE_LONG: 215 final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx); 216 return Long.toString(j.getBytes()); 217 case PRIMITIVE_DOUBLE: 218 final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx); 219 return Double.toString(d.getBytes()); 220 case PRIMITIVE_FLOAT: 221 final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx); 222 return Float.toString(f.getBytes()); 223 case PRIMITIVE_SHORT: 224 final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx); 225 return Integer.toString(s.getBytes()); 226 case PRIMITIVE_BYTE: 227 final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx); 228 return Integer.toString(b.getBytes()); 229 case PRIMITIVE_CHAR: 230 final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx); 231 return Integer.toString(ch.getBytes()); 232 case PRIMITIVE_BOOLEAN: 233 final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx); 234 if (bo.getBytes() == 0) { 235 return "false"; 236 } 237 return "true"; 238 case STRING: 239 final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); 240 return cu8.getBytes(); 241 default: 242 throw new RuntimeException( 243 "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); 244 } 245 } 246 247 @Override dump(final DataOutputStream dos)248 public void dump(final DataOutputStream dos) throws IOException 249 { 250 dos.writeByte(super.getElementValueType()); // u1 kind of value 251 switch (super.getElementValueType()) 252 { 253 case PRIMITIVE_INT: 254 case PRIMITIVE_BYTE: 255 case PRIMITIVE_CHAR: 256 case PRIMITIVE_FLOAT: 257 case PRIMITIVE_LONG: 258 case PRIMITIVE_BOOLEAN: 259 case PRIMITIVE_SHORT: 260 case PRIMITIVE_DOUBLE: 261 case STRING: 262 dos.writeShort(idx); 263 break; 264 default: 265 throw new RuntimeException( 266 "SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); 267 } 268 } 269 } 270