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