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.classfile;
020
021import java.io.DataInput;
022import java.io.DataOutputStream;
023import java.io.IOException;
024
025import org.apache.bcel.Const;
026
027/**
028 * Abstract super class for Fieldref, Methodref, InterfaceMethodref and InvokeDynamic constants.
029 *
030 * @see ConstantFieldref
031 * @see ConstantMethodref
032 * @see ConstantInterfaceMethodref
033 * @see ConstantInvokeDynamic
034 */
035public abstract class ConstantCP extends Constant {
036
037    /**
038     * References to the constants containing the class and the field signature
039     */
040    // Note that this field is used to store the
041    // bootstrap_method_attr_index of a ConstantInvokeDynamic.
042    /**
043     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
044     */
045    @java.lang.Deprecated
046    protected int class_index; // TODO make private (has getter & setter)
047    // This field has the same meaning for all subclasses.
048
049    /**
050     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
051     */
052    @java.lang.Deprecated
053    protected int name_and_type_index; // TODO make private (has getter & setter)
054
055    /**
056     * Initialize instance from file data.
057     *
058     * @param tag Constant type tag
059     * @param file Input stream
060     * @throws IOException if an I/O error occurs.
061     */
062    ConstantCP(final byte tag, final DataInput file) throws IOException {
063        this(tag, file.readUnsignedShort(), file.readUnsignedShort());
064    }
065
066    /**
067     * @param classIndex Reference to the class containing the field
068     * @param nameAndTypeIndex and the field signature
069     */
070    protected ConstantCP(final byte tag, final int classIndex, final int nameAndTypeIndex) {
071        super(tag);
072        this.class_index = classIndex;
073        this.name_and_type_index = nameAndTypeIndex;
074    }
075
076    /**
077     * Initialize from another object.
078     *
079     * @param c Source to copy.
080     */
081    public ConstantCP(final ConstantCP c) {
082        this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex());
083    }
084
085    /**
086     * Dump constant field reference to file stream in binary format.
087     *
088     * @param file Output file stream
089     * @throws IOException if an I/O error occurs.
090     */
091    @Override
092    public final void dump(final DataOutputStream file) throws IOException {
093        file.writeByte(super.getTag());
094        file.writeShort(class_index);
095        file.writeShort(name_and_type_index);
096    }
097
098    /**
099     * @return Class this field belongs to.
100     */
101    public String getClass(final ConstantPool cp) {
102        return cp.constantToString(class_index, Const.CONSTANT_Class);
103    }
104
105    /**
106     * @return Reference (index) to class this constant refers to.
107     */
108    public final int getClassIndex() {
109        return class_index;
110    }
111
112    /**
113     * @return Reference (index) to signature of the field.
114     */
115    public final int getNameAndTypeIndex() {
116        return name_and_type_index;
117    }
118
119    /**
120     * @param classIndex points to Constant_class
121     */
122    public final void setClassIndex(final int classIndex) {
123        this.class_index = classIndex;
124    }
125
126    /**
127     * @param nameAndTypeIndex points to Constant_NameAndType
128     */
129    public final void setNameAndTypeIndex(final int nameAndTypeIndex) {
130        this.name_and_type_index = nameAndTypeIndex;
131    }
132
133    /**
134     * @return String representation.
135     *
136     *         not final as ConstantInvokeDynamic needs to modify
137     */
138    @Override
139    public String toString() {
140        return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " + name_and_type_index + ")";
141    }
142}