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