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