Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

FieldGen.java

00001 package de.fub.bytecode.generic;
00002 
00003 import de.fub.bytecode.Constants;
00004 import de.fub.bytecode.classfile.*;
00005 import java.util.Vector;
00006 import java.util.Enumeration;
00007 
00008 /** 
00009  * Template class for building up a field.  The only extraordinary thing
00010  * one can do is to add a constant value attribute to a field (which must of
00011  * course be compatible with to the declared type).
00012  *
00013  * @version $Id: FieldGen.java,v 1.1.1.1 2002/01/24 03:41:39 pserver Exp $
00014  * @author  <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
00015  * @see Field
00016  */
00017 public class FieldGen extends FieldGenOrMethodGen {
00018   private int    index = -1;
00019   private Vector attributes;
00020 
00021   private Vector observers;
00022 
00023   /**
00024    * Declare a field. If it is static (isStatic() == true) and has a
00025    * basic type like int or String it may have an initial value
00026    * associated with it as defined by setInitValue().
00027    *
00028    * @param access_flags access qualifiers
00029    * @param type  field type
00030    * @param name field name
00031    * @param cp constant pool
00032    */
00033   public FieldGen(int access_flags, Type type, String name, ConstantPoolGen cp) {
00034     setAccessFlags(access_flags);
00035     setType(type);
00036     setName(name);
00037     setConstantPool(cp);
00038   }  
00039   /**
00040    * Instantiate from existing method.
00041    *
00042    * @param field Field object
00043    * @param cp constant pool (must contain the same entries as the field's constant pool)
00044    */
00045   public FieldGen(Field field, ConstantPoolGen cp) {
00046     this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp);
00047 
00048     Attribute[] attrs = field.getAttributes();
00049 
00050     for(int i=0; i < attrs.length; i++) {
00051       if(attrs[i] instanceof ConstantValue)
00052     index = ((ConstantValue)attrs[i]).getConstantValueIndex();
00053       else
00054     addAttribute(attrs[i]);
00055     }
00056   }  
00057   /** Add observer for this object.
00058    */
00059   public void addObserver(FieldObserver o) {
00060     if(observers == null)
00061       observers = new Vector();
00062 
00063     observers.add(o);
00064   }  
00065   /** Remove any initial value.
00066    */
00067   public void cancelInitValue() {
00068     index = -1;
00069   }  
00070   private void checkType(Type atype) {
00071     if(type == null)
00072       throw new ClassGenException("You haven't defined the type of the field yet");
00073     
00074     if(!isStatic())
00075       throw new ClassGenException("Only static fields may have an initial value!");
00076 
00077     if(!type.equals(atype))
00078       throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype);
00079   }  
00080   /**
00081    * Get field object after having set up all necessary values.
00082    */
00083   public Field getField() {
00084     String      signature       = getSignature();
00085     int         name_index      = cp.addUtf8(name);
00086     int         signature_index = cp.addUtf8(signature);
00087 
00088     if(index > 0) {
00089       checkType(type);
00090       addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"),
00091                      2, index, cp.getConstantPool()));
00092     }
00093 
00094     return new Field(access_flags, name_index, signature_index, getAttributes(),
00095              cp.getConstantPool());
00096   }  
00097   public String getInitValue() {
00098     if(index > 0) {
00099       Constant c = cp.getConstant(index);
00100       return cp.getConstantPool().constantToString(c);
00101     } else
00102       return null;
00103   }  
00104   public String  getSignature()  { return type.getSignature(); }  
00105   /** Remove observer for this object.
00106    */
00107   public void removeObserver(FieldObserver o) {
00108     if(observers != null)
00109       observers.removeElement(o);
00110   }  
00111   public void setInitValue(byte b) {
00112     checkType(Type.BYTE);
00113 
00114     if(b != 0)
00115       index = cp.addInteger(b);
00116   }  
00117   public void setInitValue(char c) {
00118     checkType(Type.CHAR);
00119 
00120     if(c != 0)
00121       index = cp.addInteger(c);
00122   }  
00123   public void setInitValue(double d) {
00124     checkType(Type.DOUBLE);
00125 
00126     if(d != 0.0)
00127       index = cp.addDouble(d);
00128   }  
00129   public void setInitValue(float f) {
00130     checkType(Type.FLOAT);
00131 
00132     if(f != 0.0)
00133       index = cp.addFloat(f);
00134   }  
00135   public void setInitValue(int i) {
00136     checkType(Type.INT);
00137 
00138     if(i != 0)
00139       index = cp.addInteger(i);
00140   }  
00141   public void setInitValue(long l) {
00142     checkType(Type.LONG);
00143 
00144     if(l != 0L)
00145       index = cp.addLong(l);
00146   }  
00147   /**
00148    * Set (optional) initial value of field, otherwise it will be set to null/0/false
00149    * by the JVM automatically.
00150    */
00151   public void setInitValue(String str) {
00152     checkType(new ObjectType("java.lang.String"));
00153 
00154     if(str != null)
00155       index = cp.addString(str);
00156   }  
00157   public void setInitValue(short s) {
00158     checkType(Type.SHORT);
00159 
00160     if(s != 0)
00161       index = cp.addInteger(s);
00162   }  
00163   public void setInitValue(boolean b) {
00164     checkType(Type.BOOLEAN);
00165 
00166     if(b)
00167       index = cp.addInteger(1);
00168   }  
00169   /**
00170    * Return string representation close to declaration format,
00171    * `public static final short MAX = 100', e.g..
00172    *
00173    * @return String representation of field
00174    */
00175   public final String toString() {
00176     String name, signature, access; // Short cuts to constant pool
00177 
00178     access    = Utility.accessToString(access_flags);
00179     access    = access.equals("")? "" : (access + " ");
00180     signature = type.toString();
00181     name      = getName();
00182 
00183     StringBuffer buf = new StringBuffer(access + signature + " " + name);
00184     String value = getInitValue();
00185 
00186     if(value != null)
00187       buf.append(" = " + value);
00188 
00189     return buf.toString();
00190   }  
00191   /** Call notify() method on all observers. This method is not called
00192    * automatically whenever the state has changed, but has to be
00193    * called by the user after he has finished editing the object.
00194    */
00195   public void update() {
00196     if(observers != null)
00197       for(Enumeration e = observers.elements(); e.hasMoreElements(); )
00198     ((FieldObserver)e.nextElement()).notify(this);
00199   }  
00200 }

Generated at Thu Feb 7 06:45:38 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001