View Javadoc

    1   /*
    2    * Copyright  2000-2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    *  you may not use this file except in compliance with the License.
    6    *  You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   *  Unless required by applicable law or agreed to in writing, software
    11   *  distributed under the License is distributed on an "AS IS" BASIS,
    12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *  See the License for the specific language governing permissions and
    14   *  limitations under the License.
    15   *
    16   */
    17  package org.apache.bcel.classfile;
    18
    19  import java.io.DataInputStream;
    20  import java.io.DataOutputStream;
    21  import java.io.IOException;
    22  import java.io.Serializable;
    23  import org.apache.bcel.Constants;
    24  import org.apache.bcel.util.BCELComparator;
    25
    26  /***
    27   * Abstract superclass for classes to represent the different constant types
    28   * in the constant pool of a class file. The classes keep closely to
    29   * the JVM specification.
    30   *
    31   * @version $Id: Constant.java 386056 2006-03-15 11:31:56Z tcurdt $
    32   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
    33   */
    34  public abstract class Constant implements Cloneable, Node, Serializable {
    35
    36      private static BCELComparator _cmp = new BCELComparator() {
    37
    38          public boolean equals( Object o1, Object o2 ) {
    39              Constant THIS = (Constant) o1;
    40              Constant THAT = (Constant) o2;
    41              return THIS.toString().equals(THAT.toString());
    42          }
    43
    44
    45          public int hashCode( Object o ) {
    46              Constant THIS = (Constant) o;
    47              return THIS.toString().hashCode();
    48          }
    49      };
    50      /* In fact this tag is redundant since we can distinguish different
    51       * `Constant' objects by their type, i.e., via `instanceof'. In some
    52       * places we will use the tag for switch()es anyway.
    53       *
    54       * First, we want match the specification as closely as possible. Second we
    55       * need the tag as an index to select the corresponding class name from the
    56       * `CONSTANT_NAMES' array.
    57       */
    58      protected byte tag;
    59
    60
    61      Constant(byte tag) {
    62          this.tag = tag;
    63      }
    64
    65
    66      /***
    67       * Called by objects that are traversing the nodes of the tree implicitely
    68       * defined by the contents of a Java class. I.e., the hierarchy of methods,
    69       * fields, attributes, etc. spawns a tree of objects.
    70       *
    71       * @param v Visitor object
    72       */
    73      public abstract void accept( Visitor v );
    74
    75
    76      public abstract void dump( DataOutputStream file ) throws IOException;
    77
    78
    79      /***
    80       * @return Tag of constant, i.e., its type. No setTag() method to avoid
    81       * confusion.
    82       */
    83      public final byte getTag() {
    84          return tag;
    85      }
    86
    87
    88      /***
    89       * @return String representation.
    90       */
    91      public String toString() {
    92          return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
    93      }
    94
    95
    96      /***
    97       * @return deep copy of this constant
    98       */
    99      public Constant copy() {
    100         try {
    101             return (Constant) super.clone();
    102         } catch (CloneNotSupportedException e) {
    103         }
    104         return null;
    105     }
    106
    107
    108     public Object clone() throws CloneNotSupportedException {
    109         return super.clone();
    110     }
    111
    112
    113     /***
    114      * Read one constant from the given file, the type depends on a tag byte.
    115      *
    116      * @param file Input stream
    117      * @return Constant object
    118      */
    119     static final Constant readConstant( DataInputStream file ) throws IOException,
    120             ClassFormatException {
    121         byte b = file.readByte(); // Read tag byte
    122         switch (b) {
    123             case Constants.CONSTANT_Class:
    124                 return new ConstantClass(file);
    125             case Constants.CONSTANT_Fieldref:
    126                 return new ConstantFieldref(file);
    127             case Constants.CONSTANT_Methodref:
    128                 return new ConstantMethodref(file);
    129             case Constants.CONSTANT_InterfaceMethodref:
    130                 return new ConstantInterfaceMethodref(file);
    131             case Constants.CONSTANT_String:
    132                 return new ConstantString(file);
    133             case Constants.CONSTANT_Integer:
    134                 return new ConstantInteger(file);
    135             case Constants.CONSTANT_Float:
    136                 return new ConstantFloat(file);
    137             case Constants.CONSTANT_Long:
    138                 return new ConstantLong(file);
    139             case Constants.CONSTANT_Double:
    140                 return new ConstantDouble(file);
    141             case Constants.CONSTANT_NameAndType:
    142                 return new ConstantNameAndType(file);
    143             case Constants.CONSTANT_Utf8:
    144                 return new ConstantUtf8(file);
    145             default:
    146                 throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
    147         }
    148     }
    149
    150
    151     /***
    152      * @return Comparison strategy object
    153      */
    154     public static BCELComparator getComparator() {
    155         return _cmp;
    156     }
    157
    158
    159     /***
    160      * @param comparator Comparison strategy object
    161      */
    162     public static void setComparator( BCELComparator comparator ) {
    163         _cmp = comparator;
    164     }
    165
    166
    167     /***
    168      * Return value as defined by given BCELComparator strategy.
    169      * By default two Constant objects are said to be equal when
    170      * the result of toString() is equal.
    171      *
    172      * @see java.lang.Object#equals(java.lang.Object)
    173      */
    174     public boolean equals( Object obj ) {
    175         return _cmp.equals(this, obj);
    176     }
    177
    178
    179     /***
    180      * Return value as defined by given BCELComparator strategy.
    181      * By default return the hashcode of the result of toString().
    182      *
    183      * @see java.lang.Object#hashCode()
    184      */
    185     public int hashCode() {
    186         return _cmp.hashCode(this);
    187     }
    188 }