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.IOException;
22 
23 import org.apache.bcel.Const;
24 import org.apache.bcel.generic.Type;
25 import org.apache.bcel.util.BCELComparator;
26 
27 /**
28  * This class represents the field info structure, i.e., the representation
29  * for a variable in the class. See JVM specification for details.
30  *
31  * @version $Id$
32  */
33 public final class Field extends FieldOrMethod {
34 
35     private static BCELComparator bcelComparator = new BCELComparator() {
36 
37         @Override
38         public boolean equals( final Object o1, final Object o2 ) {
39             final Field THIS = (Field) o1;
40             final Field THAT = (Field) o2;
41             return THIS.getName().equals(THAT.getName())
42                     && THIS.getSignature().equals(THAT.getSignature());
43         }
44 
45 
46         @Override
47         public int hashCode( final Object o ) {
48             final Field THIS = (Field) o;
49             return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
50         }
51     };
52 
53 
54     /**
55      * Initialize from another object. Note that both objects use the same
56      * references (shallow copy). Use clone() for a physical copy.
57      */
Field(final Field c)58     public Field(final Field c) {
59         super(c);
60     }
61 
62 
63     /**
64      * Construct object from file stream.
65      * @param file Input stream
66      */
Field(final DataInput file, final ConstantPool constant_pool)67     Field(final DataInput file, final ConstantPool constant_pool) throws IOException,
68             ClassFormatException {
69         super(file, constant_pool);
70     }
71 
72 
73     /**
74      * @param access_flags Access rights of field
75      * @param name_index Points to field name in constant pool
76      * @param signature_index Points to encoded signature
77      * @param attributes Collection of attributes
78      * @param constant_pool Array of constants
79      */
Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, final ConstantPool constant_pool)80     public Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes,
81             final ConstantPool constant_pool) {
82         super(access_flags, name_index, signature_index, attributes, constant_pool);
83     }
84 
85 
86     /**
87      * Called by objects that are traversing the nodes of the tree implicitely
88      * defined by the contents of a Java class. I.e., the hierarchy of methods,
89      * fields, attributes, etc. spawns a tree of objects.
90      *
91      * @param v Visitor object
92      */
93     @Override
accept( final Visitor v )94     public void accept( final Visitor v ) {
95         v.visitField(this);
96     }
97 
98 
99     /**
100      * @return constant value associated with this field (may be null)
101      */
getConstantValue()102     public final ConstantValue getConstantValue() {
103         for (final Attribute attribute : super.getAttributes()) {
104             if (attribute.getTag() == Const.ATTR_CONSTANT_VALUE) {
105                 return (ConstantValue) attribute;
106             }
107         }
108         return null;
109     }
110 
111 
112     /**
113      * Return string representation close to declaration format,
114      * `public static final short MAX = 100', e.g..
115      *
116      * @return String representation of field, including the signature.
117      */
118     @Override
toString()119     public final String toString() {
120         String name;
121         String signature;
122         String access; // Short cuts to constant pool
123 
124         // Get names from constant pool
125         access = Utility.accessToString(super.getAccessFlags());
126         access = access.isEmpty() ? "" : (access + " ");
127         signature = Utility.signatureToString(getSignature());
128         name = getName();
129         final StringBuilder buf = new StringBuilder(64); // CHECKSTYLE IGNORE MagicNumber
130         buf.append(access).append(signature).append(" ").append(name);
131         final ConstantValue cv = getConstantValue();
132         if (cv != null) {
133             buf.append(" = ").append(cv);
134         }
135         for (final Attribute attribute : super.getAttributes()) {
136             if (!(attribute instanceof ConstantValue)) {
137                 buf.append(" [").append(attribute).append("]");
138             }
139         }
140         return buf.toString();
141     }
142 
143 
144     /**
145      * @return deep copy of this field
146      */
copy( final ConstantPool _constant_pool )147     public final Field copy( final ConstantPool _constant_pool ) {
148         return (Field) copy_(_constant_pool);
149     }
150 
151 
152     /**
153      * @return type of field
154      */
getType()155     public Type getType() {
156         return Type.getReturnType(getSignature());
157     }
158 
159 
160     /**
161      * @return Comparison strategy object
162      */
getComparator()163     public static BCELComparator getComparator() {
164         return bcelComparator;
165     }
166 
167 
168     /**
169      * @param comparator Comparison strategy object
170      */
setComparator( final BCELComparator comparator )171     public static void setComparator( final BCELComparator comparator ) {
172         bcelComparator = comparator;
173     }
174 
175 
176     /**
177      * Return value as defined by given BCELComparator strategy.
178      * By default two Field objects are said to be equal when
179      * their names and signatures are equal.
180      *
181      * @see java.lang.Object#equals(java.lang.Object)
182      */
183     @Override
equals( final Object obj )184     public boolean equals( final Object obj ) {
185         return bcelComparator.equals(this, obj);
186     }
187 
188 
189     /**
190      * Return value as defined by given BCELComparator strategy.
191      * By default return the hashcode of the field's name XOR signature.
192      *
193      * @see java.lang.Object#hashCode()
194      */
195     @Override
hashCode()196     public int hashCode() {
197         return bcelComparator.hashCode(this);
198     }
199 }
200