KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > bcel > internal > generic > ClassGen


1 package com.sun.org.apache.bcel.internal.generic;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache BCEL" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache BCEL", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import com.sun.org.apache.bcel.internal.Constants;
58 import com.sun.org.apache.bcel.internal.classfile.*;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Iterator JavaDoc;
61
62 /**
63  * Template class for building up a java class. May be initialized with an
64  * existing java class (file).
65  *
66  * @see JavaClass
67  * @version $Id: ClassGen.java,v 1.1.1.1 2001/10/29 20:00:07 jvanzyl Exp $
68  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
69  */

70 public class ClassGen extends AccessFlags implements Cloneable JavaDoc {
71   /* Corresponds to the fields found in a JavaClass object.
72    */

73   private String JavaDoc class_name, super_class_name, file_name;
74   private int class_name_index = -1, superclass_name_index = -1;
75   private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
76
77   private ConstantPoolGen cp; // Template for building up constant pool
78

79   // ArrayLists instead of arrays to gather fields, methods, etc.
80
private ArrayList JavaDoc field_vec = new ArrayList JavaDoc();
81   private ArrayList JavaDoc method_vec = new ArrayList JavaDoc();
82   private ArrayList JavaDoc attribute_vec = new ArrayList JavaDoc();
83   private ArrayList JavaDoc interface_vec = new ArrayList JavaDoc();
84
85   /** Convenience constructor to set up some important values initially.
86    *
87    * @param class_name fully qualified class name
88    * @param super_class_name fully qualified superclass name
89    * @param file_name source file name
90    * @param access_flags access qualifiers
91    * @param interfaces implemented interfaces
92    */

93   public ClassGen(String JavaDoc class_name, String JavaDoc super_class_name, String JavaDoc file_name,
94           int access_flags, String JavaDoc[] interfaces) {
95     this.class_name = class_name;
96     this.super_class_name = super_class_name;
97     this.file_name = file_name;
98     this.access_flags = access_flags;
99     cp = new ConstantPoolGen(); // Create empty constant pool
100

101     // Put everything needed by default into the constant pool and the vectors
102
addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
103                 cp.addUtf8(file_name), cp.getConstantPool()));
104     class_name_index = cp.addClass(class_name);
105     superclass_name_index = cp.addClass(super_class_name);
106
107     if(interfaces != null)
108       for(int i=0; i < interfaces.length; i++)
109     addInterface(interfaces[i]);
110   }
111
112   /**
113    * Initialize with existing class.
114    * @param clazz JavaClass object (e.g. read from file)
115    */

116   public ClassGen(JavaClass clazz) {
117     class_name_index = clazz.getClassNameIndex();
118     superclass_name_index = clazz.getSuperclassNameIndex();
119     class_name = clazz.getClassName();
120     super_class_name = clazz.getSuperclassName();
121     file_name = clazz.getSourceFileName();
122     access_flags = clazz.getAccessFlags();
123     cp = new ConstantPoolGen(clazz.getConstantPool());
124     major = clazz.getMajor();
125     minor = clazz.getMinor();
126
127     Attribute[] attributes = clazz.getAttributes();
128     Method[] methods = clazz.getMethods();
129     Field[] fields = clazz.getFields();
130     String JavaDoc[] interfaces = clazz.getInterfaceNames();
131     
132     for(int i=0; i < interfaces.length; i++)
133       addInterface(interfaces[i]);
134
135     for(int i=0; i < attributes.length; i++)
136       addAttribute(attributes[i]);
137
138     for(int i=0; i < methods.length; i++)
139       addMethod(methods[i]);
140
141     for(int i=0; i < fields.length; i++)
142       addField(fields[i]);
143   }
144
145   /**
146    * @return the (finally) built up Java class object.
147    */

