1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel.classfile;
19
20 import java.io.DataInputStream;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.util.HashMap;
25 import java.util.Map;
26 import org.apache.bcel.Constants;
27 import org.apache.bcel.classfile.ConstantUtf8;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public abstract class Attribute implements Cloneable, Node, Serializable
52 {
53 private static final long serialVersionUID = -1707826820310002955L;
54
55 protected int name_index;
56
57 protected int length;
58
59 protected byte tag;
60
61 protected ConstantPool constant_pool;
62
63 protected Attribute(byte tag, int name_index, int length,
64 ConstantPool constant_pool)
65 {
66 this.tag = tag;
67 this.name_index = name_index;
68 this.length = length;
69 this.constant_pool = constant_pool;
70 }
71
72
73
74
75
76
77
78
79
80 public abstract void accept(Visitor v);
81
82
83
84
85
86
87
88
89 public void dump(DataOutputStream file) throws IOException
90 {
91 file.writeShort(name_index);
92 file.writeInt(length);
93 }
94
95 private static final Map<String, AttributeReader> readers = new HashMap<String, AttributeReader>();
96
97
98
99
100
101
102
103
104
105
106
107 public static void addAttributeReader(String name, AttributeReader r)
108 {
109 readers.put(name, r);
110 }
111
112
113
114
115
116
117
118 public static void removeAttributeReader(String name)
119 {
120 readers.remove(name);
121 }
122
123
124
125
126
127
128
129
130
131
132
133 public static final Attribute readAttribute(DataInputStream file,
134 ConstantPool constant_pool) throws IOException,
135 ClassFormatException
136 {
137 ConstantUtf8 c;
138 String name;
139 int name_index;
140 int length;
141 byte tag = Constants.ATTR_UNKNOWN;
142
143 name_index = file.readUnsignedShort();
144 c = (ConstantUtf8) constant_pool.getConstant(name_index,
145 Constants.CONSTANT_Utf8);
146 name = c.getBytes();
147
148 length = file.readInt();
149
150
151 for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++)
152 {
153 if (name.equals(Constants.ATTRIBUTE_NAMES[i]))
154 {
155 tag = i;
156 break;
157 }
158 }
159
160 switch (tag)
161 {
162 case Constants.ATTR_UNKNOWN:
163 AttributeReader r = readers.get(name);
164 if (r != null)
165 {
166 return r.createAttribute(name_index, length, file,
167 constant_pool);
168 }
169 return new Unknown(name_index, length, file, constant_pool);
170 case Constants.ATTR_CONSTANT_VALUE:
171 return new ConstantValue(name_index, length, file, constant_pool);
172 case Constants.ATTR_SOURCE_FILE:
173 return new SourceFile(name_index, length, file, constant_pool);
174 case Constants.ATTR_CODE:
175 return new Code(name_index, length, file, constant_pool);
176 case Constants.ATTR_EXCEPTIONS:
177 return new ExceptionTable(name_index, length, file, constant_pool);
178 case Constants.ATTR_LINE_NUMBER_TABLE:
179 return new LineNumberTable(name_index, length, file, constant_pool);
180 case Constants.ATTR_LOCAL_VARIABLE_TABLE:
181 return new LocalVariableTable(name_index, length, file,
182 constant_pool);
183 case Constants.ATTR_INNER_CLASSES:
184 return new InnerClasses(name_index, length, file, constant_pool);
185 case Constants.ATTR_SYNTHETIC:
186 return new Synthetic(name_index, length, file, constant_pool);
187 case Constants.ATTR_DEPRECATED:
188 return new Deprecated(name_index, length, file, constant_pool);
189 case Constants.ATTR_PMG:
190 return new PMGClass(name_index, length, file, constant_pool);
191 case Constants.ATTR_SIGNATURE:
192 return new Signature(name_index, length, file, constant_pool);
193 case Constants.ATTR_STACK_MAP:
194 return new StackMap(name_index, length, file, constant_pool);
195 case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
196 return new RuntimeVisibleAnnotations(name_index, length, file,
197 constant_pool);
198 case Constants.ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS:
199 return new RuntimeInvisibleAnnotations(name_index, length, file,
200 constant_pool);
201 case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS:
202 return new RuntimeVisibleParameterAnnotations(name_index, length,
203 file, constant_pool);
204 case Constants.ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS:
205 return new RuntimeInvisibleParameterAnnotations(name_index, length,
206 file, constant_pool);
207 case Constants.ATTR_ANNOTATION_DEFAULT:
208 return new AnnotationDefault(name_index, length, file,
209 constant_pool);
210 case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE:
211 return new LocalVariableTypeTable(name_index, length, file,
212 constant_pool);
213 case Constants.ATTR_ENCLOSING_METHOD:
214 return new EnclosingMethod(name_index, length, file, constant_pool);
215 case Constants.ATTR_STACK_MAP_TABLE:
216 return new StackMapTable(name_index, length, file, constant_pool);
217 default:
218 throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag);
219 }
220 }
221
222
223
224
225 public String getName()
226 {
227 ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index,
228 Constants.CONSTANT_Utf8);
229 return c.getBytes();
230 }
231
232
233
234
235 public final int getLength()
236 {
237 return length;
238 }
239
240
241
242
243
244 public final void setLength(int length)
245 {
246 this.length = length;
247 }
248
249
250
251
252
253 public final void setNameIndex(int name_index)
254 {
255 this.name_index = name_index;
256 }
257
258
259
260
261 public final int getNameIndex()
262 {
263 return name_index;
264 }
265
266
267
268
269
270 public final byte getTag()
271 {
272 return tag;
273 }
274
275
276
277
278
279 public final ConstantPool getConstantPool()
280 {
281 return constant_pool;
282 }
283
284
285
286
287
288
289 public final void setConstantPool(ConstantPool constant_pool)
290 {
291 this.constant_pool = constant_pool;
292 }
293
294
295
296
297
298
299
300 @Override
301 public Object clone()
302 {
303 Object o = null;
304 try
305 {
306 o = super.clone();
307 }
308 catch (CloneNotSupportedException e)
309 {
310 e.printStackTrace();
311 }
312 return o;
313 }
314
315
316
317
318 public abstract Attribute copy(ConstantPool _constant_pool);
319
320
321
322
323 @Override
324 public String toString()
325 {
326 return Constants.ATTRIBUTE_NAMES[tag];
327 }
328 }