--- old/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java 2017-08-08 16:04:23.174893951 -0700 +++ new/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java 2017-08-08 16:04:23.090889745 -0700 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -18,255 +17,295 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.bcel.internal.classfile; - -import com.sun.org.apache.bcel.internal.Constants; -import java.io.*; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.HashMap; +import java.util.Map; + +import com.sun.org.apache.bcel.internal.Const; /** * Abstract super class for Attribute objects. Currently the * ConstantValue, SourceFile, Code, * Exceptiontable, LineNumberTable, * LocalVariableTable, InnerClasses and - * Synthetic attributes are supported. The - * Unknown attribute stands for non-standard-attributes. + * Synthetic attributes are supported. The Unknown + * attribute stands for non-standard-attributes. * - * @author M. Dahm - * @see ConstantValue - * @see SourceFile - * @see Code - * @see Unknown - * @see ExceptionTable - * @see LineNumberTable - * @see LocalVariableTable - * @see InnerClasses - * @see Synthetic - * @see Deprecated - * @see Signature -*/ -public abstract class Attribute implements Cloneable, Node, Serializable { - protected int name_index; // Points to attribute name in constant pool - protected int length; // Content length of attribute field - protected byte tag; // Tag to distiguish subclasses - protected ConstantPool constant_pool; - - protected Attribute(byte tag, int name_index, int length, - ConstantPool constant_pool) { - this.tag = tag; - this.name_index = name_index; - this.length = length; - this.constant_pool = constant_pool; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - public abstract void accept(Visitor v); - - /** - * Dump attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public void dump(DataOutputStream file) throws IOException - { - file.writeShort(name_index); - file.writeInt(length); - } - - private static HashMap readers = new HashMap(); - - /** Add an Attribute reader capable of parsing (user-defined) attributes - * named "name". You should not add readers for the standard attributes - * such as "LineNumberTable", because those are handled internally. - * - * @param name the name of the attribute as stored in the class file - * @param r the reader object - */ - public static void addAttributeReader(String name, AttributeReader r) { - readers.put(name, r); - } - - /** Remove attribute reader - * - * @param name the name of the attribute as stored in the class file - */ - public static void removeAttributeReader(String name) { - readers.remove(name); - } - - /* Class method reads one attribute from the input data stream. - * This method must not be accessible from the outside. It is - * called by the Field and Method constructor methods. - * - * @see Field - * @see Method - * @param file Input stream - * @param constant_pool Array of constants - * @return Attribute - * @throws IOException - * @throws ClassFormatException - */ - public static final Attribute readAttribute(DataInputStream file, - ConstantPool constant_pool) - throws IOException, ClassFormatException - { - ConstantUtf8 c; - String name; - int name_index; - int length; - byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute - - // Get class name from constant pool via `name_index' indirection - name_index = (int)file.readUnsignedShort(); - c = (ConstantUtf8)constant_pool.getConstant(name_index, - Constants.CONSTANT_Utf8); - name = c.getBytes(); - - // Length of data in bytes - length = file.readInt(); - - // Compare strings to find known attribute - for(byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) { - if(name.equals(Constants.ATTRIBUTE_NAMES[i])) { - tag = i; // found! - break; - } - } - - // Call proper constructor, depending on `tag' - switch(tag) { - case Constants.ATTR_UNKNOWN: - AttributeReader r = (AttributeReader)readers.get(name); - - if(r != null) - return r.createAttribute(name_index, length, file, constant_pool); - else - return new Unknown(name_index, length, file, constant_pool); - - case Constants.ATTR_CONSTANT_VALUE: - return new ConstantValue(name_index, length, file, constant_pool); - - case Constants.ATTR_SOURCE_FILE: - return new SourceFile(name_index, length, file, constant_pool); - - case Constants.ATTR_CODE: - return new Code(name_index, length, file, constant_pool); - - case Constants.ATTR_EXCEPTIONS: - return new ExceptionTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LINE_NUMBER_TABLE: - return new LineNumberTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LOCAL_VARIABLE_TABLE: - return new LocalVariableTable(name_index, length, file, constant_pool); - - case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE: - return new LocalVariableTypeTable(name_index, length, file, constant_pool); - - case Constants.ATTR_INNER_CLASSES: - return new InnerClasses(name_index, length, file, constant_pool); - - case Constants.ATTR_SYNTHETIC: - return new Synthetic(name_index, length, file, constant_pool); - - case Constants.ATTR_DEPRECATED: - return new Deprecated(name_index, length, file, constant_pool); - - case Constants.ATTR_PMG: - return new PMGClass(name_index, length, file, constant_pool); - - case Constants.ATTR_SIGNATURE: - return new Signature(name_index, length, file, constant_pool); - - case Constants.ATTR_STACK_MAP: - return new StackMap(name_index, length, file, constant_pool); - - default: // Never reached - throw new IllegalStateException("Ooops! default case reached."); - } - } - - /** - * @return Length of attribute field in bytes. - */ - public final int getLength() { return length; } - - /** - * @param Attribute length in bytes. - */ - public final void setLength(int length) { - this.length = length; - } - - /** - * @param name_index of attribute. - */ - public final void setNameIndex(int name_index) { - this.name_index = name_index; - } - - /** - * @return Name index in constant pool of attribute name. - */ - public final int getNameIndex() { return name_index; } - - /** - * @return Tag of attribute, i.e., its type. Value may not be altered, thus - * there is no setTag() method. - */ - public final byte getTag() { return tag; } - - /** - * @return Constant pool used by this object. - * @see ConstantPool - */ - public final ConstantPool getConstantPool() { return constant_pool; } - - /** - * @param constant_pool Constant pool to be used for this object. - * @see ConstantPool - */ - public final void setConstantPool(ConstantPool constant_pool) { - this.constant_pool = constant_pool; - } - - /** - * Use copy() if you want to have a deep copy(), i.e., with all references - * copied correctly. - * - * @return shallow copy of this attribute - */ - public Object clone() { - Object o = null; - - try { - o = super.clone(); - } catch(CloneNotSupportedException e) { - e.printStackTrace(); // Never occurs - } - - return o; - } - - /** - * @return deep copy of this attribute - */ - public abstract Attribute copy(ConstantPool constant_pool); - - /** - * @return attribute name. - */ - public String toString() { - return Constants.ATTRIBUTE_NAMES[tag]; - } + * @version $Id: Attribute.java 1750029 2016-06-23 22:14:38Z sebb $ + * @see ConstantValue + * @see SourceFile + * @see Code + * @see Unknown + * @see ExceptionTable + * @see LineNumberTable + * @see LocalVariableTable + * @see InnerClasses + * @see Synthetic + * @see Deprecated + * @see Signature + */ +public abstract class Attribute implements Cloneable, Node { + + private int name_index; // Points to attribute name in constant pool + private int length; // Content length of attribute field + private final byte tag; // Tag to distinguish subclasses + private ConstantPool constant_pool; + + protected Attribute(final byte tag, final int name_index, final int length, final ConstantPool constant_pool) { + this.tag = tag; + this.name_index = name_index; + this.length = length; + this.constant_pool = constant_pool; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public abstract void accept(Visitor v); + + /** + * Dump attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump(final DataOutputStream file) throws IOException { + file.writeShort(name_index); + file.writeInt(length); + } + + private static final Map readers = new HashMap<>(); + + /** + * Add an Attribute reader capable of parsing (user-defined) attributes + * named "name". You should not add readers for the standard attributes such + * as "LineNumberTable", because those are handled internally. + * + * @param name the name of the attribute as stored in the class file + * @param r the reader object + */ + public static void addAttributeReader(final String name, final UnknownAttributeReader r) { + readers.put(name, r); + } + + /** + * Remove attribute reader + * + * @param name the name of the attribute as stored in the class file + */ + public static void removeAttributeReader(final String name) { + readers.remove(name); + } + + /** + * Class method reads one attribute from the input data stream. This method + * must not be accessible from the outside. It is called by the Field and + * Method constructor methods. + * + * @see Field + * @see Method + * + * @param file Input stream + * @param constant_pool Array of constants + * @return Attribute + * @throws IOException + * @throws ClassFormatException + */ + public static Attribute readAttribute(final DataInputStream file, final ConstantPool constant_pool) + throws IOException, ClassFormatException { + return readAttribute((DataInput) file, constant_pool); + } + + /** + * Class method reads one attribute from the input data stream. This method + * must not be accessible from the outside. It is called by the Field and + * Method constructor methods. + * + * @see Field + * @see Method + * + * @param file Input stream + * @param constant_pool Array of constants + * @return Attribute + * @throws IOException + * @throws ClassFormatException + * @since 6.0 + */ + public static Attribute readAttribute(final DataInput file, final ConstantPool constant_pool) + throws IOException, ClassFormatException { + byte tag = Const.ATTR_UNKNOWN; // Unknown attribute + // Get class name from constant pool via `name_index' indirection + final int name_index = file.readUnsignedShort(); + final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + final String name = c.getBytes(); + + // Length of data in bytes + final int length = file.readInt(); + + // Compare strings to find known attribute + for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) { + if (name.equals(Const.getAttributeName(i))) { + tag = i; // found! + break; + } + } + + // Call proper constructor, depending on `tag' + switch (tag) { + case Const.ATTR_UNKNOWN: + final Object r = readers.get(name); + if (r instanceof UnknownAttributeReader) { + return ((UnknownAttributeReader) r).createAttribute(name_index, length, file, constant_pool); + } + return new Unknown(name_index, length, file, constant_pool); + case Const.ATTR_CONSTANT_VALUE: + return new ConstantValue(name_index, length, file, constant_pool); + case Const.ATTR_SOURCE_FILE: + return new SourceFile(name_index, length, file, constant_pool); + case Const.ATTR_CODE: + return new Code(name_index, length, file, constant_pool); + case Const.ATTR_EXCEPTIONS: + return new ExceptionTable(name_index, length, file, constant_pool); + case Const.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(name_index, length, file, constant_pool); + case Const.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(name_index, length, file, constant_pool); + case Const.ATTR_INNER_CLASSES: + return new InnerClasses(name_index, length, file, constant_pool); + case Const.ATTR_SYNTHETIC: + return new Synthetic(name_index, length, file, constant_pool); + case Const.ATTR_DEPRECATED: + return new Deprecated(name_index, length, file, constant_pool); + case Const.ATTR_PMG: + return new PMGClass(name_index, length, file, constant_pool); + case Const.ATTR_SIGNATURE: + return new Signature(name_index, length, file, constant_pool); + case Const.ATTR_STACK_MAP: + return new StackMap(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: + return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: + return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool); + case Const.ATTR_ANNOTATION_DEFAULT: + return new AnnotationDefault(name_index, length, file, constant_pool); + case Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE: + return new LocalVariableTypeTable(name_index, length, file, constant_pool); + case Const.ATTR_ENCLOSING_METHOD: + return new EnclosingMethod(name_index, length, file, constant_pool); + case Const.ATTR_STACK_MAP_TABLE: + return new StackMap(name_index, length, file, constant_pool); + case Const.ATTR_BOOTSTRAP_METHODS: + return new BootstrapMethods(name_index, length, file, constant_pool); + case Const.ATTR_METHOD_PARAMETERS: + return new MethodParameters(name_index, length, file, constant_pool); + default: + // Never reached + throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag); + } + } + + /** + * @return Name of attribute + * @since 6.0 + */ + public String getName() { + final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return Length of attribute field in bytes. + */ + public final int getLength() { + return length; + } + + /** + * @param length length in bytes. + */ + public final void setLength(final int length) { + this.length = length; + } + + /** + * @param name_index of attribute. + */ + public final void setNameIndex(final int name_index) { + this.name_index = name_index; + } + + /** + * @return Name index in constant pool of attribute name. + */ + public final int getNameIndex() { + return name_index; + } + + /** + * @return Tag of attribute, i.e., its type. Value may not be altered, thus + * there is no setTag() method. + */ + public final byte getTag() { + return tag; + } + + /** + * @return Constant pool used by this object. + * @see ConstantPool + */ + public final ConstantPool getConstantPool() { + return constant_pool; + } + + /** + * @param constant_pool Constant pool to be used for this object. + * @see ConstantPool + */ + public final void setConstantPool(final ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * Use copy() if you want to have a deep copy(), i.e., with all references + * copied correctly. + * + * @return shallow copy of this attribute + */ + @Override + public Object clone() { + Attribute attr = null; + try { + attr = (Attribute) super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + return attr; + } + + /** + * @return deep copy of this attribute + */ + public abstract Attribute copy(ConstantPool _constant_pool); + + /** + * @return attribute name. + */ + @Override + public String toString() { + return Const.getAttributeName(tag); + } }