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