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