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.ElementValuePair;
027
028/**
029 * Generates element value pairs in annotations.
030 *
031 * @since 6.0
032 */
033public class ElementValuePairGen {
034    private final int nameIdx;
035
036    private final ElementValueGen value;
037
038    private final ConstantPoolGen constantPoolGen;
039
040    /**
041     * Constructs an ElementValuePairGen from an ElementValuePair.
042     *
043     * @param nvp the element value pair.
044     * @param cpool the constant pool.
045     * @param copyPoolEntries whether to copy pool entries.
046     */
047    public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
048        this.constantPoolGen = cpool;
049        // J5ASSERT:
050        // Could assert nvp.getNameString() points to the same thing as
051        // constantPoolGen.getConstant(nvp.getNameIndex())
052        // if
053        // (!nvp.getNameString().equals(((ConstantUtf8) constantPoolGen.getConstant(nvp.getNameIndex())).getBytes()))
054        // {
055        // throw new IllegalArgumentException("envp buggered");
056        // }
057        if (copyPoolEntries) {
058            nameIdx = cpool.addUtf8(nvp.getNameString());
059        } else {
060            nameIdx = nvp.getNameIndex();
061        }
062        value = ElementValueGen.copy(nvp.getValue(), cpool, copyPoolEntries);
063    }
064
065    /**
066     * Constructs an ElementValuePairGen.
067     *
068     * @param idx the name index.
069     * @param value the element value.
070     * @param cpool the constant pool.
071     */
072    protected ElementValuePairGen(final int idx, final ElementValueGen value, final ConstantPoolGen cpool) {
073        this.nameIdx = idx;
074        this.value = value;
075        this.constantPoolGen = cpool;
076    }
077
078    /**
079     * Constructs an ElementValuePairGen.
080     *
081     * @param name the name.
082     * @param value the element value.
083     * @param cpool the constant pool.
084     */
085    public ElementValuePairGen(final String name, final ElementValueGen value, final ConstantPoolGen cpool) {
086        this.nameIdx = cpool.addUtf8(name);
087        this.value = value;
088        this.constantPoolGen = cpool;
089    }
090
091    /**
092     * Dumps this element value pair to a DataOutputStream.
093     *
094     * @param dos the output stream.
095     * @throws IOException if an I/O error occurs.
096     */
097    protected void dump(final DataOutputStream dos) throws IOException {
098        dos.writeShort(nameIdx); // u2 name of the element
099        value.dump(dos);
100    }
101
102    /**
103     * Retrieves an immutable version of this ElementValuePairGen.
104     *
105     * @return an immutable ElementValuePair.
106     */
107    public ElementValuePair getElementNameValuePair() {
108        final ElementValue immutableValue = value.getElementValue();
109        return new ElementValuePair(nameIdx, immutableValue, constantPoolGen.getConstantPool());
110    }
111
112    /**
113     * Gets the name index.
114     *
115     * @return the name index.
116     */
117    public int getNameIndex() {
118        return nameIdx;
119    }
120
121    /**
122     * Gets the name string.
123     *
124     * @return the name string.
125     */
126    public final String getNameString() {
127        // ConstantString cu8 = (ConstantString) constantPoolGen.getConstant(nameIdx);
128        return ((ConstantUtf8) constantPoolGen.getConstant(nameIdx)).getBytes();
129    }
130
131    /**
132     * Gets the value.
133     *
134     * @return the element value.
135     */
136    public final ElementValueGen getValue() {
137        return value;
138    }
139
140    @Override
141    public String toString() {
142        return "ElementValuePair:[" + getNameString() + "=" + value.stringifyValue() + "]";
143    }
144}