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