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