001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.generic; 019 020import java.io.DataOutputStream; 021import java.io.IOException; 022 023import org.apache.bcel.classfile.ConstantDouble; 024import org.apache.bcel.classfile.ConstantFloat; 025import org.apache.bcel.classfile.ConstantInteger; 026import org.apache.bcel.classfile.ConstantLong; 027import org.apache.bcel.classfile.ConstantUtf8; 028import org.apache.bcel.classfile.ElementValue; 029import org.apache.bcel.classfile.SimpleElementValue; 030 031/** 032 * @since 6.0 033 */ 034public class SimpleElementValueGen extends ElementValueGen 035{ 036 // For primitive types and string type, this points to the value entry in 037 // the cpGen 038 // For 'class' this points to the class entry in the cpGen 039 private int idx; 040 041 // ctors for each supported type... type could be inferred but for now lets 042 // force it to be passed 043 /** 044 * Protected ctor used for deserialization, doesn't *put* an entry in the 045 * constant pool, assumes the one at the supplied index is correct. 046 */ 047 protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) 048 { 049 super(type, cpGen); 050 this.idx = idx; 051 } 052 053 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) 054 { 055 super(type, cpGen); 056 idx = getConstantPool().addInteger(value); 057 } 058 059 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) 060 { 061 super(type, cpGen); 062 idx = getConstantPool().addLong(value); 063 } 064 065 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) 066 { 067 super(type, cpGen); 068 idx = getConstantPool().addDouble(value); 069 } 070 071 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) 072 { 073 super(type, cpGen); 074 idx = getConstantPool().addFloat(value); 075 } 076 077 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) 078 { 079 super(type, cpGen); 080 idx = getConstantPool().addInteger(value); 081 } 082 083 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) 084 { 085 super(type, cpGen); 086 idx = getConstantPool().addInteger(value); 087 } 088 089 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) 090 { 091 super(type, cpGen); 092 idx = getConstantPool().addInteger(value); 093 } 094 095 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) 096 { 097 super(type, cpGen); 098 if (value) { 099 idx = getConstantPool().addInteger(1); 100 } else { 101 idx = getConstantPool().addInteger(0); 102 } 103 } 104 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 */ 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 175 public ElementValue getElementValue() 176 { 177 return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); 178 } 179 180 public int getIndex() 181 { 182 return idx; 183 } 184 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 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 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 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}