View Javadoc

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