KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > structures > AttributeInfo


1 /*
2 This library is free software; you can redistribute it and/or
3 modify it under the terms of the GNU General Public
4 License as published by the Free Software Foundation; either
5 version 2 of the license, or (at your option) any later version.
6 */

7 package org.gjt.jclasslib.structures;
8
9 import org.gjt.jclasslib.structures.attributes.*;
10 import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;
11
12 import java.io.*;
13
14 /**
15  * Base class for all attribute structures in the <tt>attribute</tt> package.
16  *
17  * @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>, <a HREF="mailto:vitor.carreira@gmail.com">Vitor Carreira</a>
18  * @version $Revision: 1.6 $ $Date: 2004/12/28 13:04:32 $
19  */

20 public class AttributeInfo extends AbstractStructureWithAttributes {
21
22     /**
23      * Set this JVM System property to true to skip reading of all attributes.
24      * Some class file operations may fail in this case.
25      */

26     public static final String JavaDoc SYSTEM_PROPERTY_SKIP_ATTRIBUTES = "jclasslib.io.skipAttributes";
27
28     private int attributeNameIndex;
29     private int attributeLength;
30     private byte[] info;
31
32     /**
33      * Factory method for creating <tt>AttributeInfo</tt> structures. <p>
34      * An <tt>AttributeInfo</tt> of the appropriate subtype from the <tt>attributes</tt> package
35      * is created unless the type of the attribute is unknown in which case an instance of
36      * <tt>AttributeInfo</tt> is returned. <p>
37      * <p/>
38      * Attributes are skipped if the environment variable <tt>SYSTEM_PROPERTY_SKIP_ATTRIBUTES</tt>
39      * is set to true.
40      *
41      * @param in the <tt>DataInput</tt> from which to read the <tt>AttributeInfo</tt> structure
42      * @param classFile the parent class file of the structure to be created
43      * @return the new <tt>AttributeInfo</tt> structure
44      * @throws InvalidByteCodeException if the byte code is invalid
45      * @throws IOException if an exception occurs with the <tt>DataInput</tt>
46      */

47     public static AttributeInfo createOrSkip(DataInput in, ClassFile classFile)
48             throws InvalidByteCodeException, IOException {
49
50         AttributeInfo attributeInfo = null;
51
52         if (Boolean.getBoolean(SYSTEM_PROPERTY_SKIP_ATTRIBUTES)) {
53             in.skipBytes(2);
54             in.skipBytes(in.readInt());
55         } else {
56             int attributeNameIndex = in.readUnsignedShort();
57             int attributeLength = in.readInt();
58
59             ConstantUtf8Info cpInfoName = classFile.getConstantPoolUtf8Entry(attributeNameIndex);
60             String JavaDoc attributeName = null;
61
62             if (cpInfoName == null) {
63                 return null;
64             }
65
66             attributeName = cpInfoName.getString();
67
68             if (ConstantValueAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
69                 attributeInfo = new ConstantValueAttribute();
70
71             } else if (CodeAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
72                 attributeInfo = new CodeAttribute();
73
74             } else if (ExceptionsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
75                 attributeInfo = new ExceptionsAttribute();
76
77             } else if (InnerClassesAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
78                 attributeInfo = new InnerClassesAttribute();
79
80             } else if (SyntheticAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
81                 attributeInfo = new SyntheticAttribute();
82
83             } else if (SourceFileAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
84                 attributeInfo = new SourceFileAttribute();
85
86             } else if (LineNumberTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
87                 attributeInfo = new LineNumberTableAttribute();
88
89             } else if (LocalVariableTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
90                 attributeInfo = new LocalVariableTableAttribute();
91
92             } else if (DeprecatedAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
93                 attributeInfo = new DeprecatedAttribute();
94
95             } else if (EnclosingMethodAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
96                 attributeInfo = new EnclosingMethodAttribute();
97
98             } else if (SignatureAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
99                 attributeInfo = new SignatureAttribute();
100
101             } else if (LocalVariableTypeTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
102                 attributeInfo = new LocalVariableTypeTableAttribute();
103
104             } else if (RuntimeVisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
105                 attributeInfo = new RuntimeVisibleAnnotationsAttribute();
106
107             } else if (RuntimeInvisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
108                 attributeInfo = new RuntimeInvisibleAnnotationsAttribute();
109
110             } else if (AnnotationDefaultAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
111                 attributeInfo = new AnnotationDefaultAttribute();
112
113             } else {
114                 attributeInfo = new AttributeInfo(attributeLength);
115             }
116             attributeInfo.setAttributeNameIndex(attributeNameIndex);
117             attributeInfo.setClassFile(classFile);
118             attributeInfo.read(in);
119         }
120
121         return attributeInfo;
122     }
123
124     /**
125      * Constructor.
126      */

127     protected AttributeInfo() {
128     }
129
130     private AttributeInfo(int attributeLength) {
131         this.attributeLength = attributeLength;
132     }
133
134     /**
135      * Get the constant pool index for the name of the attribute.
136      *
137      * @return the index
138      */

139     public int getAttributeNameIndex() {
140         return attributeNameIndex;
141     }
142
143     /**
144      * Set the constant pool index for the name of the attribute.
145      *
146      * @param attributeNameIndex the new index
147      */

148     public void setAttributeNameIndex(int attributeNameIndex) {
149         this.attributeNameIndex = attributeNameIndex;
150     }
151
152     /**
153      * Get the raw bytes of the attribute. <p>
154      * <p/>
155      * Is non-null only if attribute is of unknown type.
156      *
157      * @return the byte array
158      */

159     public byte[] getInfo() {
160         return info;
161     }
162
163     /**
164      * Set the raw bytes of the attribute. <p>
165      * <p/>
166      * Works only if attribute is an instance of <tt>AttributeInfo</tt>.
167      *
168      * @param info the new byte array
169      */

170     public void setInfo(byte[] info) {
171         this.info = info;
172     }
173
174     /**
175      * Get the name of the attribute.
176      *
177      * @return the name
178      * @throws InvalidByteCodeException if the byte code is invalid
179      */

180     public String JavaDoc getName() throws InvalidByteCodeException {
181         return classFile.getConstantPoolUtf8Entry(attributeNameIndex).getString();
182     }
183
184     public void read(DataInput in)
185             throws InvalidByteCodeException, IOException {
186
187         info = new byte[attributeLength];
188         in.readFully(info);
189
190         if (debug) debug("read " + getDebugMessage());
191     }
192
193     public void write(DataOutput out)
194             throws InvalidByteCodeException, IOException {
195
196         out.writeShort(attributeNameIndex);
197         out.writeInt(getAttributeLength());
198         if (getClass().equals(AttributeInfo.class)) {
199             out.write(info);
200             if (debug) debug("wrote " + getDebugMessage());
201         }
202     }
203
204     /**
205      * Get the length of this attribute as a number of bytes.
206      *
207      * @return the length
208      */

209     public int getAttributeLength() {
210         return getLength(info);
211     }
212
213     // cannot override debug because subclasses will call super.debug
214
// and expect to call the implementation in AbstractStructure
215
private String JavaDoc getDebugMessage() {
216         String JavaDoc type;
217         try {
218             type = classFile.getConstantPoolUtf8Entry(attributeNameIndex).getString();
219         } catch (InvalidByteCodeException ex) {
220             type = "(unknown)";
221         }
222
223         return "uninterpreted attribute of reported type " + type;
224     }
225
226     protected String JavaDoc printAccessFlagsVerbose(int accessFlags) {
227         if (accessFlags != 0)
228             throw new RuntimeException JavaDoc("Access flags should be zero: " + Integer.toHexString(accessFlags));
229         return "";
230     }
231
232 }
233
Popular Tags