1 17 package org.apache.bcel.generic; 18 19 import java.util.ArrayList ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import org.apache.bcel.Constants; 23 import org.apache.bcel.classfile.AccessFlags; 24 import org.apache.bcel.classfile.Attribute; 25 import org.apache.bcel.classfile.ConstantPool; 26 import org.apache.bcel.classfile.Field; 27 import org.apache.bcel.classfile.JavaClass; 28 import org.apache.bcel.classfile.Method; 29 import org.apache.bcel.classfile.SourceFile; 30 import org.apache.bcel.util.BCELComparator; 31 32 40 public class ClassGen extends AccessFlags implements Cloneable { 41 42 44 private String class_name, super_class_name, file_name; 45 private int class_name_index = -1, superclass_name_index = -1; 46 private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1; 47 private ConstantPoolGen cp; private List field_vec = new ArrayList (); 50 private List method_vec = new ArrayList (); 51 private List attribute_vec = new ArrayList (); 52 private List interface_vec = new ArrayList (); 53 private static BCELComparator _cmp = new BCELComparator() { 54 55 public boolean equals( Object o1, Object o2 ) { 56 ClassGen THIS = (ClassGen) o1; 57 ClassGen THAT = (ClassGen) o2; 58 return THIS.getClassName().equals(THAT.getClassName()); 59 } 60 61 62 public int hashCode( Object o ) { 63 ClassGen THIS = (ClassGen) o; 64 return THIS.getClassName().hashCode(); 65 } 66 }; 67 68 69 78 public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, 79 String [] interfaces, ConstantPoolGen cp) { 80 this.class_name = class_name; 81 this.super_class_name = super_class_name; 82 this.file_name = file_name; 83 this.access_flags = access_flags; 84 this.cp = cp; 85 if (file_name != null) { 87 addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp 88 .getConstantPool())); 89 } 90 class_name_index = cp.addClass(class_name); 91 superclass_name_index = cp.addClass(super_class_name); 92 if (interfaces != null) { 93 for (int i = 0; i < interfaces.length; i++) { 94 addInterface(interfaces[i]); 95 } 96 } 97 } 98 99 100 108 public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, 109 String [] interfaces) { 110 this(class_name, super_class_name, file_name, access_flags, interfaces, 111 new ConstantPoolGen()); 112 } 113 114 115 119 public ClassGen(JavaClass clazz) { 120 class_name_index = clazz.getClassNameIndex(); 121 superclass_name_index = clazz.getSuperclassNameIndex(); 122 class_name = clazz.getClassName(); 123 super_class_name = clazz.getSuperclassName(); 124 file_name = clazz.getSourceFileName(); 125 access_flags = clazz.getAccessFlags(); 126 cp = new ConstantPoolGen(clazz.getConstantPool()); 127 major = clazz.getMajor(); 128 minor = clazz.getMinor(); 129 Attribute[] attributes = clazz.getAttributes(); 130 Method[] methods = clazz.getMethods(); 131 Field[] fields = clazz.getFields(); 132 String [] interfaces = clazz.getInterfaceNames(); 133 for (int i = 0; i < interfaces.length; i++) { 134 addInterface(interfaces[i]); 135 } 136 for (int i = 0; i < attributes.length; i++) { 137 addAttribute(attributes[i]); 138 } 139 for (int i = 0; i < methods.length; i++) { 140 addMethod(methods[i]); 141 } 142 for (int i = 0; i < fields.length; i++) { 143 addField(fields[i]); 144 } 145 } 146 147 148 151 public JavaClass getJavaClass() { 152 int[] interfaces = getInterfaces(); 153 Field[] fields = getFields(); 154 Method[] methods = getMethods(); 155 Attribute[] attributes = getAttributes(); 156 ConstantPool _cp = this.cp.getFinalConstantPool(); 158 return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, 159 access_flags, _cp, interfaces, fields, methods, attributes); 160 } 161 162 163 167 public void addInterface( String name ) { 168 interface_vec.add(name); 169 } 170 171 172 176 public void removeInterface( String name ) { 177 interface_vec.remove(name); 178 } 179 180 181 184 public int getMajor() { 185 return major; 186 } 187 188 189 192 public void setMajor( int major ) { 193 this.major = major; 194 } 195 196 197 200 public void setMinor( int minor ) { 201 this.minor = minor; 202 } 203 204 205 208 public int getMinor() { 209 return minor; 210 } 211 212 213 217 public void addAttribute( Attribute a ) { 218 attribute_vec.add(a); 219 } 220 221 222 226 public void addMethod( Method m ) { 227 method_vec.add(m); 228 } 229 230 231 237 public void addEmptyConstructor( int access_flags ) { 238 InstructionList il = new InstructionList(); 239 il.append(InstructionConstants.THIS); il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V"))); 241 il.append(InstructionConstants.RETURN); 242 MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", 243 class_name, il, cp); 244 mg.setMaxStack(1); 245 addMethod(mg.getMethod()); 246 } 247 248 249 253 public void addField( Field f ) { 254 field_vec.add(f); 255 } 256 257 258 public boolean containsField( Field f ) { 259 return field_vec.contains(f); 260 } 261 262 263 265 public Field containsField( String name ) { 266 for (Iterator e = field_vec.iterator(); e.hasNext();) { 267 Field f = (Field) e.next(); 268 if (f.getName().equals(name)) { 269 return f; 270 } 271 } 272 return null; 273 } 274 275 276 278 public Method containsMethod( String name, String signature ) { 279 for (Iterator e = method_vec.iterator(); e.hasNext();) { 280 Method m = (Method) e.next(); 281 if (m.getName().equals(name) && m.getSignature().equals(signature)) { 282 return m; 283 } 284 } 285 return null; 286 } 287 288 289 293 public void removeAttribute( Attribute a ) { 294 attribute_vec.remove(a); 295 } 296 297 298 302 public void removeMethod( Method m ) { 303 method_vec.remove(m); 304 } 305 306 307 310 public void replaceMethod( Method old, Method new_ ) { 311 if (new_ == null) { 312 throw new ClassGenException("Replacement method must not be null"); 313 } 314 int i = method_vec.indexOf(old); 315 if (i < 0) { 316 method_vec.add(new_); 317 } else { 318 method_vec.set(i, new_); 319 } 320 } 321 322 323 326 public void replaceField( Field old, Field new_ ) { 327 if (new_ == null) { 328 throw new ClassGenException("Replacement method must not be null"); 329 } 330 int i = field_vec.indexOf(old); 331 if (i < 0) { 332 field_vec.add(new_); 333 } else { 334 field_vec.set(i, new_); 335 } 336 } 337 338 339 343 public void removeField( Field f ) { 344 field_vec.remove(f); 345 } 346 347 348 public String getClassName() { 349 return class_name; 350 } 351 352 353 public String getSuperclassName() { 354 return super_class_name; 355 } 356 357 358 public String getFileName() { 359 return file_name; 360 } 361 362 363 public void setClassName( String name ) { 364 class_name = name.replace('/', '.'); 365 class_name_index = cp.addClass(name); 366 } 367 368 369 public void setSuperclassName( String name ) { 370 super_class_name = name.replace('/', '.'); 371 superclass_name_index = cp.addClass(name); 372 } 373 374 375 public Method[] getMethods() { 376 return (Method[]) method_vec.toArray(new Method[method_vec.size()]); 377 } 378 379 380 public void setMethods( Method[] methods ) { 381 method_vec.clear(); 382 for (int m = 0; m < methods.length; m++) { 383 addMethod(methods[m]); 384 } 385 } 386 387 388 public void setMethodAt( Method method, int pos ) { 389 method_vec.set(pos, method); 390 } 391 392 393 public Method getMethodAt( int pos ) { 394 return (Method) method_vec.get(pos); 395 } 396 397 398 public String [] getInterfaceNames() { 399 int size = interface_vec.size(); 400 String [] interfaces = new String [size]; 401 interface_vec.toArray(interfaces); 402 return interfaces; 403 } 404 405 406 public int[] getInterfaces() { 407 int size = interface_vec.size(); 408 int[] interfaces = new int[size]; 409 for (int i = 0; i < size; i++) { 410 interfaces[i] = cp.addClass((String ) interface_vec.get(i)); 411 } 412 return interfaces; 413 } 414 415 416 public Field[] getFields() { 417 return (Field[]) field_vec.toArray(new Field[field_vec.size()]); 418 } 419 420 421 public Attribute[] getAttributes() { 422 return (Attribute[]) attribute_vec.toArray(new Attribute[attribute_vec.size()]); 423 } 424 425 426 public ConstantPoolGen getConstantPool() { 427 return cp; 428 } 429 430 431 public void setConstantPool( ConstantPoolGen constant_pool ) { 432 cp = constant_pool; 433 } 434 435 436 public void setClassNameIndex( int class_name_index ) { 437 this.class_name_index = class_name_index; 438 class_name = cp.getConstantPool().getConstantString(class_name_index, 439 Constants.CONSTANT_Class).replace('/', '.'); 440 } 441 442 443 public void setSuperclassNameIndex( int superclass_name_index ) { 444 this.superclass_name_index = superclass_name_index; 445 super_class_name = cp.getConstantPool().getConstantString(superclass_name_index, 446 Constants.CONSTANT_Class).replace('/', '.'); 447 } 448 449 450 public int getSuperclassNameIndex() { 451 return superclass_name_index; 452 } 453 454 455 public int getClassNameIndex() { 456 return class_name_index; 457 } 458 459 private ArrayList observers; 460 461 462 464 public void addObserver( ClassObserver o ) { 465 if (observers == null) { 466 observers = new ArrayList (); 467 } 468 observers.add(o); 469 } 470 471 472 474 public void removeObserver( ClassObserver o ) { 475 if (observers != null) { 476 observers.remove(o); 477 } 478 } 479 480 481 485 public void update() { 486 if (observers != null) { 487 for (Iterator e = observers.iterator(); e.hasNext();) { 488 ((ClassObserver) e.next()).notify(this); 489 } 490 } 491 } 492 493 494 public Object clone() { 495 try { 496 return super.clone(); 497 } catch (CloneNotSupportedException e) { 498 System.err.println(e); 499 return null; 500 } 501 } 502 503 504 507 public static BCELComparator getComparator() { 508 return _cmp; 509 } 510 511 512 515 public static void setComparator( BCELComparator comparator ) { 516 _cmp = comparator; 517 } 518 519 520 527 public boolean equals( Object obj ) { 528 return _cmp.equals(this, obj); 529 } 530 531 532 538 public int hashCode() { 539 return _cmp.hashCode(this); 540 } 541 } 542 | Popular Tags |