Home | History | Annotate | Download | only in classfile
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  */
     18 package org.apache.bcel.classfile;
     19 
     20 import java.io.DataInput;
     21 import java.io.DataInputStream;
     22 import java.io.DataOutputStream;
     23 import java.io.IOException;
     24 
     25 import org.apache.bcel.Const;
     26 
     27 /**
     28  * Abstract super class for fields and methods.
     29  *
     30  * @version $Id$
     31  */
     32 public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node {
     33 
     34     /**
     35      * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
     36      */
     37     @java.lang.Deprecated
     38     protected int name_index; // Points to field name in constant pool
     39 
     40     /**
     41      * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
     42      */
     43     @java.lang.Deprecated
     44     protected int signature_index; // Points to encoded signature
     45 
     46     /**
     47      * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
     48      */
     49     @java.lang.Deprecated
     50     protected Attribute[] attributes; // Collection of attributes
     51 
     52     /**
     53      * @deprecated (since 6.0) will be removed (not needed)
     54      */
     55     @java.lang.Deprecated
     56     protected int attributes_count; // No. of attributes
     57 
     58     // @since 6.0
     59     private AnnotationEntry[] annotationEntries; // annotations defined on the field or method
     60 
     61     /**
     62      * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
     63      */
     64     @java.lang.Deprecated
     65     protected ConstantPool constant_pool;
     66 
     67     private String signatureAttributeString = null;
     68     private boolean searchedForSignatureAttribute = false;
     69 
     70     FieldOrMethod() {
     71     }
     72 
     73 
     74     /**
     75      * Initialize from another object. Note that both objects use the same
     76      * references (shallow copy). Use clone() for a physical copy.
     77      */
     78     protected FieldOrMethod(final FieldOrMethod c) {
     79         this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c
     80                 .getConstantPool());
     81     }
     82 
     83 
     84     /**
     85      * Construct object from file stream.
     86      * @param file Input stream
     87      * @throws IOException
     88      * @throws ClassFormatException
     89      * @deprecated (6.0) Use {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead.
     90      */
     91     @java.lang.Deprecated
     92     protected FieldOrMethod(final DataInputStream file, final ConstantPool constant_pool) throws IOException,
     93             ClassFormatException {
     94         this((DataInput) file, constant_pool);
     95     }
     96 
     97     /**
     98      * Construct object from file stream.
     99      * @param file Input stream
    100      * @throws IOException
    101      * @throws ClassFormatException
    102      */
    103     protected FieldOrMethod(final DataInput file, final ConstantPool constant_pool) throws IOException, ClassFormatException {
    104         this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null,
    105                 constant_pool);
    106         final int attributes_count = file.readUnsignedShort();
    107         attributes = new Attribute[attributes_count];
    108         for (int i = 0; i < attributes_count; i++) {
    109             attributes[i] = Attribute.readAttribute(file, constant_pool);
    110         }
    111         this.attributes_count = attributes_count; // init deprecated field
    112     }
    113 
    114 
    115     /**
    116      * @param access_flags Access rights of method
    117      * @param name_index Points to field name in constant pool
    118      * @param signature_index Points to encoded signature
    119      * @param attributes Collection of attributes
    120      * @param constant_pool Array of constants
    121      */
    122     protected FieldOrMethod(final int access_flags, final int name_index, final int signature_index,
    123             final Attribute[] attributes, final ConstantPool constant_pool) {
    124         super(access_flags);
    125         this.name_index = name_index;
    126         this.signature_index = signature_index;
    127         this.constant_pool = constant_pool;
    128         setAttributes(attributes);
    129     }
    130 
    131 
    132     /**
    133      * Dump object to file stream on binary format.
    134      *
    135      * @param file Output file stream
    136      * @throws IOException
    137      */
    138     public final void dump( final DataOutputStream file ) throws IOException {
    139         file.writeShort(super.getAccessFlags());
    140         file.writeShort(name_index);
    141         file.writeShort(signature_index);
    142         file.writeShort(attributes.length);
    143         for (final Attribute attribute : attributes) {
    144             attribute.dump(file);
    145         }
    146     }
    147 
    148 
    149     /**
    150      * @return Collection of object attributes.
    151      */
    152     public final Attribute[] getAttributes() {
    153         return attributes;
    154     }
    155 
    156 
    157     /**
    158      * @param attributes Collection of object attributes.
    159      */
    160     public final void setAttributes( final Attribute[] attributes ) {
    161         this.attributes = attributes;
    162         this.attributes_count = attributes != null ? attributes.length : 0; // init deprecated field
    163     }
    164 
    165 
    166     /**
    167      * @return Constant pool used by this object.
    168      */
    169     public final ConstantPool getConstantPool() {
    170         return constant_pool;
    171     }
    172 
    173 
    174     /**
    175      * @param constant_pool Constant pool to be used for this object.
    176      */
    177     public final void setConstantPool( final ConstantPool constant_pool ) {
    178         this.constant_pool = constant_pool;
    179     }
    180 
    181 
    182     /**
    183      * @return Index in constant pool of object's name.
    184      */
    185     public final int getNameIndex() {
    186         return name_index;
    187     }
    188 
    189 
    190     /**
    191      * @param name_index Index in constant pool of object's name.
    192      */
    193     public final void setNameIndex( final int name_index ) {
    194         this.name_index = name_index;
    195     }
    196 
    197 
    198     /**
    199      * @return Index in constant pool of field signature.
    200      */
    201     public final int getSignatureIndex() {
    202         return signature_index;
    203     }
    204 
    205 
    206     /**
    207      * @param signature_index Index in constant pool of field signature.
    208      */
    209     public final void setSignatureIndex( final int signature_index ) {
    210         this.signature_index = signature_index;
    211     }
    212 
    213 
    214     /**
    215      * @return Name of object, i.e., method name or field name
    216      */
    217     public final String getName() {
    218         ConstantUtf8 c;
    219         c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8);
    220         return c.getBytes();
    221     }
    222 
    223 
    224     /**
    225      * @return String representation of object's type signature (java style)
    226      */
    227     public final String getSignature() {
    228         ConstantUtf8 c;
    229         c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8);
    230         return c.getBytes();
    231     }
    232 
    233 
    234     /**
    235      * @return deep copy of this field
    236      */
    237     protected FieldOrMethod copy_( final ConstantPool _constant_pool ) {
    238         FieldOrMethod c = null;
    239 
    240         try {
    241           c = (FieldOrMethod)clone();
    242         } catch(final CloneNotSupportedException e) {
    243             // ignored, but will cause NPE ...
    244         }
    245 
    246         c.constant_pool    = constant_pool;
    247         c.attributes       = new Attribute[attributes.length];
    248         c.attributes_count = attributes_count; // init deprecated field
    249 
    250         for (int i = 0; i < attributes.length; i++) {
    251             c.attributes[i] = attributes[i].copy(constant_pool);
    252         }
    253 
    254         return c;
    255     }
    256 
    257     /**
    258      * @return Annotations on the field or method
    259      * @since 6.0
    260      */
    261     public AnnotationEntry[] getAnnotationEntries() {
    262         if (annotationEntries == null) {
    263             annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes());
    264         }
    265 
    266         return annotationEntries;
    267     }
    268 
    269     /**
    270      * Hunts for a signature attribute on the member and returns its contents.  So where the 'regular' signature
    271      * may be (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector&lt;Ljava/lang/String&gt;;'
    272      * Coded for performance - searches for the attribute only when requested - only searches for it once.
    273      * @since 6.0
    274      */
    275     public final String getGenericSignature()
    276     {
    277         if (!searchedForSignatureAttribute)
    278         {
    279             boolean found = false;
    280             for (int i = 0; !found && i < attributes.length; i++)
    281             {
    282                 if (attributes[i] instanceof Signature)
    283                 {
    284                     signatureAttributeString = ((Signature) attributes[i])
    285                             .getSignature();
    286                     found = true;
    287                 }
    288             }
    289             searchedForSignatureAttribute = true;
    290         }
    291         return signatureAttributeString;
    292     }
    293 }
    294