KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bcel > generic > FieldGen


1 /*
2  * Copyright 2000-2004 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 package org.apache.bcel.generic;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import org.apache.bcel.Constants;
23 import org.apache.bcel.classfile.Attribute;
24 import org.apache.bcel.classfile.Constant;
25 import org.apache.bcel.classfile.ConstantObject;
26 import org.apache.bcel.classfile.ConstantPool;
27 import org.apache.bcel.classfile.ConstantValue;
28 import org.apache.bcel.classfile.Field;
29 import org.apache.bcel.classfile.Utility;
30 import org.apache.bcel.util.BCELComparator;
31
32 /**
33  * Template class for building up a field. The only extraordinary thing
34  * one can do is to add a constant value attribute to a field (which must of
35  * course be compatible with to the declared type).
36  *
37  * @version $Id: FieldGen.java 386056 2006-03-15 11:31:56Z tcurdt $
38  * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
39  * @see Field
40  */

41 public class FieldGen extends FieldGenOrMethodGen {
42
43     private Object JavaDoc value = null;
44     private static BCELComparator _cmp = new BCELComparator() {
45
46         public boolean equals( Object JavaDoc o1, Object JavaDoc o2 ) {
47             FieldGen THIS = (FieldGen) o1;
48             FieldGen THAT = (FieldGen) o2;
49             return THIS.getName().equals(THAT.getName())
50                     && THIS.getSignature().equals(THAT.getSignature());
51         }
52
53
54         public int hashCode( Object JavaDoc o ) {
55             FieldGen THIS = (FieldGen) o;
56             return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
57         }
58     };
59
60
61     /**
62      * Declare a field. If it is static (isStatic() == true) and has a
63      * basic type like int or String it may have an initial value
64      * associated with it as defined by setInitValue().
65      *
66      * @param access_flags access qualifiers
67      * @param type field type
68      * @param name field name
69      * @param cp constant pool
70      */

71     public FieldGen(int access_flags, Type type, String JavaDoc name, ConstantPoolGen cp) {
72         setAccessFlags(access_flags);
73         setType(type);
74         setName(name);
75         setConstantPool(cp);
76     }
77
78
79     /**
80      * Instantiate from existing field.
81      *
82      * @param field Field object
83      * @param cp constant pool (must contain the same entries as the field's constant pool)
84      */

85     public FieldGen(Field field, ConstantPoolGen cp) {
86         this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp);
87         Attribute[] attrs = field.getAttributes();
88         for (int i = 0; i < attrs.length; i++) {
89             if (attrs[i] instanceof ConstantValue) {
90                 setValue(((ConstantValue) attrs[i]).getConstantValueIndex());
91             } else {
92                 addAttribute(attrs[i]);
93             }
94         }
95     }
96
97
98     private void setValue( int index ) {
99         ConstantPool cp = this.cp.getConstantPool();
100         Constant c = cp.getConstant(index);
101         value = ((ConstantObject) c).getConstantValue(cp);
102     }
103
104
105     /**
106      * Set (optional) initial value of field, otherwise it will be set to null/0/false
107      * by the JVM automatically.
108      */

109     public void setInitValue( String JavaDoc str ) {
110         checkType(new ObjectType("java.lang.String"));
111         if (str != null) {
112             value = str;
113         }
114     }
115
116
117     public void setInitValue( long l ) {
118         checkType(Type.LONG);
119         if (l != 0L) {
120             value = new Long JavaDoc(l);
121         }
122     }
123
124
125     public void setInitValue( int i ) {
126         checkType(Type.INT);
127         if (i != 0) {
128             value = new Integer JavaDoc(i);
129         }
130     }
131
132
133     public void setInitValue( short s ) {
134         checkType(Type.SHORT);
135         if (s != 0) {
136             value = new Integer JavaDoc(s);
137         }
138     }
139
140
141     public void setInitValue( char c ) {
142         checkType(Type.CHAR);
143         if (c != 0) {
144             value = new Integer JavaDoc(c);
145         }
146     }
147
148
149     public void setInitValue( byte b ) {
150         checkType(Type.BYTE);
151         if (b != 0) {
152             value = new Integer JavaDoc(b);
153         }
154     }
155
156
157     public void setInitValue( boolean b ) {
158         checkType(Type.BOOLEAN);
159         if (b) {
160             value = new Integer JavaDoc(1);
161         }
162     }
163
164
165     public void setInitValue( float f ) {
166         checkType(Type.FLOAT);
167         if (f != 0.0) {
168             value = new Float JavaDoc(f);
169         }
170     }
171
172
173     public void setInitValue( double d ) {
174         checkType(Type.DOUBLE);
175         if (d != 0.0) {
176             value = new Double JavaDoc(d);
177         }
178     }
179
180
181     /** Remove any initial value.
182      */

