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    private int index;
030
031    public SimpleElementValue(final int type, final int index, final ConstantPool cpool) {
032        super(type, cpool);
033        this.index = index;
034    }
035
036    @Override
037    public void dump(final DataOutputStream dos) throws IOException {
038        final int type = super.getType();
039        dos.writeByte(type); // u1 kind of value
040        switch (type) {
041        case PRIMITIVE_INT:
042        case PRIMITIVE_BYTE:
043        case PRIMITIVE_CHAR:
044        case PRIMITIVE_FLOAT:
045        case PRIMITIVE_LONG:
046        case PRIMITIVE_BOOLEAN:
047        case PRIMITIVE_SHORT:
048        case PRIMITIVE_DOUBLE:
049        case STRING:
050            dos.writeShort(getIndex());
051            break;
052        default:
053            throw new IllegalStateException("SimpleElementValue doesnt know how to write out type " + type);
054        }
055    }
056
057    /**
058     * @return Value entry index in the cpool
059     */
060    public int getIndex() {
061        return index;
062    }
063
064    public boolean getValueBoolean() {
065        if (super.getType() != PRIMITIVE_BOOLEAN) {
066            throw new IllegalStateException("Dont call getValueBoolean() on a non BOOLEAN ElementValue");
067        }
068        final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
069        return bo.getBytes() != 0;
070    }
071
072    public byte getValueByte() {
073        if (super.getType() != PRIMITIVE_BYTE) {
074            throw new IllegalStateException("Dont call getValueByte() on a non BYTE ElementValue");
075        }
076        return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
077    }
078
079    public char getValueChar() {
080        if (super.getType() != PRIMITIVE_CHAR) {
081            throw new IllegalStateException("Dont call getValueChar() on a non CHAR ElementValue");
082        }
083        return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
084    }
085
086    public double getValueDouble() {
087        if (super.getType() != PRIMITIVE_DOUBLE) {
088            throw new IllegalStateException("Dont call getValueDouble() on a non DOUBLE ElementValue");
089        }
090        final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex());
091        return d.getBytes();
092    }
093
094    public float getValueFloat() {
095        if (super.getType() != PRIMITIVE_FLOAT) {
096            throw new IllegalStateException("Dont call getValueFloat() on a non FLOAT ElementValue");
097        }
098        final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex());
099        return f.getBytes();
100    }
101
102    public int getValueInt() {
103        if (super.getType() != PRIMITIVE_INT) {
104            throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue");
105        }
106        return super.getConstantPool().getConstantInteger(getIndex()).getBytes();
107    }
108
109    public long getValueLong() {
110        if (super.getType() != PRIMITIVE_LONG) {
111            throw new IllegalStateException("Dont call getValueLong() on a non LONG ElementValue");
112        }
113        final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex());
114        return j.getBytes();
115    }
116
117    public short getValueShort() {
118        if (super.getType() != PRIMITIVE_SHORT) {
119            throw new IllegalStateException("Dont call getValueShort() on a non SHORT ElementValue");
120        }
121        final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
122        return (short) s.getBytes();
123    }
124
125    public String getValueString() {
126        if (super.getType() != STRING) {
127            throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue");
128        }
129        return super.getConstantPool().getConstantUtf8(getIndex()).getBytes();
130    }
131
132    public void setIndex(final int index) {
133        this.index = index;
134    }
135
136    // Whatever kind of value it is, return it as a string
137    @Override
138    public String stringifyValue() {
139        final ConstantPool cpool = super.getConstantPool();
140        final int type = super.getType();
141        switch (type) {
142        case PRIMITIVE_INT:
143            return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes());
144        case PRIMITIVE_LONG:
145            final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class);
146            return Long.toString(j.getBytes());
147        case PRIMITIVE_DOUBLE:
148            final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class);
149            return Double.toString(d.getBytes());
150        case PRIMITIVE_FLOAT:
151            final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class);
152            return Float.toString(f.getBytes());
153        case PRIMITIVE_SHORT:
154            final ConstantInteger s = cpool.getConstantInteger(getIndex());
155            return Integer.toString(s.getBytes());
156        case PRIMITIVE_BYTE:
157            final ConstantInteger b = cpool.getConstantInteger(getIndex());
158            return Integer.toString(b.getBytes());
159        case PRIMITIVE_CHAR:
160            final ConstantInteger ch = cpool.getConstantInteger(getIndex());
161            return String.valueOf((char) ch.getBytes());
162        case PRIMITIVE_BOOLEAN:
163            final ConstantInteger bo = cpool.getConstantInteger(getIndex());
164            if (bo.getBytes() == 0) {
165                return "false";
166            }
167            return "true";
168        case STRING:
169            return cpool.getConstantUtf8(getIndex()).getBytes();
170        default:
171            throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type);
172        }
173    }
174
175    @Override
176    public String toString() {
177        return stringifyValue();
178    }
179}