    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.generic;
    018
    019import java.io.DataOutputStream;
    020import java.io.IOException;
    021
    022import org.apache.bcel.classfile.ConstantUtf8;
    023import org.apache.bcel.classfile.ElementValue;
    024import org.apache.bcel.classfile.EnumElementValue;
    025
    026/**
    027 * @since 6.0
    028 */
    029public class EnumElementValueGen extends ElementValueGen {
    030    // For enum types, these two indices point to the type and value
    031    private final int typeIdx;
    032
    033    private final int valueIdx;
    034
    035    public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
    036        super(ENUM_CONSTANT, cpool);
    037        if (copyPoolEntries) {
    038            typeIdx = cpool.addUtf8(value.getEnumTypeString()); // was addClass(value.getEnumTypeString());
    039            valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString());
    040        } else {
    041            typeIdx = value.getTypeIndex();
    042            valueIdx = value.getValueIndex();
    043        }
    044    }
    045
    046    /**
    047     * This ctor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx.
    048     * This ctor is used for deserialization
    049     */
    050    protected EnumElementValueGen(final int typeIdx, final int valueIdx, final ConstantPoolGen cpool) {
    051        super(ENUM_CONSTANT, cpool);
    052        if (super.getElementValueType() != ENUM_CONSTANT) {
    053            throw new IllegalArgumentException("Only element values of type enum can be built with this ctor - type specified: " + super.getElementValueType());
    054        }
    055        this.typeIdx = typeIdx;
    056        this.valueIdx = valueIdx;
    057    }
    058
    059    public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) {
    060        super(ENUM_CONSTANT, cpool);
    061        typeIdx = cpool.addUtf8(t.getSignature()); // was addClass(t);
    062        valueIdx = cpool.addUtf8(value); // was addString(value);
    063    }
    064
    065    @Override
    066    public void dump(final DataOutputStream dos) throws IOException {
    067        dos.writeByte(super.getElementValueType()); // u1 type of value (ENUM_CONSTANT == 'e')
    068        dos.writeShort(typeIdx); // u2
    069        dos.writeShort(valueIdx); // u2
    070    }
    071
    072    /**
    073     * Return immutable variant of this EnumElementValue
    074     */
    075    @Override
    076    public ElementValue getElementValue() {
    077        System.err.println("Duplicating value: " + getEnumTypeString() + ":" + getEnumValueString());
    078        return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, getConstantPool().getConstantPool());
    079    }
    080
    081    // BCELBUG: Should we need to call utility.signatureToString() on the output
    082    // here?
    083    public String getEnumTypeString() {
    084        // Constant cc = getConstantPool().getConstant(typeIdx);
    085        // ConstantClass cu8 =
    086        // (ConstantClass) getConstantPool().getConstant(typeIdx);
    087        // return
    088        // ((ConstantUtf8) getConstantPool().getConstant(cu8.getNameIndex())).getBytes();
    089        return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getBytes();
    090        // return Utility.signatureToString(cu8.getBytes());
    091    }
    092
    093    public String getEnumValueString() {
    094        return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes();
    095        // ConstantString cu8 =
    096        // (ConstantString) getConstantPool().getConstant(valueIdx);
    097        // return
    098        // ((ConstantUtf8) getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
    099    }
    100
    101    public int getTypeIndex() {
    102        return typeIdx;
    103    }
    104
    105    public int getValueIndex() {
    106        return valueIdx;
    107    }
    108
    109    @Override
    110    public String stringifyValue() {
    111        final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx);
    112        return cu8.getBytes();
    113        // ConstantString cu8 =
    114        // (ConstantString) getConstantPool().getConstant(valueIdx);
    115        // return
    116        // ((ConstantUtf8) getConstantPool().getConstant(cu8.getStringIndex())).getBytes();
    117    }
    118}