< prev index next >
src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java
Print this page
*** 16,418 ****
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.sun.org.apache.bcel.internal.generic;
-
- 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
! * @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
* @param cp constant pool to use
*/
! public ClassGen(String class_name, String super_class_name, String file_name,
! int access_flags, String[] interfaces, ConstantPoolGen cp) {
this.class_name = class_name;
this.super_class_name = super_class_name;
this.file_name = file_name;
- this.access_flags = access_flags;
this.cp = cp;
-
// Put everything needed by default into the constant pool and the vectors
! if(file_name != null)
! 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]);
}
! /** 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, super_class_name, file_name, access_flags, interfaces,
new ConstantPoolGen());
}
/**
* 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;
}
}
}
--- 16,579 ----
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.bcel.internal.generic;
import java.util.ArrayList;
! import java.util.List;
!
! import com.sun.org.apache.bcel.internal.Const;
! import com.sun.org.apache.bcel.internal.classfile.AccessFlags;
! import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry;
! import com.sun.org.apache.bcel.internal.classfile.Annotations;
! import com.sun.org.apache.bcel.internal.classfile.Attribute;
! import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
! import com.sun.org.apache.bcel.internal.classfile.Field;
! import com.sun.org.apache.bcel.internal.classfile.JavaClass;
! import com.sun.org.apache.bcel.internal.classfile.Method;
! import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations;
! import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations;
! import com.sun.org.apache.bcel.internal.classfile.SourceFile;
! import com.sun.org.apache.bcel.internal.util.BCELComparator;
/**
* Template class for building up a java class. May be initialized with an
* existing java class (file).
*
* @see JavaClass
! * @version $Id: ClassGen.java 1749603 2016-06-21 20:50:19Z ggregory $
*/
public class ClassGen extends AccessFlags implements Cloneable {
+
/* Corresponds to the fields found in a JavaClass object.
*/
! private String class_name;
! private String super_class_name;
! private final String file_name;
! private int class_name_index = -1;
! private int superclass_name_index = -1;
! private int major = Const.MAJOR;
! private int minor = Const.MINOR;
private ConstantPoolGen cp; // Template for building up constant pool
// ArrayLists instead of arrays to gather fields, methods, etc.
! private final List<Field> field_vec = new ArrayList<>();
! private final List<Method> method_vec = new ArrayList<>();
! private final List<Attribute> attribute_vec = new ArrayList<>();
! private final List<String> interface_vec = new ArrayList<>();
! private final List<AnnotationEntryGen> annotation_vec = new ArrayList<>();
!
! private static BCELComparator _cmp = new BCELComparator() {
!
! @Override
! public boolean equals(final Object o1, final Object o2) {
! final ClassGen THIS = (ClassGen) o1;
! final ClassGen THAT = (ClassGen) o2;
! return THIS.getClassName().equals(THAT.getClassName());
! }
!
! @Override
! public int hashCode(final Object o) {
! final ClassGen THIS = (ClassGen) o;
! return THIS.getClassName().hashCode();
! }
! };
! /**
! * 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
* @param cp constant pool to use
*/
! public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags,
! final String[] interfaces, final ConstantPoolGen cp) {
! super(access_flags);
this.class_name = class_name;
this.super_class_name = super_class_name;
this.file_name = file_name;
this.cp = cp;
// Put everything needed by default into the constant pool and the vectors
! if (file_name != null) {
! 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 (final String interface1 : interfaces) {
! addInterface(interface1);
! }
! }
}
! /**
! * 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(final String class_name, final String super_class_name, final String file_name, final int access_flags,
! final String[] interfaces) {
this(class_name, super_class_name, file_name, access_flags, interfaces,
new ConstantPoolGen());
}
/**
* Initialize with existing class.
+ *
* @param clazz JavaClass object (e.g. read from file)
*/
! public ClassGen(final JavaClass clazz) {
! super(clazz.getAccessFlags());
class_name_index = clazz.getClassNameIndex();
superclass_name_index = clazz.getSuperclassNameIndex();
class_name = clazz.getClassName();
super_class_name = clazz.getSuperclassName();
file_name = clazz.getSourceFileName();
cp = new ConstantPoolGen(clazz.getConstantPool());
major = clazz.getMajor();
minor = clazz.getMinor();
+ final Attribute[] attributes = clazz.getAttributes();
+ // J5TODO: Could make unpacking lazy, done on first reference
+ final AnnotationEntryGen[] annotations = unpackAnnotations(attributes);
+ final Method[] methods = clazz.getMethods();
+ final Field[] fields = clazz.getFields();
+ final String[] interfaces = clazz.getInterfaceNames();
+ for (final String interface1 : interfaces) {
+ addInterface(interface1);
+ }
+ for (final Attribute attribute : attributes) {
+ if (!(attribute instanceof Annotations)) {
+ addAttribute(attribute);
+ }
+ }
+ for (final AnnotationEntryGen annotation : annotations) {
+ addAnnotationEntry(annotation);
+ }
+ for (final Method method : methods) {
+ addMethod(method);
+ }
+ for (final Field field : fields) {
+ addField(field);
+ }
+ }
! /**
! * Look for attributes representing annotations and unpack them.
! */
! private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs) {
! final List<AnnotationEntryGen> annotationGenObjs = new ArrayList<>();
! for (final Attribute attr : attrs) {
! if (attr instanceof RuntimeVisibleAnnotations) {
! final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr;
! final AnnotationEntry[] annos = rva.getAnnotationEntries();
! for (final AnnotationEntry a : annos) {
! annotationGenObjs.add(new AnnotationEntryGen(a,
! getConstantPool(), false));
! }
! } else if (attr instanceof RuntimeInvisibleAnnotations) {
! final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
! final AnnotationEntry[] annos = ria.getAnnotationEntries();
! for (final AnnotationEntry a : annos) {
! annotationGenObjs.add(new AnnotationEntryGen(a,
! getConstantPool(), false));
! }
! }
! }
! return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]);
}
/**
* @return the (finally) built up Java class object.
*/
public JavaClass getJavaClass() {
! final int[] interfaces = getInterfaces();
! final Field[] fields = getFields();
! final Method[] methods = getMethods();
! Attribute[] attributes;
! if (annotation_vec.isEmpty()) {
! attributes = getAttributes();
! } else {
! // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
! final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries());
! attributes = new Attribute[attribute_vec.size() + annAttributes.length];
! attribute_vec.toArray(attributes);
! System.arraycopy(annAttributes, 0, attributes, attribute_vec.size(), annAttributes.length);
! }
// Must be last since the above calls may still add something to it
! final ConstantPool _cp = this.cp.getFinalConstantPool();
! return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor,
! super.getAccessFlags(), _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 final void addInterface(final String name) {
interface_vec.add(name);
}
/**
* Remove an interface from this class.
+ *
* @param name interface to remove (fully qualified name)
*/
! public void removeInterface(final 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(final int major) { // TODO could be package-protected - only called by test code
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(final int minor) { // TODO could be package-protected - only called by test code
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 final void addAttribute(final Attribute a) {
! attribute_vec.add(a);
! }
!
! public final void addAnnotationEntry(final AnnotationEntryGen a) {
! annotation_vec.add(a);
! }
/**
* Add a method to this class.
+ *
* @param m method to add
*/
! public final void addMethod(final Method m) {
! method_vec.add(m);
! }
/**
* Convenience method.
*
! * Add an empty constructor to this class that does nothing but calling
! * super().
! *
! * @param access_flags rights for constructor
*/
! public void addEmptyConstructor(final int access_flags) {
! final InstructionList il = new InstructionList();
! il.append(InstructionConst.THIS); // Push `this'
! il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
! il.append(InstructionConst.RETURN);
! final 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 final void addField(final Field f) {
! field_vec.add(f);
! }
! public boolean containsField(final Field f) {
! return field_vec.contains(f);
! }
! /**
! * @return field object with given name, or null
*/
! public Field containsField(final String name) {
! for (final Field f : field_vec) {
! if (f.getName().equals(name)) {
return f;
}
! }
return null;
}
! /**
! * @return method object with given name and signature, or null
*/
! public Method containsMethod(final String name, final String signature) {
! for (final Method m : method_vec) {
! 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(final Attribute a) {
! attribute_vec.remove(a);
! }
/**
* Remove a method from this class.
+ *
* @param m method to remove
*/
! public void removeMethod(final 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(final Method old, final Method new_) {
! if (new_ == null) {
throw new ClassGenException("Replacement method must not be null");
! }
! final 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(final Field old, final Field new_) {
! if (new_ == null) {
throw new ClassGenException("Replacement method must not be null");
! }
! final 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(final 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(final String name) {
class_name = name.replace('/', '.');
class_name_index = cp.addClass(name);
}
! public void setSuperclassName(final String name) {
super_class_name = name.replace('/', '.');
superclass_name_index = cp.addClass(name);
}
public Method[] getMethods() {
! return method_vec.toArray(new Method[method_vec.size()]);
}
! public void setMethods(final Method[] methods) {
method_vec.clear();
! for (final Method method : methods) {
! addMethod(method);
! }
}
! public void setMethodAt(final Method method, final int pos) {
method_vec.set(pos, method);
}
! public Method getMethodAt(final int pos) {
! return method_vec.get(pos);
}
public String[] getInterfaceNames() {
! final int size = interface_vec.size();
! final String[] interfaces = new String[size];
interface_vec.toArray(interfaces);
return interfaces;
}
public int[] getInterfaces() {
! final int size = interface_vec.size();
! final int[] interfaces = new int[size];
! for (int i = 0; i < size; i++) {
! interfaces[i] = cp.addClass(interface_vec.get(i));
! }
return interfaces;
}
public Field[] getFields() {
! return field_vec.toArray(new Field[field_vec.size()]);
}
public Attribute[] getAttributes() {
! return attribute_vec.toArray(new Attribute[attribute_vec.size()]);
! }
!
! // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here?
! public AnnotationEntryGen[] getAnnotationEntries() {
! return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]);
}
! public ConstantPoolGen getConstantPool() {
! return cp;
! }
!
! public void setConstantPool(final ConstantPoolGen constant_pool) {
cp = constant_pool;
}
! public void setClassNameIndex(final int class_name_index) {
this.class_name_index = class_name_index;
! class_name = cp.getConstantPool().getConstantString(class_name_index,
! Const.CONSTANT_Class).replace('/', '.');
}
! public void setSuperclassNameIndex(final int superclass_name_index) {
this.superclass_name_index = superclass_name_index;
! super_class_name = cp.getConstantPool().getConstantString(superclass_name_index,
! Const.CONSTANT_Class).replace('/', '.');
}
! public int getSuperclassNameIndex() {
! return superclass_name_index;
! }
! public int getClassNameIndex() {
! return class_name_index;
! }
! private List<ClassObserver> observers;
! /**
! * Add observer for this object.
*/
! public void addObserver(final ClassObserver o) {
! if (observers == null) {
! observers = new ArrayList<>();
! }
observers.add(o);
}
! /**
! * Remove observer for this object.
*/
! public void removeObserver(final 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 (final ClassObserver observer : observers) {
! observer.notify(this);
! }
! }
}
+ @Override
public Object clone() {
try {
return super.clone();
! } catch (final CloneNotSupportedException e) {
! throw new Error("Clone Not Supported"); // never happens
! }
}
+
+ /**
+ * @return Comparison strategy object
+ */
+ public static BCELComparator getComparator() {
+ return _cmp;
+ }
+
+ /**
+ * @param comparator Comparison strategy object
+ */
+ public static void setComparator(final BCELComparator comparator) {
+ _cmp = comparator;
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy. By default two
+ * ClassGen objects are said to be equal when their class names are equal.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ return _cmp.equals(this, obj);
+ }
+
+ /**
+ * Return value as defined by given BCELComparator strategy. By default
+ * return the hashcode of the class name.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return _cmp.hashCode(this);
}
}
< prev index next >