< prev index next >

src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java

Print this page


   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 
  25 import com.sun.org.apache.bcel.internal.Constants;
  26 import com.sun.org.apache.bcel.internal.classfile.*;
  27 import java.util.ArrayList;
  28 import java.util.Iterator;














  29 
  30 /**
  31  * Template class for building up a java class. May be initialized with an
  32  * existing java class (file).
  33  *
  34  * @see JavaClass
  35  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  36  */
  37 public class ClassGen extends AccessFlags implements Cloneable {

  38   /* Corresponds to the fields found in a JavaClass object.
  39    */
  40   private String   class_name, super_class_name, file_name;
  41   private int      class_name_index = -1, superclass_name_index = -1;
  42   private int      major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
  43 



  44   private ConstantPoolGen cp; // Template for building up constant pool
  45 
  46   // ArrayLists instead of arrays to gather fields, methods, etc.
  47   private ArrayList   field_vec     = new ArrayList();
  48   private ArrayList   method_vec    = new ArrayList();
  49   private ArrayList   attribute_vec = new ArrayList();
  50   private ArrayList   interface_vec = new ArrayList();

















  51 
  52   /** Convenience constructor to set up some important values initially.

  53    *
  54    * @param class_name fully qualified class name
  55    * @param super_class_name fully qualified superclass name
  56    * @param file_name source file name
  57    * @param access_flags access qualifiers
  58    * @param interfaces implemented interfaces
  59    * @param cp constant pool to use
  60    */
  61   public ClassGen(String class_name, String super_class_name, String file_name,
  62                   int access_flags, String[] interfaces, ConstantPoolGen cp) {

  63     this.class_name       = class_name;
  64     this.super_class_name = super_class_name;
  65     this.file_name        = file_name;
  66     this.access_flags     = access_flags;
  67     this.cp               = cp;
  68 
  69     // Put everything needed by default into the constant pool and the vectors
  70     if(file_name != null)
  71       addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2,
  72                                   cp.addUtf8(file_name), cp.getConstantPool()));
  73 
  74     class_name_index      = cp.addClass(class_name);
  75     superclass_name_index = cp.addClass(super_class_name);
  76 
  77     if(interfaces != null)
  78       for(int i=0; i < interfaces.length; i++)
  79         addInterface(interfaces[i]);

  80   }
  81 
  82   /** Convenience constructor to set up some important values initially.

  83    *
  84    * @param class_name fully qualified class name
  85    * @param super_class_name fully qualified superclass name
  86    * @param file_name source file name
  87    * @param access_flags access qualifiers
  88    * @param interfaces implemented interfaces
  89    */
  90   public ClassGen(String class_name, String super_class_name, String file_name,
  91                   int access_flags, String[] interfaces) {
  92     this(class_name, super_class_name, file_name, access_flags, interfaces,
  93          new ConstantPoolGen());
  94   }
  95 
  96   /**
  97    * Initialize with existing class.

  98    * @param clazz JavaClass object (e.g. read from file)
  99    */
 100   public ClassGen(JavaClass clazz) {

 101     class_name_index      = clazz.getClassNameIndex();
 102     superclass_name_index = clazz.getSuperclassNameIndex();
 103     class_name            = clazz.getClassName();
 104     super_class_name      = clazz.getSuperclassName();
 105     file_name             = clazz.getSourceFileName();
 106     access_flags          = clazz.getAccessFlags();
 107     cp                    = new ConstantPoolGen(clazz.getConstantPool());
 108     major                 = clazz.getMajor();
 109     minor                 = clazz.getMinor();
























 110 
 111     Attribute[] attributes = clazz.getAttributes();
 112     Method[]    methods    = clazz.getMethods();
 113     Field[]     fields     = clazz.getFields();
 114     String[]    interfaces = clazz.getInterfaceNames();
 115 
 116     for(int i=0; i < interfaces.length; i++)
 117       addInterface(interfaces[i]);
 118 
 119     for(int i=0; i < attributes.length; i++)
 120       addAttribute(attributes[i]);
 121 
 122     for(int i=0; i < methods.length; i++)
 123       addMethod(methods[i]);
 124 
 125     for(int i=0; i < fields.length; i++)
 126       addField(fields[i]);







 127   }
 128 
 129   /**
 130    * @return the (finally) built up Java class object.
 131    */
 132   public JavaClass getJavaClass() {
 133     int[]        interfaces = getInterfaces();
 134     Field[]      fields     = getFields();
 135     Method[]     methods    = getMethods();
 136     Attribute[]  attributes = getAttributes();
 137 








 138     // Must be last since the above calls may still add something to it
 139     ConstantPool cp         = this.cp.getFinalConstantPool();
 140 
 141     return new JavaClass(class_name_index, superclass_name_index,
 142                          file_name, major, minor, access_flags,
 143                          cp, interfaces, fields, methods, attributes);
 144   }
 145 
 146   /**
 147    * Add an interface to this class, i.e., this class has to implement it.

 148    * @param name interface to implement (fully qualified class name)
 149    */
 150   public void addInterface(String name) {
 151     interface_vec.add(name);
 152   }
 153 
 154   /**
 155    * Remove an interface from this class.

 156    * @param name interface to remove (fully qualified name)
 157    */
 158   public void removeInterface(String name) {
 159     interface_vec.remove(name);
 160   }
 161 
 162   /**
 163    * @return major version number of class file
 164    */
 165   public int  getMajor()      { return major; }


 166 
 167   /** Set major version number of class file, default value is 45 (JDK 1.1)


 168    * @param major major version number
 169    */
 170   public void setMajor(int major) {
 171     this.major = major;
 172   }
 173 
 174   /** Set minor version number of class file, default value is 3 (JDK 1.1)


 175    * @param minor minor version number
 176    */
 177   public void setMinor(int minor) {
 178     this.minor = minor;
 179   }
 180 
 181   /**
 182    * @return minor version number of class file
 183    */
 184   public int  getMinor()      { return minor; }


 185 
 186   /**
 187    * Add an attribute to this class.

 188    * @param a attribute to add
 189    */
 190   public void addAttribute(Attribute a)    { attribute_vec.add(a); }






 191 
 192   /**
 193    * Add a method to this class.

 194    * @param m method to add
 195    */
 196   public void addMethod(Method m)          { method_vec.add(m); }


 197 
 198   /**
 199    * Convenience method.
 200    *
 201    * Add an empty constructor to this class that does nothing but calling super().
 202    * @param access rights for constructor


 203    */
 204   public void addEmptyConstructor(int access_flags) {
 205     InstructionList il = new InstructionList();
 206     il.append(InstructionConstants.THIS); // Push `this'
 207     il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name,
 208                                                 "<init>", "()V")));
 209     il.append(InstructionConstants.RETURN);
 210 
 211     MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null,
 212                        "<init>", class_name, il, cp);
 213     mg.setMaxStack(1);
 214     addMethod(mg.getMethod());
 215   }
 216 
 217   /**
 218    * Add a field to this class.

 219    * @param f field to add
 220    */
 221   public void addField(Field f)            { field_vec.add(f); }


 222 
 223   public boolean containsField(Field f)    { return field_vec.contains(f); }


 224 
 225   /** @return field object with given name, or null

 226    */
 227   public Field containsField(String name) {
 228     for(Iterator e=field_vec.iterator(); e.hasNext(); ) {
 229       Field f = (Field)e.next();
 230       if(f.getName().equals(name))
 231         return f;
 232     }
 233 
 234     return null;
 235   }
 236 
 237   /** @return method object with given name and signature, or null

 238    */
 239   public Method containsMethod(String name, String signature) {
 240     for(Iterator e=method_vec.iterator(); e.hasNext();) {
 241       Method m = (Method)e.next();
 242       if(m.getName().equals(name) && m.getSignature().equals(signature))
 243         return m;
 244     }
 245 
 246     return null;
 247   }
 248 
 249   /**
 250    * Remove an attribute from this class.

 251    * @param a attribute to remove
 252    */
 253   public void removeAttribute(Attribute a) { attribute_vec.remove(a); }


 254 
 255   /**
 256    * Remove a method from this class.

 257    * @param m method to remove
 258    */
 259   public void removeMethod(Method m)       { method_vec.remove(m); }


 260 
 261   /** Replace given method with new one. If the old one does not exist
 262    * add the new_ method to the class anyway.

 263    */
 264   public void replaceMethod(Method old, Method new_) {
 265     if(new_ == null)
 266       throw new ClassGenException("Replacement method must not be null");
 267 
 268     int i = method_vec.indexOf(old);
 269 
 270     if(i < 0)
 271       method_vec.add(new_);
 272     else
 273       method_vec.set(i, new_);
 274   }

 275 
 276   /** Replace given field with new one. If the old one does not exist
 277    * add the new_ field to the class anyway.

 278    */
 279   public void replaceField(Field old, Field new_) {
 280     if(new_ == null)
 281       throw new ClassGenException("Replacement method must not be null");
 282 
 283     int i = field_vec.indexOf(old);
 284 
 285     if(i < 0)
 286       field_vec.add(new_);
 287     else
 288       field_vec.set(i, new_);
 289   }

 290 
 291   /**
 292    * Remove a field to this class.

 293    * @param f field to remove
 294    */
 295   public void removeField(Field f)         { field_vec.remove(f); }






 296 
 297   public String getClassName()      { return class_name; }
 298   public String getSuperclassName() { return super_class_name; }
 299   public String getFileName()       { return file_name; }




 300 
 301   public void setClassName(String name) {
 302     class_name = name.replace('/', '.');
 303     class_name_index = cp.addClass(name);
 304   }
 305 
 306   public void setSuperclassName(String name) {
 307     super_class_name = name.replace('/', '.');
 308     superclass_name_index = cp.addClass(name);
 309   }
 310 
 311   public Method[] getMethods() {
 312     Method[] methods = new Method[method_vec.size()];
 313     method_vec.toArray(methods);
 314     return methods;
 315   }
 316 
 317   public void setMethods(Method[] methods) {
 318     method_vec.clear();
 319     for(int m=0; m<methods.length; m++)
 320       addMethod(methods[m]);

 321   }
 322 
 323   public void setMethodAt(Method method, int pos) {
 324     method_vec.set(pos, method);
 325   }
 326 
 327   public Method getMethodAt(int pos) {
 328     return (Method)method_vec.get(pos);
 329   }
 330 
 331   public String[] getInterfaceNames() {
 332     int      size = interface_vec.size();
 333     String[] interfaces = new String[size];
 334 
 335     interface_vec.toArray(interfaces);
 336     return interfaces;
 337   }
 338 
 339   public int[] getInterfaces() {
 340     int   size = interface_vec.size();
 341     int[] interfaces = new int[size];
 342 
 343     for(int i=0; i < size; i++)
 344       interfaces[i] = cp.addClass((String)interface_vec.get(i));
 345 
 346     return interfaces;
 347   }
 348 
 349   public Field[] getFields() {
 350     Field[] fields = new Field[field_vec.size()];
 351     field_vec.toArray(fields);
 352     return fields;
 353   }
 354 
 355   public Attribute[] getAttributes() {
 356     Attribute[] attributes = new Attribute[attribute_vec.size()];
 357     attribute_vec.toArray(attributes);
 358     return attributes;



 359   }
 360 
 361   public ConstantPoolGen getConstantPool() { return cp; }
 362   public void setConstantPool(ConstantPoolGen constant_pool) {



 363     cp = constant_pool;
 364   }
 365 
 366   public void setClassNameIndex(int class_name_index) {
 367     this.class_name_index = class_name_index;
 368     class_name = cp.getConstantPool().
 369       getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
 370   }
 371 
 372   public void setSuperclassNameIndex(int superclass_name_index) {
 373     this.superclass_name_index = superclass_name_index;
 374     super_class_name = cp.getConstantPool().
 375       getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
 376   }
 377 
 378   public int getSuperclassNameIndex() { return superclass_name_index; }


 379 
 380   public int getClassNameIndex()   { return class_name_index; }


 381 
 382   private ArrayList observers;
 383 
 384   /** Add observer for this object.

 385    */
 386   public void addObserver(ClassObserver o) {
 387     if(observers == null)
 388       observers = new ArrayList();
 389 
 390     observers.add(o);
 391   }
 392 
 393   /** Remove observer for this object.

 394    */
 395   public void removeObserver(ClassObserver o) {
 396     if(observers != null)
 397       observers.remove(o);
 398   }

 399 
 400   /** Call notify() method on all observers. This method is not called
 401    * automatically whenever the state has changed, but has to be
 402    * called by the user after he has finished editing the object.

 403    */
 404   public void update() {
 405     if(observers != null)
 406       for(Iterator e = observers.iterator(); e.hasNext(); )
 407         ((ClassObserver)e.next()).notify(this);


 408   }
 409 

 410   public Object clone() {
 411     try {
 412       return super.clone();
 413     } catch(CloneNotSupportedException e) {
 414       System.err.println(e);
 415       return null;
 416     }



































 417   }
 418 }
   1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */

  21 package com.sun.org.apache.bcel.internal.generic;
  22 



  23 import java.util.ArrayList;
  24 import java.util.List;
  25 
  26 import com.sun.org.apache.bcel.internal.Const;
  27 import com.sun.org.apache.bcel.internal.classfile.AccessFlags;
  28 import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry;
  29 import com.sun.org.apache.bcel.internal.classfile.Annotations;
  30 import com.sun.org.apache.bcel.internal.classfile.Attribute;
  31 import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
  32 import com.sun.org.apache.bcel.internal.classfile.Field;
  33 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
  34 import com.sun.org.apache.bcel.internal.classfile.Method;
  35 import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations;
  36 import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations;
  37 import com.sun.org.apache.bcel.internal.classfile.SourceFile;
  38 import com.sun.org.apache.bcel.internal.util.BCELComparator;
  39 
  40 /**
  41  * Template class for building up a java class. May be initialized with an
  42  * existing java class (file).
  43  *
  44  * @see JavaClass
  45  * @version $Id: ClassGen.java 1749603 2016-06-21 20:50:19Z ggregory $
  46  */
  47 public class ClassGen extends AccessFlags implements Cloneable {
  48 
  49     /* Corresponds to the fields found in a JavaClass object.
  50      */
  51     private String class_name;
  52     private String super_class_name;
  53     private final String file_name;
  54     private int class_name_index = -1;
  55     private int superclass_name_index = -1;
  56     private int major = Const.MAJOR;
  57     private int minor = Const.MINOR;
  58     private ConstantPoolGen cp; // Template for building up constant pool

  59     // ArrayLists instead of arrays to gather fields, methods, etc.
  60     private final List<Field> field_vec = new ArrayList<>();
  61     private final List<Method> method_vec = new ArrayList<>();
  62     private final List<Attribute> attribute_vec = new ArrayList<>();
  63     private final List<String> interface_vec = new ArrayList<>();
  64     private final List<AnnotationEntryGen> annotation_vec = new ArrayList<>();
  65 
  66     private static BCELComparator _cmp = new BCELComparator() {
  67 
  68         @Override
  69         public boolean equals(final Object o1, final Object o2) {
  70             final ClassGen THIS = (ClassGen) o1;
  71             final ClassGen THAT = (ClassGen) o2;
  72             return THIS.getClassName().equals(THAT.getClassName());
  73         }
  74 
  75         @Override
  76         public int hashCode(final Object o) {
  77             final ClassGen THIS = (ClassGen) o;
  78             return THIS.getClassName().hashCode();
  79         }
  80     };
  81 
  82     /**
  83      * Convenience constructor to set up some important values initially.
  84      *
  85      * @param class_name fully qualified class name
  86      * @param super_class_name fully qualified superclass name
  87      * @param file_name source file name
  88      * @param access_flags access qualifiers
  89      * @param interfaces implemented interfaces
  90      * @param cp constant pool to use
  91      */
  92     public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags,
  93             final String[] interfaces, final ConstantPoolGen cp) {
  94         super(access_flags);
  95         this.class_name = class_name;
  96         this.super_class_name = super_class_name;
  97         this.file_name = file_name;

  98         this.cp = cp;

  99         // Put everything needed by default into the constant pool and the vectors
 100         if (file_name != null) {
 101             addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp
 102                     .getConstantPool()));
 103         }
 104         class_name_index = cp.addClass(class_name);
 105         superclass_name_index = cp.addClass(super_class_name);
 106         if (interfaces != null) {
 107             for (final String interface1 : interfaces) {
 108                 addInterface(interface1);
 109             }
 110         }
 111     }
 112 
 113     /**
 114      * Convenience constructor to set up some important values initially.
 115      *
 116      * @param class_name fully qualified class name
 117      * @param super_class_name fully qualified superclass name
 118      * @param file_name source file name
 119      * @param access_flags access qualifiers
 120      * @param interfaces implemented interfaces
 121      */
 122     public ClassGen(final String class_name, final String super_class_name, final String file_name, final int access_flags,
 123             final String[] interfaces) {
 124         this(class_name, super_class_name, file_name, access_flags, interfaces,
 125                 new ConstantPoolGen());
 126     }
 127 
 128     /**
 129      * Initialize with existing class.
 130      *
 131      * @param clazz JavaClass object (e.g. read from file)
 132      */
 133     public ClassGen(final JavaClass clazz) {
 134         super(clazz.getAccessFlags());
 135         class_name_index = clazz.getClassNameIndex();
 136         superclass_name_index = clazz.getSuperclassNameIndex();
 137         class_name = clazz.getClassName();
 138         super_class_name = clazz.getSuperclassName();
 139         file_name = clazz.getSourceFileName();

 140         cp = new ConstantPoolGen(clazz.getConstantPool());
 141         major = clazz.getMajor();
 142         minor = clazz.getMinor();
 143         final Attribute[] attributes = clazz.getAttributes();
 144         // J5TODO: Could make unpacking lazy, done on first reference
 145         final AnnotationEntryGen[] annotations = unpackAnnotations(attributes);
 146         final Method[] methods = clazz.getMethods();
 147         final Field[] fields = clazz.getFields();
 148         final String[] interfaces = clazz.getInterfaceNames();
 149         for (final String interface1 : interfaces) {
 150             addInterface(interface1);
 151         }
 152         for (final Attribute attribute : attributes) {
 153             if (!(attribute instanceof Annotations)) {
 154                 addAttribute(attribute);
 155             }
 156         }
 157         for (final AnnotationEntryGen annotation : annotations) {
 158             addAnnotationEntry(annotation);
 159         }
 160         for (final Method method : methods) {
 161             addMethod(method);
 162         }
 163         for (final Field field : fields) {
 164             addField(field);
 165         }
 166     }
 167 
 168     /**
 169      * Look for attributes representing annotations and unpack them.
 170      */
 171     private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs) {
 172         final List<AnnotationEntryGen> annotationGenObjs = new ArrayList<>();
 173         for (final Attribute attr : attrs) {
 174             if (attr instanceof RuntimeVisibleAnnotations) {
 175                 final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr;
 176                 final AnnotationEntry[] annos = rva.getAnnotationEntries();
 177                 for (final AnnotationEntry a : annos) {
 178                     annotationGenObjs.add(new AnnotationEntryGen(a,
 179                             getConstantPool(), false));
 180                 }
 181             } else if (attr instanceof RuntimeInvisibleAnnotations) {
 182                 final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
 183                 final AnnotationEntry[] annos = ria.getAnnotationEntries();
 184                 for (final AnnotationEntry a : annos) {
 185                     annotationGenObjs.add(new AnnotationEntryGen(a,
 186                             getConstantPool(), false));
 187                 }
 188             }
 189         }
 190         return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]);
 191     }
 192 
 193     /**
 194      * @return the (finally) built up Java class object.
 195      */
 196     public JavaClass getJavaClass() {
 197         final int[] interfaces = getInterfaces();
 198         final Field[] fields = getFields();
 199         final Method[] methods = getMethods();
 200         Attribute[] attributes;
 201         if (annotation_vec.isEmpty()) {
 202             attributes = getAttributes();
 203         } else {
 204             // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
 205             final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries());
 206             attributes = new Attribute[attribute_vec.size() + annAttributes.length];
 207             attribute_vec.toArray(attributes);
 208             System.arraycopy(annAttributes, 0, attributes, attribute_vec.size(), annAttributes.length);
 209         }
 210         // Must be last since the above calls may still add something to it
 211         final ConstantPool _cp = this.cp.getFinalConstantPool();
 212         return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor,
 213                 super.getAccessFlags(), _cp, interfaces, fields, methods, attributes);


 214     }
 215 
 216     /**
 217      * Add an interface to this class, i.e., this class has to implement it.
 218      *
 219      * @param name interface to implement (fully qualified class name)
 220      */
 221     public final void addInterface(final String name) {
 222         interface_vec.add(name);
 223     }
 224 
 225     /**
 226      * Remove an interface from this class.
 227      *
 228      * @param name interface to remove (fully qualified name)
 229      */
 230     public void removeInterface(final String name) {
 231         interface_vec.remove(name);
 232     }
 233 
 234     /**
 235      * @return major version number of class file
 236      */
 237     public int getMajor() {
 238         return major;
 239     }
 240 
 241     /**
 242      * Set major version number of class file, default value is 45 (JDK 1.1)
 243      *
 244      * @param major major version number
 245      */
 246     public void setMajor(final int major) { // TODO could be package-protected - only called by test code
 247         this.major = major;
 248     }
 249 
 250     /**
 251      * Set minor version number of class file, default value is 3 (JDK 1.1)
 252      *
 253      * @param minor minor version number
 254      */
 255     public void setMinor(final int minor) {  // TODO could be package-protected - only called by test code
 256         this.minor = minor;
 257     }
 258 
 259     /**
 260      * @return minor version number of class file
 261      */
 262     public int getMinor() {
 263         return minor;
 264     }
 265 
 266     /**
 267      * Add an attribute to this class.
 268      *
 269      * @param a attribute to add
 270      */
 271     public final void addAttribute(final Attribute a) {
 272         attribute_vec.add(a);
 273     }
 274 
 275     public final void addAnnotationEntry(final AnnotationEntryGen a) {
 276         annotation_vec.add(a);
 277     }
 278 
 279     /**
 280      * Add a method to this class.
 281      *
 282      * @param m method to add
 283      */
 284     public final void addMethod(final Method m) {
 285         method_vec.add(m);
 286     }
 287 
 288     /**
 289      * Convenience method.
 290      *
 291      * Add an empty constructor to this class that does nothing but calling
 292      * super().
 293      *
 294      * @param access_flags rights for constructor
 295      */
 296     public void addEmptyConstructor(final int access_flags) {
 297         final InstructionList il = new InstructionList();
 298         il.append(InstructionConst.THIS); // Push `this'
 299         il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
 300         il.append(InstructionConst.RETURN);
 301         final MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>",
 302                 class_name, il, cp);


 303         mg.setMaxStack(1);
 304         addMethod(mg.getMethod());
 305     }
 306 
 307     /**
 308      * Add a field to this class.
 309      *
 310      * @param f field to add
 311      */
 312     public final void addField(final Field f) {
 313         field_vec.add(f);
 314     }
 315 
 316     public boolean containsField(final Field f) {
 317         return field_vec.contains(f);
 318     }
 319 
 320     /**
 321      * @return field object with given name, or null
 322      */
 323     public Field containsField(final String name) {
 324         for (final Field f : field_vec) {
 325             if (f.getName().equals(name)) {

 326                 return f;
 327             }
 328         }
 329         return null;
 330     }
 331 
 332     /**
 333      * @return method object with given name and signature, or null
 334      */
 335     public Method containsMethod(final String name, final String signature) {
 336         for (final Method m : method_vec) {
 337             if (m.getName().equals(name) && m.getSignature().equals(signature)) {

 338                 return m;
 339             }
 340         }
 341         return null;
 342     }
 343 
 344     /**
 345      * Remove an attribute from this class.
 346      *
 347      * @param a attribute to remove
 348      */
 349     public void removeAttribute(final Attribute a) {
 350         attribute_vec.remove(a);
 351     }
 352 
 353     /**
 354      * Remove a method from this class.
 355      *
 356      * @param m method to remove
 357      */
 358     public void removeMethod(final Method m) {
 359         method_vec.remove(m);
 360     }
 361 
 362     /**
 363      * Replace given method with new one. If the old one does not exist add the
 364      * new_ method to the class anyway.
 365      */
 366     public void replaceMethod(final Method old, final Method new_) {
 367         if (new_ == null) {
 368             throw new ClassGenException("Replacement method must not be null");
 369         }
 370         final int i = method_vec.indexOf(old);
 371         if (i < 0) {

 372             method_vec.add(new_);
 373         } else {
 374             method_vec.set(i, new_);
 375         }
 376     }
 377 
 378     /**
 379      * Replace given field with new one. If the old one does not exist add the
 380      * new_ field to the class anyway.
 381      */
 382     public void replaceField(final Field old, final Field new_) {
 383         if (new_ == null) {
 384             throw new ClassGenException("Replacement method must not be null");
 385         }
 386         final int i = field_vec.indexOf(old);
 387         if (i < 0) {

 388             field_vec.add(new_);
 389         } else {
 390             field_vec.set(i, new_);
 391         }
 392     }
 393 
 394     /**
 395      * Remove a field to this class.
 396      *
 397      * @param f field to remove
 398      */
 399     public void removeField(final Field f) {
 400         field_vec.remove(f);
 401     }
 402 
 403     public String getClassName() {
 404         return class_name;
 405     }
 406 
 407     public String getSuperclassName() {
 408         return super_class_name;
 409     }
 410 
 411     public String getFileName() {
 412         return file_name;
 413     }
 414 
 415     public void setClassName(final String name) {
 416         class_name = name.replace('/', '.');
 417         class_name_index = cp.addClass(name);
 418     }
 419 
 420     public void setSuperclassName(final String name) {
 421         super_class_name = name.replace('/', '.');
 422         superclass_name_index = cp.addClass(name);
 423     }
 424 
 425     public Method[] getMethods() {
 426         return method_vec.toArray(new Method[method_vec.size()]);


 427     }
 428 
 429     public void setMethods(final Method[] methods) {
 430         method_vec.clear();
 431         for (final Method method : methods) {
 432             addMethod(method);
 433         }
 434     }
 435 
 436     public void setMethodAt(final Method method, final int pos) {
 437         method_vec.set(pos, method);
 438     }
 439 
 440     public Method getMethodAt(final int pos) {
 441         return method_vec.get(pos);
 442     }
 443 
 444     public String[] getInterfaceNames() {
 445         final int size = interface_vec.size();
 446         final String[] interfaces = new String[size];

 447         interface_vec.toArray(interfaces);
 448         return interfaces;
 449     }
 450 
 451     public int[] getInterfaces() {
 452         final int size = interface_vec.size();
 453         final int[] interfaces = new int[size];
 454         for (int i = 0; i < size; i++) {
 455             interfaces[i] = cp.addClass(interface_vec.get(i));
 456         }

 457         return interfaces;
 458     }
 459 
 460     public Field[] getFields() {
 461         return field_vec.toArray(new Field[field_vec.size()]);


 462     }
 463 
 464     public Attribute[] getAttributes() {
 465         return attribute_vec.toArray(new Attribute[attribute_vec.size()]);
 466     }
 467 
 468     //  J5TODO: Should we make calling unpackAnnotations() lazy and put it in here?
 469     public AnnotationEntryGen[] getAnnotationEntries() {
 470         return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]);
 471     }
 472 
 473     public ConstantPoolGen getConstantPool() {
 474         return cp;
 475     }
 476 
 477     public void setConstantPool(final ConstantPoolGen constant_pool) {
 478         cp = constant_pool;
 479     }
 480 
 481     public void setClassNameIndex(final int class_name_index) {
 482         this.class_name_index = class_name_index;
 483         class_name = cp.getConstantPool().getConstantString(class_name_index,
 484                 Const.CONSTANT_Class).replace('/', '.');
 485     }
 486 
 487     public void setSuperclassNameIndex(final int superclass_name_index) {
 488         this.superclass_name_index = superclass_name_index;
 489         super_class_name = cp.getConstantPool().getConstantString(superclass_name_index,
 490                 Const.CONSTANT_Class).replace('/', '.');
 491     }
 492 
 493     public int getSuperclassNameIndex() {
 494         return superclass_name_index;
 495     }
 496 
 497     public int getClassNameIndex() {
 498         return class_name_index;
 499     }
 500 
 501     private List<ClassObserver> observers;
 502 
 503     /**
 504      * Add observer for this object.
 505      */
 506     public void addObserver(final ClassObserver o) {
 507         if (observers == null) {
 508             observers = new ArrayList<>();
 509         }
 510         observers.add(o);
 511     }
 512 
 513     /**
 514      * Remove observer for this object.
 515      */
 516     public void removeObserver(final ClassObserver o) {
 517         if (observers != null) {
 518             observers.remove(o);
 519         }
 520     }
 521 
 522     /**
 523      * Call notify() method on all observers. This method is not called
 524      * automatically whenever the state has changed, but has to be called by the
 525      * user after he has finished editing the object.
 526      */
 527     public void update() {
 528         if (observers != null) {
 529             for (final ClassObserver observer : observers) {
 530                 observer.notify(this);
 531             }
 532         }
 533     }
 534 
 535     @Override
 536     public Object clone() {
 537         try {
 538             return super.clone();
 539         } catch (final CloneNotSupportedException e) {
 540             throw new Error("Clone Not Supported"); // never happens
 541         }
 542     }
 543 
 544     /**
 545      * @return Comparison strategy object
 546      */
 547     public static BCELComparator getComparator() {
 548         return _cmp;
 549     }
 550 
 551     /**
 552      * @param comparator Comparison strategy object
 553      */
 554     public static void setComparator(final BCELComparator comparator) {
 555         _cmp = comparator;
 556     }
 557 
 558     /**
 559      * Return value as defined by given BCELComparator strategy. By default two
 560      * ClassGen objects are said to be equal when their class names are equal.
 561      *
 562      * @see java.lang.Object#equals(java.lang.Object)
 563      */
 564     @Override
 565     public boolean equals(final Object obj) {
 566         return _cmp.equals(this, obj);
 567     }
 568 
 569     /**
 570      * Return value as defined by given BCELComparator strategy. By default
 571      * return the hashcode of the class name.
 572      *
 573      * @see java.lang.Object#hashCode()
 574      */
 575     @Override
 576     public int hashCode() {
 577         return _cmp.hashCode(this);
 578     }
 579 }
< prev index next >