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