    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.DataInput;
    021import java.io.DataOutputStream;
    022import java.io.IOException;
    023
    024/**
    025 * @since 6.0
    026 */
    027public abstract class ElementValue
    028{
    029    /**
    030     * @deprecated (since 6.0) will be made private and final; do not access directly, use getter
    031     */
    032    @java.lang.Deprecated
    033    protected int type; // TODO should be final
    034
    035    /**
    036     * @deprecated (since 6.0) will be made private and final; do not access directly, use getter
    037     */
    038    @java.lang.Deprecated
    039    protected ConstantPool cpool; // TODO should be final
    040
    041    @Override
    042    public String toString()
    043    {
    044        return stringifyValue();
    045    }
    046
    047    protected ElementValue(final int type, final ConstantPool cpool)
    048    {
    049        this.type = type;
    050        this.cpool = cpool;
    051    }
    052
    053    public int getElementValueType()
    054    {
    055        return type;
    056    }
    057
    058    public abstract String stringifyValue();
    059
    060    public abstract void dump(DataOutputStream dos) throws IOException;
    061
    062    public static final byte STRING            = 's';
    063    public static final byte ENUM_CONSTANT     = 'e';
    064    public static final byte CLASS             = 'c';
    065    public static final byte ANNOTATION        = '@';
    066    public static final byte ARRAY             = '[';
    067    public static final byte PRIMITIVE_INT     = 'I';
    068    public static final byte PRIMITIVE_BYTE    = 'B';
    069    public static final byte PRIMITIVE_CHAR    = 'C';
    070    public static final byte PRIMITIVE_DOUBLE  = 'D';
    071    public static final byte PRIMITIVE_FLOAT   = 'F';
    072    public static final byte PRIMITIVE_LONG    = 'J';
    073    public static final byte PRIMITIVE_SHORT   = 'S';
    074    public static final byte PRIMITIVE_BOOLEAN = 'Z';
    075
    076    public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException
    077    {
    078        final byte type = input.readByte();
    079        switch (type)
    080        {
    081            case PRIMITIVE_BYTE:
    082            case PRIMITIVE_CHAR:
    083            case PRIMITIVE_DOUBLE:
    084            case PRIMITIVE_FLOAT:
    085            case PRIMITIVE_INT:
    086            case PRIMITIVE_LONG:
    087            case PRIMITIVE_SHORT:
    088            case PRIMITIVE_BOOLEAN:
    089            case STRING:
    090                return new SimpleElementValue(type, input.readUnsignedShort(), cpool);
    091
    092            case ENUM_CONSTANT:
    093                return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool);
    094
    095            case CLASS:
    096                return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool);
    097
    098            case ANNOTATION:
    099                // TODO isRuntimeVisible
    100                return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool);
    101
    102            case ARRAY:
    103                final int numArrayVals = input.readUnsignedShort();
    104                final ElementValue[] evalues = new ElementValue[numArrayVals];
    105                for (int j = 0; j < numArrayVals; j++)
    106                {
    107                    evalues[j] = ElementValue.readElementValue(input, cpool);
    108                }
    109                return new ArrayElementValue(ARRAY, evalues, cpool);
    110
    111            default:
    112                throw new IllegalArgumentException("Unexpected element value kind in annotation: " + type);
    113        }
    114    }
    115
    116    /** @since 6.0 */
    117    final ConstantPool getConstantPool() {
    118        return cpool;
    119    }
    120
    121    /** @since 6.0 */
    122    final int getType() {
    123        return type;
    124    }
    125
    126    public String toShortString()
    127    {
    128        return stringifyValue();
    129    }
    130}