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