jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java
changeset 46174 5611d2529b49
parent 44797 8b3b3b911b8a
equal deleted inserted replaced
46173:5546b5710844 46174:5611d2529b49
     1 /*
     1 /*
     2  * reserved comment block
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT REMOVE OR ALTER!
       
     4  */
     3  */
     5 /*
     4 /*
     6  * Licensed to the Apache Software Foundation (ASF) under one or more
     5  * Licensed to the Apache Software Foundation (ASF) under one or more
     7  * contributor license agreements.  See the NOTICE file distributed with
     6  * contributor license agreements.  See the NOTICE file distributed with
     8  * this work for additional information regarding copyright ownership.
     7  * this work for additional information regarding copyright ownership.
    16  * distributed under the License is distributed on an "AS IS" BASIS,
    15  * distributed under the License is distributed on an "AS IS" BASIS,
    17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18  * See the License for the specific language governing permissions and
    17  * See the License for the specific language governing permissions and
    19  * limitations under the License.
    18  * limitations under the License.
    20  */
    19  */
    21 
       
    22 package com.sun.org.apache.bcel.internal.classfile;
    20 package com.sun.org.apache.bcel.internal.classfile;
    23 
    21 
       
    22 import java.io.DataInput;
       
    23 import java.io.DataOutputStream;
       
    24 import java.io.IOException;
    24 
    25 
    25 import  com.sun.org.apache.bcel.internal.Constants;
    26 import com.sun.org.apache.bcel.internal.Const;
    26 import  java.io.*;
    27 import com.sun.org.apache.bcel.internal.util.BCELComparator;
    27 
    28 
    28 /**
    29 /**
    29  * Abstract superclass for classes to represent the different constant types
    30  * Abstract superclass for classes to represent the different constant types in
    30  * in the constant pool of a class file. The classes keep closely to
    31  * the constant pool of a class file. The classes keep closely to the JVM
    31  * the JVM specification.
    32  * specification.
    32  *
    33  *
    33  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
    34  * @version $Id: Constant.java 1749603 2016-06-21 20:50:19Z ggregory $
    34  */
    35  */
    35 public abstract class Constant implements Cloneable, Node, Serializable {
    36 public abstract class Constant implements Cloneable, Node {
    36   /* In fact this tag is redundant since we can distinguish different
       
    37    * `Constant' objects by their type, i.e., via `instanceof'. In some
       
    38    * places we will use the tag for switch()es anyway.
       
    39    *
       
    40    * First, we want match the specification as closely as possible. Second we
       
    41    * need the tag as an index to select the corresponding class name from the
       
    42    * `CONSTANT_NAMES' array.
       
    43    */
       
    44   protected byte tag;
       
    45 
    37 
    46   Constant(byte tag) { this.tag = tag; }
    38     private static BCELComparator bcelComparator = new BCELComparator() {
    47 
    39 
    48   /**
    40         @Override
    49    * Called by objects that are traversing the nodes of the tree implicitely
    41         public boolean equals(final Object o1, final Object o2) {
    50    * defined by the contents of a Java class. I.e., the hierarchy of methods,
    42             final Constant THIS = (Constant) o1;
    51    * fields, attributes, etc. spawns a tree of objects.
    43             final Constant THAT = (Constant) o2;
    52    *
    44             return THIS.toString().equals(THAT.toString());
    53    * @param v Visitor object
    45         }
    54    */
       
    55   public abstract void accept(Visitor v);
       
    56 
    46 
    57   public abstract void dump(DataOutputStream file) throws IOException;
    47         @Override
       
    48         public int hashCode(final Object o) {
       
    49             final Constant THIS = (Constant) o;
       
    50             return THIS.toString().hashCode();
       
    51         }
       
    52     };
    58 
    53 
    59   /**
    54     /* In fact this tag is redundant since we can distinguish different
    60    * @return Tag of constant, i.e., its type. No setTag() method to avoid
    55      * `Constant' objects by their type, i.e., via `instanceof'. In some
    61    * confusion.
    56      * places we will use the tag for switch()es anyway.
    62    */
    57      *
    63   public final byte getTag() { return tag; }
    58      * First, we want match the specification as closely as possible. Second we
       
    59      * need the tag as an index to select the corresponding class name from the
       
    60      * `CONSTANT_NAMES' array.
       
    61      */
       
    62     private byte tag;
    64 
    63 
    65   /**
    64     Constant(final byte tag) {
    66    * @return String representation.
    65         this.tag = tag;
    67    */
    66     }
    68   public String toString() {
       
    69     return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
       
    70   }
       
    71 
    67 
    72   /**
    68     /**
    73    * @return deep copy of this constant
    69      * Called by objects that are traversing the nodes of the tree implicitely
    74    */
    70      * defined by the contents of a Java class. I.e., the hierarchy of methods,
    75   public Constant copy() {
    71      * fields, attributes, etc. spawns a tree of objects.
    76     try {
    72      *
    77       return (Constant)super.clone();
    73      * @param v Visitor object
    78     } catch(CloneNotSupportedException e) {}
    74      */
       
    75     @Override
       
    76     public abstract void accept(Visitor v);
    79 
    77 
    80     return null;
    78     public abstract void dump(DataOutputStream file) throws IOException;
    81   }
       
    82 
    79 
    83   public Object clone() throws CloneNotSupportedException {
    80     /**
    84     return super.clone();
    81      * @return Tag of constant, i.e., its type. No setTag() method to avoid
    85   }
    82      * confusion.
       
    83      */
       
    84     public final byte getTag() {
       
    85         return tag;
       
    86     }
    86 
    87 
    87   /**
    88     /**
    88    * Read one constant from the given file, the type depends on a tag byte.
    89      * @return String representation.
    89    *
    90      */
    90    * @param file Input stream
    91     @Override
    91    * @return Constant object
    92     public String toString() {
    92    */
    93         return Const.getConstantName(tag) + "[" + tag + "]";
    93   static final Constant readConstant(DataInputStream file)
    94     }
    94     throws IOException, ClassFormatException
       
    95   {
       
    96     byte b = file.readByte(); // Read tag byte
       
    97 
    95 
    98     switch(b) {
    96     /**
    99     case Constants.CONSTANT_Class:              return new ConstantClass(file);
    97      * @return deep copy of this constant
   100     case Constants.CONSTANT_Fieldref:           return new ConstantFieldref(file);
    98      */
   101     case Constants.CONSTANT_Methodref:          return new ConstantMethodref(file);
    99     public Constant copy() {
   102     case Constants.CONSTANT_InterfaceMethodref: return new
   100         try {
   103                                         ConstantInterfaceMethodref(file);
   101             return (Constant) super.clone();
   104     case Constants.CONSTANT_String:             return new ConstantString(file);
   102         } catch (final CloneNotSupportedException e) {
   105     case Constants.CONSTANT_Integer:            return new ConstantInteger(file);
   103             // TODO should this throw?
   106     case Constants.CONSTANT_Float:              return new ConstantFloat(file);
   104         }
   107     case Constants.CONSTANT_Long:               return new ConstantLong(file);
   105         return null;
   108     case Constants.CONSTANT_Double:             return new ConstantDouble(file);
       
   109     case Constants.CONSTANT_NameAndType:        return new ConstantNameAndType(file);
       
   110     case Constants.CONSTANT_Utf8:               return new ConstantUtf8(file);
       
   111     default:
       
   112       throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
       
   113     }
   106     }
   114   }
   107 
       
   108     @Override
       
   109     public Object clone() {
       
   110         try {
       
   111             return super.clone();
       
   112         } catch (final CloneNotSupportedException e) {
       
   113             throw new Error("Clone Not Supported"); // never happens
       
   114         }
       
   115     }
       
   116 
       
   117     /**
       
   118      * Read one constant from the given input, the type depends on a tag byte.
       
   119      *
       
   120      * @param input Input stream
       
   121      * @return Constant object
       
   122      * @since 6.0 made public
       
   123      */
       
   124     public static Constant readConstant(final DataInput input) throws IOException,
       
   125             ClassFormatException {
       
   126         final byte b = input.readByte(); // Read tag byte
       
   127         switch (b) {
       
   128             case Const.CONSTANT_Class:
       
   129                 return new ConstantClass(input);
       
   130             case Const.CONSTANT_Fieldref:
       
   131                 return new ConstantFieldref(input);
       
   132             case Const.CONSTANT_Methodref:
       
   133                 return new ConstantMethodref(input);
       
   134             case Const.CONSTANT_InterfaceMethodref:
       
   135                 return new ConstantInterfaceMethodref(input);
       
   136             case Const.CONSTANT_String:
       
   137                 return new ConstantString(input);
       
   138             case Const.CONSTANT_Integer:
       
   139                 return new ConstantInteger(input);
       
   140             case Const.CONSTANT_Float:
       
   141                 return new ConstantFloat(input);
       
   142             case Const.CONSTANT_Long:
       
   143                 return new ConstantLong(input);
       
   144             case Const.CONSTANT_Double:
       
   145                 return new ConstantDouble(input);
       
   146             case Const.CONSTANT_NameAndType:
       
   147                 return new ConstantNameAndType(input);
       
   148             case Const.CONSTANT_Utf8:
       
   149                 return ConstantUtf8.getInstance(input);
       
   150             case Const.CONSTANT_MethodHandle:
       
   151                 return new ConstantMethodHandle(input);
       
   152             case Const.CONSTANT_MethodType:
       
   153                 return new ConstantMethodType(input);
       
   154             case Const.CONSTANT_InvokeDynamic:
       
   155                 return new ConstantInvokeDynamic(input);
       
   156             default:
       
   157                 throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
       
   158         }
       
   159     }
       
   160 
       
   161     /**
       
   162      * @return Comparison strategy object
       
   163      */
       
   164     public static BCELComparator getComparator() {
       
   165         return bcelComparator;
       
   166     }
       
   167 
       
   168     /**
       
   169      * @param comparator Comparison strategy object
       
   170      */
       
   171     public static void setComparator(final BCELComparator comparator) {
       
   172         bcelComparator = comparator;
       
   173     }
       
   174 
       
   175     /**
       
   176      * Return value as defined by given BCELComparator strategy. By default two
       
   177      * Constant objects are said to be equal when the result of toString() is
       
   178      * equal.
       
   179      *
       
   180      * @see java.lang.Object#equals(java.lang.Object)
       
   181      */
       
   182     @Override
       
   183     public boolean equals(final Object obj) {
       
   184         return bcelComparator.equals(this, obj);
       
   185     }
       
   186 
       
   187     /**
       
   188      * Return value as defined by given BCELComparator strategy. By default
       
   189      * return the hashcode of the result of toString().
       
   190      *
       
   191      * @see java.lang.Object#hashCode()
       
   192      */
       
   193     @Override
       
   194     public int hashCode() {
       
   195         return bcelComparator.hashCode(this);
       
   196     }
   115 }
   197 }