KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > cojen > classfile > Attribute


1 /*
2  * Copyright 2004 Brian S O'Neill
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.cojen.classfile;
18
19 import java.io.DataInput JavaDoc;
20 import java.io.DataOutput JavaDoc;
21 import java.io.IOException JavaDoc;
22 import org.cojen.classfile.attribute.CodeAttr;
23 import org.cojen.classfile.attribute.ConstantValueAttr;
24 import org.cojen.classfile.attribute.DeprecatedAttr;
25 import org.cojen.classfile.attribute.EnclosingMethodAttr;
26 import org.cojen.classfile.attribute.ExceptionsAttr;
27 import org.cojen.classfile.attribute.InnerClassesAttr;
28 import org.cojen.classfile.attribute.LineNumberTableAttr;
29 import org.cojen.classfile.attribute.LocalVariableTableAttr;
30 import org.cojen.classfile.attribute.RuntimeInvisibleAnnotationsAttr;
31 import org.cojen.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttr;
32 import org.cojen.classfile.attribute.RuntimeVisibleAnnotationsAttr;
33 import org.cojen.classfile.attribute.RuntimeVisibleParameterAnnotationsAttr;
34 import org.cojen.classfile.attribute.SignatureAttr;
35 import org.cojen.classfile.attribute.SourceFileAttr;
36 import org.cojen.classfile.attribute.SyntheticAttr;
37 import org.cojen.classfile.attribute.UnknownAttr;
38 import org.cojen.classfile.constant.ConstantUTFInfo;
39
40 /**
41  * This class corresponds to the attribute_info structure defined in section
42  * 4.7 of <i>The Java Virtual Machine Specification</i>.
43  *
44  * @author Brian S O'Neill
45  * @see ClassFile
46  */

