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

ClassGen.java

00001 package de.fub.bytecode.generic;
00002 
00003 import de.fub.bytecode.Constants;
00004 import de.fub.bytecode.classfile.*;
00005 import java.util.*;
00006 
00007 /** 
00008  * Template class for building up a java class. May be initialized by an
00009  * existing java class (file).
00010  *
00011  * @see JavaClass
00012  * @version $Id: ClassGen.java,v 1.1.1.1 2002/01/24 03:44:04 pserver Exp $
00013  * @author  <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
00014  */
00015 public class ClassGen extends AccessFlags implements Constants {
00016   /* Corresponds to the fields found in a JavaClass object.
00017    */
00018   private String   class_name, super_class_name, file_name;
00019   private int      class_name_index, superclass_name_index;
00020 
00021   private ConstantPoolGen cp; // Template for building up constant pool
00022 
00023   // Vectors instead of arrays to gather fields, methods, etc.
00024   private Vector   field_vec     = new Vector();
00025   private Vector   method_vec    = new Vector();
00026   private Vector   attribute_vec = new Vector();
00027   private Vector   interface_vec = new Vector();
00028 
00029   private static final class Int {
00030     Int(int i) { value = i; }
00031     int value;
00032 
00033     public boolean equals(Object o) { return value == ((Int)o).value; }
00034   }
00035   /**
00036    * Initialize with existing class.
00037    * @param clazz JavaClass object (e.g. read from file)
00038    */
00039   public ClassGen(JavaClass clazz) {
00040     class_name_index      = clazz.getClassNameIndex();
00041     superclass_name_index = clazz.getSuperclassNameIndex();
00042     class_name            = clazz.getClassName();
00043     super_class_name      = clazz.getSuperclassName();
00044     file_name             = clazz.getSourceFileName();
00045     access_flags          = clazz.getAccessFlags();
00046     cp                    = new ConstantPoolGen(clazz.getConstantPool());
00047 
00048     Attribute[] attributes = clazz.getAttributes();
00049     Method[]    methods    = clazz.getMethods();
00050     Field[]     fields     = clazz.getFields();
00051     int[]       interfaces = clazz.getInterfaces();
00052     
00053     for(int i=0; i < interfaces.length; i++)
00054       addInterface(interfaces[i]);
00055 
00056     for(int i=0; i < attributes.length; i++)
00057       addAttribute(attributes[i]);
00058 
00059     for(int i=0; i < methods.length; i++)
00060       addMethod(methods[i]);
00061 
00062     for(int i=0; i < fields.length; i++)
00063       addField(fields[i]);
00064   }  
00065   /**
00066    * @param class_name fully qualified class name
00067    * @param super_class_name fully qualified superclass name
00068    * @param file_name source file name
00069    * @param access_flags access qualifiers
00070    * @param interfaces implemented interfaces
00071    */
00072   public ClassGen(String class_name, String super_class_name, String file_name,
00073           int access_flags, String[] interfaces) {
00074     this.class_name       = class_name;
00075     this.super_class_name = super_class_name;
00076     this.file_name        = file_name;
00077     this.access_flags     = access_flags;
00078     cp = new ConstantPoolGen(); // Create empty constant pool
00079 
00080     // Put everything needed by default into the constant pool and the vectors
00081     addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
00082                 cp.addUtf8(file_name), cp.getConstantPool()));
00083     class_name_index      = cp.addClass(class_name);
00084     superclass_name_index = cp.addClass(super_class_name);
00085 
00086     if(interfaces != null)
00087       for(int i=0; i < interfaces.length; i++)
00088     addInterface(interfaces[i]);
00089   }  
00090   /**
00091    * Add an attribute to this class.
00092    * @param a attribute to add
00093    */
00094   public void addAttribute(Attribute a)    { attribute_vec.addElement(a); }  
00095   /**
00096    * Convenience method.
00097    *
00098    * Add an empty constructor to this class that does nothing but calling super().
00099    * @param access rights for constructor
00100    */
00101   public void addEmptyConstructor(int access_flags) {
00102     InstructionList il = new InstructionList();
00103     il.append(InstructionConstants.THIS); // Push `this'
00104     il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
00105                         "<init>", "()V")));
00106     il.append(InstructionConstants.RETURN);
00107 
00108     MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
00109                "<init>", class_name, il, cp);
00110     mg.setMaxStack(1);
00111     addMethod(mg.getMethod());
00112   }  
00113   /**
00114    * Add a field to this class.
00115    * @param f field to add
00116    */
00117   public void addField(Field f)            { field_vec.addElement(f); }  
00118   /**
00119    * Add an interface to this class, i.e. this class has to implement it.
00120    * @param i interface to implement (must be index in constant pool pointing to a ConstantClass)
00121    */
00122   public void addInterface(int i) {
00123     interface_vec.addElement(new Int(i)); // Wrapped in Int object
00124   }  
00125   /**
00126    * Add an interface to this class, i.e. this class has to implement it.
00127    * @param i interface to implement (fully qualified class name)
00128    */
00129   public void addInterface(String i) {
00130     addInterface(cp.addClass(i));
00131   }  
00132   /**
00133    * Add a method to this class.
00134    * @param m method to add
00135    */
00136   public void addMethod(Method m)          { method_vec.addElement(m); }  
00137   public boolean containsField(Field f)    { return field_vec.contains(f); }  
00138   public Field containsField(String name) {
00139     for(Enumeration e=field_vec.elements(); e.hasMoreElements();) {
00140       Field f = (Field)e.nextElement();
00141       if(f.getName().equals(name))
00142     return f;
00143     }
00144 
00145     return null;
00146   }  
00147   public Method containsMethod(String name, String signature) {
00148     for(Enumeration e=method_vec.elements(); e.hasMoreElements();) {
00149       Method m = (Method)e.nextElement();
00150       if(m.getName().equals(name) && m.getSignature().equals(signature))
00151     return m;
00152     }
00153 
00154     return null;
00155   }  
00156   public Attribute[] getAttributes() {
00157     Attribute[] attributes = new Attribute[attribute_vec.size()];
00158     attribute_vec.copyInto(attributes);
00159     return attributes;
00160   }  
00161   public String getClassName()      { return class_name; }  
00162   public int getClassNameIndex()   { return class_name_index; }  
00163   public ConstantPoolGen getConstantPool() { return cp; }  
00164   public Field[] getFields() {
00165     Field[] fields = new Field[field_vec.size()];
00166     field_vec.copyInto(fields);
00167     return fields;
00168   }  
00169   public String getFileName()       { return file_name; }  
00170   public int[] getInterfaces() {
00171     int   size       = interface_vec.size();
00172     int[] interfaces = new int[size];
00173 
00174     for(int i=0; i < size; i++)
00175       interfaces[i] = ((Int)interface_vec.elementAt(i)).value;
00176 
00177     return interfaces;
00178   }  
00179   /**
00180    * @return the (finally) built up Java class object.
00181    */
00182   public JavaClass getJavaClass() {
00183     return new JavaClass(class_name_index, superclass_name_index,
00184              file_name, MAJOR_1_1, MINOR_1_1, access_flags,
00185              cp.getFinalConstantPool(),
00186              getInterfaces(), getFields(), getMethods(), getAttributes());
00187   }  
00188   public Method[] getMethods() {
00189     Method[] methods = new Method[method_vec.size()];
00190     method_vec.copyInto(methods);
00191     return methods;
00192   }  
00193   public String getSuperclassName() { return super_class_name; }  
00194   public int getSuperclassNameIndex() { return superclass_name_index; }  
00195   /**
00196    * Remove an attribute from this class.
00197    * @param a attribute to remove
00198    */
00199   public void removeAttribute(Attribute a) { attribute_vec.removeElement(a); }  
00200   /**
00201    * Remove a field to this class.
00202    * @param f field to remove
00203    */
00204   public void removeField(Field f)         { field_vec.removeElement(f); }  
00205   /**
00206    * Remove an interface from this class.
00207    * @param i interface to remove (index in constant pool)
00208    */
00209   public void removeInterface(int i) {
00210     i = interface_vec.indexOf(new Int(i));
00211     if(i >= 0)
00212       interface_vec.removeElementAt(i);
00213   }  
00214   /**
00215    * Remove a method from this class.
00216    * @param m method to remove
00217    */
00218   public void removeMethod(Method m)       { method_vec.removeElement(m); }  
00219   public void setClassNameIndex(int class_name_index) {
00220     this.class_name_index = class_name_index;
00221   }  
00222   public void setConstantPool(ConstantPoolGen constant_pool) {
00223     cp = constant_pool;
00224   }  
00225   public void setMethods(Method[] methods) {
00226     method_vec.removeAllElements();
00227     for (int m=0; m<methods.length; m++)
00228       addMethod(methods[m]);
00229   }  
00230   public void setSuperclassNameIndex(int superclass_name_index) {
00231     this.superclass_name_index = superclass_name_index;
00232   }  
00233 }

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