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