    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.bcel.generic;
    020
    021import java.io.DataOutputStream;
    022import java.io.IOException;
    023
    024import org.apache.bcel.classfile.ConstantUtf8;
    025import org.apache.bcel.classfile.ElementValue;
    026import org.apache.bcel.classfile.EnumElementValue;
    027
    028/**
    029 * Generates enum element values in annotations.
    030 *
    031 * @since 6.0
    032 */
    033public class EnumElementValueGen extends ElementValueGen {
    034    // For enum types, these two indices point to the type and value
    035    private final int typeIdx;
    036
    037    private final int valueIdx;
    038
    039    /**
    040     * Constructs an EnumElementValueGen from an EnumElementValue.
    041     *
    042     * @param value the enum element value.
    043     * @param cpool the constant pool.
    044     * @param copyPoolEntries whether to copy pool entries.
    045     */
    046    public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
    047        super(ENUM_CONSTANT, cpool);
    048        if (copyPoolEntries) {
    049            typeIdx = cpool.addUtf8(value.getEnumTypeString()); // was addClass(value.getEnumTypeString());
    050            valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString());
    051        } else {
    052            typeIdx = value.getTypeIndex();
    053            valueIdx = value.getValueIndex();
    054        }
    055    }
    056
    057    /**
    058     * This constructor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx.
    059     * This constructor is used for deserialization.
    060     *
    061     * @param typeIdx the type index.
    062     * @param valueIdx the value index.
    063     * @param cpool the constant pool.
    064     */
    065    protected EnumElementValueGen(final int typeIdx, final int valueIdx, final ConstantPoolGen cpool) {
    066        super(ENUM_CONSTANT, cpool);
    067        if (super.getElementValueType() != ENUM_CONSTANT) {
    068            throw new IllegalArgumentException("Only element values of type enum can be built with this ctor - type specified: " + super.getElementValueType());
    069        }
    070        this.typeIdx = typeIdx;
    071        this.valueIdx = valueIdx;
    072    }
    073
    074    /**
    075     * Constructs an EnumElementValueGen.
    076     *
    077     * @param t the object type.
    078     * @param value the value.
    079     * @param cpool the constant pool.
    080     */
    081    public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) {
    082        super(ENUM_CONSTANT, cpool);
    083        typeIdx = cpool.addUtf8(t.getSignature()); // was addClass(t);
    084        valueIdx = cpool.addUtf8(value); // was addString(value);
    085    }
    086
    087    @Override
    088    public void dump(final DataOutputStream dos) throws IOException {
    089        dos.writeByte(super.getElementValueType()); // u1 type of value (ENUM_CONSTANT == 'e')
    090        dos.writeShort(typeIdx); // u2
    091        dos.writeShort(valueIdx); // u2
    092    }
    093
    094    /**
    095     * Returns immutable variant of this EnumElementValueGen.
    096     *
    097     * @return immutable variant.
    098     */
    099    @Override
    100    public ElementValue getElementValue() {
    101        System.err.println("Duplicating value: " + getEnumTypeString() + ":" + getEnumValueString());
    102        return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, getConstantPool().getConstantPool());
    103    }
    104
    105    /**
    106     * Gets the enum type string.
    107     *
    108     * @return the enum type string.
    109     */
    110    public String getEnumTypeString() {
    111        // ...existing code...
    112        return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getBytes();
    113        // ...existing code...
    114    }
    115
    116    /**
    117     * Gets the enum value string.
    118     *
    119     * @return the enum value string.
    120     */
    121    public String getEnumValueString() {
    122        return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes();
    123        // ...existing code...
    124    }
    125
    126    /**
    127     * Gets the type index.
    128     *
    129     * @return the type index.
    130     */
    131    public int getTypeIndex() {
    132        return typeIdx;
    133    }
    134
    135    /**
    136     * Gets the value index.
    137     *
    138     * @return the value index.
    139     */
    140    public int getValueIndex() {
    141        return valueIdx;
    142    }
    143
    144    @Override
    145    public String stringifyValue() {
    146        final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx);
    147        return cu8.getBytes();
    148        // ConstantString cu8 =
    149        // (ConstantString) getConstantPool().getConstant(valueIdx);
    150        // return
    151        // ((ConstantUtf8) getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
    152    }
    153}