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