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
00010
00011
00012
00013
00014
00015
00016 public class ClassGen extends AccessFlags implements Cloneable {
00017
00018
00019 private String class_name, super_class_name, file_name;
00020 private int class_name_index = -1, superclass_name_index = -1;
00021 private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
00022
00023 private ConstantPoolGen cp;
00024
00025
00026 private Vector field_vec = new Vector();
00027 private Vector method_vec = new Vector();
00028 private Vector attribute_vec = new Vector();
00029 private Vector interface_vec = new Vector();
00030
00031 private Vector observers;
00032
00033
00034
00035
00036
00037 public ClassGen(JavaClass clazz) {
00038 class_name_index = clazz.getClassNameIndex();
00039 superclass_name_index = clazz.getSuperclassNameIndex();
00040 class_name = clazz.getClassName();
00041 super_class_name = clazz.getSuperclassName();
00042 file_name = clazz.getSourceFileName();
00043 access_flags = clazz.getAccessFlags();
00044 cp = new ConstantPoolGen(clazz.getConstantPool());
00045 major = clazz.getMajor();
00046 minor = clazz.getMinor();
00047
00048 Attribute[] attributes = clazz.getAttributes();
00049 Method[] methods = clazz.getMethods();
00050 Field[] fields = clazz.getFields();
00051 String[] interfaces = clazz.getInterfaceNames();
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
00067
00068
00069
00070
00071
00072
00073 public ClassGen(String class_name, String super_class_name, String file_name,
00074 int access_flags, String[] interfaces) {
00075 this.class_name = class_name;
00076 this.super_class_name = super_class_name;
00077 this.file_name = file_name;
00078 this.access_flags = access_flags;
00079 cp = new ConstantPoolGen();
00080
00081
00082 addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
00083 cp.addUtf8(file_name), cp.getConstantPool()));
00084 class_name_index = cp.addClass(class_name);
00085 superclass_name_index = cp.addClass(super_class_name);
00086
00087 if(interfaces != null)
00088 for(int i=0; i < interfaces.length; i++)
00089 addInterface(interfaces[i]);
00090 }
00091
00092
00093
00094
00095 public void addAttribute(Attribute a) { attribute_vec.addElement(a); }
00096
00097
00098
00099
00100
00101
00102 public void addEmptyConstructor(int access_flags) {
00103 InstructionList il = new InstructionList();
00104 il.append(InstructionConstants.THIS);
00105 il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
00106 "<init>", "()V")));
00107 il.append(InstructionConstants.RETURN);
00108
00109 MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
00110 "<init>", class_name, il, cp);
00111 mg.setMaxStack(1);
00112 addMethod(mg.getMethod());
00113 }
00114
00115
00116
00117
00118 public void addField(Field f) { field_vec.addElement(f); }
00119
00120
00121
00122
00123 public void addInterface(String name) {
00124 interface_vec.addElement(name);
00125 }
00126
00127
00128
00129
00130 public void addMethod(Method m) { method_vec.addElement(m); }
00131
00132
00133 public void addObserver(ClassObserver o) {
00134 if(observers == null)
00135 observers = new Vector();
00136
00137 observers.add(o);
00138 }
00139 public Object clone() {
00140 try {
00141 return super.clone();
00142 } catch(CloneNotSupportedException e) {
00143 System.err.println(e);
00144 return null;
00145 }
00146 }
00147 public boolean containsField(Field f) { return field_vec.contains(f); }
00148
00149
00150 public Field containsField(String name) {
00151 for(Enumeration e=field_vec.elements(); e.hasMoreElements();) {
00152 Field f = (Field)e.nextElement();
00153 if(f.getName().equals(name))
00154 return f;
00155 }
00156
00157 return null;
00158 }
00159
00160
00161 public Method containsMethod(String name, String signature) {
00162 for(Enumeration e=method_vec.elements(); e.hasMoreElements();) {
00163 Method m = (Method)e.nextElement();
00164 if(m.getName().equals(name) && m.getSignature().equals(signature))
00165 return m;
00166 }
00167
00168 return null;
00169 }
00170 public Attribute[] getAttributes() {
00171 Attribute[] attributes = new Attribute[attribute_vec.size()];
00172 attribute_vec.copyInto(attributes);
00173 return attributes;
00174 }
00175 public String getClassName() { return class_name; }
00176 public int getClassNameIndex() { return class_name_index; }
00177 public ConstantPoolGen getConstantPool() { return cp; }
00178 public Field[] getFields() {
00179 Field[] fields = new Field[field_vec.size()];
00180 field_vec.copyInto(fields);
00181 return fields;
00182 }
00183 public String getFileName() { return file_name; }
00184 public String[] getInterfaceNames() {
00185 int size = interface_vec.size();
00186 String[] interfaces = new String[size];
00187
00188 interface_vec.toArray(interfaces);
00189 return interfaces;
00190 }
00191 public int[] getInterfaces() {
00192 int size = interface_vec.size();
00193 int[] interfaces = new int[size];
00194
00195 for(int i=0; i < size; i++)
00196 interfaces[i] = cp.addClass((String)interface_vec.elementAt(i));
00197
00198 return interfaces;
00199 }
00200
00201
00202
00203 public JavaClass getJavaClass() {
00204 int[] interfaces = getInterfaces();
00205 Field[] fields = getFields();
00206 Method[] methods = getMethods();
00207 Attribute[] attributes = getAttributes();
00208
00209
00210 ConstantPool cp = this.cp.getFinalConstantPool();
00211
00212 return new JavaClass(class_name_index, superclass_name_index,
00213 file_name, major, minor, access_flags,
00214 cp, interfaces, fields, methods, attributes);
00215 }
00216
00217
00218
00219 public int getMajor() { return major; }
00220 public Method getMethodAt(int pos) {
00221 return (Method)method_vec.elementAt(pos);
00222 }
00223 public Method[] getMethods() {
00224 Method[] methods = new Method[method_vec.size()];
00225 method_vec.copyInto(methods);
00226 return methods;
00227 }
00228
00229
00230
00231 public int getMinor() { return minor; }
00232 public String getSuperclassName() { return super_class_name; }
00233 public int getSuperclassNameIndex() { return superclass_name_index; }
00234
00235
00236
00237
00238 public void removeAttribute(Attribute a) { attribute_vec.removeElement(a); }
00239
00240
00241
00242
00243 public void removeField(Field f) { field_vec.removeElement(f); }
00244
00245
00246
00247
00248 public void removeInterface(String name) {
00249 interface_vec.remove(name);
00250 }
00251
00252
00253
00254
00255 public void removeMethod(Method m) { method_vec.removeElement(m); }
00256
00257
00258 public void removeObserver(ClassObserver o) {
00259 if(observers != null)
00260 observers.removeElement(o);
00261 }
00262
00263
00264
00265 public void replaceField(Field old, Field new_) {
00266 if(new_ == null)
00267 throw new ClassGenException("Replacement method must not be null");
00268
00269 int i = field_vec.indexOf(old);
00270
00271 if(i < 0)
00272 field_vec.addElement(new_);
00273 else
00274 field_vec.setElementAt(new_, i);
00275 }
00276
00277
00278
00279 public void replaceMethod(Method old, Method new_) {
00280 if(new_ == null)
00281 throw new ClassGenException("Replacement method must not be null");
00282
00283 int i = method_vec.indexOf(old);
00284
00285 if(i < 0)
00286 method_vec.addElement(new_);
00287 else
00288 method_vec.setElementAt(new_, i);
00289 }
00290 public void setClassName(String name) {
00291 class_name = name.replace('/', '.');
00292 class_name_index = cp.addClass(name);
00293 }
00294 public void setClassNameIndex(int class_name_index) {
00295 this.class_name_index = class_name_index;
00296 class_name = cp.getConstantPool().
00297 getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
00298 }
00299 public void setConstantPool(ConstantPoolGen constant_pool) {
00300 cp = constant_pool;
00301 }
00302
00303
00304
00305 public void setMajor(int major) {
00306 this.major = major;
00307 }
00308 public void setMethodAt(Method method, int pos) {
00309 method_vec.setElementAt(method, pos);
00310 }
00311 public void setMethods(Method[] methods) {
00312 method_vec.removeAllElements();
00313 for (int m=0; m<methods.length; m++)
00314 addMethod(methods[m]);
00315 }
00316
00317
00318
00319 public void setMinor(int minor) {
00320 this.minor = minor;
00321 }
00322 public void setSuperclassName(String name) {
00323 super_class_name = name.replace('/', '.');
00324 superclass_name_index = cp.addClass(name);
00325 }
00326 public void setSuperclassNameIndex(int superclass_name_index) {
00327 this.superclass_name_index = superclass_name_index;
00328 super_class_name = cp.getConstantPool().
00329 getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
00330 }
00331
00332
00333
00334
00335 public void update() {
00336 if(observers != null)
00337 for(Enumeration e = observers.elements(); e.hasMoreElements(); )
00338 ((ClassObserver)e.nextElement()).notify(this);
00339 }
00340 }