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  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataInputStream;
22  import java.io.DataOutputStream;
23  import java.io.IOException;
24  
25  import org.apache.bcel.Const;
26  
27  /**
28   * Abstract super class for fields and methods.
29   *
30   */
31  public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node {
32  
33      /**
34       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
35       */
36      @java.lang.Deprecated
37      protected int name_index; // Points to field name in constant pool
38  
39      /**
40       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
41       */
42      @java.lang.Deprecated
43      protected int signature_index; // Points to encoded signature
44  
45      /**
46       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
47       */
48      @java.lang.Deprecated
49      protected Attribute[] attributes; // Collection of attributes
50  
51      /**
52       * @deprecated (since 6.0) will be removed (not needed)
53       */
54      @java.lang.Deprecated
55      protected int attributes_count; // No. of attributes
56  
57      // @since 6.0
58      private AnnotationEntry[] annotationEntries; // annotations defined on the field or method
59  
60      /**
61       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
62       */
63      @java.lang.Deprecated
64      protected ConstantPool constant_pool;
65  
66      private String signatureAttributeString = null;
67      private boolean searchedForSignatureAttribute = false;
68  
69      FieldOrMethod() {
70      }
71  
72  
73      /**
74       * Initialize from another object. Note that both objects use the same
75       * references (shallow copy). Use clone() for a physical copy.
76       */
77      protected FieldOrMethodeldOrMethod.html#FieldOrMethod">FieldOrMethod(final FieldOrMethod c) {
78          this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c
79                  .getConstantPool());
80      }
81  
82  
83      /**
84       * Construct object from file stream.
85       * @param file Input stream
86       * @throws IOException
87       * @throws ClassFormatException
88       * @deprecated (6.0) Use {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead.
89       */
90      @java.lang.Deprecated
91      protected FieldOrMethod(final DataInputStream file, final ConstantPool constant_pool) throws IOException,
92              ClassFormatException {
93          this((DataInput) file, constant_pool);
94      }
95  
96      /**
97       * Construct object from file stream.
98       * @param file Input stream
99       * @throws IOException
100      * @throws ClassFormatException
101      */
102     protected FieldOrMethod(final DataInput file, final ConstantPool constant_pool) throws IOException, ClassFormatException {
103         this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null,
104                 constant_pool);
105         final int attributes_count = file.readUnsignedShort();
106         attributes = new Attribute[attributes_count];
107         for (int i = 0; i < attributes_count; i++) {
108             attributes[i] = Attribute.readAttribute(file, constant_pool);
109         }
110         this.attributes_count = attributes_count; // init deprecated field
111     }
112 
113 
114     /**
115      * @param access_flags Access rights of method
116      * @param name_index Points to field name in constant pool
117      * @param signature_index Points to encoded signature
118      * @param attributes Collection of attributes
119      * @param constant_pool Array of constants
120      */
121     protected FieldOrMethod(final int access_flags, final int name_index, final int signature_index,
122             final Attribute[] attributes, final ConstantPool constant_pool) {
123         super(access_flags);
124         this.name_index = name_index;
125         this.signature_index = signature_index;
126         this.constant_pool = constant_pool;
127         setAttributes(attributes);
128     }
129 
130 
131     /**
132      * Dump object to file stream on binary format.
133      *
134      * @param file Output file stream
135      * @throws IOException
136      */
137     public final void dump(final DataOutputStream file) throws IOException {
138         file.writeShort(super.getAccessFlags());
139         file.writeShort(name_index);
140         file.writeShort(signature_index);
141         file.writeShort(attributes_count);
142         if (attributes != null) {
143             for (final Attribute attribute : attributes) {
144                 attribute.dump(file);
145             }
146         }
147     }
148 
149 
150     /**
151      * @return Collection of object attributes.
152      */
153     public final Attribute[] getAttributes() {
154         return attributes;
155     }
156 
157 
158     /**
159      * @param attributes Collection of object attributes.
160      */
161     public final void setAttributes( final Attribute[] attributes ) {
162         this.attributes = attributes;
163         this.attributes_count = attributes != null ? attributes.length : 0; // init deprecated field
164     }
165 
166 
167     /**
168      * @return Constant pool used by this object.
169      */
170     public final ConstantPool getConstantPool() {
171         return constant_pool;
172     }
173 
174 
175     /**
176      * @param constant_pool Constant pool to be used for this object.
177      */
178     public final void setConstantPool( final ConstantPool constant_pool ) {
179         this.constant_pool = constant_pool;
180     }
181 
182 
183     /**
184      * @return Index in constant pool of object's name.
185      */
186     public final int getNameIndex() {
187         return name_index;
188     }
189 
190 
191     /**
192      * @param name_index Index in constant pool of object's name.
193      */
194     public final void setNameIndex( final int name_index ) {
195         this.name_index = name_index;
196     }
197 
198 
199     /**
200      * @return Index in constant pool of field signature.
201      */
202     public final int getSignatureIndex() {
203         return signature_index;
204     }
205 
206 
207     /**
208      * @param signature_index Index in constant pool of field signature.
209      */
210     public final void setSignatureIndex( final int signature_index ) {
211         this.signature_index = signature_index;
212     }
213 
214 
215     /**
216      * @return Name of object, i.e., method name or field name
217      */
218     public final String getName() {
219         ConstantUtf8 c;
220         c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8);
221         return c.getBytes();
222     }
223 
224 
225     /**
226      * @return String representation of object's type signature (java style)
227      */
228     public final String getSignature() {
229         ConstantUtf8 c;
230         c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8);
231         return c.getBytes();
232     }
233 
234 
235     /**
236      * @return deep copy of this field
237      */
238     protected FieldOrMethod copy_( final ConstantPool _constant_pool ) {
239         FieldOrMethod c = null;
240 
241         try {
242           c = (FieldOrMethod)clone();
243         } catch(final CloneNotSupportedException e) {
244             // ignored, but will cause NPE ...
245         }
246 
247         c.constant_pool    = constant_pool;
248         c.attributes       = new Attribute[attributes.length];
249         c.attributes_count = attributes_count; // init deprecated field
250 
251         for (int i = 0; i < attributes.length; i++) {
252             c.attributes[i] = attributes[i].copy(constant_pool);
253         }
254 
255         return c;
256     }
257 
258     /**
259      * @return Annotations on the field or method
260      * @since 6.0
261      */
262     public AnnotationEntry[] getAnnotationEntries() {
263         if (annotationEntries == null) {
264             annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes());
265         }
266 
267         return annotationEntries;
268     }
269 
270     /**
271      * Hunts for a signature attribute on the member and returns its contents.  So where the 'regular' signature
272      * may be (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector&lt;Ljava/lang/String&gt;;'
273      * Coded for performance - searches for the attribute only when requested - only searches for it once.
274      * @since 6.0
275      */
276     public final String getGenericSignature()
277     {
278         if (!searchedForSignatureAttribute)
279         {
280             boolean found = false;
281             for (int i = 0; !found && i < attributes.length; i++)
282             {
283                 if (attributes[i] instanceof Signature)
284                 {
285                     signatureAttributeString = ((Signature) attributes[i])
286                             .getSignature();
287                     found = true;
288                 }
289             }
290             searchedForSignatureAttribute = true;
291         }
292         return signatureAttributeString;
293     }
294 }