148   public JavaClass getJavaClass() {
149     int[] interfaces = getInterfaces();
150     Field[] fields = getFields();
151     Method[] methods = getMethods();
152     Attribute[] attributes = getAttributes();
153
154     // Must be last since the above calls may still add something to it
155
ConstantPool cp = this.cp.getFinalConstantPool();
156     
157     return new JavaClass(class_name_index, superclass_name_index,
158              file_name, major, minor, access_flags,
159              cp, interfaces, fields, methods, attributes);
160   }
161
162   /**
163    * Add an interface to this class, i.e., this class has to implement it.
164    * @param name interface to implement (fully qualified class name)
165    */

166   public void addInterface(String JavaDoc name) {
167     interface_vec.add(name);
168   }
169
170   /**
171    * Remove an interface from this class.
172    * @param name interface to remove (fully qualified name)
173    */

174   public void removeInterface(String JavaDoc name) {
175     interface_vec.remove(name);
176   }
177
178   /**
179    * @return major version number of class file
180    */

181   public int getMajor() { return major; }
182
183   /** Set major version number of class file, default value is 45 (JDK 1.1)
184    * @param major major version number
185    */

186   public void setMajor(int major) {
187     this.major = major;
188   }
189
190   /** Set minor version number of class file, default value is 3 (JDK 1.1)
191    * @param minor minor version number
192    */

193   public void setMinor(int minor) {
194     this.minor = minor;
195   }
196
197   /**
198    * @return minor version number of class file
199    */

200   public int getMinor() { return minor; }
201
202   /**
203    * Add an attribute to this class.
204    * @param a attribute to add
205    */

206   public void addAttribute(Attribute a) { attribute_vec.add(a); }
207
208   /**
209    * Add a method to this class.
210    * @param m method to add
211    */

212   public void addMethod(Method m) { method_vec.add(m); }
213
214   /**
215    * Convenience method.
216    *
217    * Add an empty constructor to this class that does nothing but calling super().
218    * @param access rights for constructor
219    */

220   public void addEmptyConstructor(int access_flags) {
221     InstructionList il = new InstructionList();
222     il.append(InstructionConstants.THIS); // Push `this'
223
il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
224                         "<init>", "()V")));
225     il.append(InstructionConstants.RETURN);
226
227     MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
228                "<init>", class_name, il, cp);
229     mg.setMaxStack(1);
230     addMethod(mg.getMethod());
231   }
232
233   /**
234    * Add a field to this class.
235    * @param f field to add
236    */

237   public void addField(Field f) { field_vec.add(f); }
238
239   public boolean containsField(Field f) { return field_vec.contains(f); }
240   
241   /** @return field object with given name, or null
242    */

243   public Field containsField(String JavaDoc name) {
244     for(Iterator JavaDoc e=field_vec.iterator(); e.hasNext(); ) {
245       Field f = (Field)e.next();
246       if(f.getName().equals(name))
247     return f;
248     }
249
250     return null;
251   }
252
253   /** @return method object with given name and signature, or null
254    */

255   public Method containsMethod(String JavaDoc name, String JavaDoc signature) {
256     for(Iterator JavaDoc e=method_vec.iterator(); e.hasNext();) {
257       Method m = (Method)e.next();
258       if(m.getName().equals(name) && m.getSignature().equals(signature))
259     return m;
260     }
261
262     return null;
263   }
264
265   /**
266    * Remove an attribute from this class.
267    * @param a attribute to remove
268    */

269   public void removeAttribute(Attribute a) { attribute_vec.remove(a); }
270
271   /**
272    * Remove a method from this class.
273    * @param m method to remove
274    */

275   public void removeMethod(Method m) { method_vec.remove(m); }
276
277   /** Replace given method with new one. If the old one does not exist
278    * add the new_ method to the class anyway.
279    */

280   public void replaceMethod(Method old, Method new_) {
281     if(new_ == null)
282       throw new ClassGenException("Replacement method must not be null");
283
284     int i = method_vec.indexOf(old);
285
286     if(i < 0)
287       method_vec.add(new_);
288     else
289       method_vec.set(i, new_);
290   }
291
292   /** Replace given field with new one. If the old one does not exist
293    * add the new_ field to the class anyway.
294    */

