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.classfile; 020 021import java.io.DataOutputStream; 022import java.io.IOException; 023 024import org.apache.bcel.Const; 025 026/** 027 * Represents a simple element value in an annotation. 028 * 029 * @since 6.0 030 */ 031public class SimpleElementValue extends ElementValue { 032 private int index; 033 034 /** 035 * Constructs a SimpleElementValue. 036 * 037 * @param type The element value type. 038 * @param index The index into the constant pool. 039 * @param cpool The constant pool. 040 */ 041 public SimpleElementValue(final int type, final int index, final ConstantPool cpool) { 042 super(type, cpool); 043 this.index = index; 044 } 045 046 @Override 047 public void dump(final DataOutputStream dos) throws IOException { 048 final int type = super.getType(); 049 dos.writeByte(type); // u1 kind of value 050 switch (type) { 051 case PRIMITIVE_INT: 052 case PRIMITIVE_BYTE: 053 case PRIMITIVE_CHAR: 054 case PRIMITIVE_FLOAT: 055 case PRIMITIVE_LONG: 056 case PRIMITIVE_BOOLEAN: 057 case PRIMITIVE_SHORT: 058 case PRIMITIVE_DOUBLE: 059 case STRING: 060 dos.writeShort(getIndex()); 061 break; 062 default: 063 throw new ClassFormatException("SimpleElementValue doesn't know how to write out type " + type); 064 } 065 } 066 067 /** 068 * Gets the value entry index in the constant pool. 069 * 070 * @return Value entry index in the constant pool. 071 */ 072 public int getIndex() { 073 return index; 074 } 075 076 /** 077 * Gets the boolean value. 078 * 079 * @return The boolean value. 080 */ 081 public boolean getValueBoolean() { 082 if (super.getType() != PRIMITIVE_BOOLEAN) { 083 throw new IllegalStateException("Don't call getValueBoolean() on a non BOOLEAN ElementValue"); 084 } 085 final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); 086 return bo.getBytes() != 0; 087 } 088 089 /** 090 * Gets the byte value. 091 * 092 * @return The byte value. 093 */ 094 public byte getValueByte() { 095 if (super.getType() != PRIMITIVE_BYTE) { 096 throw new IllegalStateException("Don't call getValueByte() on a non BYTE ElementValue"); 097 } 098 return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes(); 099 } 100 101 /** 102 * Gets the char value. 103 * 104 * @return The char value. 105 */ 106 public char getValueChar() { 107 if (super.getType() != PRIMITIVE_CHAR) { 108 throw new IllegalStateException("Don't call getValueChar() on a non CHAR ElementValue"); 109 } 110 return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes(); 111 } 112 113 /** 114 * Gets the double value. 115 * 116 * @return The double value. 117 */ 118 public double getValueDouble() { 119 if (super.getType() != PRIMITIVE_DOUBLE) { 120 throw new IllegalStateException("Don't call getValueDouble() on a non DOUBLE ElementValue"); 121 } 122 final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex()); 123 return d.getBytes(); 124 } 125 126 /** 127 * Gets the float value. 128 * 129 * @return The float value. 130 */ 131 public float getValueFloat() { 132 if (super.getType() != PRIMITIVE_FLOAT) { 133 throw new IllegalStateException("Don't call getValueFloat() on a non FLOAT ElementValue"); 134 } 135 final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex()); 136 return f.getBytes(); 137 } 138 139 /** 140 * Gets the int value. 141 * 142 * @return The int value. 143 */ 144 public int getValueInt() { 145 if (super.getType() != PRIMITIVE_INT) { 146 throw new IllegalStateException("Don't call getValueInt() on a non INT ElementValue"); 147 } 148 return super.getConstantPool().getConstantInteger(getIndex()).getBytes(); 149 } 150 151 /** 152 * Gets the long value. 153 * 154 * @return The long value. 155 */ 156 public long getValueLong() { 157 if (super.getType() != PRIMITIVE_LONG) { 158 throw new IllegalStateException("Don't call getValueLong() on a non LONG ElementValue"); 159 } 160 final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex()); 161 return j.getBytes(); 162 } 163 164 /** 165 * Gets the short value. 166 * 167 * @return The short value. 168 */ 169 public short getValueShort() { 170 if (super.getType() != PRIMITIVE_SHORT) { 171 throw new IllegalStateException("Don't call getValueShort() on a non SHORT ElementValue"); 172 } 173 final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); 174 return (short) s.getBytes(); 175 } 176 177 /** 178 * Gets the string value. 179 * 180 * @return The string value. 181 */ 182 public String getValueString() { 183 if (super.getType() != STRING) { 184 throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue"); 185 } 186 return super.getConstantPool().getConstantUtf8(getIndex()).getBytes(); 187 } 188 189 /** 190 * Sets the index into the constant pool. 191 * 192 * @param index The index. 193 */ 194 public void setIndex(final int index) { 195 this.index = index; 196 } 197 198 // Whatever kind of value it is, return it as a string 199 @Override 200 public String stringifyValue() { 201 final ConstantPool cpool = super.getConstantPool(); 202 final int type = super.getType(); 203 switch (type) { 204 case PRIMITIVE_INT: 205 return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes()); 206 case PRIMITIVE_LONG: 207 final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class); 208 return Long.toString(j.getBytes()); 209 case PRIMITIVE_DOUBLE: 210 final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class); 211 return Double.toString(d.getBytes()); 212 case PRIMITIVE_FLOAT: 213 final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class); 214 return Float.toString(f.getBytes()); 215 case PRIMITIVE_SHORT: 216 final ConstantInteger s = cpool.getConstantInteger(getIndex()); 217 return Integer.toString(s.getBytes()); 218 case PRIMITIVE_BYTE: 219 final ConstantInteger b = cpool.getConstantInteger(getIndex()); 220 return Integer.toString(b.getBytes()); 221 case PRIMITIVE_CHAR: 222 final ConstantInteger ch = cpool.getConstantInteger(getIndex()); 223 return String.valueOf((char) ch.getBytes()); 224 case PRIMITIVE_BOOLEAN: 225 final ConstantInteger bo = cpool.getConstantInteger(getIndex()); 226 if (bo.getBytes() == 0) { 227 return "false"; 228 } 229 return "true"; 230 case STRING: 231 return cpool.getConstantUtf8(getIndex()).getBytes(); 232 default: 233 throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type); 234 } 235 } 236 237 @Override 238 public String toString() { 239 return stringifyValue(); 240 } 241}