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 // For primitive types and string type, this points to the value entry in 036 // the cpGen 037 // For 'class' this points to the class entry in the cpGen 038 private final int idx; 039 040 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) { 041 super(type, cpGen); 042 if (value) { 043 idx = getConstantPool().addInteger(1); 044 } else { 045 idx = getConstantPool().addInteger(0); 046 } 047 } 048 049 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) { 050 super(type, cpGen); 051 idx = getConstantPool().addInteger(value); 052 } 053 054 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) { 055 super(type, cpGen); 056 idx = getConstantPool().addInteger(value); 057 } 058 059 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) { 060 super(type, cpGen); 061 idx = getConstantPool().addDouble(value); 062 } 063 064 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) { 065 super(type, cpGen); 066 idx = getConstantPool().addFloat(value); 067 } 068 069 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) { 070 super(type, cpGen); 071 idx = getConstantPool().addInteger(value); 072 } 073 074 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) { 075 super(type, cpGen); 076 idx = getConstantPool().addLong(value); 077 } 078 079 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) { 080 super(type, cpGen); 081 idx = getConstantPool().addInteger(value); 082 } 083 084 public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) { 085 super(type, cpGen); 086 idx = getConstantPool().addUtf8(value); 087 } 088 089 // ctors for each supported type... type could be inferred but for now lets 090 // force it to be passed 091 /** 092 * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool, assumes the one at the supplied 093 * index is correct. 094 */ 095 protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) { 096 super(type, cpGen); 097 this.idx = idx; 098 } 099 100 /** 101 * The boolean controls whether we copy info from the 'old' constant pool to the 'new'. You need to use this ctor if the 102 * annotation is being copied from one file to another. 103 */ 104 public SimpleElementValueGen(final SimpleElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { 105 super(value.getElementValueType(), cpool); 106 if (!copyPoolEntries) { 107 // J5ASSERT: Could assert value.stringifyValue() is the same as 108 // cpool.getConstant(SimpleElementValuevalue.getIndex()) 109 idx = value.getIndex(); 110 } else { 111 switch (value.getElementValueType()) { 112 case STRING: 113 idx = cpool.addUtf8(value.getValueString()); 114 break; 115 case PRIMITIVE_INT: 116 idx = cpool.addInteger(value.getValueInt()); 117 break; 118 case PRIMITIVE_BYTE: 119 idx = cpool.addInteger(value.getValueByte()); 120 break; 121 case PRIMITIVE_CHAR: 122 idx = cpool.addInteger(value.getValueChar()); 123 break; 124 case PRIMITIVE_LONG: 125 idx = cpool.addLong(value.getValueLong()); 126 break; 127 case PRIMITIVE_FLOAT: 128 idx = cpool.addFloat(value.getValueFloat()); 129 break; 130 case PRIMITIVE_DOUBLE: 131 idx = cpool.addDouble(value.getValueDouble()); 132 break; 133 case PRIMITIVE_BOOLEAN: 134 if (value.getValueBoolean()) { 135 idx = cpool.addInteger(1); 136 } else { 137 idx = cpool.addInteger(0); 138 } 139 break; 140 case PRIMITIVE_SHORT: 141 idx = cpool.addInteger(value.getValueShort()); 142 break; 143 default: 144 throw new IllegalArgumentException("SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); 145 } 146 } 147 } 148 149 @Override 150 public void dump(final DataOutputStream dos) throws IOException { 151 dos.writeByte(super.getElementValueType()); // u1 kind of value 152 switch (super.getElementValueType()) { 153 case PRIMITIVE_INT: 154 case PRIMITIVE_BYTE: 155 case PRIMITIVE_CHAR: 156 case PRIMITIVE_FLOAT: 157 case PRIMITIVE_LONG: 158 case PRIMITIVE_BOOLEAN: 159 case PRIMITIVE_SHORT: 160 case PRIMITIVE_DOUBLE: 161 case STRING: 162 dos.writeShort(idx); 163 break; 164 default: 165 throw new IllegalStateException("SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); 166 } 167 } 168 169 /** 170 * Return immutable variant 171 */ 172 @Override 173 public ElementValue getElementValue() { 174 return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); 175 } 176 177 public int getIndex() { 178 return idx; 179 } 180 181 public int getValueInt() { 182 if (super.getElementValueType() != PRIMITIVE_INT) { 183 throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue"); 184 } 185 final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); 186 return c.getBytes(); 187 } 188 189 public String getValueString() { 190 if (super.getElementValueType() != STRING) { 191 throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue"); 192 } 193 final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); 194 return c.getBytes(); 195 } 196 197 // Whatever kind of value it is, return it as a string 198 @Override 199 public String stringifyValue() { 200 switch (super.getElementValueType()) { 201 case PRIMITIVE_INT: 202 final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); 203 return Integer.toString(c.getBytes()); 204 case PRIMITIVE_LONG: 205 final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx); 206 return Long.toString(j.getBytes()); 207 case PRIMITIVE_DOUBLE: 208 final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx); 209 return Double.toString(d.getBytes()); 210 case PRIMITIVE_FLOAT: 211 final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx); 212 return Float.toString(f.getBytes()); 213 case PRIMITIVE_SHORT: 214 final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx); 215 return Integer.toString(s.getBytes()); 216 case PRIMITIVE_BYTE: 217 final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx); 218 return Integer.toString(b.getBytes()); 219 case PRIMITIVE_CHAR: 220 final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx); 221 return Integer.toString(ch.getBytes()); 222 case PRIMITIVE_BOOLEAN: 223 final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx); 224 if (bo.getBytes() == 0) { 225 return "false"; 226 } 227 return "true"; 228 case STRING: 229 final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); 230 return cu8.getBytes(); 231 default: 232 throw new IllegalStateException("SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); 233 } 234 } 235}