- package com.sun.org.apache.bcel.internal.generic;
 - /* ====================================================================
 - * The Apache Software License, Version 1.1
 - *
 - * Copyright (c) 2001 The Apache Software Foundation. All rights
 - * reserved.
 - *
 - * Redistribution and use in source and binary forms, with or without
 - * modification, are permitted provided that the following conditions
 - * are met:
 - *
 - * 1. Redistributions of source code must retain the above copyright
 - * notice, this list of conditions and the following disclaimer.
 - *
 - * 2. Redistributions in binary form must reproduce the above copyright
 - * notice, this list of conditions and the following disclaimer in
 - * the documentation and/or other materials provided with the
 - * distribution.
 - *
 - * 3. The end-user documentation included with the redistribution,
 - * if any, must include the following acknowledgment:
 - * "This product includes software developed by the
 - * Apache Software Foundation (http://www.apache.org/)."
 - * Alternately, this acknowledgment may appear in the software itself,
 - * if and wherever such third-party acknowledgments normally appear.
 - *
 - * 4. The names "Apache" and "Apache Software Foundation" and
 - * "Apache BCEL" must not be used to endorse or promote products
 - * derived from this software without prior written permission. For
 - * written permission, please contact apache@apache.org.
 - *
 - * 5. Products derived from this software may not be called "Apache",
 - * "Apache BCEL", nor may "Apache" appear in their name, without
 - * prior written permission of the Apache Software Foundation.
 - *
 - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 - * SUCH DAMAGE.
 - * ====================================================================
 - *
 - * This software consists of voluntary contributions made by many
 - * individuals on behalf of the Apache Software Foundation. For more
 - * information on the Apache Software Foundation, please see
 - * <http://www.apache.org/>.
 - */
 - import com.sun.org.apache.bcel.internal.Constants;
 - import com.sun.org.apache.bcel.internal.classfile.*;
 - import java.util.ArrayList;
 - import java.util.Iterator;
 - /**
 - * Template class for building up a java class. May be initialized with an
 - * existing java class (file).
 - *
 - * @see JavaClass
 - * @version $Id: ClassGen.java,v 1.1.1.1 2001/10/29 20:00:07 jvanzyl Exp $
 - * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
 - */
 - public class ClassGen extends AccessFlags implements Cloneable {
 - /* Corresponds to the fields found in a JavaClass object.
 - */
 - private String class_name, super_class_name, file_name;
 - private int class_name_index = -1, superclass_name_index = -1;
 - private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
 - private ConstantPoolGen cp; // Template for building up constant pool
 - // ArrayLists instead of arrays to gather fields, methods, etc.
 - private ArrayList field_vec = new ArrayList();
 - private ArrayList method_vec = new ArrayList();
 - private ArrayList attribute_vec = new ArrayList();
 - private ArrayList interface_vec = new ArrayList();
 - /** Convenience constructor to set up some important values initially.
 - *
 - * @param class_name fully qualified class name
 - * @param super_class_name fully qualified superclass name
 - * @param file_name source file name
 - * @param access_flags access qualifiers
 - * @param interfaces implemented interfaces
 - */
 - public ClassGen(String class_name, String super_class_name, String file_name,
 - int access_flags, String[] interfaces) {
 - this.class_name = class_name;
 - this.super_class_name = super_class_name;
 - this.file_name = file_name;
 - this.access_flags = access_flags;
 - cp = new ConstantPoolGen(); // Create empty constant pool
 - // Put everything needed by default into the constant pool and the vectors
 - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
 - cp.addUtf8(file_name), cp.getConstantPool()));
 - class_name_index = cp.addClass(class_name);
 - superclass_name_index = cp.addClass(super_class_name);
 - if(interfaces != null)
 - for(int i=0; i < interfaces.length; i++)
 - addInterface(interfaces[i]);
 - }
 - /**
 - * Initialize with existing class.
 - * @param clazz JavaClass object (e.g. read from file)
 - */
 - public ClassGen(JavaClass clazz) {
 - class_name_index = clazz.getClassNameIndex();
 - superclass_name_index = clazz.getSuperclassNameIndex();
 - class_name = clazz.getClassName();
 - super_class_name = clazz.getSuperclassName();
 - file_name = clazz.getSourceFileName();
 - access_flags = clazz.getAccessFlags();
 - cp = new ConstantPoolGen(clazz.getConstantPool());
 - major = clazz.getMajor();
 - minor = clazz.getMinor();
 - Attribute[] attributes = clazz.getAttributes();
 - Method[] methods = clazz.getMethods();
 - Field[] fields = clazz.getFields();
 - String[] interfaces = clazz.getInterfaceNames();
 - for(int i=0; i < interfaces.length; i++)
 - addInterface(interfaces[i]);
 - for(int i=0; i < attributes.length; i++)
 - addAttribute(attributes[i]);
 - for(int i=0; i < methods.length; i++)
 - addMethod(methods[i]);
 - for(int i=0; i < fields.length; i++)
 - addField(fields[i]);
 - }
 - /**
 - * @return the (finally) built up Java class object.
 - */
 - public JavaClass getJavaClass() {
 - int[] interfaces = getInterfaces();
 - Field[] fields = getFields();
 - Method[] methods = getMethods();
 - Attribute[] attributes = getAttributes();
 - // Must be last since the above calls may still add something to it
 - ConstantPool cp = this.cp.getFinalConstantPool();
 - return new JavaClass(class_name_index, superclass_name_index,
 - file_name, major, minor, access_flags,
 - cp, interfaces, fields, methods, attributes);
 - }
 - /**
 - * Add an interface to this class, i.e., this class has to implement it.
 - * @param name interface to implement (fully qualified class name)
 - */
 - public void addInterface(String name) {
 - interface_vec.add(name);
 - }
 - /**
 - * Remove an interface from this class.
 - * @param name interface to remove (fully qualified name)
 - */
 - public void removeInterface(String name) {
 - interface_vec.remove(name);
 - }
 - /**
 - * @return major version number of class file
 - */
 - public int getMajor() { return major; }
 - /** Set major version number of class file, default value is 45 (JDK 1.1)
 - * @param major major version number
 - */
 - public void setMajor(int major) {
 - this.major = major;
 - }
 - /** Set minor version number of class file, default value is 3 (JDK 1.1)
 - * @param minor minor version number
 - */
 - public void setMinor(int minor) {
 - this.minor = minor;
 - }
 - /**
 - * @return minor version number of class file
 - */
 - public int getMinor() { return minor; }
 - /**
 - * Add an attribute to this class.
 - * @param a attribute to add
 - */
 - public void addAttribute(Attribute a) { attribute_vec.add(a); }
 - /**
 - * Add a method to this class.
 - * @param m method to add
 - */
 - public void addMethod(Method m) { method_vec.add(m); }
 - /**
 - * Convenience method.
 - *
 - * Add an empty constructor to this class that does nothing but calling super().
 - * @param access rights for constructor
 - */
 - public void addEmptyConstructor(int access_flags) {
 - InstructionList il = new InstructionList();
 - il.append(InstructionConstants.THIS); // Push `this'
 - il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
 - "<init>", "()V")));
 - il.append(InstructionConstants.RETURN);
 - MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
 - "<init>", class_name, il, cp);
 - mg.setMaxStack(1);
 - addMethod(mg.getMethod());
 - }
 - /**
 - * Add a field to this class.
 - * @param f field to add
 - */
 - public void addField(Field f) { field_vec.add(f); }
 - public boolean containsField(Field f) { return field_vec.contains(f); }
 - /** @return field object with given name, or null
 - */
 - public Field containsField(String name) {
 - for(Iterator e=field_vec.iterator(); e.hasNext(); ) {
 - Field f = (Field)e.next();
 - if(f.getName().equals(name))
 - return f;
 - }
 - return null;
 - }
 - /** @return method object with given name and signature, or null
 - */
 - public Method containsMethod(String name, String signature) {
 - for(Iterator e=method_vec.iterator(); e.hasNext();) {
 - Method m = (Method)e.next();
 - if(m.getName().equals(name) && m.getSignature().equals(signature))
 - return m;
 - }
 - return null;
 - }
 - /**
 - * Remove an attribute from this class.
 - * @param a attribute to remove
 - */
 - public void removeAttribute(Attribute a) { attribute_vec.remove(a); }
 - /**
 - * Remove a method from this class.
 - * @param m method to remove
 - */
 - public void removeMethod(Method m) { method_vec.remove(m); }
 - /** Replace given method with new one. If the old one does not exist
 - * add the new_ method to the class anyway.
 - */
 - public void replaceMethod(Method old, Method new_) {
 - if(new_ == null)
 - throw new ClassGenException("Replacement method must not be null");
 - int i = method_vec.indexOf(old);
 - if(i < 0)
 - method_vec.add(new_);
 - else
 - method_vec.set(i, new_);
 - }
 - /** Replace given field with new one. If the old one does not exist
 - * add the new_ field to the class anyway.
 - */
 - public void replaceField(Field old, Field new_) {
 - if(new_ == null)
 - throw new ClassGenException("Replacement method must not be null");
 - int i = field_vec.indexOf(old);
 - if(i < 0)
 - field_vec.add(new_);
 - else
 - field_vec.set(i, new_);
 - }
 - /**
 - * Remove a field to this class.
 - * @param f field to remove
 - */
 - public void removeField(Field f) { field_vec.remove(f); }
 - public String getClassName() { return class_name; }
 - public String getSuperclassName() { return super_class_name; }
 - public String getFileName() { return file_name; }
 - public void setClassName(String name) {
 - class_name = name.replace('/', '.');
 - class_name_index = cp.addClass(name);
 - }
 - public void setSuperclassName(String name) {
 - super_class_name = name.replace('/', '.');
 - superclass_name_index = cp.addClass(name);
 - }
 - public Method[] getMethods() {
 - Method[] methods = new Method[method_vec.size()];
 - method_vec.toArray(methods);
 - return methods;
 - }
 - public void setMethods(Method[] methods) {
 - method_vec.clear();
 - for(int m=0; m<methods.length; m++)
 - addMethod(methods[m]);
 - }
 - public void setMethodAt(Method method, int pos) {
 - method_vec.set(pos, method);
 - }
 - public Method getMethodAt(int pos) {
 - return (Method)method_vec.get(pos);
 - }
 - public String[] getInterfaceNames() {
 - int size = interface_vec.size();
 - String[] interfaces = new String[size];
 - interface_vec.toArray(interfaces);
 - return interfaces;
 - }
 - public int[] getInterfaces() {
 - int size = interface_vec.size();
 - int[] interfaces = new int[size];
 - for(int i=0; i < size; i++)
 - interfaces[i] = cp.addClass((String)interface_vec.get(i));
 - return interfaces;
 - }
 - public Field[] getFields() {
 - Field[] fields = new Field[field_vec.size()];
 - field_vec.toArray(fields);
 - return fields;
 - }
 - public Attribute[] getAttributes() {
 - Attribute[] attributes = new Attribute[attribute_vec.size()];
 - attribute_vec.toArray(attributes);
 - return attributes;
 - }
 - public ConstantPoolGen getConstantPool() { return cp; }
 - public void setConstantPool(ConstantPoolGen constant_pool) {
 - cp = constant_pool;
 - }
 - public void setClassNameIndex(int class_name_index) {
 - this.class_name_index = class_name_index;
 - class_name = cp.getConstantPool().
 - getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
 - }
 - public void setSuperclassNameIndex(int superclass_name_index) {
 - this.superclass_name_index = superclass_name_index;
 - super_class_name = cp.getConstantPool().
 - getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
 - }
 - public int getSuperclassNameIndex() { return superclass_name_index; }
 - public int getClassNameIndex() { return class_name_index; }
 - private ArrayList observers;
 - /** Add observer for this object.
 - */
 - public void addObserver(ClassObserver o) {
 - if(observers == null)
 - observers = new ArrayList();
 - observers.add(o);
 - }
 - /** Remove observer for this object.
 - */
 - public void removeObserver(ClassObserver o) {
 - if(observers != null)
 - observers.remove(o);
 - }
 - /** Call notify() method on all observers. This method is not called
 - * automatically whenever the state has changed, but has to be
 - * called by the user after he has finished editing the object.
 - */
 - public void update() {
 - if(observers != null)
 - for(Iterator e = observers.iterator(); e.hasNext(); )
 - ((ClassObserver)e.next()).notify(this);
 - }
 - public Object clone() {
 - try {
 - return super.clone();
 - } catch(CloneNotSupportedException e) {
 - System.err.println(e);
 - return null;
 - }
 - }
 - }