295   public void replaceField(Field old, Field new_) {
296     if(new_ == null)
297       throw new ClassGenException("Replacement method must not be null");
298
299     int i = field_vec.indexOf(old);
300
301     if(i < 0)
302       field_vec.add(new_);
303     else
304       field_vec.set(i, new_);
305   }
306
307   /**
308    * Remove a field to this class.
309    * @param f field to remove
310    */

311   public void removeField(Field f) { field_vec.remove(f); }
312
313   public String JavaDoc getClassName() { return class_name; }
314   public String JavaDoc getSuperclassName() { return super_class_name; }
315   public String JavaDoc getFileName() { return file_name; }
316
317   public void setClassName(String JavaDoc name) {
318     class_name = name.replace('/', '.');
319     class_name_index = cp.addClass(name);
320   }
321
322   public void setSuperclassName(String JavaDoc name) {
323     super_class_name = name.replace('/', '.');
324     superclass_name_index = cp.addClass(name);
325   }
326
327   public Method[] getMethods() {
328     Method[] methods = new Method[method_vec.size()];
329     method_vec.toArray(methods);
330     return methods;
331   }
332
333   public void setMethods(Method[] methods) {
334     method_vec.clear();
335     for(int m=0; m<methods.length; m++)
336       addMethod(methods[m]);
337   }
338
339   public void setMethodAt(Method method, int pos) {
340     method_vec.set(pos, method);
341   }
342
343   public Method getMethodAt(int pos) {
344     return (Method)method_vec.get(pos);
345   }
346
347   public String JavaDoc[] getInterfaceNames() {
348     int size = interface_vec.size();
349     String JavaDoc[] interfaces = new String JavaDoc[size];
350
351     interface_vec.toArray(interfaces);
352     return interfaces;
353   }
354
355   public int[] getInterfaces() {
356     int size = interface_vec.size();
357     int[] interfaces = new int[size];
358
359     for(int i=0; i < size; i++)
360       interfaces[i] = cp.addClass((String JavaDoc)interface_vec.get(i));
361
362     return interfaces;
363   }
364
365   public Field[] getFields() {
366     Field[] fields = new Field[field_vec.size()];
367     field_vec.toArray(fields);
368     return fields;
369   }
370
371   public Attribute[] getAttributes() {
372     Attribute[] attributes = new Attribute[attribute_vec.size()];
373     attribute_vec.toArray(attributes);
374     return attributes;
375   }
376
377   public ConstantPoolGen getConstantPool() { return cp; }
378   public void setConstantPool(ConstantPoolGen constant_pool) {
379     cp = constant_pool;
380   }
381
382   public void setClassNameIndex(int class_name_index) {
383     this.class_name_index = class_name_index;
384     class_name = cp.getConstantPool().
385       getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
386   }
387
388   public void setSuperclassNameIndex(int superclass_name_index) {
389     this.superclass_name_index = superclass_name_index;
390     super_class_name = cp.getConstantPool().
391       getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
392   }
393
394   public int getSuperclassNameIndex() { return superclass_name_index; }
395
396   public int getClassNameIndex() { return class_name_index; }
397
398   private ArrayList JavaDoc observers;
399
400   /** Add observer for this object.
401    */

402   public void addObserver(ClassObserver o) {
403     if(observers == null)
404       observers = new ArrayList JavaDoc();
405
406     observers.add(o);
407   }
408
409   /** Remove observer for this object.
410    */

411   public void removeObserver(ClassObserver o) {
412     if(observers != null)
413       observers.remove(o);
414   }
415
416   /** Call notify() method on all observers. This method is not called
417    * automatically whenever the state has changed, but has to be
418    * called by the user after he has finished editing the object.
419    */

420   public void update() {
421     if(observers != null)
422       for(Iterator JavaDoc e = observers.iterator(); e.hasNext(); )
423     ((ClassObserver)e.next()).notify(this);
424   }
425
426   public Object JavaDoc clone() {
427     try {
428       return super.clone();
429     } catch(CloneNotSupportedException JavaDoc e) {
430       System.err.println(e);
431       return null;
432     }
433   }
434 }
435
Popular Tags