47 public abstract class Attribute {
48     final static Attribute[] NO_ATTRIBUTES = new Attribute[0];
49
50     public static final String JavaDoc CODE = "Code";
51     public static final String JavaDoc CONSTANT_VALUE = "ConstantValue";
52     public static final String JavaDoc DEPRECATED = "Deprecated";
53     public static final String JavaDoc EXCEPTIONS = "Exceptions";
54     public static final String JavaDoc INNER_CLASSES = "InnerClasses";
55     public static final String JavaDoc LINE_NUMBER_TABLE = "LineNumberTable";
56     public static final String JavaDoc LOCAL_VARIABLE_TABLE = "LocalVariableTable";
57     public static final String JavaDoc SOURCE_FILE = "SourceFile";
58     public static final String JavaDoc SYNTHETIC = "Synthetic";
59     public static final String JavaDoc SIGNATURE = "Signature";
60     public static final String JavaDoc ENCLOSING_METHOD = "EnclosingMethod";
61     public static final String JavaDoc RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
62     public static final String JavaDoc RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
63     public static final String JavaDoc RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS =
64         "RuntimeVisibleParamaterAnnotations";
65     public static final String JavaDoc RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS =
66         "RuntimeInvisibleParamaterAnnotations";
67
68     /** The ConstantPool that this attribute is defined against. */
69     private final ConstantPool mCp;
70
71     private String JavaDoc mName;
72     private ConstantUTFInfo mNameConstant;
73     
74     protected Attribute(ConstantPool cp, String JavaDoc name) {
75         mCp = cp;
76         mName = name;
77         mNameConstant = cp.addConstantUTF(name);
78     }
79
80     /**
81      * Returns the ConstantPool that this attribute is defined against.
82      */

83     public ConstantPool getConstantPool() {
84         return mCp;
85     }
86  
87     /**
88      * Returns the name of this attribute.
89      */

90     public String JavaDoc getName() {
91         return mName;
92     }
93     
94     public ConstantUTFInfo getNameConstant() {
95         return mNameConstant;
96     }
97     
98     /**
99      * Some attributes have sub-attributes. Default implementation returns an
100      * empty array.
101      */

102     public Attribute[] getAttributes() {
103         return NO_ATTRIBUTES;
104     }
105
106     /**
107      * Returns the length (in bytes) of this attribute in the class file.
108      */

109     public abstract int getLength();
110     
111     /**
112      * This method writes the 16 bit name constant index followed by the
113      * 32 bit attribute length, followed by the attribute specific data.
114      */

115     public final void writeTo(DataOutput JavaDoc dout) throws IOException JavaDoc {
116         dout.writeShort(mNameConstant.getIndex());
117         dout.writeInt(getLength());
118         writeDataTo(dout);
119     }
120
121     /**
122      * Write just the attribute specific data. The default implementation
123      * writes nothing.
124      */

125     public void writeDataTo(DataOutput JavaDoc dout) throws IOException JavaDoc {
126     }
127
128     /**
129      * @param attrFactory optional factory for reading custom attributes
130      */

131     public static Attribute readFrom(ConstantPool cp,
132                                      DataInput JavaDoc din,
133                                      AttributeFactory attrFactory)
134         throws IOException JavaDoc
135     {
136         int index = din.readUnsignedShort();
137         String JavaDoc name = ((ConstantUTFInfo)cp.getConstant(index)).getValue();
138         int length = din.readInt();
139
140         attrFactory = new Factory(attrFactory);
141         return attrFactory.createAttribute(cp, name, length, din);
142     }
143
144     private static class Factory implements AttributeFactory {
145         private final AttributeFactory mAttrFactory;
146
147         public Factory(AttributeFactory attrFactory) {
148             mAttrFactory = attrFactory;
149         }
150
151         public Attribute createAttribute(ConstantPool cp,
152                                          String JavaDoc name,
153                                          int length,
154                                          DataInput JavaDoc din) throws IOException JavaDoc {
155             if (name.length() > 0) {
156                 switch (name.charAt(0)) {
157                 case 'C':
158                     if (name.equals(CODE)) {
159                         return new CodeAttr(cp, name, length, din, mAttrFactory);
160                     } else if (name.equals(CONSTANT_VALUE)) {
161                         return new ConstantValueAttr(cp, name, length, din);
162                     }
163                     break;
164                 case 'D':
165                     if (name.equals(DEPRECATED)) {
166                         return new DeprecatedAttr(cp, name, length, din);
167                     }
168                     break;
169                 case 'E':
170                     if (name.equals(EXCEPTIONS)) {
171                         return new ExceptionsAttr(cp, name, length, din);
172                     } else if (name.equals(ENCLOSING_METHOD)) {
173                         return new EnclosingMethodAttr(cp, name, length, din);
174                     }
175                     break;
176                 case 'I':
177                     if (name.equals(INNER_CLASSES)) {
178                         return new InnerClassesAttr(cp, name, length, din);
179                     }
180                     break;
181                 case 'L':
182                     if (name.equals(LINE_NUMBER_TABLE)) {
183                         return new LineNumberTableAttr(cp, name, length, din);
184                     } else if (name.equals(LOCAL_VARIABLE_TABLE)) {
185                         return new LocalVariableTableAttr(cp, name, length, din);
186                     }
187                     break;
188                 case 'R':
189                     if (name.equals(RUNTIME_VISIBLE_ANNOTATIONS)) {
190                         return new RuntimeVisibleAnnotationsAttr(cp, name, length, din);
191                     } else if (name.equals(RUNTIME_INVISIBLE_ANNOTATIONS)) {
192                         return new RuntimeInvisibleAnnotationsAttr(cp, name, length, din);
193                     } else if (name.equals(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS)) {
194                         return new RuntimeVisibleParameterAnnotationsAttr(cp, name, length, din);
195                     } else if (name.equals(RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS)) {
196                         return new RuntimeInvisibleParameterAnnotationsAttr(cp, name, length, din);
197                     }
198                     break;
199                 case 'S':
200                     if (name.equals(SOURCE_FILE)) {
201                         return new SourceFileAttr(cp, name, length, din);
202                     } else if (name.equals(SYNTHETIC)) {
203                         return new SyntheticAttr(cp, name, length, din);
204                     } else if (name.equals(SIGNATURE)) {
205                         return new SignatureAttr(cp, name, length, din);
206                     }
207                     break;
208                 }
209             }
210
211             if (mAttrFactory != null) {
212                 Attribute attr = mAttrFactory.createAttribute(cp, name, length, din);
213                 if (attr != null) {
214                     return attr;
215                 }
216             }
217
218             // Default case, return attribute that captures the data, but
219
// doesn't decode it.
220
return new UnknownAttr(cp, name, length, din);
221         }
222     }
223 }
224
Popular Tags