View Javadoc

1   /*
2    * Copyright 2005 The Apache Software Foundation.
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  
18  package org.apache.jdo.impl.enhancer.classfile;
19  
20  import java.util.Stack;
21  import java.util.Vector;
22  import java.util.Hashtable;
23  import java.io.*;
24  
25  /***
26   * An abstract base class for the attributes within a class file
27   */
28  public abstract class ClassAttribute implements VMConstants {
29  
30      /* The name of the attribute */
31      private ConstUtf8 attributeName;
32  
33      /***
34       * Returns the name of the attribute
35       */
36      public ConstUtf8 attrName() {
37          return attributeName;
38      }
39  
40      /***
41       * Compares this instance with another for structural equality.
42       */
43      //@olsen: added method
44      public boolean isEqual(Stack msg, Object obj) {
45          if (!(obj instanceof ClassAttribute)) {
46              msg.push("obj/obj.getClass() = "
47                       + (obj == null ? null : obj.getClass()));
48              msg.push("this.getClass() = "
49                       + this.getClass());
50              return false;
51          }
52          ClassAttribute other = (ClassAttribute)obj;
53  
54          if (!this.attributeName.isEqual(msg, other.attributeName)) {
55              msg.push(String.valueOf("attributeName = "
56                                      + other.attributeName));
57              msg.push(String.valueOf("attributeName = "
58                                      + this.attributeName));
59              return false;
60          }
61          return true;
62      }
63  
64      /***
65       * Constructor
66       */
67      ClassAttribute(ConstUtf8 theAttrName) {
68          attributeName = theAttrName;
69      }
70  
71      /***
72       * General attribute reader 
73       */
74      static ClassAttribute read(DataInputStream data, ConstantPool pool)
75  	throws IOException {
76  
77          ClassAttribute attr = null;
78          int attrNameIndex = data.readUnsignedShort();
79          ConstUtf8 attrName8 = (ConstUtf8) pool.constantAt(attrNameIndex);
80          String attrName = attrName8.asString();
81          int attrLength = data.readInt();
82  
83          if (attrName.equals(CodeAttribute.expectedAttrName)) {
84              /* The old style code attribute reader uses more memory and
85                 cpu when the instructions don't need to be examined than the
86                 new deferred attribute reader.  We may at some point decide that
87                 we want to change the default based on the current situation
88                 but for now we will just use the deferred reader in all cases. */
89              if (true) {
90                  attr = CodeAttribute.read(attrName8, attrLength, data, pool);
91              } else {
92                  attr = CodeAttribute.read(attrName8, data, pool);
93              }
94          }
95          else if (attrName.equals(SourceFileAttribute.expectedAttrName)) {
96              attr = SourceFileAttribute.read(attrName8, data, pool);
97          }
98          else if (attrName.equals(ConstantValueAttribute.expectedAttrName)) {
99              attr = ConstantValueAttribute.read(attrName8, data, pool);
100         }
101         else if (attrName.equals(ExceptionsAttribute.expectedAttrName)) {
102             attr = ExceptionsAttribute.read(attrName8, data, pool);
103         }
104         else if (attrName.equals(AnnotatedClassAttribute.expectedAttrName)) {
105             attr = AnnotatedClassAttribute.read(attrName8, data, pool);
106         }
107         else {
108             /* Unrecognized method attribute */
109             byte attrBytes[] = new byte[attrLength];
110             data.readFully(attrBytes);
111             attr = new GenericAttribute (attrName8, attrBytes);
112         }
113 
114         return attr;
115     }
116 
117     /*
118      * CodeAttribute attribute reader
119      */
120 
121     static ClassAttribute read(DataInputStream data, CodeEnv env)
122 	throws IOException {
123         ClassAttribute attr = null;
124         int attrNameIndex = data.readUnsignedShort();
125         ConstUtf8 attrName8 = (ConstUtf8) env.pool().constantAt(attrNameIndex);
126         String attrName = attrName8.asString();
127         int attrLength = data.readInt();
128 
129         if (attrName.equals(LineNumberTableAttribute.expectedAttrName)) {
130             attr = LineNumberTableAttribute.read(attrName8, data, env);
131         }
132         else if (attrName.equals(LocalVariableTableAttribute.expectedAttrName)) {
133             attr = LocalVariableTableAttribute.read(attrName8, data, env);
134         }
135         else if (attrName.equals(AnnotatedMethodAttribute.expectedAttrName)) {
136             attr = AnnotatedMethodAttribute.read(attrName8, data, env);
137         }
138         //@olsen: fix 4467428, added support for synthetic code attribute
139         else if (attrName.equals(SyntheticAttribute.expectedAttrName)) {
140             attr = SyntheticAttribute.read(attrName8, data, env.pool());
141         }
142         else {
143             /* Unrecognized method attribute */
144             byte attrBytes[] = new byte[attrLength];
145             data.readFully(attrBytes);
146             attr = new GenericAttribute (attrName8, attrBytes);
147         }
148 
149         return attr;
150     }
151 
152     /***
153      * Write the attribute to the output stream
154      */
155     abstract void write(DataOutputStream out) throws IOException;
156 
157     /***
158      * Print a description of the attribute to the print stream
159      */
160     abstract void print(PrintStream out, int indent);
161 }
162