1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.bcel.internal.classfile; 23 24 25 import com.sun.org.apache.bcel.internal.Constants; 26 import java.io.*; 27 28 /** 29 * Abstract superclass for classes to represent the different constant types 30 * in the constant pool of a class file. The classes keep closely to 31 * the JVM specification. 32 * 33 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 34 */ 35 public abstract class Constant implements Cloneable, Node, Serializable { 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 46 Constant(byte tag) { this.tag = tag; } 47 48 /** 49 * Called by objects that are traversing the nodes of the tree implicitely 50 * defined by the contents of a Java class. I.e., the hierarchy of methods, 51 * fields, attributes, etc. spawns a tree of objects. 52 * 53 * @param v Visitor object 54 */ 55 public abstract void accept(Visitor v); 56 57 public abstract void dump(DataOutputStream file) throws IOException; 58 59 /** 60 * @return Tag of constant, i.e., its type. No setTag() method to avoid 61 * confusion. 62 */ 63 public final byte getTag() { return tag; } 64 65 /** 66 * @return String representation. 67 */ 68 public String toString() { 69 return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; 70 } 71 72 /** 73 * @return deep copy of this constant 74 */ 75 public Constant copy() { 76 try { 77 return (Constant)super.clone(); 78 } catch(CloneNotSupportedException e) {} 79 80 return null; 81 } 82 83 public Object clone() throws CloneNotSupportedException { 84 return super.clone(); 85 } 86 87 /** 88 * Read one constant from the given file, the type depends on a tag byte. 89 * 90 * @param file Input stream 91 * @return Constant object 92 */ 93 static final Constant readConstant(DataInputStream file) 94 throws IOException, ClassFormatException 95 { 96 byte b = file.readByte(); // Read tag byte 97 98 switch(b) { 99 case Constants.CONSTANT_Class: return new ConstantClass(file); 100 case Constants.CONSTANT_Fieldref: return new ConstantFieldref(file); 101 case Constants.CONSTANT_Methodref: return new ConstantMethodref(file); 102 case Constants.CONSTANT_InterfaceMethodref: return new 103 ConstantInterfaceMethodref(file); 104 case Constants.CONSTANT_String: return new ConstantString(file); 105 case Constants.CONSTANT_Integer: return new ConstantInteger(file); 106 case Constants.CONSTANT_Float: return new ConstantFloat(file); 107 case Constants.CONSTANT_Long: return new ConstantLong(file); 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 } 114 } 115 } | 1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package com.sun.org.apache.bcel.internal.classfile; 21 22 import java.io.DataInput; 23 import java.io.DataOutputStream; 24 import java.io.IOException; 25 26 import com.sun.org.apache.bcel.internal.Const; 27 import com.sun.org.apache.bcel.internal.util.BCELComparator; 28 29 /** 30 * Abstract superclass for classes to represent the different constant types in 31 * the constant pool of a class file. The classes keep closely to the JVM 32 * specification. 33 * 34 * @version $Id: Constant.java 1749603 2016-06-21 20:50:19Z ggregory $ 35 */ 36 public abstract class Constant implements Cloneable, Node { 37 38 private static BCELComparator bcelComparator = new BCELComparator() { 39 40 @Override 41 public boolean equals(final Object o1, final Object o2) { 42 final Constant THIS = (Constant) o1; 43 final Constant THAT = (Constant) o2; 44 return THIS.toString().equals(THAT.toString()); 45 } 46 47 @Override 48 public int hashCode(final Object o) { 49 final Constant THIS = (Constant) o; 50 return THIS.toString().hashCode(); 51 } 52 }; 53 54 /* In fact this tag is redundant since we can distinguish different 55 * `Constant' objects by their type, i.e., via `instanceof'. In some 56 * places we will use the tag for switch()es anyway. 57 * 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; 63 64 Constant(final byte tag) { 65 this.tag = tag; 66 } 67 68 /** 69 * Called by objects that are traversing the nodes of the tree implicitely 70 * defined by the contents of a Java class. I.e., the hierarchy of methods, 71 * fields, attributes, etc. spawns a tree of objects. 72 * 73 * @param v Visitor object 74 */ 75 @Override 76 public abstract void accept(Visitor v); 77 78 public abstract void dump(DataOutputStream file) throws IOException; 79 80 /** 81 * @return Tag of constant, i.e., its type. No setTag() method to avoid 82 * confusion. 83 */ 84 public final byte getTag() { 85 return tag; 86 } 87 88 /** 89 * @return String representation. 90 */ 91 @Override 92 public String toString() { 93 return Const.getConstantName(tag) + "[" + tag + "]"; 94 } 95 96 /** 97 * @return deep copy of this constant 98 */ 99 public Constant copy() { 100 try { 101 return (Constant) super.clone(); 102 } catch (final CloneNotSupportedException e) { 103 // TODO should this throw? 104 } 105 return null; 106 } 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 } 197 } |