1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 package com.sun.org.apache.bcel.internal.classfile; 6 7 /* ==================================================================== 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 2001 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, 26 * if any, must include the following acknowledgment: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowledgment may appear in the software itself, 30 * if and wherever such third-party acknowledgments normally appear. 31 * 32 * 4. The names "Apache" and "Apache Software Foundation" and 33 * "Apache BCEL" must not be used to endorse or promote products 34 * derived from this software without prior written permission. For 35 * written permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache", 38 * "Apache BCEL", nor may "Apache" appear in their name, without 39 * prior written permission of the Apache Software Foundation. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>. 59 */ 60 61 import com.sun.org.apache.bcel.internal.Constants; 62 import java.io.*; 63 import java.util.HashMap; 64 65 /** 66 * Abstract super class for <em>Attribute</em> objects. Currently the 67 * <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>, 68 * <em>Exceptiontable</em>, <em>LineNumberTable</em>, 69 * <em>LocalVariableTable</em>, <em>InnerClasses</em> and 70 * <em>Synthetic</em> attributes are supported. The 71 * <em>Unknown</em> attribute stands for non-standard-attributes. 72 * 73 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 74 * @see ConstantValue 75 * @see SourceFile 76 * @see Code 77 * @see Unknown 78 * @see ExceptionTable 79 * @see LineNumberTable 80 * @see LocalVariableTable 81 * @see InnerClasses 82 * @see Synthetic 83 * @see Deprecated 84 * @see Signature 85 */ 86 public abstract class Attribute implements Cloneable, Node, Serializable { 87 protected int name_index; // Points to attribute name in constant pool 88 protected int length; // Content length of attribute field 89 protected byte tag; // Tag to distiguish subclasses 90 protected ConstantPool constant_pool; 91 92 protected Attribute(byte tag, int name_index, int length, 93 ConstantPool constant_pool) { 94 this.tag = tag; 95 this.name_index = name_index; 96 this.length = length; 97 this.constant_pool = constant_pool; 98 } 99 100 /** 101 * Called by objects that are traversing the nodes of the tree implicitely 102 * defined by the contents of a Java class. I.e., the hierarchy of methods, 103 * fields, attributes, etc. spawns a tree of objects. 104 * 105 * @param v Visitor object 106 */ 107 public abstract void accept(Visitor v); 108 109 /** 110 * Dump attribute to file stream in binary format. 111 * 112 * @param file Output file stream 113 * @throws IOException 114 */ 115 public void dump(DataOutputStream file) throws IOException 116 { 117 file.writeShort(name_index); 118 file.writeInt(length); 119 } 120 121 private static HashMap readers = new HashMap(); 122 123 /** Add an Attribute reader capable of parsing (user-defined) attributes 124 * named "name". You should not add readers for the standard attributes 125 * such as "LineNumberTable", because those are handled internally. 126 * 127 * @param name the name of the attribute as stored in the class file 128 * @param r the reader object 129 */ 130 public static void addAttributeReader(String name, AttributeReader r) { 131 readers.put(name, r); 132 } 133 134 /** Remove attribute reader 135 * 136 * @param name the name of the attribute as stored in the class file 137 */ 138 public static void removeAttributeReader(String name) { 139 readers.remove(name); 140 } 141 142 /* Class method reads one attribute from the input data stream. 143 * This method must not be accessible from the outside. It is 144 * called by the Field and Method constructor methods. 145 * 146 * @see Field 147 * @see Method 148 * @param file Input stream 149 * @param constant_pool Array of constants 150 * @return Attribute 151 * @throws IOException 152 * @throws ClassFormatException 153 */ 154 public static final Attribute readAttribute(DataInputStream file, 155 ConstantPool constant_pool) 156 throws IOException, ClassFormatException 157 { 158 ConstantUtf8 c; 159 String name; 160 int name_index; 161 int length; 162 byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute 163 164 // Get class name from constant pool via `name_index' indirection 165 name_index = (int)file.readUnsignedShort(); 166 c = (ConstantUtf8)constant_pool.getConstant(name_index, 167 Constants.CONSTANT_Utf8); 168 name = c.getBytes(); 169 170 // Length of data in bytes 171 length = file.readInt(); 172 173 // Compare strings to find known attribute 174 for(byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) { 175 if(name.equals(Constants.ATTRIBUTE_NAMES[i])) { 176 tag = i; // found! 177 break; 178 } 179 } 180 181 // Call proper constructor, depending on `tag' 182 switch(tag) { 183 case Constants.ATTR_UNKNOWN: 184 AttributeReader r = (AttributeReader)readers.get(name); 185 186 if(r != null) 187 return r.createAttribute(name_index, length, file, constant_pool); 188 else 189 return new Unknown(name_index, length, file, constant_pool); 190 191 case Constants.ATTR_CONSTANT_VALUE: 192 return new ConstantValue(name_index, length, file, constant_pool); 193 194 case Constants.ATTR_SOURCE_FILE: 195 return new SourceFile(name_index, length, file, constant_pool); 196 197 case Constants.ATTR_CODE: 198 return new Code(name_index, length, file, constant_pool); 199 200 case Constants.ATTR_EXCEPTIONS: 201 return new ExceptionTable(name_index, length, file, constant_pool); 202 203 case Constants.ATTR_LINE_NUMBER_TABLE: 204 return new LineNumberTable(name_index, length, file, constant_pool); 205 206 case Constants.ATTR_LOCAL_VARIABLE_TABLE: 207 return new LocalVariableTable(name_index, length, file, constant_pool); 208 209 case Constants.ATTR_INNER_CLASSES: 210 return new InnerClasses(name_index, length, file, constant_pool); 211 212 case Constants.ATTR_SYNTHETIC: 213 return new Synthetic(name_index, length, file, constant_pool); 214 215 case Constants.ATTR_DEPRECATED: 216 return new Deprecated(name_index, length, file, constant_pool); 217 218 case Constants.ATTR_PMG: 219 return new PMGClass(name_index, length, file, constant_pool); 220 221 case Constants.ATTR_SIGNATURE: 222 return new Signature(name_index, length, file, constant_pool); 223 224 case Constants.ATTR_STACK_MAP: 225 return new StackMap(name_index, length, file, constant_pool); 226 227 default: // Never reached 228 throw new IllegalStateException("Ooops! default case reached."); 229 } 230 } 231 232 /** 233 * @return Length of attribute field in bytes. 234 */ 235 public final int getLength() { return length; } 236 237 /** 238 * @param Attribute length in bytes. 239 */ 240 public final void setLength(int length) { 241 this.length = length; 242 } 243 244 /** 245 * @param name_index of attribute. 246 */ 247 public final void setNameIndex(int name_index) { 248 this.name_index = name_index; 249 } 250 251 /** 252 * @return Name index in constant pool of attribute name. 253 */ 254 public final int getNameIndex() { return name_index; } 255 256 /** 257 * @return Tag of attribute, i.e., its type. Value may not be altered, thus 258 * there is no setTag() method. 259 */ 260 public final byte getTag() { return tag; } 261 262 /** 263 * @return Constant pool used by this object. 264 * @see ConstantPool 265 */ 266 public final ConstantPool getConstantPool() { return constant_pool; } 267 268 /** 269 * @param constant_pool Constant pool to be used for this object. 270 * @see ConstantPool 271 */ 272 public final void setConstantPool(ConstantPool constant_pool) { 273 this.constant_pool = constant_pool; 274 } 275 276 /** 277 * Use copy() if you want to have a deep copy(), i.e., with all references 278 * copied correctly. 279 * 280 * @return shallow copy of this attribute 281 */ 282 public Object clone() { 283 Object o = null; 284 285 try { 286 o = super.clone(); 287 } catch(CloneNotSupportedException e) { 288 e.printStackTrace(); // Never occurs 289 } 290 291 return o; 292 } 293 294 /** 295 * @return deep copy of this attribute 296 */ 297 public abstract Attribute copy(ConstantPool constant_pool); 298 299 /** 300 * @return attribute name. 301 */ 302 public String toString() { 303 return Constants.ATTRIBUTE_NAMES[tag]; 304 } 305 }