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