1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 import java.io.DataOutputStream;
  25 import java.io.IOException;
  26 
  27 import com.sun.org.apache.bcel.internal.classfile.ConstantDouble;
  28 import com.sun.org.apache.bcel.internal.classfile.ConstantFloat;
  29 import com.sun.org.apache.bcel.internal.classfile.ConstantInteger;
  30 import com.sun.org.apache.bcel.internal.classfile.ConstantLong;
  31 import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
  32 import com.sun.org.apache.bcel.internal.classfile.ElementValue;
  33 import com.sun.org.apache.bcel.internal.classfile.SimpleElementValue;
  34 
  35 /**
  36  * @since 6.0
  37  */
  38 public class SimpleElementValueGen extends ElementValueGen
  39 {
  40     // For primitive types and string type, this points to the value entry in
  41     // the cpGen
  42     // For 'class' this points to the class entry in the cpGen
  43     private int idx;
  44 
  45     // ctors for each supported type... type could be inferred but for now lets
  46     // force it to be passed
  47     /**
  48      * Protected ctor used for deserialization, doesn't *put* an entry in the
  49      * constant pool, assumes the one at the supplied index is correct.
  50      */
  51     protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen)
  52     {
  53         super(type, cpGen);
  54         this.idx = idx;
  55     }
  56 
  57     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value)
  58     {
  59         super(type, cpGen);
  60         idx = getConstantPool().addInteger(value);
  61     }
  62 
  63     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value)
  64     {
  65         super(type, cpGen);
  66         idx = getConstantPool().addLong(value);
  67     }
  68 
  69     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value)
  70     {
  71         super(type, cpGen);
  72         idx = getConstantPool().addDouble(value);
  73     }
  74 
  75     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value)
  76     {
  77         super(type, cpGen);
  78         idx = getConstantPool().addFloat(value);
  79     }
  80 
  81     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value)
  82     {
  83         super(type, cpGen);
  84         idx = getConstantPool().addInteger(value);
  85     }
  86 
  87     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value)
  88     {
  89         super(type, cpGen);
  90         idx = getConstantPool().addInteger(value);
  91     }
  92 
  93     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value)
  94     {
  95         super(type, cpGen);
  96         idx = getConstantPool().addInteger(value);
  97     }
  98 
  99     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value)
 100     {
 101         super(type, cpGen);
 102         if (value) {
 103             idx = getConstantPool().addInteger(1);
 104         } else {
 105             idx = getConstantPool().addInteger(0);
 106         }
 107     }
 108 
 109     public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value)
 110     {
 111         super(type, cpGen);
 112         idx = getConstantPool().addUtf8(value);
 113     }
 114 
 115     /**
 116      * The boolean controls whether we copy info from the 'old' constant pool to
 117      * the 'new'. You need to use this ctor if the annotation is being copied
 118      * from one file to another.
 119      */
 120     public SimpleElementValueGen(final SimpleElementValue value,
 121             final ConstantPoolGen cpool, final boolean copyPoolEntries)
 122     {
 123         super(value.getElementValueType(), cpool);
 124         if (!copyPoolEntries)
 125         {
 126             // J5ASSERT: Could assert value.stringifyValue() is the same as
 127             // cpool.getConstant(SimpleElementValuevalue.getIndex())
 128             idx = value.getIndex();
 129         }
 130         else
 131         {
 132             switch (value.getElementValueType())
 133             {
 134             case STRING:
 135                 idx = cpool.addUtf8(value.getValueString());
 136                 break;
 137             case PRIMITIVE_INT:
 138                 idx = cpool.addInteger(value.getValueInt());
 139                 break;
 140             case PRIMITIVE_BYTE:
 141                 idx = cpool.addInteger(value.getValueByte());
 142                 break;
 143             case PRIMITIVE_CHAR:
 144                 idx = cpool.addInteger(value.getValueChar());
 145                 break;
 146             case PRIMITIVE_LONG:
 147                 idx = cpool.addLong(value.getValueLong());
 148                 break;
 149             case PRIMITIVE_FLOAT:
 150                 idx = cpool.addFloat(value.getValueFloat());
 151                 break;
 152             case PRIMITIVE_DOUBLE:
 153                 idx = cpool.addDouble(value.getValueDouble());
 154                 break;
 155             case PRIMITIVE_BOOLEAN:
 156                 if (value.getValueBoolean())
 157                 {
 158                     idx = cpool.addInteger(1);
 159                 }
 160                 else
 161                 {
 162                     idx = cpool.addInteger(0);
 163                 }
 164                 break;
 165             case PRIMITIVE_SHORT:
 166                 idx = cpool.addInteger(value.getValueShort());
 167                 break;
 168             default:
 169                 throw new RuntimeException(
 170                     "SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType());
 171             }
 172         }
 173     }
 174 
 175     /**
 176      * Return immutable variant
 177      */
 178     @Override
 179     public ElementValue getElementValue()
 180     {
 181         return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool());
 182     }
 183 
 184     public int getIndex()
 185     {
 186         return idx;
 187     }
 188 
 189     public String getValueString()
 190     {
 191         if (super.getElementValueType() != STRING) {
 192             throw new RuntimeException(
 193                     "Dont call getValueString() on a non STRING ElementValue");
 194         }
 195         final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx);
 196         return c.getBytes();
 197     }
 198 
 199     public int getValueInt()
 200     {
 201         if (super.getElementValueType() != PRIMITIVE_INT) {
 202             throw new RuntimeException(
 203                     "Dont call getValueString() on a non STRING ElementValue");
 204         }
 205         final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx);
 206         return c.getBytes();
 207     }
 208 
 209     // Whatever kind of value it is, return it as a string
 210     @Override
 211     public String stringifyValue()
 212     {
 213         switch (super.getElementValueType())
 214         {
 215         case PRIMITIVE_INT:
 216             final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx);
 217             return Integer.toString(c.getBytes());
 218         case PRIMITIVE_LONG:
 219             final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx);
 220             return Long.toString(j.getBytes());
 221         case PRIMITIVE_DOUBLE:
 222             final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx);
 223             return Double.toString(d.getBytes());
 224         case PRIMITIVE_FLOAT:
 225             final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx);
 226             return Float.toString(f.getBytes());
 227         case PRIMITIVE_SHORT:
 228             final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx);
 229             return Integer.toString(s.getBytes());
 230         case PRIMITIVE_BYTE:
 231             final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx);
 232             return Integer.toString(b.getBytes());
 233         case PRIMITIVE_CHAR:
 234             final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx);
 235             return Integer.toString(ch.getBytes());
 236         case PRIMITIVE_BOOLEAN:
 237             final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx);
 238             if (bo.getBytes() == 0) {
 239                 return "false";
 240             }
 241             return "true";
 242         case STRING:
 243             final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx);
 244             return cu8.getBytes();
 245         default:
 246             throw new RuntimeException(
 247                 "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType());
 248         }
 249     }
 250 
 251     @Override
 252     public void dump(final DataOutputStream dos) throws IOException
 253     {
 254         dos.writeByte(super.getElementValueType()); // u1 kind of value
 255         switch (super.getElementValueType())
 256         {
 257         case PRIMITIVE_INT:
 258         case PRIMITIVE_BYTE:
 259         case PRIMITIVE_CHAR:
 260         case PRIMITIVE_FLOAT:
 261         case PRIMITIVE_LONG:
 262         case PRIMITIVE_BOOLEAN:
 263         case PRIMITIVE_SHORT:
 264         case PRIMITIVE_DOUBLE:
 265         case STRING:
 266             dos.writeShort(idx);
 267             break;
 268         default:
 269             throw new RuntimeException(
 270                 "SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType());
 271         }
 272     }
 273 }