183     public void cancelInitValue() {
184         value = null;
185     }
186
187
188     private void checkType( Type atype ) {
189         if (type == null) {
190             throw new ClassGenException("You haven't defined the type of the field yet");
191         }
192         if (!isFinal()) {
193             throw new ClassGenException("Only final fields may have an initial value!");
194         }
195         if (!type.equals(atype)) {
196             throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype);
197         }
198     }
199
200
201     /**
202      * Get field object after having set up all necessary values.
203      */

204     public Field getField() {
205         String JavaDoc signature = getSignature();
206         int name_index = cp.addUtf8(name);
207         int signature_index = cp.addUtf8(signature);
208         if (value != null) {
209             checkType(type);
210             int index = addConstant();
211             addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp
212                     .getConstantPool()));
213         }
214         return new Field(access_flags, name_index, signature_index, getAttributes(), cp
215                 .getConstantPool());
216     }
217
218
219     private int addConstant() {
220         switch (type.getType()) {
221             case Constants.T_INT:
222             case Constants.T_CHAR:
223             case Constants.T_BYTE:
224             case Constants.T_BOOLEAN:
225             case Constants.T_SHORT:
226                 return cp.addInteger(((Integer JavaDoc) value).intValue());
227             case Constants.T_FLOAT:
228                 return cp.addFloat(((Float JavaDoc) value).floatValue());
229             case Constants.T_DOUBLE:
230                 return cp.addDouble(((Double JavaDoc) value).doubleValue());
231             case Constants.T_LONG:
232                 return cp.addLong(((Long JavaDoc) value).longValue());
233             case Constants.T_REFERENCE:
234                 return cp.addString(((String JavaDoc) value));
235             default:
236                 throw new RuntimeException JavaDoc("Oops: Unhandled : " + type.getType());
237         }
238     }
239
240
241     public String JavaDoc getSignature() {
242         return type.getSignature();
243     }
244
245     private List JavaDoc observers;
246
247
248     /** Add observer for this object.
249      */

250     public void addObserver( FieldObserver o ) {
251         if (observers == null) {
252             observers = new ArrayList JavaDoc();
253         }
254         observers.add(o);
255     }
256
257
258     /** Remove observer for this object.
259      */

260     public void removeObserver( FieldObserver o ) {
261         if (observers != null) {
262             observers.remove(o);
263         }
264     }
265
266
267     /** Call notify() method on all observers. This method is not called
268      * automatically whenever the state has changed, but has to be
269      * called by the user after he has finished editing the object.
270      */

271     public void update() {
272         if (observers != null) {
273             for (Iterator JavaDoc e = observers.iterator(); e.hasNext();) {
274                 ((FieldObserver) e.next()).notify(this);
275             }
276         }
277     }
278
279
280     public String JavaDoc getInitValue() {
281         if (value != null) {
282             return value.toString();
283         } else {
284             return null;
285         }
286     }
287
288
289     /**
290      * Return string representation close to declaration format,
291      * `public static final short MAX = 100', e.g..
292      *
293      * @return String representation of field
294      */

295     public final String JavaDoc toString() {
296         String JavaDoc name, signature, access; // Short cuts to constant pool
297
access = Utility.accessToString(access_flags);
298         access = access.equals("") ? "" : (access + " ");
299         signature = type.toString();
300         name = getName();
301         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(32);
302         buf.append(access).append(signature).append(" ").append(name);
303         String JavaDoc value = getInitValue();
304         if (value != null) {
305             buf.append(" = ").append(value);
306         }
307         return buf.toString();
308     }
309
310
311     /** @return deep copy of this field
312      */

313     public FieldGen copy( ConstantPoolGen cp ) {
314         FieldGen fg = (FieldGen) clone();
315         fg.setConstantPool(cp);
316         return fg;
317     }
318
319
320     /**
321      * @return Comparison strategy object
322      */

323     public static BCELComparator getComparator() {
324         return _cmp;
325     }
326
327
328     /**
329      * @param comparator Comparison strategy object
330      */

331     public static void setComparator( BCELComparator comparator ) {
332         _cmp = comparator;
333     }
334
335
336     /**
337      * Return value as defined by given BCELComparator strategy.
338      * By default two FieldGen objects are said to be equal when
339      * their names and signatures are equal.
340      *
341      * @see java.lang.Object#equals(java.lang.Object)
342      */

343     public boolean equals( Object JavaDoc obj ) {
344         return _cmp.equals(this, obj);
345     }
346
347
348     /**
349      * Return value as defined by given BCELComparator strategy.
350      * By default return the hashcode of the field's name XOR signature.
351      *
352      * @see java.lang.Object#hashCode()
353      */

354     public int hashCode() {
355         return _cmp.hashCode(this);
356     }
357 }
358
Popular Tags