1 2 12 package com.versant.core.jdo.tools.enhancer; 13 14 import com.versant.lib.bcel.Constants; 15 import com.versant.lib.bcel.classfile.*; 16 import com.versant.lib.bcel.generic.*; 17 import com.versant.core.common.Debug; 18 import com.versant.core.jdo.tools.enhancer.info.ClassInfo; 19 import com.versant.core.jdo.tools.enhancer.info.FieldInfo; 20 import com.versant.core.jdo.tools.enhancer.utils.SerialUIDHelper; 21 import com.versant.core.jdo.tools.enhancer.utils.SwapFieldHelper; 22 import com.versant.core.jdo.tools.enhancer.utils.TableSwitchHelper; 23 import com.versant.core.metadata.ClassMetaData; 24 import com.versant.core.metadata.MDStatics; 25 26 import javax.jdo.JDOUserException; 27 import java.io.File ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.util.*; 31 import java.net.URL ; 32 33 37 public class ClassEnhancer { 38 39 40 private ClassGen classGen; 41 private ConstantPoolGen constantPoolGen; 42 private InstructionFactory instructionFactory; 43 private ClassInfo classInfo; 44 private Set fieldSet; 45 private File outputDir; 46 private ClassLoader loader; 47 private static int javaVersion; 48 49 private boolean isEmpty = false; 50 private boolean didWeAddADefaultConstructor = false; 51 52 public static final int JAVA_1_0 = 10; 53 public static final int JAVA_1_1 = 11; 54 public static final int JAVA_1_2 = 12; 55 public static final int JAVA_1_3 = 13; 56 public static final int JAVA_1_4 = 14; 57 public static final int JAVA_1_5 = 15; 58 59 private static final String getField = com.versant.lib.bcel.generic.GETFIELD.class.getName(); 60 private static final String putField = com.versant.lib.bcel.generic.PUTFIELD.class.getName(); 61 private static final String invokeSpecial = com.versant.lib.bcel.generic.INVOKESPECIAL.class.getName(); 62 private static final String aload = com.versant.lib.bcel.generic.ALOAD.class.getName(); 63 private static final String dup = com.versant.lib.bcel.generic.DUP.class.getName(); 64 65 66 private HashMap getAndSettersMap; 67 private HashMap typeToReturnType; 68 private HashMap typeToSetField; 69 private HashMap typeToFieldProvider; 70 private HashMap typeToProvidedField; 71 private HashMap typeToReplacingField; 72 private HashMap typeToGetField; 73 private HashMap typeToLoadType; 74 private HashMap typeToFieldReplacer; 75 76 private HashMap primativeTypesToWrapper; 77 78 private String fileSeparator; 79 private char charfileSeparator; private static final String VERSANT_STATE_MANAGER = com.versant.core.jdo.VersantStateManager.class.getName(); 81 82 private final static String PERSISTENCE_CAPABLE = javax.jdo.spi.PersistenceCapable.class.getName(); 83 private final static ObjectType PC_OBJECT_TYPE = new ObjectType(PERSISTENCE_CAPABLE); 84 private final static String STATE_MANAGER = javax.jdo.spi.StateManager.class.getName(); 85 private final static ObjectType SM_OBJECT_TYPE = new ObjectType(STATE_MANAGER); 86 private int CHECK_WRITE = javax.jdo.spi.PersistenceCapable.CHECK_WRITE; 87 private int CHECK_READ_WRITE = javax.jdo.spi.PersistenceCapable.CHECK_READ + javax.jdo.spi.PersistenceCapable.CHECK_WRITE; 88 private int MEDIATE_READ_WRITE = javax.jdo.spi.PersistenceCapable.MEDIATE_READ + javax.jdo.spi.PersistenceCapable.MEDIATE_WRITE; 89 private int synthetic; 90 private String vendorName = "jdoVersant"; 91 92 private long currentSerialVersionUID; 93 private static final String DIRTY_FIELD_NAME = "jdoVersantDirty"; 94 private static final String LOADED_FIELD_NAME = "jdoVersantLoaded"; 95 private static final String OID_FIELD_NAME = "jdoVersantOID"; 96 private static final String VERSION_FIELD_NAME = "jdoVersantVersion"; 97 private static final String DETACHABLE_INTERFASE = com.versant.core.jdo.VersantDetachable.class.getName(); 98 private static final String DETACHED_STATE_MANAGER = com.versant.core.jdo.VersantDetachedStateManager.class.getName(); 99 private int totlalManagedFields = 0; 100 private boolean detach; 101 private File currentOutputFile; 102 103 public static final ObjectType INTEGER_TYPE = new ObjectType( 104 "java.lang.Integer"); 105 public static final ObjectType BYTE_TYPE = new ObjectType("java.lang.Byte"); 106 public static final ObjectType CHARACTER_TYPE = new ObjectType( 107 "java.lang.Character"); 108 public static final ObjectType SHORT_TYPE = new ObjectType( 109 "java.lang.Short"); 110 public static final ObjectType FLOAT_TYPE = new ObjectType( 111 "java.lang.Float"); 112 public static final ObjectType DOUBLE_TYPE = new ObjectType( 113 "java.lang.Double"); 114 public static final ObjectType LONG_TYPE = new ObjectType("java.lang.Long"); 115 public static final ObjectType BOOLEAN_TYPE = new ObjectType( 116 "java.lang.Boolean"); 117 118 120 static { 121 122 128 try { 129 javaVersion = JAVA_1_0; 130 Class.forName("java.lang.Void"); 131 javaVersion = JAVA_1_1; 132 Class.forName("java.lang.ThreadLocal"); 133 javaVersion = JAVA_1_2; 134 Class.forName("java.lang.StrictMath"); 135 javaVersion = JAVA_1_3; 136 Class.forName("java.lang.CharSequence"); 137 javaVersion = JAVA_1_4; 138 } catch (ClassNotFoundException cnfe) { 141 } 144 } 145 146 public ClassEnhancer(File outputDir, ClassLoader loader) { 147 this.outputDir = outputDir; 148 this.loader = loader; 149 fileSeparator = System.getProperty("file.separator"); 150 charfileSeparator = fileSeparator.charAt(0); 151 152 typeToSetField = new HashMap(); 153 typeToSetField.put(Type.INT, "setIntField"); 154 typeToSetField.put(Type.BYTE, "setByteField"); 155 typeToSetField.put(Type.LONG, "setLongField"); 156 typeToSetField.put(Type.CHAR, "setCharField"); 157 typeToSetField.put(Type.SHORT, "setShortField"); 158 typeToSetField.put(Type.FLOAT, "setFloatField"); 159 typeToSetField.put(Type.DOUBLE, "setDoubleField"); 160 typeToSetField.put(Type.STRING, "setStringField"); 161 typeToSetField.put(Type.BOOLEAN,"setBooleanField"); 162 163 typeToFieldProvider = new HashMap(); 164 typeToFieldProvider.put(Type.INT, "fetchIntField"); 165 typeToFieldProvider.put(Type.BYTE, "fetchByteField"); 166 typeToFieldProvider.put(Type.CHAR, "fetchCharField"); 167 typeToFieldProvider.put(Type.SHORT, "fetchShortField"); 168 typeToFieldProvider.put(Type.FLOAT, "fetchFloatField"); 169 typeToFieldProvider.put(Type.DOUBLE, "fetchDoubleField"); 170 typeToFieldProvider.put(Type.LONG, "fetchLongField"); 171 typeToFieldProvider.put(Type.BOOLEAN,"fetchBooleanField"); 172 typeToFieldProvider.put(Type.STRING, "fetchStringField"); 173 174 typeToProvidedField = new HashMap(); 175 typeToProvidedField.put(Type.INT, "providedIntField"); 176 typeToProvidedField.put(Type.BYTE, "providedByteField"); 177 typeToProvidedField.put(Type.CHAR, "providedCharField"); 178 typeToProvidedField.put(Type.SHORT, "providedShortField"); 179 typeToProvidedField.put(Type.FLOAT, "providedFloatField"); 180 typeToProvidedField.put(Type.DOUBLE,"providedDoubleField"); 181 typeToProvidedField.put(Type.LONG, "providedLongField"); 182 typeToProvidedField.put(Type.BOOLEAN,"providedBooleanField"); 183 typeToProvidedField.put(Type.STRING,"providedStringField"); 184 185 typeToReplacingField = new HashMap(); 186 typeToReplacingField.put(Type.INT, "replacingIntField"); 187 typeToReplacingField.put(Type.BYTE, "replacingByteField"); 188 typeToReplacingField.put(Type.CHAR, "replacingCharField"); 189 typeToReplacingField.put(Type.SHORT, "replacingShortField"); 190 typeToReplacingField.put(Type.FLOAT, "replacingFloatField"); 191 typeToReplacingField.put(Type.DOUBLE, "replacingDoubleField"); 192 typeToReplacingField.put(Type.LONG, "replacingLongField"); 193 typeToReplacingField.put(Type.BOOLEAN, "replacingBooleanField"); 194 typeToReplacingField.put(Type.STRING, "replacingStringField"); 195 196 typeToFieldReplacer = new HashMap(); 197 typeToFieldReplacer.put(Type.INT, "storeIntField"); 198 typeToFieldReplacer.put(Type.BYTE, "storeByteField"); 199 typeToFieldReplacer.put(Type.CHAR, "storeCharField"); 200 typeToFieldReplacer.put(Type.SHORT, "storeShortField"); 201 typeToFieldReplacer.put(Type.FLOAT, "storeFloatField"); 202 typeToFieldReplacer.put(Type.DOUBLE, "storeDoubleField"); 203 typeToFieldReplacer.put(Type.LONG, "storeLongField"); 204 typeToFieldReplacer.put(Type.BOOLEAN, "storeBooleanField"); 205 typeToFieldReplacer.put(Type.STRING, "storeStringField"); 206 207 typeToGetField = new HashMap(); 208 typeToGetField.put(Type.INT, "getIntField"); 209 typeToGetField.put(Type.BYTE, "getByteField"); 210 typeToGetField.put(Type.CHAR, "getCharField"); 211 typeToGetField.put(Type.SHORT, "getShortField"); 212 typeToGetField.put(Type.FLOAT, "getFloatField"); 213 typeToGetField.put(Type.DOUBLE, "getDoubleField"); 214 typeToGetField.put(Type.LONG, "getLongField"); 215 typeToGetField.put(Type.BOOLEAN,"getBooleanField"); 216 typeToGetField.put(Type.STRING, "getStringField"); 217 218 typeToReturnType = new HashMap(); 219 typeToReturnType.put(Type.INT, new IRETURN()); 220 typeToReturnType.put(Type.BYTE, new IRETURN()); 221 typeToReturnType.put(Type.CHAR, new IRETURN()); 222 typeToReturnType.put(Type.SHORT, new IRETURN()); 223 typeToReturnType.put(Type.FLOAT, new FRETURN()); 224 typeToReturnType.put(Type.DOUBLE, new DRETURN()); 225 typeToReturnType.put(Type.LONG, new LRETURN()); 226 typeToReturnType.put(Type.BOOLEAN, new IRETURN()); 227 typeToReturnType.put(Type.STRING, new ARETURN()); 228 229 typeToLoadType = new HashMap(); 230 typeToLoadType.put(Type.INT, new ILOAD(1)); 231 typeToLoadType.put(Type.BYTE, new ILOAD(1)); 232 typeToLoadType.put(Type.CHAR, new ILOAD(1)); 233 typeToLoadType.put(Type.SHORT, new ILOAD(1)); 234 typeToLoadType.put(Type.FLOAT, new FLOAD(1)); 235 typeToLoadType.put(Type.DOUBLE, new DLOAD(1)); 236 typeToLoadType.put(Type.LONG, new LLOAD(1)); 237 typeToLoadType.put(Type.BOOLEAN, new ILOAD(1)); 238 typeToLoadType.put(Type.STRING, new ALOAD(1)); 239 240 241 primativeTypesToWrapper = new HashMap(8); 242 primativeTypesToWrapper.put(Type.INT, INTEGER_TYPE); 243 primativeTypesToWrapper.put(Type.BYTE, BYTE_TYPE); 244 primativeTypesToWrapper.put(Type.CHAR, CHARACTER_TYPE); 245 primativeTypesToWrapper.put(Type.SHORT, SHORT_TYPE); 246 primativeTypesToWrapper.put(Type.FLOAT, FLOAT_TYPE); 247 primativeTypesToWrapper.put(Type.DOUBLE, DOUBLE_TYPE); 248 primativeTypesToWrapper.put(Type.LONG, LONG_TYPE); 249 primativeTypesToWrapper.put(Type.BOOLEAN, BOOLEAN_TYPE); 250 251 252 } 253 254 255 256 public void setGetAndSettersMap(HashMap map){ 257 getAndSettersMap = map; 258 } 259 260 private JavaClass getJavaClass(String className)throws IOException { 261 String classFileName = className.replace('.','/')+".class"; 262 InputStream inputStream = loader.getResourceAsStream(classFileName); 263 if (inputStream == null){ 264 inputStream = loader.getResourceAsStream("/" + classFileName); 265 if (inputStream == null){ 266 throw new javax.jdo.JDOFatalUserException( 267 "Class not found: " + className); 268 } 269 } 270 ClassParser parser = new ClassParser(inputStream, classFileName); 271 return parser.parse(); 272 } 273 274 private JavaClass getOrigJavaClass(String className) throws IOException { 275 String classFileName = className.replace('.', '/') + ".class"; 276 InputStream inputStream = loader.getResourceAsStream(classFileName); 277 URL currentFileURL = loader.getResource(classFileName); 278 if (currentFileURL.toString().startsWith("jar:") && outputDir == null){ 279 throw new javax.jdo.JDOFatalUserException("Can not write class "+ className +" into a jar. Please specify a output directory."); 280 } 281 currentOutputFile = new File (currentFileURL.getFile()); 282 if (inputStream == null) { 283 inputStream = loader.getResourceAsStream("/" + classFileName); 284 currentFileURL = loader.getResource("/" + classFileName); 285 if (currentFileURL.toString().startsWith("jar:") && outputDir == null) { 286 throw new javax.jdo.JDOFatalUserException("Can not write class " + className + " into a jar. Please specify a output directory."); 287 } 288 currentOutputFile = new File (currentFileURL.getFile()); 289 if (inputStream == null) { 290 throw new javax.jdo.JDOFatalUserException("Class not found: " + className); 291 } 292 } 293 ClassParser parser = new ClassParser(inputStream, classFileName); 294 return parser.parse(); 295 } 296 297 public boolean enhance(ClassInfo classInfo,ClassMetaData cmd, boolean makeFieldsPrivate, boolean detached){ 298 try{ 299 this.detach = detached; 300 this.classInfo = classInfo; 301 fieldSet = classInfo.getFieldList(); 302 if (fieldSet.isEmpty()){ 303 isEmpty = true; 304 } else { 305 isEmpty = false; 306 } 307 JavaClass javaClass = getOrigJavaClass(classInfo.getClassName()); 308 classGen = new ClassGen(javaClass); 309 constantPoolGen = classGen.getConstantPool(); 311 instructionFactory = new InstructionFactory(constantPoolGen); 313 314 if (implementsPC()){ return false; 316 } 317 currentSerialVersionUID = SerialUIDHelper.computeSerialVersionUID(javaClass); 318 synthetic = classGen.getConstantPool().addUtf8("Synthetic"); 319 320 321 boolean topClass = classInfo.getTopPCSuperClass() == null; 322 boolean appIdentity = classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION; 323 didWeAddADefaultConstructor = false; 324 325 326 rewriteStaticConstructor(); 328 setDefaultConstructor(); 329 setClass$(); 330 addSerialVersionUID(); 331 addJdoFieldNames(); 332 addJdoFieldFlags(); 333 if (topClass) addJdoStateManager(); if (topClass) addJdoFlags(); addJdoInheritedFieldCount(); 336 addJdoPersistenceCapableSuperclass(); 337 addJdoFieldTypes(); 338 addJdoGetManagedFieldCount(); 339 if (topClass) addInterrogatives(); addFieldGetters(); 341 addFieldSetters(); 342 addJdoReplaceField(); 343 addJdoReplaceFields(); addJdoProvideField(); 345 addJdoProvideFields(); addJdoCopyFields(); 347 addJdoCopyField(); 348 if (topClass) addJdoPreSerialize(); addWriteObject(); 350 addReadObject(); 351 addRegisterClass(); 352 addJdoNewInstance1(); 353 addJdoNewInstance2(); 354 if (topClass || appIdentity) addJdoNewObjectIdInstance1(); 355 if (topClass || appIdentity) addJdoNewObjectIdInstance2(); 356 if (topClass) addJdoGetObjectId(); if (topClass) addJdoGetTransactionalObjectId(); if (topClass) addJdoReplaceStateManager(); if (topClass) addJdoCopyKeyFieldsToObjectId1(); 360 if (topClass) addJdoCopyKeyFieldsToObjectId2(); 361 if (topClass) addJdoCopyKeyFieldsFromObjectId1(); 362 if (topClass) addJdoCopyKeyFieldsFromObjectId2(); 363 if (topClass) addJdoReplaceFlags(); 365 366 addJdoInterface(); 367 if (makeFieldsPrivate){ 368 setEnhancedFieldsPrivate(); 369 } 370 swapGetterAndSetter(); 371 swapClone(); 372 373 totlalManagedFields = 0; 375 if (detach){ 376 if (topClass){ 377 ClassMetaData[] hier = cmd.pcHeirachy; 378 for (int i = 0; i < hier.length; i++) { 379 ClassMetaData classMetaData = hier[i]; 380 totlalManagedFields += classMetaData.managedFields.length; 381 } 382 addFields(); 383 addSetLoadedInt("versantSetLoaded"); addIsLoadedInt("versantIsLoaded"); addIsDirty("versantIsDirty"); addMakeDirtyInt("versantMakeDirty"); 387 addIsDirtyInt("versantIsDirty"); addSetOid("versantSetOID"); addGetOid("versantGetOID"); addGetVersion("versantGetVersion"); addSetVersion("versantSetVersion"); addGetStateManager("versantGetDetachedStateManager"); addDetachInterfase(); 394 } 395 addMakeDirtyString("versantMakeDirty"); } 397 398 if (didWeAddADefaultConstructor) { 399 isOurConstructorValid(); 400 } 401 dumpClass(); 402 403 System.out.println("Persistence Capable = " + classInfo.getClassName()); 404 405 } catch (Exception e){ 406 e.printStackTrace(); 407 if (Debug.DEBUG) { 408 Debug.ERR.println("Error in Enhancer"); 409 e.printStackTrace(Debug.ERR); 410 } 411 } 412 return true; 413 } 414 415 private void isOurConstructorValid() { 416 if (classInfo.getPersistenceCapableSuperclass() != null) { 418 return; 419 } 420 String superName = classGen.getSuperclassName(); 421 try { 422 JavaClass javaClass = getJavaClass(superName); 423 ClassGen classGen = new ClassGen(javaClass); 424 Method[] methods = classGen.getMethods(); 425 for (int i = 0; i < methods.length; i++) { 426 Method m = methods[i]; 427 if (m.isNative() || m.isAbstract()) { 430 continue; 431 } 432 if (m.getName().equals("<init>")) { if (m.getSignature().equals("()V")) { if (!m.isPrivate()) { 435 return; 436 } 437 } 438 } 439 } 440 throw new JDOUserException("Could not create a valid default constructor for class "+ this.classGen.getClassName()); 441 } catch (IOException e) { 442 } 444 } 445 446 private void addDefaultConstructorToNonPersistantSuperClasses(String superName) { 447 if (superName == null){ 449 if (classInfo.getPersistenceCapableSuperclass() != null) { 450 return; 451 } 452 superName = classGen.getSuperclassName(); 453 } 454 455 try { 456 JavaClass javaClass = getJavaClass(superName); 457 ClassGen classGen = new ClassGen(javaClass); 458 ConstantPoolGen constantPoolGen = classGen.getConstantPool(); 460 461 Method[] methods = classGen.getMethods(); 462 for (int i = 0; i < methods.length; i++) { 463 Method m = methods[i]; 464 if (m.isNative() || m.isAbstract()) { 467 continue; 468 } 469 470 if (m.getName().equals("<init>")) { if (m.getSignature().equals("()V")) { if (m.isPublic()) { 473 return; 474 } else { m.isPublic(true); 476 m.isProtected(false); m.isPrivate(false); String fileName = classGen.getClassName().replace('.', charfileSeparator) + ".class"; 479 File dumpFile = new File (outputDir, fileName); 480 try { 481 classGen.getJavaClass().dump(dumpFile); 482 } catch (IOException e) { 483 } 485 return; 486 } 487 } 488 } 489 } 490 491 InstructionList il = new InstructionList(); 492 il.append(InstructionConstants.THIS); il.append(new INVOKESPECIAL(constantPoolGen.addMethodref(classGen.getSuperclassName(), 494 "<init>", 495 "()V"))); 496 il.append(InstructionConstants.RETURN); 497 498 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, 500 Type.NO_ARGS, 501 null, 502 "<init>", 503 classGen.getClassName(), 504 il, 505 constantPoolGen); 506 methodGen.setMaxLocals(); 507 methodGen.setMaxStack(); 508 509 classGen.addMethod(methodGen.getMethod()); 510 511 String fileName = classGen.getClassName().replace('.', charfileSeparator) + ".class"; 512 File dumpFile = new File (outputDir, fileName); 513 boolean error = false; 514 try { 515 classGen.getJavaClass().dump(dumpFile); 516 } catch (IOException e) { 517 error = true; 519 520 } 521 522 if (!error){ 523 if (this.classGen.getSuperclassName().equals(classGen.getClassName())){ 526 System.out.println("WARNING: persistence capable class '" + 527 this.classGen.getClassName() + 528 "' has a non persistence super class \n'" 529 + classGen.getClassName() + 530 "', that does not have a default constructor, will add one."); 531 } 532 533 addDefaultConstructorToNonPersistantSuperClasses(classGen.getSuperclassName()); 534 } 535 536 } catch (IOException e) { 537 } 539 } 540 541 542 private void swapClone() { 543 Method[] methods = classGen.getMethods(); 545 for(int i = 0; i < methods.length; i++) { 546 Method m = methods[i]; 547 548 if (m.isNative() || m.isAbstract()){ 551 continue; 552 } 553 if (m.getName().startsWith("<cl")){ 555 continue; 556 } 557 558 boolean changed = false; 559 560 MethodGen mg = new MethodGen(m,classGen.getClassName(),constantPoolGen); 561 562 InstructionList il = mg.getInstructionList(); 564 565 InstructionHandle ih = il.getStart(); 567 568 while (ih != null) { 569 Instruction ins = ih.getInstruction(); 570 if (ins.getClass().getName().equals(invokeSpecial)){ 571 INVOKESPECIAL is = (INVOKESPECIAL)ins; 572 if (is.getClassName(constantPoolGen).equals("java.lang.Object") && 573 is.getMethodName(constantPoolGen).equals("clone") && 574 is.getSignature(constantPoolGen).equals("()Ljava/lang/Object;")) { 575 576 il.append(is,getCloneIL()); 577 il.setPositions(); 578 il.update(); 579 changed = true; 580 581 } 582 } 583 ih = ih.getNext(); 585 } 586 if (changed){ 588 il.setPositions(); 589 il.update(); 590 mg.setMaxLocals(); 591 mg.setMaxStack(); 592 classGen.replaceMethod(m,mg.getMethod()); 593 } 594 } 595 } 596 597 private InstructionList getCloneIL(){ 598 InstructionList il = new InstructionList(); 599 il.append(new DUP()); 600 il.append(instructionFactory.createCheckCast(new ObjectType(classGen.getClassName()))); 601 il.append(new ACONST_NULL()); 602 if (javaVersion >= JAVA_1_4) { 603 il.append(instructionFactory.createPutField(classGen.getClassName(), 604 "jdoStateManager", 605 SM_OBJECT_TYPE)); 606 } else { 607 il.append(instructionFactory.createPutField(getTopPCSuperOrCurrentClassName(), 608 "jdoStateManager", 609 SM_OBJECT_TYPE)); 610 } 611 il.append(new DUP()); 612 il.append(instructionFactory.createCheckCast(new ObjectType(classGen.getClassName()))); 613 il.append(new ICONST(0)); 614 if (javaVersion >= JAVA_1_4) { 615 il.append(instructionFactory.createPutField(classGen.getClassName(), 616 "jdoFlags", 617 Type.BYTE)); 618 } else { 619 il.append(instructionFactory.createPutField(getTopPCSuperOrCurrentClassName(), 620 "jdoFlags", 621 Type.BYTE)); 622 } 623 return il; 624 625 626 } 627 628 629 675 private void dumpClass()throws VerifyException{ 676 String fileName = classGen.getClassName().replace('.',charfileSeparator)+".class"; 677 File dumpFile; 678 if (outputDir != null){ 679 dumpFile = new File (outputDir,fileName); 680 } else { 681 dumpFile = currentOutputFile; 682 } 683 try { 684 classGen.getJavaClass().dump(dumpFile); 685 } catch (IOException e) { 686 throw new VerifyException(e); 687 } 688 689 } 690 691 692 693 708 private void addJdoCopyKeyFieldsFromObjectId1() { 709 if (classInfo.getTopPCSuperClass() == null || 710 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo.getObjectidClass() != null)){ 711 InstructionList il = new InstructionList(); 712 MethodGen methodGen = new MethodGen( 713 Constants.ACC_PUBLIC, 714 Type.VOID, 715 new Type[]{ 716 new ObjectType("javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer"), 717 Type.OBJECT 718 }, 719 new String []{"fc","oid"}, 720 "jdoCopyKeyFieldsFromObjectId", 721 classGen.getClassName(), 722 il, 723 constantPoolGen); 724 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 725 && classInfo.getObjectidClass() != null) { 726 Iterator iter = classInfo.getFieldList().iterator(); 727 int count = 0; 728 boolean isObject = false; 729 while (iter.hasNext()){ 730 FieldInfo info = (FieldInfo)iter.next(); 731 if (info.primaryKey()){ 732 String fieldReplacerMethod = null; 733 if (typeToFieldReplacer.containsKey(info.getType())){ 734 fieldReplacerMethod = (String )typeToFieldReplacer.get(info.getType()); 735 isObject = false; 736 } else { 737 isObject = true; 738 } 739 il.append(new ALOAD(1)); 740 il.append(instructionFactory.createGetStatic( 741 classGen.getClassName(), 742 "jdoInheritedFieldCount", 743 Type.INT)); 744 il.append(new PUSH(constantPoolGen, count)); 745 il.append(new IADD()); 746 il.append(new ALOAD(2)); 747 il.append(instructionFactory.createCheckCast(new ObjectType(classInfo.getObjectidClass()))); 748 il.append(instructionFactory.createGetField( 749 classInfo.getObjectidClass(), 750 info.getFieldName(), 751 info.getType())); 752 753 if (isObject){ 754 il.append(instructionFactory.createInvoke( 755 "javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer", 756 "storeObjectField", 757 Type.VOID, 758 new Type[]{ 759 Type.INT, 760 Type.OBJECT}, 761 Constants.INVOKEINTERFACE)); 762 } else { 763 il.append(instructionFactory.createInvoke( 764 "javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer", 765 fieldReplacerMethod, 766 Type.VOID, 767 new Type[]{ 768 Type.INT, 769 info.getType()}, 770 Constants.INVOKEINTERFACE)); 771 } 772 } 773 count ++; 774 } 775 } 776 il.append(new RETURN()); 777 methodGen.setMaxLocals(); 779 methodGen.setMaxStack(); 780 classGen.addMethod(methodGen.getMethod()); 781 il.dispose(); 782 } 783 } 784 785 private void addJdoCopyKeyFieldsFromObjectId2(){ 786 if (classInfo.getTopPCSuperClass() == null || 787 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 788 && classInfo.getObjectidClass() != null)) { 789 790 InstructionList il = new InstructionList(); 791 MethodGen methodGen = new MethodGen( 792 Constants.ACC_PROTECTED, 793 Type.VOID, 794 new Type[]{ 795 Type.OBJECT 796 }, 797 new String []{"oid"}, 798 "jdoCopyKeyFieldsFromObjectId", 799 classGen.getClassName(), 800 il, 801 constantPoolGen); 802 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 803 && classInfo.getObjectidClass() != null) { 804 805 il.append(new ALOAD(1)); 806 il.append(instructionFactory.createCheckCast(new ObjectType(classInfo.getObjectidClass()))); 807 il.append(new ASTORE(2)); 808 InstructionHandle pckStartHandle = null; 809 boolean first = true; 810 ClassInfo currentClass = getTopPCSuperOrCurrentClass(); 811 Iterator iter = currentClass.getFieldList().iterator(); 812 while (iter.hasNext()){ 813 FieldInfo info = (FieldInfo)iter.next(); 814 if (info.primaryKey()){ 815 if (first){ 816 pckStartHandle = il.append(new ALOAD(0)); 817 first = false; 818 } else { 819 il.append(new ALOAD(0)); 820 } 821 il.append(new ALOAD(2)); 822 il.append(instructionFactory.createGetField( 823 classInfo.getObjectidClass(), 824 info.getFieldName(), 825 info.getType())); 826 il.append(instructionFactory.createPutField( 827 classInfo.getClassName(), 828 info.getFieldName(), 829 info.getType())); 830 } 831 } 832 il.append(new RETURN()); 833 methodGen.addLocalVariable( 834 "pck", 835 new ObjectType(classInfo.getObjectidClass()), 836 2, 837 pckStartHandle, 838 il.getEnd()); 839 } else { 840 il.append(new RETURN()); 841 } 842 methodGen.setMaxLocals(); 844 methodGen.setMaxStack(); 845 classGen.addMethod(methodGen.getMethod()); 846 il.dispose(); 847 } 848 } 849 850 851 852 853 854 private String getTopPCSuperOrCurrentClassName(){ 855 if (classInfo.getTopPCSuperClass() == null){ 856 return classInfo.getClassName(); 857 } else { 858 return classInfo.getTopPCSuperClass().getClassName(); 859 } 860 } 861 862 private ClassInfo getTopPCSuperOrCurrentClass(){ 863 if (classInfo.getTopPCSuperClass() == null){ 864 return classInfo; 865 } else { 866 return classInfo.getTopPCSuperClass(); 867 } 868 } 869 870 private void addJdoReplaceFlags(){ 871 if (classInfo.getTopPCSuperClass() == null){ 872 InstructionList il = new InstructionList(); 873 MethodGen methodGen = new MethodGen( 874 Constants.ACC_PUBLIC , 875 Type.VOID, 876 new Type[]{}, 877 new String []{}, 878 "jdoReplaceFlags", 879 classGen.getClassName(), 880 il, 881 constantPoolGen); 882 883 il.append(new ALOAD(0)); 884 il.append(instructionFactory.createGetField( 885 getTopPCSuperOrCurrentClassName(), 886 "jdoStateManager", 887 SM_OBJECT_TYPE)); 888 IFNULL ifnull = new IFNULL(null); 889 il.append(ifnull); 890 il.append(new ALOAD(0)); 891 il.append(new ALOAD(0)); 892 il.append(instructionFactory.createGetField( 893 getTopPCSuperOrCurrentClassName(), 894 "jdoStateManager", 895 SM_OBJECT_TYPE)); 896 il.append(new ALOAD(0)); 897 il.append(instructionFactory.createInvoke( 898 STATE_MANAGER, 899 "replacingFlags", 900 Type.BYTE, 901 new Type[] {PC_OBJECT_TYPE}, 902 Constants.INVOKEINTERFACE)); 903 il.append(instructionFactory.createPutField( 904 getTopPCSuperOrCurrentClassName(), 905 "jdoFlags", 906 Type.BYTE)); 907 InstructionHandle handle = il.append(new RETURN()); 908 ifnull.setTarget(handle); 909 methodGen.setMaxLocals(); 911 methodGen.setMaxStack(); 912 913 classGen.addMethod(methodGen.getMethod()); 914 il.dispose(); 915 } 916 } 917 918 private boolean mustEnhance(Method m){ 919 String name = m.getName(); 920 if (name.startsWith(vendorName+"MakeHollow")){ 921 return false; 922 } 923 if (name.startsWith(vendorName)){ 924 return true; 925 }else if (name.startsWith("jdo")){ 926 if (classInfo.isInstanceCallbacks() && 927 (name.equals("jdoPreStore") || name.equals("jdoPreDelete")) 928 && m.getSignature().equals("()V")){ 929 return true; 930 } 931 } else { 932 return true; 933 } 934 return false; 935 } 936 937 private void swapGetterAndSetter(){ 938 939 Method[] methods = classGen.getMethods(); 941 for(int i = 0; i < methods.length; i++) { 942 Method m = methods[i]; 943 944 if (m.isNative() || m.isAbstract()){ 947 continue; 948 } 949 if (m.getName().startsWith("<cl")){ 951 continue; 952 } 953 954 if (!mustEnhance(m)){ 955 continue; 956 } 957 958 boolean changed = false; 959 960 MethodGen mg = new MethodGen(m,classGen.getClassName(),constantPoolGen); 961 962 InstructionList il = mg.getInstructionList(); 964 965 InstructionHandle ih = il.getStart(); 967 while (ih != null) { 968 Instruction ins = ih.getInstruction(); 969 if (ins.getClass().getName().equals(getField)){ GETFIELD is = (GETFIELD)ins; 971 String key = is.getClassName(constantPoolGen) +"|"+ is.getFieldName(constantPoolGen); 972 if (getAndSettersMap.containsKey(key)) { 973 SwapFieldHelper helper = (SwapFieldHelper)getAndSettersMap.get(key); 974 ih.setInstruction(instructionFactory.createInvoke( 976 helper.className, 977 helper.jdoGetName, 978 helper.type, 979 new Type[] { 980 new ObjectType(helper.className) 981 }, 982 Constants.INVOKESTATIC)); 983 il.setPositions(); 984 il.update(); 985 986 changed = true; 987 InstructionHandle prevIhDUP = ih.getPrev(); 988 Instruction iffyDup = prevIhDUP.getInstruction(); 989 if (iffyDup.getClass().getName().equals(dup)){ ih = ih.getPrev(); 991 InstructionHandle prevIhALOAD = ih.getPrev(); 992 Instruction iffyAload = prevIhALOAD.getInstruction(); 993 if (iffyAload.getClass().getName().equals(aload)){ ALOAD aLoad = (ALOAD)iffyAload; 995 ih.setInstruction(aLoad); il.setPositions(); 997 il.update(); 998 }else { 999 ih = ih.getNext(); 1000 } 1001 } 1002 } 1003 } else if (ins.getClass().getName().equals(putField)){ 1004 PUTFIELD is = (PUTFIELD)ins; 1005 String key = is.getClassName(constantPoolGen) +"|"+ is.getFieldName(constantPoolGen); 1006 if (getAndSettersMap.containsKey(key)) { 1007 SwapFieldHelper helper = (SwapFieldHelper)getAndSettersMap.get(key); 1008 ih.setInstruction(instructionFactory.createInvoke( 1010 helper.className, 1011 helper.jdoSetName, 1012 Type.VOID, 1013 new Type[] { 1014 new ObjectType(helper.className), 1015 helper.type 1016 }, 1017 Constants.INVOKESTATIC)); 1018 il.setPositions(); 1019 il.update(); 1020 changed = true; 1021 } 1022 } 1023 ih = ih.getNext(); 1025 } 1026 if (changed){ 1027 il.setPositions(); 1028 il.update(); 1029 mg.setMaxLocals(); 1030 mg.setMaxStack(); 1031 Method method = mg.getMethod(); 1032 classGen.replaceMethod(m, method); 1033 } 1034 } 1035 } 1036 1037 1038 private void setEnhancedFieldsPrivate(){ 1039 Field [] fields = classGen.getFields(); 1040 Iterator iter = fieldSet.iterator(); 1041 while (iter.hasNext()){ 1042 FieldInfo info = (FieldInfo)iter.next(); 1043 String fieldname = info.getFieldName(); 1044 for (int i = 0;i < fields.length; i++) { 1045 Field f = fields[i]; 1046 if (f.getName().equals(fieldname)){ 1047 if (!f.isPrivate()){ 1048 f.isProtected(false); 1049 f.isPublic(false); 1050 f.isPrivate(true); 1051 } 1052 } 1053 } 1054 } 1055 } 1056 1057 1058 private void addJdoInterface(){ 1059 classGen.addInterface(PERSISTENCE_CAPABLE); 1060 } 1061 1062 1063 private void addJdoCopyKeyFieldsToObjectId2(){ 1064 if (classInfo.getTopPCSuperClass() == null || 1065 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo.getObjectidClass() != null)) { 1066 InstructionList il = new InstructionList(); 1067 MethodGen methodGen = new MethodGen( 1068 Constants.ACC_PUBLIC, 1069 Type.VOID, 1070 new Type[]{ 1071 new ObjectType("javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier"), 1072 Type.OBJECT 1073 }, 1074 new String []{"fs","oid"}, 1075 "jdoCopyKeyFieldsToObjectId", 1076 classGen.getClassName(), 1077 il, 1078 constantPoolGen); 1079 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo.getObjectidClass() != null) { 1080 Iterator iter = classInfo.getFieldList().iterator(); 1081 int count = 0; 1082 boolean isObject = false; 1083 while (iter.hasNext()){ 1084 FieldInfo info = (FieldInfo)iter.next(); 1085 if (info.primaryKey()){ 1086 String fieldProviderMethod = null; 1087 if (typeToFieldProvider.containsKey(info.getType())){ 1088 fieldProviderMethod = (String )typeToFieldProvider.get(info.getType()); 1089 isObject = false; 1090 } else { 1091 isObject = true; 1092 } 1093 il.append(new ALOAD(2)); 1094 il.append(instructionFactory.createCheckCast(new ObjectType(classInfo.getObjectidClass()))); 1095 il.append(new ALOAD(1)); 1096 il.append(instructionFactory.createGetStatic( 1097 classGen.getClassName(), 1098 "jdoInheritedFieldCount", 1099 Type.INT)); 1100 il.append(new PUSH(constantPoolGen, count)); 1101 il.append(new IADD()); 1102 if (isObject){ 1103 il.append(instructionFactory.createInvoke( 1104 "javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier", 1105 "fetchObjectField", 1106 Type.OBJECT, 1107 new Type[]{Type.INT}, 1108 Constants.INVOKEINTERFACE)); 1109 il.append(instructionFactory.createCheckCast((ReferenceType)info.getType())); 1110 } else { 1111 il.append(instructionFactory.createInvoke( 1112 "javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier", 1113 fieldProviderMethod, 1114 info.getType(), 1115 new Type[]{Type.INT}, 1116 Constants.INVOKEINTERFACE)); 1117 1118 } 1119 il.append(instructionFactory.createPutField(classInfo.getObjectidClass(), 1120 info.getFieldName(), 1121 info.getType())); 1122 1123 } 1124 count ++; 1125 } 1126 } 1127 il.append(new RETURN()); 1128 1129 methodGen.setMaxLocals(); 1131 methodGen.setMaxStack(); 1132 classGen.addMethod(methodGen.getMethod()); 1133 il.dispose(); 1134 } 1135 } 1136 1137 1138 private void addJdoCopyKeyFieldsToObjectId1(){ 1140 if (classInfo.getTopPCSuperClass() == null 1141 || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 1142 && classInfo.getObjectidClass() != null)) { 1143 InstructionList il = new InstructionList(); 1144 MethodGen methodGen = new MethodGen( 1145 Constants.ACC_PUBLIC, 1146 Type.VOID, 1147 new Type[]{ 1148 Type.OBJECT 1149 }, 1150 new String []{"oid"}, 1151 "jdoCopyKeyFieldsToObjectId", 1152 classGen.getClassName(), 1153 il, 1154 constantPoolGen); 1155 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 1156 && classInfo.getObjectidClass() != null) { 1157 Iterator iter = classInfo.getFieldList().iterator(); 1158 while (iter.hasNext()){ 1159 FieldInfo info = (FieldInfo)iter.next(); 1160 if (info.primaryKey()){ 1161 il.append(new ALOAD(1)); 1162 il.append(instructionFactory.createCheckCast( 1163 new ObjectType(classInfo.getObjectidClass()))); 1164 il.append(new ALOAD(0)); 1165 il.append(instructionFactory.createGetField( 1166 classInfo.getClassName(), 1167 info.getFieldName(), 1168 info.getType())); 1169 il.append(instructionFactory.createPutField( 1170 classInfo.getObjectidClass(), 1171 info.getFieldName(), 1172 info.getType())); 1173 } 1174 } 1175 } 1176 il.append(new RETURN()); 1177 methodGen.setMaxLocals(); 1179 methodGen.setMaxStack(); 1180 classGen.addMethod(methodGen.getMethod()); 1181 il.dispose(); 1182 } 1183 } 1184 1185 1186 private void addJdoNewObjectIdInstance1(){ 1187 if (classInfo.getTopPCSuperClass() == null || 1188 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 1189 && classInfo.getObjectidClass() != null)) { 1190 InstructionList il = new InstructionList(); 1191 MethodGen methodGen = new MethodGen( 1192 Constants.ACC_PUBLIC, 1193 Type.OBJECT, 1194 null, 1195 null, 1196 "jdoNewObjectIdInstance", 1197 classGen.getClassName(), 1198 il, 1199 constantPoolGen); 1200 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 1201 && classInfo.getObjectidClass() != null) { 1202 il.append(instructionFactory.createNew(classInfo.getObjectidClass())); 1203 il.append(new DUP()); 1204 il.append(instructionFactory.createInvoke( 1205 classInfo.getObjectidClass(), 1206 "<init>", 1207 Type.VOID, 1208 new Type[]{}, 1209 Constants.INVOKESPECIAL)); 1210 } else { 1211 il.append(new ACONST_NULL()); 1212 } 1213 il.append(new ARETURN()); 1214 1215 methodGen.setMaxLocals(); 1216 methodGen.setMaxStack(); 1217 classGen.addMethod(methodGen.getMethod()); 1218 il.dispose(); 1219 } 1220 } 1221 1222 1223 private void addJdoNewObjectIdInstance2(){ 1224 if (classInfo.getTopPCSuperClass() == null || 1225 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo.getObjectidClass() != null)){ 1226 InstructionList il = new InstructionList(); 1227 MethodGen methodGen = new MethodGen( 1228 Constants.ACC_PUBLIC, 1229 Type.OBJECT, 1230 new Type[]{Type.STRING}, 1231 new String []{"str"}, 1232 "jdoNewObjectIdInstance", 1233 classGen.getClassName(), 1234 il, 1235 constantPoolGen); 1236 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION 1237 && classInfo.getObjectidClass() != null) { 1238 il.append(instructionFactory.createNew(classInfo.getObjectidClass())); 1239 il.append(new DUP()); 1240 il.append(new ALOAD(1)); 1241 il.append(instructionFactory.createInvoke( 1242 classInfo.getObjectidClass(), 1243 "<init>", 1244 Type.VOID, 1245 new Type[]{Type.STRING}, 1246 Constants.INVOKESPECIAL)); 1247 } else { 1248 il.append(new ACONST_NULL()); 1249 } 1250 il.append(new ARETURN()); 1251 1252 methodGen.setMaxLocals(); 1253 methodGen.setMaxStack(); 1254 classGen.addMethod(methodGen.getMethod()); 1255 il.dispose(); 1256 } 1257 } 1258 1259 private void addJdoReplaceStateManager(){ 1260 if (classInfo.getTopPCSuperClass() == null){ 1261 InstructionList il = new InstructionList(); 1262 MethodGen methodGen = new MethodGen( 1263 Constants.ACC_PUBLIC | Constants.ACC_SYNCHRONIZED, 1264 Type.VOID, 1265 new Type[]{SM_OBJECT_TYPE}, 1266 new String []{"sm"}, 1267 "jdoReplaceStateManager", 1268 classGen.getClassName(), 1269 il, 1270 constantPoolGen); 1271 1272 1273 il.append(new ALOAD(0)); 1274 il.append(instructionFactory.createGetField( 1275 getTopPCSuperOrCurrentClassName(), 1276 "jdoStateManager", 1277 SM_OBJECT_TYPE)); 1278 IFNULL ifnullInst1 = new IFNULL(null); 1279 il.append(ifnullInst1); 1280 il.append(new ALOAD(0)); 1281 il.append(new ALOAD(0)); 1282 il.append(instructionFactory.createGetField( 1283 getTopPCSuperOrCurrentClassName(), 1284 "jdoStateManager", 1285 SM_OBJECT_TYPE)); 1286 il.append(new ALOAD(0)); 1287 il.append(new ALOAD(1)); 1288 il.append(instructionFactory.createInvoke( 1289 STATE_MANAGER, 1290 "replacingStateManager", 1291 SM_OBJECT_TYPE, 1292 new Type[]{ 1293 PC_OBJECT_TYPE, 1294 SM_OBJECT_TYPE}, 1295 Constants.INVOKEINTERFACE)); 1296 il.append(instructionFactory.createPutField( 1297 getTopPCSuperOrCurrentClassName(), 1298 "jdoStateManager", 1299 SM_OBJECT_TYPE)); 1300 GOTO gotoInst = new GOTO(null); 1301 il.append(gotoInst); 1302 InstructionHandle secManHandle = il.append(instructionFactory.createInvoke( 1303 "java.lang.System", 1304 "getSecurityManager", 1305 new ObjectType("java.lang.SecurityManager"), 1306 new Type[]{}, 1307 Constants.INVOKESTATIC)); 1308 ifnullInst1.setTarget(secManHandle); 1309 il.append(new ASTORE(2)); 1310 InstructionHandle startSecHandle = il.append(new ALOAD(2)); 1311 IFNULL ifnullInst2 = new IFNULL(null); 1312 il.append(ifnullInst2); 1313 il.append(new ALOAD(2)); 1314 il.append(instructionFactory.createGetStatic( 1315 "javax.jdo.spi.JDOPermission", 1316 "SET_STATE_MANAGER", 1317 new ObjectType("javax.jdo.spi.JDOPermission"))); 1318 il.append(instructionFactory.createInvoke( 1319 "java.lang.SecurityManager", 1320 "checkPermission", 1321 Type.VOID, 1322 new Type[]{new ObjectType("java.security.Permission")}, 1323 Constants.INVOKEVIRTUAL)); 1324 InstructionHandle ifnullHandle = il.append(new ALOAD(0)); 1325 ifnullInst2.setTarget(ifnullHandle); 1326 il.append(new ALOAD(1)); 1327 il.append(instructionFactory.createPutField( 1328 getTopPCSuperOrCurrentClassName(), 1329 "jdoStateManager", 1330 SM_OBJECT_TYPE)); 1331 InstructionHandle gotoHandle = il.append(new RETURN()); 1332 gotoInst.setTarget(gotoHandle); 1333 methodGen.addLocalVariable( 1334 "sec", 1335 new ObjectType("java.lang.SecurityManager"), 1336 2, 1337 startSecHandle, 1338 il.getEnd()); 1339 1340 1341 methodGen.setMaxLocals(); 1342 methodGen.setMaxStack(); 1343 classGen.addMethod(methodGen.getMethod()); 1344 il.dispose(); 1345 } 1346 1347 } 1348 1349 1350 private void addJdoGetTransactionalObjectId(){ 1351 if (classInfo.getTopPCSuperClass() == null){ 1352 InstructionList il = new InstructionList(); 1353 MethodGen methodGen = new MethodGen( 1354 Constants.ACC_PUBLIC, 1355 Type.OBJECT, 1356 new Type[]{}, 1357 new String []{}, 1358 "jdoGetTransactionalObjectId", 1359 classGen.getClassName(), 1360 il, 1361 constantPoolGen); 1362 il.append(new ALOAD(0)); 1363 il.append(instructionFactory.createGetField( 1364 getTopPCSuperOrCurrentClassName(), 1365 "jdoStateManager", 1366 SM_OBJECT_TYPE)); 1367 IFNONNULL ifnonnullInst = new IFNONNULL(null); 1368 il.append(ifnonnullInst); 1369 il.append(new ACONST_NULL()); 1370 GOTO gotoInst = new GOTO(null); 1371 il.append(gotoInst); 1372 InstructionHandle ifnonnullHandle = il.append(new ALOAD(0)); 1373 il.append(instructionFactory.createGetField( 1374 getTopPCSuperOrCurrentClassName(), 1375 "jdoStateManager", 1376 SM_OBJECT_TYPE)); 1377 il.append(new ALOAD(0)); 1378 il.append(instructionFactory.createInvoke( 1379 STATE_MANAGER, 1380 "getTransactionalObjectId", 1381 Type.OBJECT, 1382 new Type[]{PC_OBJECT_TYPE}, 1383 Constants.INVOKEINTERFACE)); 1384 InstructionHandle gotoHandle = il.append(new ARETURN()); 1385 gotoInst.setTarget(gotoHandle); 1386 ifnonnullInst.setTarget(ifnonnullHandle); 1387 1388 methodGen.setMaxLocals(); 1390 methodGen.setMaxStack(); 1391 classGen.addMethod(methodGen.getMethod()); 1392 il.dispose(); 1393 } 1394 } 1395 1396 1397 private void addJdoGetObjectId(){ 1398 if (classInfo.getTopPCSuperClass() == null){ 1399 InstructionList il = new InstructionList(); 1400 MethodGen methodGen = new MethodGen( 1401 Constants.ACC_PUBLIC, 1402 Type.OBJECT, 1403 new Type[]{}, 1404 new String []{}, 1405 "jdoGetObjectId", 1406 classGen.getClassName(), 1407 il, 1408 constantPoolGen); 1409 1410 1411 il.append(new ALOAD(0)); 1412 il.append(instructionFactory.createGetField( 1413 getTopPCSuperOrCurrentClassName(), 1414 "jdoStateManager", 1415 SM_OBJECT_TYPE)); 1416 IFNONNULL ifnonnullInst = new IFNONNULL(null); 1417 il.append(ifnonnullInst); 1418 il.append(new ACONST_NULL()); 1419 GOTO gotoInst = new GOTO(null); 1420 il.append(gotoInst); 1421 InstructionHandle ifnonnullHandle = il.append(new ALOAD(0)); 1422 il.append(instructionFactory.createGetField( 1423 getTopPCSuperOrCurrentClassName(), 1424 "jdoStateManager", 1425 SM_OBJECT_TYPE)); 1426 il.append(new ALOAD(0)); 1427 il.append(instructionFactory.createInvoke( 1428 STATE_MANAGER, 1429 "getObjectId", 1430 Type.OBJECT, 1431 new Type[]{PC_OBJECT_TYPE}, 1432 Constants.INVOKEINTERFACE)); 1433 InstructionHandle gotoHandle = il.append(new ARETURN()); 1434 gotoInst.setTarget(gotoHandle); 1435 ifnonnullInst.setTarget(ifnonnullHandle); 1436 1437 methodGen.setMaxLocals(); 1439 methodGen.setMaxStack(); 1440 classGen.addMethod(methodGen.getMethod()); 1441 il.dispose(); 1442 } 1443 } 1444 1445 1446 private void addJdoNewInstance2(){ 1447 InstructionList il = new InstructionList(); 1448 MethodGen methodGen = new MethodGen( 1449 Constants.ACC_PUBLIC, 1450 PC_OBJECT_TYPE, 1451 new Type[]{SM_OBJECT_TYPE,Type.OBJECT}, 1452 new String []{"sm","oid"}, 1453 "jdoNewInstance", 1454 classGen.getClassName(), 1455 il, 1456 constantPoolGen); 1457 if (classGen.isAbstract()){ 1458 il.append(instructionFactory.createNew("javax.jdo.JDOFatalInternalException")); 1459 il.append(new DUP()); 1460 il.append(instructionFactory.createInvoke( 1461 "javax.jdo.JDOFatalInternalException", 1462 "<init>", 1463 Type.VOID, 1464 new Type[]{}, 1465 Constants.INVOKESPECIAL)); 1466 il.append(new ATHROW()); 1467 1468 } else { 1469 if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_DATASTORE){ il.append(instructionFactory.createNew(classGen.getClassName())); 1471 il.append(new DUP()); 1472 il.append(instructionFactory.createInvoke( 1473 classGen.getClassName(), 1474 "<init>", 1475 Type.VOID , 1476 new Type[]{}, 1477 Constants.INVOKESPECIAL)); 1478 il.append(new ASTORE(3)); 1479 InstructionHandle pcStartHandle = il.append(new ALOAD(3)); 1480 il.append(new ALOAD(1)); 1481 il.append(instructionFactory.createPutField( 1482 getTopPCSuperOrCurrentClassName(), 1483 "jdoStateManager", 1484 SM_OBJECT_TYPE)); 1485 il.append(new ALOAD(3)); 1486 il.append(new ICONST(1)); 1487 il.append(instructionFactory.createPutField( 1488 getTopPCSuperOrCurrentClassName(), 1489 "jdoFlags", 1490 Type.BYTE)); 1491 il.append(new ALOAD(3)); 1492 InstructionHandle returnHandle = il.append(new ARETURN()); 1493 methodGen.addLocalVariable("pc", new ObjectType(classGen.getClassName()), 3, pcStartHandle, returnHandle); 1494 } else { il.append(instructionFactory.createNew(classGen.getClassName())); 1496 il.append(new DUP()); 1497 il.append(instructionFactory.createInvoke( 1498 classGen.getClassName(), 1499 "<init>", 1500 Type.VOID , 1501 new Type[]{}, 1502 Constants.INVOKESPECIAL)); 1503 il.append(new ASTORE(3)); 1504 InstructionHandle pcStartHandle = il.append(new ALOAD(3)); 1505 il.append(new ALOAD(1)); 1506 il.append(instructionFactory.createPutField( 1507 getTopPCSuperOrCurrentClassName(), 1508 "jdoStateManager", 1509 SM_OBJECT_TYPE)); 1510 il.append(new ALOAD(3)); 1511 il.append(new ICONST(1)); 1512 il.append(instructionFactory.createPutField( 1513 getTopPCSuperOrCurrentClassName(), 1514 "jdoFlags", 1515 Type.BYTE)); 1516 il.append(new ALOAD(0)); 1517 il.append(new ALOAD(2)); 1518 il.append(instructionFactory.createInvoke( 1519 getTopPCSuperOrCurrentClass().getClassName(), 1520 "jdoCopyKeyFieldsFromObjectId", 1521 Type.VOID , 1522 new Type[]{Type.OBJECT}, 1523 Constants.INVOKEVIRTUAL)); 1524 1525 il.append(new ALOAD(3)); 1526 il.append(new ARETURN()); 1527 methodGen.addLocalVariable("pc", new ObjectType(classGen.getClassName()), 3, pcStartHandle, il.getEnd()); 1528 } 1529 } 1530 1531 methodGen.setMaxLocals(); 1533 methodGen.setMaxStack(); 1534 classGen.addMethod(methodGen.getMethod()); 1535 il.dispose(); 1536 } 1537 1538 1539 private void addJdoNewInstance1(){ 1540 InstructionList il = new InstructionList(); 1541 MethodGen methodGen = new MethodGen( 1542 Constants.ACC_PUBLIC, 1543 PC_OBJECT_TYPE, 1544 new Type[]{SM_OBJECT_TYPE}, 1545 new String []{"sm"}, 1546 "jdoNewInstance", 1547 classGen.getClassName(), 1548 il, 1549 constantPoolGen); 1550 if (classGen.isAbstract()){ 1551 il.append(instructionFactory.createNew("javax.jdo.JDOFatalInternalException")); 1552 il.append(new DUP()); 1553 il.append(instructionFactory.createInvoke( 1554 "javax.jdo.JDOFatalInternalException", 1555 "<init>", 1556 Type.VOID, 1557 new Type[]{}, 1558 Constants.INVOKESPECIAL)); 1559 il.append(new ATHROW()); 1560 } else { 1561 il.append(instructionFactory.createNew(classGen.getClassName())); 1562 il.append(new DUP()); 1563 il.append(instructionFactory.createInvoke( 1564 classGen.getClassName(), 1565 "<init>", 1566 Type.VOID , 1567 new Type[]{}, 1568 Constants.INVOKESPECIAL)); 1569 il.append(new ASTORE(2)); 1570 InstructionHandle pcStartHandle = il.append(new ALOAD(2)); 1571 il.append(new ALOAD(1)); 1572 il.append(instructionFactory.createPutField( 1573 getTopPCSuperOrCurrentClassName(), 1574 "jdoStateManager", 1575 SM_OBJECT_TYPE)); 1576 il.append(new ALOAD(2)); 1577 il.append(new ICONST(1)); 1578 il.append(instructionFactory.createPutField( 1579 getTopPCSuperOrCurrentClassName(), 1580 "jdoFlags", 1581 Type.BYTE)); 1582 il.append(new ALOAD(2)); 1583 InstructionHandle returnHandle = il.append(new ARETURN()); 1584 methodGen.addLocalVariable( 1585 "pc", 1586 new ObjectType(classGen.getClassName()), 1587 2, 1588 pcStartHandle, 1589 returnHandle); 1590 } 1591 1592 methodGen.setMaxLocals(); 1594 methodGen.setMaxStack(); 1595 classGen.addMethod(methodGen.getMethod()); 1596 il.dispose(); 1597 } 1598 1599 1600 private void addRegisterClass(){ 1601 Method m = getStaticConstructor(); 1602 MethodGen methodGen = new MethodGen( 1603 m, 1604 classGen.getClassName(), 1605 constantPoolGen); 1606 InstructionList il = methodGen.getInstructionList(); 1607 InstructionHandle returnHandle = il.getEnd(); 1609 String className = getSetClass$Field(classGen.getClassName()); 1610 InstructionHandle nopTarget = il.append(new NOP()); 1611 il.append(instructionFactory.createGetStatic( 1612 classGen.getClassName(), 1613 className, 1614 new ObjectType("java.lang.Class"))); 1615 IFNONNULL ifnonnull = new IFNONNULL(null); 1616 il.append(ifnonnull); 1617 il.append(new PUSH(constantPoolGen ,classGen.getClassName())); 1618 il.append(instructionFactory.createInvoke( 1619 classGen.getClassName(), 1620 "class$", 1621 new ObjectType("java.lang.Class") , 1622 new Type[]{Type.STRING}, 1623 Constants.INVOKESTATIC)); 1624 il.append(new DUP()); 1625 il.append(instructionFactory.createPutStatic( 1626 classGen.getClassName(), 1627 className, 1628 new ObjectType("java.lang.Class"))); 1629 GOTO gotoIns = new GOTO(null); 1630 il.append(gotoIns); 1631 InstructionHandle ifnonnullHandle = il.append(instructionFactory.createGetStatic( 1632 classGen.getClassName(), 1633 className, 1634 new ObjectType("java.lang.Class"))); 1635 ifnonnull.setTarget(ifnonnullHandle); 1636 InstructionHandle gotoHandle = il.append(instructionFactory.createGetStatic( 1637 classGen.getClassName(), 1638 "jdoFieldNames", 1639 new ArrayType("java.lang.String",1))); 1640 gotoIns.setTarget(gotoHandle); 1641 il.append(instructionFactory.createGetStatic( 1642 classGen.getClassName(), 1643 "jdoFieldTypes", 1644 new ArrayType("java.lang.Class",1))); 1645 il.append(instructionFactory.createGetStatic( 1646 classGen.getClassName(), 1647 "jdoFieldFlags", 1648 new ArrayType(Type.BYTE,1))); 1649 il.append(instructionFactory.createGetStatic( 1650 classGen.getClassName(), 1651 "jdoPersistenceCapableSuperclass", 1652 new ObjectType("java.lang.Class"))); 1653 if (classGen.isAbstract()){ 1654 il.append(new ACONST_NULL()); 1655 } else { 1656 il.append(instructionFactory.createNew(classGen.getClassName())); 1657 il.append(new DUP()); 1658 il.append(instructionFactory.createInvoke( 1659 classGen.getClassName(), 1660 "<init>", 1661 Type.VOID , 1662 new Type[]{}, 1663 Constants.INVOKESPECIAL)); 1664 } 1665 il.append(instructionFactory.createInvoke( 1666 "javax.jdo.spi.JDOImplHelper", 1667 "registerClass", 1668 Type.VOID , 1669 new Type[]{ 1670 new ObjectType("java.lang.Class"), 1671 new ArrayType(Type.STRING,1), 1672 new ArrayType("java.lang.Class",1), 1673 new ArrayType(Type.BYTE,1), 1674 new ObjectType("java.lang.Class"), 1675 PC_OBJECT_TYPE 1676 }, 1677 Constants.INVOKESTATIC)); 1678 il.append(new RETURN()); 1679 try{ 1680 il.delete(returnHandle); 1681 } catch (TargetLostException e){ 1682 InstructionHandle[] targets = e.getTargets(); 1683 for (int i = 0; i < targets.length ; i++){ 1684 InstructionTargeter[] targeters = targets[i].getTargeters(); 1685 for (int j = 0; j < targeters.length ; j++){ 1686 targeters[j].updateTarget(targets[i], nopTarget); 1687 } 1688 } 1689 } 1690 methodGen.removeNOPs(); 1691 methodGen.setMaxLocals(); 1692 methodGen.setMaxStack(); 1693 classGen.replaceMethod(m, methodGen.getMethod()); 1694 il.dispose(); 1695 } 1696 1697 1698 private boolean writeObjectExist(){ 1699 Method[] methods = classGen.getMethods(); 1700 for(int i = 0; i < methods.length; i++) { 1701 Method m = methods[i]; 1702 if (m.getName().equals("writeObject") && 1703 m.getSignature().equals("(Ljava/io/ObjectOutputStream;)V")){ 1704 return true; 1705 } 1706 } 1707 return false; 1708 1709 } 1710 1711 private Method getWriteObject() { 1712 Method[] methods = classGen.getMethods(); 1713 for (int i = 0; i < methods.length; i++) { 1714 Method m = methods[i]; 1715 if (m.getName().equals("writeObject") && 1716 m.getSignature().equals("(Ljava/io/ObjectOutputStream;)V")) { 1717 return m; 1718 } 1719 } 1720 return null; 1721 1722 } 1723 1724 private boolean readObjectExist() { 1725 Method[] methods = classGen.getMethods(); 1726 for (int i = 0; i < methods.length; i++) { 1727 Method m = methods[i]; 1728 if (m.getName().equals("readObject") && 1729 m.getSignature().equals("(Ljava/io/ObjectInputStream;)V")) { 1730 return true; 1731 } 1732 } 1733 return false; 1734 1735 } 1736 1737 private Method getReadObject() { 1738 Method[] methods = classGen.getMethods(); 1739 for (int i = 0; i < methods.length; i++) { 1740 Method m = methods[i]; 1741 if (m.getName().equals("readObject") && 1742 m.getSignature().equals("(Ljava/io/ObjectInputStream;)V")) { 1743 return m; 1744 } 1745 } 1746 return null; 1747 1748 } 1749 1750 1751 private void addWriteObject(){ 1752 boolean rename = false; 1753 if (writeObjectExist() 1754 && classInfo.getTopPCSuperClass() == null) { 1755 Method m = getWriteObject(); 1757 MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen); 1758 mg.setName("versantWriteObject"); 1759 classGen.replaceMethod(m,mg.getMethod()); 1760 rename = true; 1761 } else if (writeObjectExist() && classInfo.getTopPCSuperClass() != null){ 1762 return; 1763 } 1764 InstructionList il = new InstructionList(); 1765 MethodGen methodGen = new MethodGen( 1766 Constants.ACC_PRIVATE, 1767 Type.VOID, 1768 new Type[]{new ObjectType("java.io.ObjectOutputStream")}, 1769 new String []{"out"}, 1770 "writeObject", 1771 classGen.getClassName(), 1772 il, 1773 constantPoolGen); 1774 if (classInfo.getTopPCSuperClass() == null){ 1775 il.append(new ALOAD(0)); 1776 il.append(instructionFactory.createInvoke( 1777 getTopPCSuperOrCurrentClass().getClassName(), 1778 "jdoPreSerialize", 1779 Type.VOID , 1780 new Type[]{}, 1781 Constants.INVOKESPECIAL)); 1782 } 1783 if (rename){ 1784 il.append(new ALOAD(0)); 1785 il.append(new ALOAD(1)); 1786 il.append(instructionFactory.createInvoke( 1787 classGen.getClassName(), 1788 "versantWriteObject", 1789 Type.VOID, 1790 new Type[]{new ObjectType("java.io.ObjectOutputStream")}, 1791 Constants.INVOKESPECIAL)); 1792 } else { 1793 il.append(new ALOAD(1)); 1794 il.append(instructionFactory.createInvoke( 1795 "java.io.ObjectOutputStream", 1796 "defaultWriteObject", 1797 Type.VOID , 1798 new Type[]{}, 1799 Constants.INVOKEVIRTUAL)); 1800 } 1801 1802 if (classInfo.getTopPCSuperClass() == null && detach){ 1803 il.append(new ALOAD(0)); 1804 il.append(instructionFactory.createGetField(classGen.getClassName(), 1805 "jdoStateManager", 1806 new ObjectType(STATE_MANAGER))); 1807 il.append(new INSTANCEOF(constantPoolGen.addClass(DETACHED_STATE_MANAGER))); 1808 IFEQ ifeq = new IFEQ(null); 1809 il.append(ifeq); 1810 il.append(new ALOAD(1)); 1811 il.append(new ICONST(1)); 1812 il.append(instructionFactory.createInvoke("java.io.ObjectOutputStream", 1813 "writeBoolean", 1814 Type.VOID, 1815 new Type[]{Type.BOOLEAN}, 1816 Constants.INVOKEVIRTUAL)); 1817 il.append(new ALOAD(1)); 1818 il.append(new ALOAD(0)); 1819 il.append(instructionFactory.createGetField(classGen.getClassName(), 1820 "jdoStateManager", 1821 new ObjectType(STATE_MANAGER))); 1822 il.append(instructionFactory.createInvoke("java.io.ObjectOutputStream", 1823 "writeObject", 1824 Type.VOID, 1825 new Type[]{Type.OBJECT}, 1826 Constants.INVOKEVIRTUAL)); 1827 il.append(new ALOAD(1)); 1828 il.append(new ALOAD(0)); 1829 il.append(instructionFactory.createGetField(classGen.getClassName(), 1830 "jdoFlags", 1831 Type.BYTE)); 1832 il.append(instructionFactory.createInvoke("java.io.ObjectOutputStream", 1833 "writeByte", 1834 Type.VOID, 1835 new Type[]{Type.INT}, 1836 Constants.INVOKEVIRTUAL)); 1837 GOTO aGoto = new GOTO(null); 1838 il.append(aGoto); 1839 InstructionHandle aload1Handle = il.append(new ALOAD(1)); 1840 ifeq.setTarget(aload1Handle); 1841 il.append(new ICONST(0)); 1842 il.append(instructionFactory.createInvoke("java.io.ObjectOutputStream", 1843 "writeBoolean", 1844 Type.VOID, 1845 new Type[]{Type.BOOLEAN}, 1846 Constants.INVOKEVIRTUAL)); 1847 InstructionHandle returnHandle = il.append(new RETURN()); 1848 aGoto.setTarget(returnHandle); 1849 } else { 1850 il.append(new RETURN()); 1851 } 1852 1853 methodGen.addException("java.io.IOException"); 1854 methodGen.setMaxLocals(); 1855 methodGen.setMaxStack(); 1856 classGen.addMethod(methodGen.getMethod()); 1857 il.dispose(); 1858 1859 } 1860 1861 private void addReadObject() { 1862 if (classInfo.getTopPCSuperClass() == null && detach) { 1863 boolean rename = false; 1864 if (readObjectExist()) { 1865 Method m = getReadObject(); 1867 MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen); 1868 mg.setName("versantReadObject"); 1869 classGen.replaceMethod(m, mg.getMethod()); 1870 rename = true; 1871 } 1872 1873 InstructionList il = new InstructionList(); 1874 MethodGen methodGen = new MethodGen(Constants.ACC_PRIVATE, 1875 Type.VOID, 1876 new Type[]{new ObjectType("java.io.ObjectInputStream")}, 1877 new String []{"in"}, 1878 "readObject", 1879 classGen.getClassName(), 1880 il, 1881 constantPoolGen); 1882 1883 if (rename){ 1884 il.append(new ALOAD(0)); 1885 il.append(new ALOAD(1)); il.append(instructionFactory.createInvoke( 1886 classGen.getClassName(), 1887 "versantReadObject", 1888 Type.VOID, 1889 new Type[]{new ObjectType("java.io.ObjectInputStream")}, 1890 Constants.INVOKESPECIAL)); 1891 1892 1893 } else { 1894 il.append(new ALOAD(1)); 1895 il.append(instructionFactory.createInvoke("java.io.ObjectInputStream", 1896 "defaultReadObject", 1897 Type.VOID, 1898 new Type[]{}, 1899 Constants.INVOKEVIRTUAL)); 1900 } 1901 il.append(new ALOAD(1)); 1902 il.append(instructionFactory.createInvoke("java.io.ObjectInputStream", 1903 "readBoolean", 1904 Type.BOOLEAN, 1905 new Type[]{}, 1906 Constants.INVOKEVIRTUAL)); 1907 IFEQ ifeq = new IFEQ(null); 1908 il.append(ifeq); il.append(new ALOAD(0)); 1910 il.append(new ALOAD(1)); 1911 il.append(instructionFactory.createInvoke("java.io.ObjectInputStream", 1912 "readObject", 1913 Type.OBJECT, 1914 new Type[]{}, 1915 Constants.INVOKEVIRTUAL)); 1916 il.append(instructionFactory.createCheckCast(new ObjectType(DETACHED_STATE_MANAGER))); 1917 il.append(instructionFactory.createPutField(classGen.getClassName(), 1918 "jdoStateManager", 1919 new ObjectType(STATE_MANAGER))); 1920 il.append(new ALOAD(0)); 1921 il.append(new ALOAD(1)); 1922 il.append(instructionFactory.createInvoke("java.io.ObjectInputStream", 1923 "readByte", 1924 Type.BYTE, 1925 new Type[]{}, 1926 Constants.INVOKEVIRTUAL)); 1927 il.append(instructionFactory.createPutField(classGen.getClassName(), 1928 "jdoFlags", 1929 Type.BYTE)); 1930 1931 1932 InstructionHandle returnHandle = il.append(new RETURN()); 1933 ifeq.setTarget(returnHandle); 1934 1935 methodGen.addException("java.io.IOException"); 1936 methodGen.addException("java.lang.ClassNotFoundException"); 1937 methodGen.setMaxLocals(); 1938 methodGen.setMaxStack(); 1939 classGen.addMethod(methodGen.getMethod()); 1940 il.dispose(); 1941 } 1942 } 1943 1944 1945 private void addJdoPreSerialize(){ 1946 if (classInfo.getTopPCSuperClass() == null){ 1947 InstructionList il = new InstructionList(); 1948 MethodGen methodGen = new MethodGen( 1949 Constants.ACC_PRIVATE, 1950 Type.VOID, 1951 new Type[]{}, 1952 new String []{}, 1953 "jdoPreSerialize", 1954 classGen.getClassName(), 1955 il, 1956 constantPoolGen); 1957 1958 InstructionHandle returnHandle = il.insert(new RETURN()); 1959 il.insert(instructionFactory.createInvoke( 1960 STATE_MANAGER, 1961 "preSerialize", 1962 Type.VOID , 1963 new Type[]{PC_OBJECT_TYPE}, 1964 Constants.INVOKEINTERFACE)); 1965 il.insert(new ALOAD(0)); 1966 il.insert(instructionFactory.createGetField( 1967 getTopPCSuperOrCurrentClassName(), 1968 "jdoStateManager", 1969 SM_OBJECT_TYPE)); 1970 il.insert(new ALOAD(0)); 1971 il.insert(new IFNULL(returnHandle)); 1972 il.insert(instructionFactory.createGetField( 1973 getTopPCSuperOrCurrentClassName(), 1974 "jdoStateManager", 1975 SM_OBJECT_TYPE)); 1976 il.insert(new ALOAD(0)); 1977 1978 methodGen.setMaxLocals(); 1980 methodGen.setMaxStack(); 1981 classGen.addMethod(methodGen.getMethod()); 1982 il.dispose(); 1983 } 1984 } 1985 1986 1987 private void addJdoCopyFields(){ 1988 InstructionList il = new InstructionList(); 1989 MethodGen methodGen = new MethodGen( 1990 Constants.ACC_PUBLIC, 1991 Type.VOID, 1992 new Type[]{Type.OBJECT, new ArrayType(Type.INT,1)}, 1993 new String []{"pc","fieldNumbers"}, 1994 "jdoCopyFields", 1995 classGen.getClassName(), 1996 il, 1997 constantPoolGen); 1998 1999 il.append(new ALOAD(1)); 2000 il.append(instructionFactory.createCheckCast(new ObjectType(classGen.getClassName()))); 2001 il.append(new ASTORE(3)); 2002 InstructionHandle otherStartHandle = il.append(new ALOAD(3)); 2003 il.append(instructionFactory.createGetField( 2004 getTopPCSuperOrCurrentClassName(), 2005 "jdoStateManager", 2006 SM_OBJECT_TYPE)); 2007 il.append(new ALOAD(0)); 2008 il.append(instructionFactory.createGetField( 2009 getTopPCSuperOrCurrentClassName(), 2010 "jdoStateManager", 2011 SM_OBJECT_TYPE)); 2012 IF_ACMPEQ if_acmpeq = new IF_ACMPEQ(null); 2013 il.append(if_acmpeq); 2014 il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2015 il.append(new DUP()); 2016 il.append(new PUSH(constantPoolGen,"this.jdoStateManager != other.jdoStateManager")); 2017 il.append(instructionFactory.createInvoke( 2018 "java.lang.IllegalArgumentException", 2019 "<init>", 2020 Type.VOID, 2021 new Type[]{Type.STRING}, 2022 Constants.INVOKESPECIAL)); 2023 il.append(new ATHROW()); 2024 InstructionHandle if_acmpeqHandle = il.append(new ALOAD(0)); 2025 if_acmpeq.setTarget(if_acmpeqHandle); 2026 il.append(instructionFactory.createGetField( 2027 getTopPCSuperOrCurrentClassName(), 2028 "jdoStateManager", 2029 SM_OBJECT_TYPE)); 2030 IFNONNULL ifnonnull = new IFNONNULL(null); 2031 il.append(ifnonnull); 2032 il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2033 il.append(new DUP()); 2034 il.append(new PUSH(constantPoolGen,"this.jdoStateManager == null")); 2035 il.append(instructionFactory.createInvoke( 2036 "java.lang.IllegalArgumentException", 2037 "<init>", 2038 Type.VOID, 2039 new Type[]{Type.STRING}, 2040 Constants.INVOKESPECIAL)); 2041 il.append(new ATHROW()); 2042 InstructionHandle ifnonnullHandle = il.append(new ICONST(0)); 2043 ifnonnull.setTarget(ifnonnullHandle); 2044 il.append(new ISTORE(4)); 2045 GOTO aGoto = new GOTO(null); 2046 InstructionHandle iStartHandle = il.append(aGoto); 2047 InstructionHandle if_icmpltHandle = il.append(new ALOAD(0)); 2048 il.append(new ALOAD(3)); 2049 il.append(new ALOAD(2)); 2050 il.append(new ILOAD(4)); 2051 il.append(new IALOAD()); 2052 il.append(instructionFactory.createInvoke( 2053 classGen.getClassName(), 2054 "jdoCopyField", 2055 Type.VOID, 2056 new Type[]{new ObjectType(classGen.getClassName()),Type.INT}, 2057 Constants.INVOKEVIRTUAL)); 2058 il.append(new IINC(4,1)); 2059 InstructionHandle aGotoHandle = il.append(new ILOAD(4)); 2060 aGoto.setTarget(aGotoHandle); 2061 il.append(new ALOAD(2)); 2062 il.append(new ARRAYLENGTH()); 2063 il.append(new IF_ICMPLT(if_icmpltHandle)); 2064 il.append(new RETURN()); 2065 2066 methodGen.addLocalVariable("other", new ObjectType(classGen.getClassName()), 3, otherStartHandle, il.getEnd()); 2067 methodGen.addLocalVariable("i", Type.INT, 4, iStartHandle, il.getEnd()); 2068 methodGen.setMaxLocals(); 2070 methodGen.setMaxStack(); 2071 classGen.addMethod(methodGen.getMethod()); 2072 il.dispose(); 2073 } 2074 2075 2076 private void addJdoCopyField(){ 2077 InstructionList il = new InstructionList(); 2078 MethodGen methodGen = new MethodGen( 2079 Constants.ACC_PUBLIC, 2080 Type.VOID, 2081 new Type[]{new ObjectType(classGen.getClassName()), Type.INT}, 2082 new String []{"other","fieldNumber"}, 2083 "jdoCopyField", 2084 classGen.getClassName(), 2085 il, 2086 constantPoolGen); 2087 2088 il.append(new ILOAD(2)); 2089 il.append(instructionFactory.createGetStatic( 2090 classGen.getClassName(), 2091 "jdoInheritedFieldCount", 2092 Type.INT)); 2093 il.append(new ISUB()); 2094 il.append(new ISTORE(3)); 2095 InstructionHandle relativeFieldStartHandle = il.append(new ILOAD(3)); 2096 2097 int switchCount = fieldSet.size(); 2098 int[] match = new int[switchCount]; 2099 InstructionHandle[] targets = new InstructionHandle[switchCount]; 2100 ArrayList tempInsLists = new ArrayList(switchCount+1); 2101 int i = 0; 2102 ArrayList tempList = new ArrayList(fieldSet); 2103 for (Iterator fieldIter = tempList.iterator(); fieldIter.hasNext();i++) { 2104 FieldInfo fieldInfo = (FieldInfo)fieldIter.next(); 2105 InstructionList tempIL = new InstructionList(); 2106 match[i] = fieldInfo.getFieldNo(); 2107 targets[i] = tempIL.append(new ALOAD(0)); 2108 tempIL.append(new ALOAD(1)); 2109 tempIL.append(instructionFactory.createGetField( 2110 classGen.getClassName(), 2111 fieldInfo.getFieldName(), 2112 fieldInfo.getType())); 2113 tempIL.append(instructionFactory.createPutField( 2114 classGen.getClassName(), 2115 fieldInfo.getFieldName(), 2116 fieldInfo.getType())); 2117 tempIL.append(new RETURN()); 2118 tempInsLists.add(tempIL); 2119 } 2120 InstructionList tempIL = new InstructionList(); 2122 InstructionHandle defaultHandle = null; 2123 if (classInfo.getTopPCSuperClass() == null){ 2124 defaultHandle = tempIL.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2125 tempIL.append(new DUP()); 2126 tempIL.append(new PUSH(constantPoolGen,"fieldNumber")); 2127 tempIL.append(instructionFactory.createInvoke( 2128 "java.lang.IllegalArgumentException", 2129 "<init>", 2130 Type.VOID , 2131 new Type[]{Type.STRING}, 2132 Constants.INVOKESPECIAL)); 2133 tempIL.append(new ATHROW()); 2134 } else { 2135 defaultHandle = tempIL.append(new ALOAD(0)); 2136 tempIL.append(new ALOAD(1)); 2137 tempIL.append(new ILOAD(2)); 2138 tempIL.append(instructionFactory.createInvoke( 2139 classInfo.getTopPCSuperClass().getClassName(), 2140 "jdoCopyField", 2141 Type.VOID, 2142 new Type[]{new ObjectType(classInfo.getTopPCSuperClass().getClassName()), 2143 Type.INT}, 2144 Constants.INVOKESPECIAL)); 2145 } 2146 tempInsLists.add(tempIL); 2147 il.append(new LOOKUPSWITCH(match,targets,defaultHandle)); 2149 for (Iterator tempIlIter = tempInsLists.iterator(); tempIlIter.hasNext();) { InstructionList list = (InstructionList) tempIlIter.next(); 2151 il.append(list); 2152 } 2153 il.append(new RETURN()); 2154 2155 methodGen.addLocalVariable("relativeField", Type.INT, 3, relativeFieldStartHandle, il.getEnd()); 2156 2157 methodGen.setMaxLocals(); 2159 methodGen.setMaxStack(); 2160 classGen.addMethod(methodGen.getMethod()); 2161 il.dispose(); 2162 } 2163 2164 2165 private void addJdoProvideFields(){ 2166 2167 InstructionList il = new InstructionList(); 2168 MethodGen methodGen = new MethodGen( 2169 Constants.ACC_PUBLIC , 2170 Type.VOID, 2171 new Type[]{new ArrayType(Type.INT,1)}, 2172 new String []{"fieldNumbers"}, 2173 "jdoProvideFields", 2174 classGen.getClassName(), 2175 il, 2176 constantPoolGen); 2177 il.append(new ICONST(0)); 2178 il.append(new ISTORE(2)); 2179 InstructionHandle iloadHandle = il.append(new ILOAD(2)); 2180 il.append(new ALOAD(1)); 2181 il.append(new ARRAYLENGTH()); 2182 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 2183 il.append(if_icmpge); 2184 il.append(new ALOAD(1)); 2185 il.append(new ILOAD(2)); 2186 il.append(new IALOAD()); 2187 il.append(new ISTORE(3)); 2188 InstructionHandle aloadHandle = il.append(new ALOAD(0)); 2189 il.append(new ILOAD(3)); 2190 il.append(instructionFactory.createInvoke( 2191 classGen.getClassName(), 2192 "jdoProvideField", 2193 Type.VOID , 2194 new Type[]{Type.INT}, 2195 Constants.INVOKEVIRTUAL)); 2196 InstructionHandle iincHandle = il.append(new IINC(2,1)); 2197 il.append(new GOTO(iloadHandle)); 2198 InstructionHandle returnHandle = il.append(new RETURN()); 2199 if_icmpge.setTarget(returnHandle); 2200 methodGen.addLocalVariable("i",Type.INT,2,iloadHandle,returnHandle); 2201 methodGen.addLocalVariable("fieldNumber",Type.INT,3,aloadHandle,iincHandle); 2202 methodGen.setMaxLocals(); 2204 methodGen.setMaxStack(); 2205 classGen.addMethod(methodGen.getMethod()); 2206 il.dispose(); 2207 } 2208 2209 private void addJdoProvideField(){ 2210 2211 ArrayList myList = new ArrayList(fieldSet); 2212 ListIterator fieldIter = myList.listIterator(); 2213 2214 while (fieldIter.hasNext()){fieldIter.next();} 2215 2216 InstructionList il = new InstructionList(); 2217 2218 MethodGen methodGen = new MethodGen( 2219 Constants.ACC_PUBLIC, 2220 Type.VOID, 2221 new Type[]{Type.INT}, 2222 new String []{"fieldNumber"}, 2223 "jdoProvideField", 2224 classGen.getClassName(), 2225 il, 2226 constantPoolGen); 2227 2228 if (!isEmpty){ 2229 int size = fieldSet.size(); 2230 int[] match = new int[size]; 2231 int fieldNum = size; 2232 InstructionHandle[] targets = new InstructionHandle[size]; 2233 InstructionHandle defaultHandle = null; 2234 InstructionHandle returnHandel = null; 2235 Set switchList = new TreeSet(); 2236 if (classInfo.getPersistenceCapableSuperclass() == null){ 2237 defaultHandle = il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2238 il.append(new DUP()); 2239 2240 il.append(instructionFactory.createNew("java.lang.StringBuffer")); 2241 il.append(new DUP()); 2242 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2243 "<init>", 2244 Type.VOID, 2245 new Type[]{}, 2246 Constants.INVOKESPECIAL)); 2247 il.append(new PUSH(constantPoolGen, "Class " + classGen.getClassName() + 2248 " called with invalid fieldNumber = ")); 2249 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2250 "append", 2251 Type.STRINGBUFFER, 2252 new Type[]{Type.STRING}, 2253 Constants.INVOKEVIRTUAL)); 2254 il.append(new ILOAD(1)); 2255 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2256 "append", 2257 Type.STRINGBUFFER, 2258 new Type[]{Type.INT}, 2259 Constants.INVOKEVIRTUAL)); 2260 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2261 "toString", 2262 Type.STRING, 2263 new Type[]{}, 2264 Constants.INVOKEVIRTUAL)); 2265 2266 il.append(instructionFactory.createInvoke( 2267 "java.lang.IllegalArgumentException", 2268 "<init>", 2269 Type.VOID , 2270 new Type[]{Type.STRING}, 2271 Constants.INVOKESPECIAL)); 2272 il.append(new ATHROW()); 2273 returnHandel = il.append(new RETURN()); 2274 } else { 2275 returnHandel = il.insert(new RETURN()); 2276 il.insert(new ATHROW()); 2277 il.insert(instructionFactory.createInvoke( 2278 "java.lang.IllegalArgumentException", 2279 "<init>", 2280 Type.VOID , 2281 new Type[]{Type.STRING}, 2282 Constants.INVOKESPECIAL)); 2283 2285 il.insert(instructionFactory.createInvoke("java.lang.StringBuffer", 2286 "toString", 2287 Type.STRING, 2288 new Type[]{}, 2289 Constants.INVOKEVIRTUAL)); 2290 il.insert(instructionFactory.createInvoke("java.lang.StringBuffer", 2291 "append", 2292 Type.STRINGBUFFER, 2293 new Type[]{Type.INT}, 2294 Constants.INVOKEVIRTUAL)); 2295 il.insert(new ILOAD(1)); 2296 il.insert(instructionFactory.createInvoke("java.lang.StringBuffer", 2297 "append", 2298 Type.STRINGBUFFER, 2299 new Type[]{Type.STRING}, 2300 Constants.INVOKEVIRTUAL)); 2301 il.insert(new PUSH(constantPoolGen, "Class " + classGen.getClassName() + 2302 " called with invalid fieldNumber = ")); 2303 il.insert(instructionFactory.createInvoke("java.lang.StringBuffer", 2304 "<init>", 2305 Type.VOID, 2306 new Type[]{}, 2307 Constants.INVOKESPECIAL)); 2308 il.insert(new DUP()); 2309 il.insert(instructionFactory.createNew("java.lang.StringBuffer")); 2310 2311 2312 il.insert(new DUP()); 2313 InstructionHandle newHandel = il.insert(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2314 il.insert(new GOTO(returnHandel)); 2315 il.insert(instructionFactory.createInvoke( 2316 classInfo.getPersistenceCapableSuperclass(), 2317 "jdoProvideField", 2318 Type.VOID , 2319 new Type[]{Type.INT}, 2320 Constants.INVOKESPECIAL)); 2321 il.insert(new ILOAD(1)); 2322 il.insert(new ALOAD(0)); 2323 il.insert(new IFGE(newHandel)); 2324 defaultHandle = il.insert(new ILOAD(2)); 2325 } 2326 2327 while (fieldIter.hasPrevious()){ 2328 FieldInfo fieldInfo = (FieldInfo)fieldIter.previous(); 2329 fieldNum --; 2330 Type fieldType = fieldInfo.getType(); 2331 String stateManagerProvidedField = null; 2332 boolean isObject = false; 2333 if (typeToProvidedField.containsKey(fieldInfo.getType())){ 2334 stateManagerProvidedField = (String )typeToProvidedField.get(fieldInfo.getType()); 2335 isObject = false; 2336 } else { 2337 isObject = true; 2338 } 2339 2340 il.insert(new GOTO(returnHandel)); 2341 2342 if (isObject){ 2343 il.insert(instructionFactory.createInvoke( 2344 STATE_MANAGER, 2345 "providedObjectField", 2346 Type.VOID , 2347 new Type[]{PC_OBJECT_TYPE,Type.INT,Type.OBJECT}, 2348 Constants.INVOKEINTERFACE)); 2349 } else { 2350 il.insert(instructionFactory.createInvoke( 2351 STATE_MANAGER, 2352 stateManagerProvidedField, 2353 Type.VOID, 2354 new Type[]{PC_OBJECT_TYPE,Type.INT,fieldType}, 2355 Constants.INVOKEINTERFACE)); 2356 } 2357 il.insert(instructionFactory.createGetField( 2358 classGen.getClassName(), 2359 fieldInfo.getFieldName(), 2360 fieldType)); 2361 2362 il.insert(new ALOAD(0)); 2363 il.insert(new ILOAD(1)); 2364 il.insert(new ALOAD(0)); 2365 il.insert(instructionFactory.createGetField( 2366 getTopPCSuperOrCurrentClassName(), 2367 "jdoStateManager", 2368 SM_OBJECT_TYPE)); 2369 InstructionHandle switchHandel = il.insert(new ALOAD(0)); 2370 TableSwitchHelper tsh = new TableSwitchHelper(); 2371 tsh.match = fieldNum; 2372 tsh.target = switchHandel; 2373 switchList.add(tsh); 2374 2375 } 2376 Iterator sIter = switchList.iterator(); 2377 int count = 0; 2378 while (sIter.hasNext()){ 2379 TableSwitchHelper tsh = (TableSwitchHelper)sIter.next(); 2380 match[count] = tsh.match; 2381 targets[count] = tsh.target; 2382 count ++; 2383 } 2384 2385 il.insert(new TABLESWITCH(match,targets,defaultHandle)); 2386 InstructionHandle relativeFieldFromHandle = il.insert(new ILOAD(2)); 2387 il.insert(new ISTORE(2)); 2388 il.insert(new ISUB()); 2389 il.insert(instructionFactory.createGetStatic( 2390 classGen.getClassName(), 2391 "jdoInheritedFieldCount", 2392 Type.INT)); 2393 il.insert(new ILOAD(1)); 2394 methodGen.addLocalVariable("relativeField",Type.INT,2,relativeFieldFromHandle,returnHandel); 2395 } else if (classInfo.getPersistenceCapableSuperclass() != null){ 2396 2397 2398 il.append(new ILOAD(1)); 2399 il.append(instructionFactory.createGetStatic( 2400 classGen.getClassName(), 2401 "jdoInheritedFieldCount", 2402 Type.INT)); 2403 il.append(new ISUB()); 2404 il.append(new ISTORE(2)); 2405 InstructionHandle relativeField_Start = il.append(new ILOAD(2)); 2406 IFGE ifge = new IFGE(null); 2407 il.append(ifge); 2408 il.append(new ALOAD(0)); 2409 il.append(new ILOAD(1)); 2410 il.append(instructionFactory.createInvoke( 2411 classInfo.getPersistenceCapableSuperclass(), 2412 "jdoProvideField", 2413 Type.VOID , 2414 new Type[]{Type.INT}, 2415 Constants.INVOKESPECIAL)); 2416 GOTO aGoto = new GOTO(null); 2417 il.append(aGoto); 2418 InstructionHandle newHandel = il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2419 ifge.setTarget(newHandel); 2420 il.append(new DUP()); 2421 il.append(instructionFactory.createNew("java.lang.StringBuffer")); 2423 il.append(new DUP()); 2424 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2425 "<init>", 2426 Type.VOID, 2427 new Type[]{}, 2428 Constants.INVOKESPECIAL)); 2429 il.append(new PUSH(constantPoolGen, "Class "+classGen.getClassName() + 2430 " called with invalid fieldNumber = ")); 2431 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2432 "append", 2433 Type.STRINGBUFFER, 2434 new Type[]{Type.STRING}, 2435 Constants.INVOKEVIRTUAL)); 2436 il.append(new ILOAD(1)); 2437 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2438 "append", 2439 Type.STRINGBUFFER, 2440 new Type[]{Type.INT}, 2441 Constants.INVOKEVIRTUAL)); 2442 il.append(instructionFactory.createInvoke("java.lang.StringBuffer", 2443 "toString", 2444 Type.STRING, 2445 new Type[]{}, 2446 Constants.INVOKEVIRTUAL)); 2447 2448 il.append(instructionFactory.createInvoke( 2449 "java.lang.IllegalArgumentException", 2450 "<init>", 2451 Type.VOID , 2452 new Type[]{Type.STRING}, 2453 Constants.INVOKESPECIAL)); 2454 il.append(new ATHROW()); 2455 il.append(new RETURN()); 2456 aGoto.setTarget(il.getEnd()); 2457 2458 methodGen.addLocalVariable("relativeField",Type.INT,2,relativeField_Start,il.getEnd()); 2459 2460 } else { 2461 il.append(new RETURN()); 2462 } 2463 methodGen.setMaxLocals(); 2465 methodGen.setMaxStack(); 2466 classGen.addMethod(methodGen.getMethod()); 2467 il.dispose(); 2468 } 2469 2470 private void addJdoReplaceFields(){ 2471 InstructionList il = new InstructionList(); 2472 MethodGen methodGen = new MethodGen( 2473 Constants.ACC_PUBLIC , 2474 Type.VOID, 2475 new Type[]{new ArrayType(Type.INT,1)}, 2476 new String []{"fieldNumbers"}, 2477 "jdoReplaceFields", 2478 classGen.getClassName(), 2479 il, 2480 constantPoolGen); 2481 il.append(new ICONST(0)); 2482 il.append(new ISTORE(2)); 2483 InstructionHandle iloadHandle = il.append(new ILOAD(2)); 2484 il.append(new ALOAD(1)); 2485 il.append(new ARRAYLENGTH()); 2486 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 2487 il.append(if_icmpge); 2488 il.append(new ALOAD(1)); 2489 il.append(new ILOAD(2)); 2490 il.append(new IALOAD()); 2491 il.append(new ISTORE(3)); 2492 InstructionHandle aloadHandle = il.append(new ALOAD(0)); 2493 il.append(new ILOAD(3)); 2494 il.append(instructionFactory.createInvoke( 2495 classGen.getClassName(), 2496 "jdoReplaceField", 2497 Type.VOID , 2498 new Type[]{Type.INT}, 2499 Constants.INVOKEVIRTUAL)); 2500 InstructionHandle iincHandle = il.append(new IINC(2,1)); 2501 il.append(new GOTO(iloadHandle)); 2502 InstructionHandle returnHandle = il.append(new RETURN()); 2503 if_icmpge.setTarget(returnHandle); 2504 methodGen.addLocalVariable("i",Type.INT,2,iloadHandle,returnHandle); 2505 methodGen.addLocalVariable("fieldNumber",Type.INT,3,aloadHandle,iincHandle); 2506 methodGen.setMaxLocals(); 2508 methodGen.setMaxStack(); 2509 classGen.addMethod(methodGen.getMethod()); 2510 il.dispose(); 2511 } 2512 2513 private void addJdoReplaceField(){ 2514 2515 int size = fieldSet.size(); 2516 int[] match = new int[size]; 2517 InstructionHandle[] targets = new InstructionHandle[size]; 2518 InstructionHandle defaultHandle = null; 2519 InstructionHandle returnHandel = null; 2520 Set switchList = new TreeSet(); 2521 ArrayList myList = new ArrayList(fieldSet); 2522 ListIterator fieldIter = myList.listIterator(); 2523 int fieldNum = size; 2524 while (fieldIter.hasNext()){fieldIter.next();} 2525 InstructionList il = new InstructionList(); 2526 2527 MethodGen methodGen = new MethodGen( 2528 Constants.ACC_PUBLIC, 2529 Type.VOID, 2530 new Type[]{Type.INT}, 2531 new String []{"fieldNumber"}, 2532 "jdoReplaceField", 2533 classGen.getClassName(), 2534 il, 2535 constantPoolGen); 2536 if (!isEmpty){ 2537 if (classInfo.getPersistenceCapableSuperclass() == null){ 2538 defaultHandle = il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2539 il.append(new DUP()); 2540 il.append(new PUSH(constantPoolGen,"fieldNumber")); 2541 il.append(instructionFactory.createInvoke( 2542 "java.lang.IllegalArgumentException", 2543 "<init>", 2544 Type.VOID , 2545 new Type[]{Type.STRING}, 2546 Constants.INVOKESPECIAL)); 2547 il.append(new ATHROW()); 2548 returnHandel = il.append(new RETURN()); 2549 } else { 2550 returnHandel = il.insert(new RETURN()); 2551 il.insert(new ATHROW()); 2552 il.insert(instructionFactory.createInvoke( 2553 "java.lang.IllegalArgumentException", 2554 "<init>", 2555 Type.VOID , 2556 new Type[]{Type.STRING}, 2557 Constants.INVOKESPECIAL)); 2558 il.insert(new PUSH(constantPoolGen,"fieldNumber")); 2559 il.insert(new DUP()); 2560 InstructionHandle newHandel = il.insert(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2561 il.insert(new GOTO(returnHandel)); 2562 il.insert(instructionFactory.createInvoke( 2563 classInfo.getPersistenceCapableSuperclass(), 2564 "jdoReplaceField", 2565 Type.VOID , 2566 new Type[]{Type.INT}, 2567 Constants.INVOKESPECIAL)); 2568 il.insert(new ILOAD(1)); 2569 il.insert(new ALOAD(0)); 2570 il.insert(new IFGE(newHandel)); 2571 defaultHandle = il.insert(new ILOAD(2)); 2572 } 2573 2574 while (fieldIter.hasPrevious()){ 2575 FieldInfo fieldInfo = (FieldInfo)fieldIter.previous(); 2576 fieldNum --; 2577 Type fieldType = fieldInfo.getType(); 2578 String stateManagerReplaceField = null; 2579 boolean isObject = false; 2580 if (typeToReplacingField.containsKey(fieldInfo.getType())){ 2581 stateManagerReplaceField = (String )typeToReplacingField.get(fieldInfo.getType()); 2582 isObject = false; 2583 } else { 2584 isObject = true; 2585 } 2586 2587 il.insert(new GOTO(returnHandel)); 2588 il.insert(instructionFactory.createPutField( 2589 classGen.getClassName(), 2590 fieldInfo.getFieldName(), 2591 fieldType)); 2592 if (isObject){ 2593 if (fieldInfo.isArray()){ 2594 il.insert(instructionFactory.createCheckCast(new ObjectType(fieldInfo.getSignature()))); 2595 }else{ 2596 il.insert(instructionFactory.createCheckCast(new ObjectType(fieldInfo.getReturnType()))); 2597 } 2598 il.insert(instructionFactory.createInvoke( 2599 STATE_MANAGER, 2600 "replacingObjectField", 2601 Type.OBJECT , 2602 new Type[]{PC_OBJECT_TYPE,Type.INT}, 2603 Constants.INVOKEINTERFACE)); 2604 } else { 2605 il.insert(instructionFactory.createInvoke( 2606 STATE_MANAGER, 2607 stateManagerReplaceField, 2608 fieldType , 2609 new Type[]{PC_OBJECT_TYPE,Type.INT}, 2610 Constants.INVOKEINTERFACE)); 2611 } 2612 il.insert(new ILOAD(1)); 2613 il.insert(new ALOAD(0)); 2614 il.insert(instructionFactory.createGetField( 2615 getTopPCSuperOrCurrentClassName(), 2616 "jdoStateManager", 2617 SM_OBJECT_TYPE)); 2618 il.insert(new ALOAD(0)); 2619 InstructionHandle switchHandel = il.insert(new ALOAD(0)); 2620 TableSwitchHelper tsh = new TableSwitchHelper(); 2621 tsh.match = fieldNum; 2622 tsh.target = switchHandel; 2623 switchList.add(tsh); 2624 } 2625 Iterator sIter = switchList.iterator(); 2626 int count = 0; 2627 while (sIter.hasNext()){ 2628 TableSwitchHelper tsh = (TableSwitchHelper)sIter.next(); 2629 match[count] = tsh.match; 2630 targets[count] = tsh.target; 2631 count ++; 2632 } 2633 2634 il.insert(new TABLESWITCH(match,targets,defaultHandle)); 2635 InstructionHandle relativeFieldFromHandle = il.insert(new ILOAD(2)); 2636 il.insert(new ISTORE(2)); 2637 il.insert(new ISUB()); 2638 il.insert(instructionFactory.createGetStatic( 2639 classGen.getClassName(), 2640 "jdoInheritedFieldCount", 2641 Type.INT)); 2642 il.insert(new ILOAD(1)); 2643 methodGen.addLocalVariable("relativeField",Type.INT,2,relativeFieldFromHandle,returnHandel); 2644 } else if (classInfo.getPersistenceCapableSuperclass() != null){ 2645 il.append(new ILOAD(1)); 2646 il.append(instructionFactory.createGetStatic( 2647 classGen.getClassName(), 2648 "jdoInheritedFieldCount", 2649 Type.INT)); 2650 il.append(new ISUB()); 2651 il.append(new ISTORE(2)); 2652 InstructionHandle relativeField_Start = il.append(new ILOAD(2)); 2653 IFGE ifge = new IFGE(null); 2654 il.append(ifge); 2655 il.append(new ALOAD(0)); 2656 il.append(new ILOAD(1)); 2657 2658 il.append(instructionFactory.createInvoke( 2659 classInfo.getPersistenceCapableSuperclass(), 2660 "jdoReplaceField", 2661 Type.VOID , 2662 new Type[]{Type.INT}, 2663 Constants.INVOKESPECIAL)); 2664 GOTO aGoto = new GOTO(null); 2665 il.append(aGoto); 2666 InstructionHandle newHandel = il.append(instructionFactory.createNew("java.lang.IllegalArgumentException")); 2667 ifge.setTarget(newHandel); 2668 il.append(new DUP()); 2669 il.append(new PUSH(constantPoolGen,"fieldNumber")); 2670 il.append(instructionFactory.createInvoke( 2671 "java.lang.IllegalArgumentException", 2672 "<init>", 2673 Type.VOID , 2674 new Type[]{Type.STRING}, 2675 Constants.INVOKESPECIAL)); 2676 il.append(new ATHROW()); 2677 il.append(new RETURN()); 2678 aGoto.setTarget(il.getEnd()); 2679 2680 methodGen.addLocalVariable("relativeField",Type.INT,2,relativeField_Start,il.getEnd()); 2681 } else { 2682 il.append(new RETURN()); 2683 } 2684 2685 methodGen.setMaxLocals(); 2687 methodGen.setMaxStack(); 2688 classGen.addMethod(methodGen.getMethod()); 2689 il.dispose(); 2690 } 2691 2692 2693 2694 2695 2696 private void addFieldGetters(){ 2697 Iterator fieldIter = fieldSet.iterator(); 2698 int fieldNum = 0; 2699 2700 while (fieldIter.hasNext()){ 2701 FieldInfo fieldInfo = (FieldInfo)fieldIter.next(); 2702 int acc = Constants.ACC_STATIC | 2703 (fieldInfo.isPrivate() ? Constants.ACC_PRIVATE : (short)0) | 2704 (fieldInfo.isProtected() ? Constants.ACC_PROTECTED : (short)0) | 2705 (fieldInfo.isPublic() ? Constants.ACC_PUBLIC : (short)0); 2706 Type returnType = fieldInfo.getType(); 2707 ReturnInstruction returnInstruction; 2708 String stateManagerGetField = null; 2709 boolean isObject = false; 2710 if (typeToGetField.containsKey(returnType)){ 2711 stateManagerGetField = (String )typeToGetField.get(returnType); 2712 returnInstruction = (ReturnInstruction)typeToReturnType.get(returnType); 2713 isObject = false; 2714 } else { 2715 stateManagerGetField = "getObjectField"; 2716 returnInstruction = new ARETURN(); 2717 isObject = true; 2718 } 2719 2720 InstructionList il = new InstructionList(); 2721 2722 MethodGen methodGen = new MethodGen( 2723 acc, 2724 returnType, 2725 new Type[]{new ObjectType(classGen.getClassName())}, 2726 new String []{"x"}, 2727 fieldInfo.getJdoGetName(), 2728 classGen.getClassName(), 2729 il, 2730 constantPoolGen); 2731 2732 2733 if (fieldInfo.getFlag() == CHECK_READ_WRITE ){ il.append(new ALOAD(0)); 2735 il.append(instructionFactory.createGetField( 2736 getTopPCSuperOrCurrentClassName(), 2737 "jdoFlags", 2738 Type.BYTE)); 2739 IFGT ifgt = new IFGT(null); 2740 il.append(ifgt); 2741 il.append(new ALOAD(0)); 2742 il.append(instructionFactory.createGetField( 2743 classGen.getClassName(), 2744 fieldInfo.getFieldName(), 2745 returnType)); 2746 il.append(returnInstruction); 2747 InstructionHandle ifgtHandel = il.append(new ALOAD(0)); 2748 ifgt.setTarget(ifgtHandel); 2749 il.append(instructionFactory.createGetField( 2750 getTopPCSuperOrCurrentClassName(), 2751 "jdoStateManager", 2752 SM_OBJECT_TYPE)); 2753 il.append(new ASTORE(1)); 2754 InstructionHandle smHandle = il.append(new ALOAD(1)); 2755 IFNULL ifnull = new IFNULL(null); il.append(ifnull); 2757 il.append(new ALOAD(1)); 2758 il.append(new ALOAD(0)); 2759 il.append(instructionFactory.createGetStatic( 2760 classGen.getClassName(), 2761 "jdoInheritedFieldCount", 2762 Type.INT)); 2763 il.append(new PUSH(constantPoolGen, fieldNum)); 2764 il.append(new IADD()); 2765 il.append(instructionFactory.createInvoke( 2766 STATE_MANAGER, 2767 "isLoaded", 2768 Type.BOOLEAN , 2769 new Type[]{PC_OBJECT_TYPE,Type.INT}, 2770 Constants.INVOKEINTERFACE)); 2771 IFEQ ifeq = new IFEQ(null); 2772 il.append(ifeq); il.append(new ALOAD(0)); 2774 il.append(instructionFactory.createGetField( 2775 classGen.getClassName(), 2776 fieldInfo.getFieldName(), 2777 returnType)); 2778 il.append(returnInstruction); 2779 InstructionHandle ifeqHandel = il.append(new ALOAD(1)); 2780 ifeq.setTarget(ifeqHandel); 2781 il.append(new ALOAD(0)); 2782 il.append(instructionFactory.createGetStatic( 2783 classGen.getClassName(), 2784 "jdoInheritedFieldCount", 2785 Type.INT)); 2786 il.append(new PUSH(constantPoolGen, fieldNum)); 2787 il.append(new IADD()); 2788 il.append(new ALOAD(0)); 2789 il.append(instructionFactory.createGetField( 2790 classGen.getClassName(), 2791 fieldInfo.getFieldName(), 2792 returnType)); 2793 if (isObject){ il.append(instructionFactory.createInvoke( 2795 STATE_MANAGER, 2796 stateManagerGetField, 2797 Type.OBJECT , 2798 new Type[]{ 2799 PC_OBJECT_TYPE, 2800 Type.INT, 2801 Type.OBJECT}, 2802 Constants.INVOKEINTERFACE)); 2803 il.append(instructionFactory.createCheckCast((ReferenceType)fieldInfo.getType())); 2804 } else { 2805 il.append(instructionFactory.createInvoke( 2806 STATE_MANAGER, 2807 stateManagerGetField, 2808 returnType , 2809 new Type[]{ 2810 PC_OBJECT_TYPE, 2811 Type.INT, 2812 returnType}, 2813 Constants.INVOKEINTERFACE)); 2814 } 2815 il.append(returnInstruction); 2816 InstructionHandle ifNullHandle = il.append(new ALOAD(0)); 2817 ifnull.setTarget(ifNullHandle); 2818 il.append(instructionFactory.createGetField( 2819 classGen.getClassName(), 2820 fieldInfo.getFieldName(), 2821 returnType)); 2822 il.append(returnInstruction); 2823 methodGen.addLocalVariable("sm",SM_OBJECT_TYPE ,1,smHandle,il.getEnd()); 2824 2825 } else if (fieldInfo.getFlag() == MEDIATE_READ_WRITE){ 2826 2827 il.append(new ALOAD(0)); 2828 il.append(instructionFactory.createGetField( 2829 getTopPCSuperOrCurrentClassName(), 2830 "jdoStateManager", 2831 SM_OBJECT_TYPE)); 2832 il.append(new ASTORE(1)); 2833 InstructionHandle smHandle = il.append(new ALOAD(1)); 2834 IFNULL ifnull = new IFNULL(null); il.append(ifnull); 2836 il.append(new ALOAD(1)); 2837 il.append(new ALOAD(0)); 2838 il.append(instructionFactory.createGetStatic( 2839 classGen.getClassName(), 2840 "jdoInheritedFieldCount", 2841 Type.INT)); 2842 il.append(new PUSH(constantPoolGen, fieldNum)); 2843 il.append(new IADD()); 2844 il.append(instructionFactory.createInvoke( 2845 STATE_MANAGER, 2846 "isLoaded", 2847 Type.BOOLEAN , 2848 new Type[]{PC_OBJECT_TYPE,Type.INT}, 2849 Constants.INVOKEINTERFACE)); 2850 IFEQ ifeq = new IFEQ(null); 2851 il.append(ifeq); il.append(new ALOAD(0)); 2853 il.append(instructionFactory.createGetField( 2854 classGen.getClassName(), 2855 fieldInfo.getFieldName(), 2856 returnType)); 2857 il.append(returnInstruction); 2858 InstructionHandle ifeqHandel = il.append(new ALOAD(1)); 2859 ifeq.setTarget(ifeqHandel); 2860 il.append(new ALOAD(0)); 2861 il.append(instructionFactory.createGetStatic( 2862 classGen.getClassName(), 2863 "jdoInheritedFieldCount", 2864 Type.INT)); 2865 il.append(new PUSH(constantPoolGen, fieldNum)); 2866 il.append(new IADD()); 2867 il.append(new ALOAD(0)); 2868 il.append(instructionFactory.createGetField( 2869 classGen.getClassName(), 2870 fieldInfo.getFieldName(), 2871 returnType)); 2872 if (isObject){ il.append(instructionFactory.createInvoke( 2874 STATE_MANAGER, 2875 stateManagerGetField, 2876 Type.OBJECT , 2877 new Type[]{ 2878 PC_OBJECT_TYPE, 2879 Type.INT, 2880 Type.OBJECT}, 2881 Constants.INVOKEINTERFACE)); 2882 il.append(instructionFactory.createCheckCast((ReferenceType)fieldInfo.getType())); 2883 } else { 2884 il.append(instructionFactory.createInvoke( 2885 STATE_MANAGER, 2886 stateManagerGetField, 2887 returnType , 2888 new Type[]{ 2889 PC_OBJECT_TYPE, 2890 Type.INT, 2891 returnType}, 2892 Constants.INVOKEINTERFACE)); 2893 } 2894 il.append(returnInstruction); 2895 InstructionHandle ifNullHandle = il.append(new ALOAD(0)); 2896 ifnull.setTarget(ifNullHandle); 2897 il.append(instructionFactory.createGetField( 2898 classGen.getClassName(), 2899 fieldInfo.getFieldName(), 2900 returnType)); 2901 il.append(returnInstruction); 2902 methodGen.addLocalVariable("sm",SM_OBJECT_TYPE,1,smHandle,il.getEnd()); 2903 2904 2905 } else { if (fieldInfo.primaryKey() && 2907 (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION) && 2908 classInfo.isKeyGen()){ 2909 2910 il.append(new ALOAD(0)); 2911 il.append(instructionFactory.createGetField(classGen.getClassName(), 2912 "jdoStateManager", 2913 new ObjectType("javax.jdo.spi.StateManager"))); 2914 il.append(new INSTANCEOF(constantPoolGen.addClass(VERSANT_STATE_MANAGER))); 2915 IFEQ ifeq = new IFEQ(null); 2916 il.append(ifeq); il.append(new ALOAD(0)); 2918 il.append(instructionFactory.createGetField(classGen.getClassName(), 2919 "jdoStateManager", 2920 new ObjectType("javax.jdo.spi.StateManager"))); 2921 il.append(instructionFactory.createCheckCast(new ObjectType(VERSANT_STATE_MANAGER))); 2922 il.append(instructionFactory.createGetStatic(classGen.getClassName(), 2923 "jdoInheritedFieldCount", 2924 Type.INT)); 2925 il.append(new PUSH(constantPoolGen, fieldInfo.getFieldNo())); 2926 il.append(new IADD()); 2927 il.append(instructionFactory.createInvoke(VERSANT_STATE_MANAGER, 2928 "fillNewAppPKField", 2929 Type.VOID, 2930 new Type[]{Type.INT}, 2931 Constants.INVOKEINTERFACE)); 2932 InstructionHandle nopHandle = il.append(new NOP()); 2933 ifeq.setTarget(nopHandle); 2934 } 2935 il.append(new ALOAD(0)); 2936 il.append(instructionFactory.createGetField( 2937 classGen.getClassName(), 2938 fieldInfo.getFieldName(), 2939 returnType)); 2940 il.append(returnInstruction); 2941 } 2942 methodGen.removeNOPs(); 2943 makeSynthetic(methodGen); 2944 methodGen.setMaxLocals(); 2945 methodGen.setMaxStack(); 2946 classGen.addMethod(methodGen.getMethod()); 2947 il.dispose(); 2948 fieldNum ++; 2949 2950 } 2951 2952 } 2953 2954 private void makeSynthetic(FieldGenOrMethodGen gen) { 2955 gen.addAttribute(new Synthetic(synthetic, 0, null, gen.getConstantPool().getConstantPool())); 2956 } 2957 2958 2959 private void addFieldSetters(){ 2960 Iterator fieldIter = fieldSet.iterator(); 2961 int fieldNum = 0; 2962 2963 while (fieldIter.hasNext()){ 2964 FieldInfo fieldInfo = (FieldInfo)fieldIter.next(); 2965 2966 int acc = Constants.ACC_STATIC | 2967 (fieldInfo.isPrivate() ? Constants.ACC_PRIVATE : (short)0) | 2968 (fieldInfo.isProtected() ? Constants.ACC_PROTECTED : (short)0) | 2969 (fieldInfo.isPublic() ? Constants.ACC_PUBLIC : (short)0); 2970 2971 Type fieldType = fieldInfo.getType(); 2972 boolean isObject = false; 2973 String stateManagerSetField = null; 2974 if (typeToSetField.containsKey(fieldType)){ 2975 stateManagerSetField = (String )typeToSetField.get(fieldType); 2976 isObject = false; 2977 } else { 2978 stateManagerSetField = "setObjectField"; 2979 isObject = true; 2980 } 2981 2982 InstructionList il = new InstructionList(); 2983 MethodGen methodGen = new MethodGen( 2984 acc, 2985 Type.VOID, 2986 new Type[]{new ObjectType(classGen.getClassName()), 2987 fieldType}, 2988 new String []{"x", 2989 "newValue"}, 2990 fieldInfo.getJdoSetName(), 2991 classGen.getClassName(), 2992 il, 2993 constantPoolGen); 2994 2995 int flags = fieldInfo.getFlag(); 2996 boolean isLorD = false; 2997 if (fieldType.equals(Type.LONG) || fieldType.equals(Type.DOUBLE)) isLorD = true; 2998 IFNE ifne = new IFNE(null); 2999 if (flags == CHECK_READ_WRITE || flags == CHECK_WRITE ){ il.append(new ALOAD(0)); 3001 il.append(instructionFactory.createGetField( 3002 getTopPCSuperOrCurrentClassName(), 3003 "jdoFlags", 3004 Type.BYTE)); 3005 3006 il.append(ifne); il.append(new ALOAD(0)); 3008 if (isObject){ 3009 il.append(new ALOAD(1)); 3010 } else { 3011 il.append((LoadInstruction)typeToLoadType.get(fieldType)); 3012 } 3013 il.append(instructionFactory.createPutField( 3014 classGen.getClassName(), 3015 fieldInfo.getFieldName(), 3016 fieldType)); 3017 il.append(new RETURN()); 3018 } 3019 InstructionHandle ifneHandel = il.append(new ALOAD(0)); 3020 ifne.setTarget(ifneHandel); 3021 il.append(instructionFactory.createGetField( 3022 getTopPCSuperOrCurrentClassName(), 3023 "jdoStateManager", 3024 SM_OBJECT_TYPE)); 3025 il.append(new ASTORE((isLorD ? 3 : 2))); 3026 InstructionHandle smStartHandle = il.append(new ALOAD((isLorD ? 3 : 2))); 3027 IFNULL ifnull = new IFNULL(null); 3028 il.append(ifnull); 3029 il.append(new ALOAD((isLorD ? 3 : 2))); 3030 il.append(new ALOAD(0)); 3031 il.append(instructionFactory.createGetStatic( 3032 classGen.getClassName(), 3033 "jdoInheritedFieldCount", 3034 Type.INT)); 3035 il.append(new PUSH(constantPoolGen, fieldNum)); 3036 il.append(new IADD()); 3037 il.append(new ALOAD(0)); 3038 il.append(instructionFactory.createGetField( 3039 classGen.getClassName(), 3040 fieldInfo.getFieldName(), 3041 fieldType)); 3042 if (isObject){ il.append(new ALOAD(1)); 3044 il.append(instructionFactory.createInvoke( 3045 STATE_MANAGER, 3046 stateManagerSetField, 3047 Type.VOID , 3048 new Type[]{PC_OBJECT_TYPE, 3049 Type.INT, 3050 Type.OBJECT, 3051 Type.OBJECT}, 3052 Constants.INVOKEINTERFACE)); 3053 } else { 3054 il.append((LoadInstruction)typeToLoadType.get(fieldType)); 3055 il.append(instructionFactory.createInvoke( 3056 STATE_MANAGER, 3057 stateManagerSetField, 3058 Type.VOID, 3059 new Type[]{PC_OBJECT_TYPE, 3060 Type.INT, 3061 fieldType, 3062 fieldType}, 3063 Constants.INVOKEINTERFACE)); 3064 } 3065 GOTO aGoto = new GOTO(null); 3066 il.append(aGoto); 3067 InstructionHandle ifnullHandle = il.append(new ALOAD(0)); 3068 ifnull.setTarget(ifnullHandle); 3069 if (isObject){ il.append(new ALOAD(1)); 3071 } else { 3072 il.append((LoadInstruction)typeToLoadType.get(fieldType)); 3073 } 3074 il.append(instructionFactory.createPutField( 3075 classGen.getClassName(), 3076 fieldInfo.getFieldName(), 3077 fieldType)); 3078 InstructionHandle lastHandle = il.append(new RETURN()); 3079 aGoto.setTarget(lastHandle); 3080 3081 3082 methodGen.addLocalVariable( 3083 "sm", 3084 SM_OBJECT_TYPE, 3085 (isLorD ? 3 : 2), 3086 smStartHandle, 3087 il.getEnd()); 3088 3089 makeSynthetic(methodGen); 3090 methodGen.setMaxLocals(); 3091 methodGen.setMaxStack(); 3092 classGen.addMethod(methodGen.getMethod()); 3093 il.dispose(); 3094 fieldNum ++; 3095 3096 } 3097 3098 } 3099 3100 3101 private void addJdoGetManagedFieldCount(){ 3102 InstructionList il = new InstructionList(); 3103 MethodGen methodGen = new MethodGen( 3104 Constants.ACC_STATIC | Constants.ACC_PROTECTED, 3105 Type.INT, 3106 null, 3107 null, 3108 "jdoGetManagedFieldCount", 3109 classGen.getClassName(), 3110 il, 3111 constantPoolGen); 3112 il.append(instructionFactory.createGetStatic( 3113 classGen.getClassName(), 3114 "jdoInheritedFieldCount", 3115 Type.INT)); 3116 il.append(new PUSH(constantPoolGen, fieldSet.size())); 3117 il.append(new IADD()); 3118 il.append(new IRETURN()); 3119 3120 methodGen.setMaxLocals(); 3122 methodGen.setMaxStack(); 3123 classGen.addMethod(methodGen.getMethod()); 3124 il.dispose(); 3125 } 3126 3127 3128 3129 private void addJdoInheritedFieldCount(){ 3130 FieldGen fieldGen = new FieldGen( 3131 Constants.ACC_PRIVATE | Constants.ACC_STATIC , Type.INT, 3133 "jdoInheritedFieldCount", 3134 constantPoolGen); 3135 makeSynthetic(fieldGen); 3136 classGen.addField(fieldGen.getField()); 3137 Method m = getStaticConstructor(); 3138 MethodGen methodGen = new MethodGen( 3139 m, 3140 classGen.getClassName(), 3141 constantPoolGen); 3142 InstructionList il = methodGen.getInstructionList(); 3143 InstructionHandle initialReturnHandle = il.getEnd(); 3144 InstructionHandle nopTarget = il.append(new NOP()); 3145 if (classInfo.getPersistenceCapableSuperclass() == null){ 3146 il.append(new ICONST(0)); 3147 } else { 3148 il.append(instructionFactory.createInvoke( 3149 classInfo.getPersistenceCapableSuperclass(), 3150 "jdoGetManagedFieldCount", 3151 Type.INT, 3152 new Type[]{}, 3153 Constants.INVOKESTATIC)); 3154 } 3155 il.append(instructionFactory.createPutStatic( 3156 classGen.getClassName(), 3157 "jdoInheritedFieldCount", 3158 Type.INT)); 3159 il.append(new RETURN()); 3160 try{ 3161 il.delete(initialReturnHandle); 3163 } catch (TargetLostException e){ 3164 InstructionHandle[] targets = e.getTargets(); 3165 for (int i = 0; i < targets.length ; i++){ 3166 InstructionTargeter[] targeters = targets[i].getTargeters(); 3167 for (int j = 0; j < targeters.length ; j++){ 3168 targeters[j].updateTarget(targets[i], nopTarget); 3169 } 3170 } 3171 } 3172 3173 methodGen.removeNOPs(); 3174 methodGen.setMaxLocals(); 3175 methodGen.setMaxStack(); 3176 classGen.replaceMethod(m,methodGen.getMethod()); 3177 il.dispose(); 3178 } 3179 3180 private void addJdoFieldTypes(){ 3181 FieldGen fieldGen = new FieldGen( 3182 Constants.ACC_PRIVATE | Constants.ACC_STATIC , new ArrayType("java.lang.Class",1), 3184 "jdoFieldTypes", 3185 constantPoolGen); 3186 makeSynthetic(fieldGen); 3187 classGen.addField(fieldGen.getField()); 3188 Method m = getStaticConstructor(); 3189 MethodGen methodGen = new MethodGen( 3190 m, 3191 classGen.getClassName(), 3192 constantPoolGen); 3193 InstructionList il = methodGen.getInstructionList(); 3194 3195 InstructionHandle initialReturnHandle = il.getEnd(); 3196 InstructionHandle nopTarget = il.append(new NOP()); 3197 il.append(new PUSH(constantPoolGen, fieldSet.size())); 3198 il.append(new ANEWARRAY(constantPoolGen.addClass(new ObjectType("java.lang.Class")))); 3199 il.append(new DUP()); 3200 Iterator iter = fieldSet.iterator(); 3201 int push = 0; 3202 while (iter.hasNext()){ 3203 FieldInfo field = (FieldInfo)iter.next(); 3204 if(field.isPrimative()){ 3205 il.append(new PUSH(constantPoolGen, push)); 3206 il.append(instructionFactory.createGetStatic( 3207 field.getPrimativeTypeObject(), 3208 "TYPE", 3209 new ObjectType("java.lang.Class"))); 3210 il.append(new AASTORE()); 3211 il.append(new DUP()); 3212 } else { 3213 InstructionList tempIl = new InstructionList(); 3214 String returnType = field.getReturnType(); 3215 String fieldName = getSetClass$Field(field); 3216 tempIl.insert(new DUP()); 3217 InstructionHandle gotoAASTORE = tempIl.insert(new AASTORE()); 3218 InstructionHandle gotoGetStatic = tempIl.insert(instructionFactory.createGetStatic( 3219 classGen.getClassName(), 3220 fieldName, 3221 new ObjectType("java.lang.Class"))); 3222 tempIl.insert(new GOTO(gotoAASTORE)); 3223 tempIl.insert(instructionFactory.createPutStatic( 3224 classGen.getClassName(), 3225 fieldName, 3226 new ObjectType("java.lang.Class"))); 3227 tempIl.insert(new DUP()); 3228 tempIl.insert(instructionFactory.createInvoke( 3229 classGen.getClassName(), 3230 "class$", 3231 new ObjectType("java.lang.Class"), 3232 new Type[]{new ObjectType("java.lang.String")}, 3233 Constants.INVOKESTATIC)); 3234 if (field.isArray()){ 3235 tempIl.insert(new PUSH(constantPoolGen,field.getSignature().replace('/','.'))); 3236 } else { 3237 tempIl.insert(new PUSH(constantPoolGen,returnType)); 3238 } 3239 3240 tempIl.insert(new IFNONNULL(gotoGetStatic)); 3241 tempIl.insert(instructionFactory.createGetStatic( 3242 classGen.getClassName(), 3243 fieldName, 3244 new ObjectType("java.lang.Class"))); 3245 tempIl.insert(new PUSH(constantPoolGen, push)); 3246 3247 il.append(tempIl); 3248 } 3249 push++; 3250 } 3251 try{ 3252 il.delete(il.getEnd()); 3253 } catch (TargetLostException e){ e.printStackTrace(); 3255 } 3256 3257 il.append(instructionFactory.createPutStatic( 3258 classGen.getClassName(), 3259 "jdoFieldTypes", 3260 new ArrayType(new ObjectType("java.lang.Class"),1))); 3261 il.append(new RETURN()); 3262 try{ 3263 il.delete(initialReturnHandle); 3264 } catch (TargetLostException e){ 3265 InstructionHandle[] targets = e.getTargets(); 3266 for (int i = 0; i < targets.length ; i++){ 3267 InstructionTargeter[] targeters = targets[i].getTargeters(); 3268 for (int j = 0; j < targeters.length ; j++){ 3269 targeters[j].updateTarget(targets[i], nopTarget); 3270 } 3271 } 3272 } 3273 methodGen.removeNOPs(); 3274 methodGen.setMaxLocals(); 3275 methodGen.setMaxStack(); 3276 classGen.replaceMethod(m,methodGen.getMethod()); 3277 il.dispose(); 3278 } 3279 3280 3281 private void addJdoFieldFlags(){ 3282 FieldGen fieldGen = new FieldGen( 3283 Constants.ACC_PRIVATE | Constants.ACC_STATIC , new ArrayType(Type.BYTE,1), 3285 "jdoFieldFlags", 3286 constantPoolGen); 3287 3288 makeSynthetic(fieldGen); 3289 classGen.addField(fieldGen.getField()); 3290 Method m = getStaticConstructor(); 3291 MethodGen methodGen = new MethodGen( 3292 m, 3293 classGen.getClassName(), 3294 constantPoolGen); 3295 InstructionList il = methodGen.getInstructionList(); 3296 3297 InstructionHandle initialReturnHandle = il.getEnd(); 3298 InstructionHandle nopTarget = il.append(new NOP()); 3299 il.append(new PUSH(constantPoolGen, fieldSet.size())); 3300 il.append(new NEWARRAY((Type.BYTE).getType())); 3301 Iterator iter = fieldSet.iterator(); 3302 int push = 0; 3303 while (iter.hasNext()){ 3304 FieldInfo field = (FieldInfo)iter.next(); 3305 il.append(new DUP()); 3306 il.append(new PUSH(constantPoolGen, push)); 3307 il.append(new PUSH(constantPoolGen, field.getFlag())); 3308 il.append(new BASTORE()); 3309 push++; 3310 } 3311 il.append(instructionFactory.createPutStatic( 3312 classGen.getClassName(), 3313 "jdoFieldFlags", 3314 new ArrayType(Type.BYTE,1))); 3315 il.append(new RETURN()); 3316 try{ 3317 il.delete(initialReturnHandle); 3318 } catch (TargetLostException e){ 3319 InstructionHandle[] targets = e.getTargets(); 3320 for (int i = 0; i < targets.length ; i++){ 3321 InstructionTargeter[] targeters = targets[i].getTargeters(); 3322 for (int j = 0; j < targeters.length ; j++){ 3323 targeters[j].updateTarget(targets[i], nopTarget); 3324 } 3325 } 3326 } 3327 methodGen.removeNOPs(); 3328 methodGen.setMaxLocals(); 3329 methodGen.setMaxStack(); 3330 classGen.replaceMethod(m,methodGen.getMethod()); 3331 il.dispose(); 3332 3333 } 3334 3335 3336 3337 3338 private void addInterrogatives(){ 3339 if (classInfo.getTopPCSuperClass() == null){ 3340 setInterrogative("jdoIsPersistent","isPersistent"); 3341 setInterrogative("jdoIsTransactional","isTransactional"); 3342 setInterrogative("jdoIsNew","isNew"); 3343 setInterrogative("jdoIsDirty","isDirty"); 3344 setInterrogative("jdoIsDeleted","isDeleted"); 3345 setJdoGetPersistanceManager(); 3346 setJdoMakeDirty(); 3347 } 3348 } 3349 3350 3356 private void setJdoGetPersistanceManager(){ 3357 InstructionList il = new InstructionList(); 3358 MethodGen methodGen = new MethodGen( 3359 Constants.ACC_PUBLIC , 3360 new ObjectType("javax.jdo.PersistenceManager"), 3361 null, 3362 null, 3363 "jdoGetPersistenceManager", 3364 classGen.getClassName(), 3365 il, 3366 constantPoolGen); 3367 3368 InstructionHandle ireturnHandle = il.insert(new ARETURN()); 3369 il.insert(instructionFactory.createInvoke( 3370 STATE_MANAGER, 3371 "getPersistenceManager", 3372 new ObjectType("javax.jdo.PersistenceManager"), 3373 new Type[]{PC_OBJECT_TYPE}, 3374 Constants.INVOKEINTERFACE)); 3375 il.insert(new ALOAD(0)); 3376 il.insert(instructionFactory.createGetField( 3377 getTopPCSuperOrCurrentClassName(), 3378 "jdoStateManager", 3379 SM_OBJECT_TYPE)); 3380 InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0)); 3381 il.insert(new GOTO(ireturnHandle)); 3382 il.insert(new ACONST_NULL()); 3383 il.insert(new IFNONNULL(ifNonNullHandle)); 3384 il.insert(instructionFactory.createGetField( 3385 getTopPCSuperOrCurrentClassName(), 3386 "jdoStateManager", 3387 SM_OBJECT_TYPE)); 3388 il.insert(new ALOAD(0)); 3389 3390 methodGen.setMaxLocals(); 3392 methodGen.setMaxStack(); 3393 classGen.addMethod(methodGen.getMethod()); 3394 il.dispose(); 3395 3396 } 3397 3406 private void setJdoMakeDirty(){ 3407 InstructionList il = new InstructionList(); 3408 MethodGen methodGen = new MethodGen( 3409 Constants.ACC_PUBLIC , 3410 Type.VOID, 3411 new Type[]{Type.STRING}, 3412 new String []{"fieldName"}, 3413 "jdoMakeDirty", 3414 classGen.getClassName(), 3415 il, 3416 constantPoolGen); 3417 il.insert(new RETURN()); 3418 il.insert(instructionFactory.createInvoke( 3419 STATE_MANAGER, 3420 "makeDirty", 3421 Type.VOID, 3422 new Type[]{PC_OBJECT_TYPE, Type.STRING}, 3423 Constants.INVOKEINTERFACE)); 3424 il.insert(new ALOAD(1)); 3425 il.insert(new ALOAD(0)); 3426 il.insert(instructionFactory.createGetField( 3427 getTopPCSuperOrCurrentClassName(), 3428 "jdoStateManager", 3429 SM_OBJECT_TYPE)); 3430 InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0)); 3431 il.insert(new RETURN()); 3432 il.insert(new IFNONNULL(ifNonNullHandle)); 3433 il.insert(instructionFactory.createGetField( 3434 getTopPCSuperOrCurrentClassName(), 3435 "jdoStateManager", 3436 SM_OBJECT_TYPE)); 3437 il.insert(new ALOAD(0)); 3438 3439 methodGen.setMaxLocals(); 3441 methodGen.setMaxStack(); 3442 classGen.addMethod(methodGen.getMethod()); 3443 il.dispose(); 3444 } 3445 3446 private void addJdoFieldNames(){ 3447 FieldGen fieldGen = new FieldGen( 3448 Constants.ACC_PRIVATE | Constants.ACC_STATIC , new ArrayType(Type.STRING,1), 3450 "jdoFieldNames", 3451 constantPoolGen); 3452 makeSynthetic(fieldGen); 3453 classGen.addField(fieldGen.getField()); 3454 Method m = getStaticConstructor(); 3455 MethodGen methodGen = new MethodGen( 3456 m, 3457 classGen.getClassName(), 3458 constantPoolGen); 3459 InstructionList il = methodGen.getInstructionList(); 3460 3461 InstructionHandle initialReturnHandle = il.getEnd(); 3462 3463 InstructionHandle nopTarget = il.append(new NOP()); 3464 il.append(new PUSH(constantPoolGen, fieldSet.size())); 3465 il.append(new ANEWARRAY(constantPoolGen.addClass(Type.STRING))); 3466 3467 Iterator iter = fieldSet.iterator(); 3468 int push = 0; 3469 while (iter.hasNext()){ 3470 FieldInfo field = (FieldInfo)iter.next(); 3471 il.append(new DUP()); 3472 il.append(new PUSH(constantPoolGen, push)); 3473 il.append(new PUSH(constantPoolGen,field.getFieldName())); 3474 il.append(new AASTORE()); 3475 push++; 3476 } 3477 il.append(instructionFactory.createPutStatic( 3478 classGen.getClassName(), 3479 "jdoFieldNames", 3480 new ArrayType(Type.STRING,1))); 3481 il.append(new RETURN()); 3482 try{ 3483 il.delete(initialReturnHandle); 3485 } catch (TargetLostException e){ 3486 InstructionHandle[] targets = e.getTargets(); 3487 for (int i = 0; i < targets.length ; i++){ 3488 InstructionTargeter[] targeters = targets[i].getTargeters(); 3489 for (int j = 0; j < targeters.length ; j++){ 3490 targeters[j].updateTarget(targets[i], nopTarget); 3491 } 3492 } 3493 } 3494 3495 methodGen.removeNOPs(); 3496 methodGen.setMaxLocals(); 3497 methodGen.setMaxStack(); 3498 classGen.replaceMethod(m,methodGen.getMethod()); 3499 il.dispose(); 3500 } 3501 3502 3503 private void setInterrogative(String methodName,String callingMethodName){ 3504 InstructionList il = new InstructionList(); 3505 MethodGen methodGen = new MethodGen( 3506 Constants.ACC_PUBLIC , 3507 Type.BOOLEAN, 3508 null, 3509 null, 3510 methodName, 3511 classGen.getClassName(), 3512 il, 3513 constantPoolGen); 3514 InstructionHandle ireturnHandle = il.insert(new IRETURN()); 3515 il.insert(instructionFactory.createInvoke( 3516 STATE_MANAGER, 3517 callingMethodName, 3518 Type.BOOLEAN, 3519 new Type[]{PC_OBJECT_TYPE}, 3520 Constants.INVOKEINTERFACE)); 3521 il.insert(new ALOAD(0)); 3522 il.insert(instructionFactory.createGetField( 3523 getTopPCSuperOrCurrentClassName(), 3524 "jdoStateManager", 3525 SM_OBJECT_TYPE)); 3526 InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0)); 3527 il.insert(new GOTO(ireturnHandle)); 3528 il.insert(new ICONST(0)); 3529 il.insert(new IFNONNULL(ifNonNullHandle)); 3530 il.insert(instructionFactory.createGetField( 3531 getTopPCSuperOrCurrentClassName(), 3532 "jdoStateManager", 3533 SM_OBJECT_TYPE)); 3534 il.insert(new ALOAD(0)); 3535 3536 methodGen.setMaxLocals(); 3538 methodGen.setMaxStack(); 3539 classGen.addMethod(methodGen.getMethod()); 3540 il.dispose(); 3541 3542 } 3543 3544 private void addSerialVersionUID(){ 3545 if (!hasSerialVersionUID()){ 3546 FieldGen fieldGen = new FieldGen( 3547 Constants.ACC_PRIVATE | Constants.ACC_STATIC | Constants.ACC_FINAL, 3548 Type.LONG, 3549 "serialVersionUID", 3550 constantPoolGen); 3551 fieldGen.setInitValue(currentSerialVersionUID); 3552 makeSynthetic(fieldGen); 3553 classGen.addField(fieldGen.getField()); 3554 3555 if (javaVersion >= JAVA_1_4){ 3556 3559 } 3560 } 3561 } 3562 3567 private boolean hasSerialVersionUID(){ 3568 Field [] fields = classGen.getFields(); 3569 for(int i = 0; i < fields.length; i++) { 3570 Field f = fields[i]; 3571 if (f.getName().equals("serialVersionUID")){ 3572 return true; 3573 } 3574 } 3575 return false; 3576 } 3577 3578 3583 private void addJdoPersistenceCapableSuperclass(){ 3584 FieldGen fieldGen = new FieldGen( 3585 Constants.ACC_PRIVATE | Constants.ACC_STATIC , new ObjectType("java.lang.Class"), 3587 "jdoPersistenceCapableSuperclass", 3588 constantPoolGen); 3589 makeSynthetic(fieldGen); 3590 classGen.addField(fieldGen.getField()); 3591 Method m = getStaticConstructor(); 3592 MethodGen methodGen = new MethodGen( 3593 m, 3594 classGen.getClassName(), 3595 constantPoolGen); 3596 InstructionList il = methodGen.getInstructionList(); 3597 InstructionHandle initialReturnHandle = il.getEnd(); 3598 InstructionHandle nopTarget = il.append(new NOP()); 3599 if (classInfo.getPersistenceCapableSuperclass() == null){ 3600 il.append(InstructionConstants.ACONST_NULL); 3601 il.append(instructionFactory.createPutStatic( 3602 classGen.getClassName(), 3603 "jdoPersistenceCapableSuperclass", 3604 new ObjectType("java.lang.Class"))); 3605 } else { 3606 3607 String className = classInfo.getPersistenceCapableSuperclass(); 3608 String fieldName = getSetClass$Field(className); 3609 3610 il.append(instructionFactory.createGetStatic( 3611 classGen.getClassName(), 3612 fieldName, 3613 new ObjectType("java.lang.Class"))); 3614 IFNONNULL ifNonNull = new IFNONNULL(null); 3615 il.append(ifNonNull); 3616 il.append(new PUSH(constantPoolGen,className)); 3617 il.append(instructionFactory.createInvoke( 3618 classGen.getClassName(), 3619 "class$", 3620 new ObjectType("java.lang.Class"), 3621 new Type[]{new ObjectType("java.lang.String")}, 3622 Constants.INVOKESTATIC)); 3623 il.append(new DUP()); 3624 il.append(instructionFactory.createPutStatic( 3625 classGen.getClassName(), 3626 fieldName, 3627 new ObjectType("java.lang.Class"))); 3628 GOTO gotoInst = new GOTO(null); 3629 il.append(gotoInst); 3630 InstructionHandle ifNonNullHandle = il.append(instructionFactory.createGetStatic( 3631 classGen.getClassName(), 3632 fieldName, 3633 new ObjectType("java.lang.Class"))); 3634 ifNonNull.setTarget(ifNonNullHandle); 3635 InstructionHandle gotoHandle = il.append(instructionFactory.createPutStatic( 3636 classGen.getClassName(), 3637 "jdoPersistenceCapableSuperclass", 3638 new ObjectType("java.lang.Class"))); 3639 gotoInst.setTarget(gotoHandle); 3640 } 3641 il.append(new RETURN()); 3642 try{ 3643 il.delete(initialReturnHandle); 3644 } catch (TargetLostException e){ 3645 InstructionHandle[] targets = e.getTargets(); 3646 for (int i = 0; i < targets.length ; i++){ 3647 InstructionTargeter[] targeters = targets[i].getTargeters(); 3648 for (int j = 0; j < targeters.length ; j++){ 3649 targeters[j].updateTarget(targets[i], nopTarget); 3650 } 3651 } 3652 } 3653 methodGen.removeNOPs(); 3654 methodGen.setMaxLocals(); 3655 methodGen.setMaxStack(); 3656 classGen.replaceMethod(m,methodGen.getMethod()); 3657 il.dispose(); 3658 } 3659 3667 private String getSetClass$Field(String className){ 3668 String fullClassName = "class."+className; 3669 String fieldName = fullClassName.replace('.','$'); 3670 Field [] fields = classGen.getFields(); 3671 for(int i = 0; i < fields.length; i++) { 3672 Field f = fields[i]; 3673 if (f.getName().equals(fieldName)){ 3674 return fieldName; 3675 } 3676 } 3677 FieldGen fieldGen = new FieldGen( 3678 Constants.ACC_STATIC, 3679 new ObjectType("java.lang.Class"), 3680 fieldName, 3681 constantPoolGen); 3682 classGen.addField(fieldGen.getField()); 3683 return fieldName; 3684 3685 } 3686 3694 private String getSetClass$Field(FieldInfo field){ 3695 String fullClassName = null; 3696 if (field.isArray()){ 3697 fullClassName = ("array" + field.getSignature()).replace('/', '$'); 3698 fullClassName = fullClassName.replace('[', '$'); 3699 fullClassName = (fullClassName.replace(';', ' ')).trim(); 3700 }else{ 3701 fullClassName = "class."+field.getReturnType(); 3702 } 3703 String fieldName = fullClassName.replace('.','$'); 3704 Field [] fields = classGen.getFields(); 3705 for(int i = 0; i < fields.length; i++) { 3706 Field f = fields[i]; 3707 if (f.getName().equals(fieldName)){ 3708 return fieldName; 3709 } 3710 } 3711 FieldGen fieldGen = new FieldGen( 3712 Constants.ACC_STATIC, 3713 new ObjectType("java.lang.Class"), 3714 fieldName, 3715 constantPoolGen); 3716 makeSynthetic(fieldGen); 3717 classGen.addField(fieldGen.getField()); 3718 return fieldName; 3719 3720 } 3721 3726 private boolean implementsPC(){ 3727 String [] interfaceNames = classGen.getInterfaceNames(); 3728 for(int i = 0; i < interfaceNames.length; i++) { 3729 if (interfaceNames[i].equals(PERSISTENCE_CAPABLE)){ 3730 return true; 3731 } 3732 } 3733 return false; 3734 } 3735 3741 private void setClass$(){ 3742 Method[] methods = classGen.getMethods(); 3743 for(int i = 0; i < methods.length; i++) { 3744 Method m = methods[i]; 3745 3746 if (m.getName().equals("class$") && 3747 "(Ljava/lang/String;)Ljava/lang/Class;".equals(m.getSignature())){ 3748 return; 3749 } 3750 } 3751 InstructionList il = new InstructionList(); 3753 MethodGen methodGen = new MethodGen( 3754 Constants.ACC_STATIC, 3755 new ObjectType("java.lang.Class"), 3756 new Type[]{new ObjectType("java.lang.String")}, 3757 new String []{"x0"}, 3758 "class$", 3759 classGen.getClassName(), 3760 il, 3761 constantPoolGen); 3762 3763 InstructionHandle tryStart = il.append(new ALOAD(0)); 3764 il.append(instructionFactory.createInvoke( 3765 "java.lang.Class", 3766 "forName", 3767 new ObjectType("java.lang.Class"), 3768 new Type[]{new ObjectType("java.lang.String")}, 3769 Constants.INVOKESTATIC)); 3770 InstructionHandle tryEnd = il.append(new ARETURN()); 3771 InstructionHandle handler = il.append(new ASTORE(1)); 3772 InstructionHandle varStart = il.append(instructionFactory.createNew("java.lang.NoClassDefFoundError")); 3773 il.append(new DUP()); 3774 il.append(new ALOAD(1)); 3775 il.append(instructionFactory.createInvoke( 3776 "java.lang.Throwable", 3777 "getMessage", 3778 new ObjectType("java.lang.String"), 3779 new Type[]{}, 3780 Constants.INVOKEVIRTUAL)); 3781 il.append(instructionFactory.createInvoke( 3782 "java.lang.NoClassDefFoundError", 3783 "<init>", 3784 Type.VOID, 3785 new Type[]{new ObjectType("java.lang.String")}, 3786 Constants.INVOKESPECIAL)); 3787 InstructionHandle varEnd = il.append(new ATHROW()); 3788 methodGen.addLocalVariable("x1",new ObjectType("java.lang.ClassNotFoundException"),varStart,varEnd); 3789 methodGen.addExceptionHandler(tryStart,tryEnd,handler,new ObjectType("java.lang.ClassNotFoundException")); 3790 makeSynthetic(methodGen); 3791 methodGen.setMaxLocals(); 3792 methodGen.setMaxStack(); 3793 Method class$Method = methodGen.getMethod(); 3794 classGen.addMethod(class$Method); 3795 il.dispose(); 3796 return ; 3797 3798 } 3799 3800 private void rewriteStaticConstructor(){ 3801 Method[] methods = classGen.getMethods(); 3802 for (int k = 0; k < methods.length; k++) { 3803 Method m = methods[k]; 3804 if (m.isNative() || m.isAbstract()) { 3807 continue; 3808 } 3809 if (m.getName().equals("<clinit>")) { boolean hasChanges = false; 3811 MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen); 3812 3813 InstructionList il = mg.getInstructionList(); 3815 Instruction ins; 3816 InstructionHandle ih = il.getStart(); 3817 while (ih != null) { 3818 ins = ih.getInstruction(); 3819 if (ins instanceof LDC) { 3820 LDC ldc = (LDC) ins; 3821 Constant c = constantPoolGen.getConstantPool().getConstant(ldc.getIndex()); 3822 if (c.getTag() == Constants.CONSTANT_Class) { 3823 hasChanges = true; 3824 String name = constantPoolGen.getConstantPool().getConstantString(ldc.getIndex(), Constants.CONSTANT_Class); 3825 3826 if (!name.startsWith("[")) { 3827 name = "L" + name + ";"; 3828 } 3829 3830 Type type = Type.getType(name); 3831 InstructionList tempIl = pushDotClass(type); 3832 InstructionHandle startTarget = tempIl.getStart(); 3833 InstructionHandle newTarget = tempIl.getEnd(); 3834 il.append(ih, tempIl); 3835 try { 3836 il.delete(ih); 3837 } catch (TargetLostException e) { 3838 InstructionHandle[] targets = e.getTargets(); 3839 for (int i = 0; i < targets.length; i++) { 3840 InstructionTargeter[] targeters = targets[i].getTargeters(); 3841 for (int j = 0; j < targeters.length; j++) { 3842 targeters[j].updateTarget(targets[i], newTarget); 3843 } 3844 } 3845 } 3846 il.setPositions(); 3847 il.update(); 3848 LineNumberGen[] numbersGen = mg.getLineNumbers(); 3850 if (numbersGen != null){ 3851 for (int i = 0; i < numbersGen.length; i++) { 3852 LineNumberGen lineNumberGen = numbersGen[i]; 3853 if (lineNumberGen.containsTarget(newTarget)){ 3854 lineNumberGen.setInstruction(startTarget); 3855 } 3856 } 3857 } 3858 3859 ih = il.getStart(); 3860 3861 } 3862 } 3863 ih = ih.getNext(); 3864 } 3865 if (hasChanges){ 3866 il.setPositions(); 3867 il.update(); 3868 mg.removeNOPs(); 3869 mg.setMaxLocals(); 3870 mg.setMaxStack(); 3871 classGen.replaceMethod(m, mg.getMethod()); 3872 } 3873 } 3874 } 3875 } 3876 3881 private Method getStaticConstructor(){ 3882 Method[] methods = classGen.getMethods(); 3883 for(int i = 0; i < methods.length; i++) { 3884 Method m = methods[i]; 3885 if (m.isNative() || m.isAbstract()){ 3888 continue; 3889 } 3890 if (m.getName().equals("<clinit>")){ return m; 3892 } 3893 } 3894 InstructionList il = new InstructionList(); 3896 MethodGen methodGen = new MethodGen( 3897 Constants.ACC_STATIC, 3898 Type.VOID, 3899 null, 3900 null, 3901 "<clinit>", 3902 classGen.getClassName(), 3903 il, 3904 constantPoolGen); 3905 3906 il.append(new RETURN()); 3907 methodGen.setMaxLocals(); 3909 methodGen.setMaxStack(); 3910 Method clMethod = methodGen.getMethod(); 3911 classGen.addMethod(clMethod); 3912 il.dispose(); 3913 return clMethod; 3914 3915 } 3916 3917 3921 private void addJdoStateManager(){ 3922 if (classInfo.getPersistenceCapableSuperclass() == null){ 3924 FieldGen fieldGen = new FieldGen( 3925 Constants.ACC_PROTECTED | Constants.ACC_TRANSIENT, 3926 SM_OBJECT_TYPE, 3927 "jdoStateManager", 3928 constantPoolGen); 3929 makeSynthetic(fieldGen); 3930 classGen.addField(fieldGen.getField()); 3931 } 3932 } 3933 3939 private void addJdoFlags() { 3940 if (classInfo.getPersistenceCapableSuperclass() == null){ 3942 FieldGen fieldGen = new FieldGen( 3943 Constants.ACC_PROTECTED | Constants.ACC_TRANSIENT, 3944 Type.BYTE, 3945 "jdoFlags", 3946 constantPoolGen); 3947 makeSynthetic(fieldGen); 3948 classGen.addField(fieldGen.getField()); 3949 List constructors = getInitilizationConstructors(); Iterator iter = constructors.iterator(); 3951 while (iter.hasNext()){ 3952 Method constructor = (Method)iter.next(); 3953 MethodGen mg = new MethodGen( 3954 constructor, 3955 classInfo.getClassName(), 3956 constantPoolGen); 3957 3958 InstructionList il = mg.getInstructionList(); 3959 InstructionHandle ih = il.getStart(); 3961 while (ih != null) { 3962 Instruction ins = ih.getInstruction(); 3963 3964 if (ins instanceof INVOKESPECIAL) { InstructionList tmpIl = new InstructionList(); 3966 tmpIl.append(new ALOAD(0)); 3967 tmpIl.append(new ICONST(0)); tmpIl.append(instructionFactory.createPutField(classInfo.getClassName(), 3969 "jdoFlags", 3970 Type.BYTE)); 3971 il.append(ih, tmpIl); 3972 il.setPositions(); 3973 il.update(); 3974 3975 mg.setInstructionList(il); 3976 mg.setMaxLocals(); 3977 mg.setMaxStack(); 3978 classGen.replaceMethod(constructor, mg.getMethod()); 3979 il.dispose(); 3980 break; 3981 } 3982 ih = ih.getNext(); 3984 } 3985 } 3986 } 3987 } 3988 3989 3992 private List getConstructors(){ 3993 ArrayList constuctors = new ArrayList(); 3994 Method[] methods = classGen.getMethods(); 3995 for(int i = 0; i < methods.length; i++) { 3996 Method m = methods[i]; 3997 if (m.isNative() || m.isAbstract()){ 4000 continue; 4001 } 4002 if (m.getName().equals("<init>")){ constuctors.add(m); 4004 } 4005 } 4006 return constuctors; 4007 } 4008 4012 private void setDefaultConstructor(){ 4013 boolean setDefautConstructor = true; 4015 Method[] methods = classGen.getMethods(); 4016 for(int i = 0; i < methods.length; i++) { 4017 Method m = methods[i]; 4018 if (m.isNative() || m.isAbstract()){ 4021 continue; 4022 } 4023 4024 if (m.getName().equals("<init>")){ if (m.getSignature().equals("()V")){ if (m.isPublic() ){ 4028 setDefautConstructor = false; }else { m.isPublic(true); 4031 m.isProtected(false); m.isPrivate(false); setDefautConstructor = false; } 4035 } 4036 } 4037 } 4038 if (setDefautConstructor){ 4039 InstructionList il = new InstructionList(); 4040 il.append(InstructionConstants.THIS); il.append(new INVOKESPECIAL(constantPoolGen.addMethodref( 4042 classGen.getSuperclassName(), 4043 "<init>", 4044 "()V"))); 4045 il.append(InstructionConstants.RETURN); 4046 4047 MethodGen methodGen = new MethodGen( 4048 Constants.ACC_PUBLIC, Type.VOID, 4050 Type.NO_ARGS, 4051 null, 4052 "<init>", 4053 classGen.getClassName(), 4054 il, 4055 constantPoolGen); 4056 methodGen.setMaxLocals(); 4057 methodGen.setMaxStack(); 4058 4059 classGen.addMethod(methodGen.getMethod()); 4060 didWeAddADefaultConstructor = true; 4061 } 4065 } 4066 4067 4070 private List getInitilizationConstructors(){ 4071 ArrayList initConst = new ArrayList(); 4072 List list = getConstructors(); 4073 Iterator iter = list.iterator(); 4074 while (iter.hasNext()){ 4075 Method m = (Method)iter.next(); 4076 4077 MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen); 4078 4079 InstructionList il = mg.getInstructionList(); 4081 4082 InstructionHandle ih = il.getStart(); 4084 while (ih != null) { 4085 Instruction ins = ih.getInstruction(); 4086 if (ins.getClass().getName().equals(invokeSpecial)) { 4087 INVOKESPECIAL is = (INVOKESPECIAL) ins; 4088 if (is.getClassName(constantPoolGen).equals(classGen.getSuperclassName()) && 4089 is.getMethodName(constantPoolGen).equals("<init>")) { 4090 initConst.add(m); 4091 } 4092 } 4093 ih = ih.getNext(); 4095 } 4096 } 4097 return initConst; 4098 } 4099 4100 4101 4104 4169 4170 4171 4172 4180 private InstructionList pushDotClass(Type type) { 4181 InstructionList il = new InstructionList(); 4182 String signature = type.getSignature(); 4183 String fieldName = null; 4184 String tempFieldName = null; 4185 String loadName = null; 4186 4187 if (signature.startsWith("[")) { 4188 tempFieldName = ("array" + signature).replace('/', '$'); 4189 tempFieldName = tempFieldName.replace('[', '$'); 4190 fieldName = (tempFieldName.replace(';', ' ')).trim(); 4191 loadName = signature.replace('/', '.'); 4192 } else { 4193 tempFieldName = ("class/" + signature).replace('/', '$'); 4194 fieldName = (tempFieldName.replace(';', ' ')).trim(); 4195 loadName = type.toString(); 4196 } 4197 4198 il.append(instructionFactory.createGetStatic(classGen.getClassName(), fieldName, new ObjectType("java.lang.Class"))); 4199 IFNONNULL ifnonnull = new IFNONNULL(null); 4200 il.append(ifnonnull); 4201 il.append(new PUSH(constantPoolGen, loadName)); 4202 il.append(instructionFactory.createInvoke( 4203 classGen.getClassName(), 4204 "class$", 4205 new ObjectType("java.lang.Class"), 4206 new Type[]{Type.STRING}, 4207 Constants.INVOKESTATIC)); 4208 il.append(new DUP()); 4209 il.append(instructionFactory.createPutStatic( 4210 classGen.getClassName(), 4211 fieldName, 4212 new ObjectType("java.lang.Class"))); 4213 GOTO aGoto = new GOTO(null); 4214 il.append(aGoto); 4215 InstructionHandle getStaticHandle = il.append(instructionFactory.createGetStatic( 4216 classGen.getClassName(), 4217 fieldName, 4218 new ObjectType("java.lang.Class"))); 4219 ifnonnull.setTarget(getStaticHandle); 4220 InstructionHandle lastHandle = il.append(new NOP()); 4221 aGoto.setTarget(lastHandle); 4222 4223 setClass$(); 4224 Field[] fields = classGen.getFields(); 4225 for (int i = 0; i < fields.length; i++) { 4226 Field f = fields[i]; 4227 if (f.getName().equals(fieldName)) { 4228 return il; 4229 } 4230 } 4231 FieldGen fieldGen = new FieldGen( 4232 Constants.ACC_STATIC | Constants.ACC_PRIVATE, 4233 new ObjectType("java.lang.Class"), 4234 fieldName, 4235 constantPoolGen); 4236 classGen.addField(fieldGen.getField()); 4237 return il; 4238 4239 } 4240 4241 4242 4243 4246 static String getSignature(Class clazz) { 4247 String type = null; 4248 if (clazz.isArray()) { 4249 Class cl = clazz; 4250 int dimensions = 0; 4251 while (cl.isArray()) { 4252 dimensions++; 4253 cl = cl.getComponentType(); 4254 } 4255 StringBuffer sb = new StringBuffer (); 4256 for (int i = 0; i < dimensions; i++) { 4257 sb.append("["); 4258 } 4259 sb.append(getSignature(cl)); 4260 type = sb.toString(); 4261 } else if (clazz.isPrimitive()) { 4262 if (clazz == Integer.TYPE) { 4263 type = "I"; 4264 } else if (clazz == Byte.TYPE) { 4265 type = "B"; 4266 } else if (clazz == Long.TYPE) { 4267 type = "J"; 4268 } else if (clazz == Float.TYPE) { 4269 type = "F"; 4270 } else if (clazz == Double.TYPE) { 4271 type = "D"; 4272 } else if (clazz == Short.TYPE) { 4273 type = "S"; 4274 } else if (clazz == Character.TYPE) { 4275 type = "C"; 4276 } else if (clazz == Boolean.TYPE) { 4277 type = "Z"; 4278 } else if (clazz == Void.TYPE) { 4279 type = "V"; 4280 } 4281 } else { 4282 type = "L" + clazz.getName().replace('.', '/') + ";"; 4283 } 4284 return type; 4285 } 4286 4287 4289 4290 private void addIsDirtyInt(String methodName) { 4291 4292 InstructionList il = new InstructionList(); 4293 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.BOOLEAN, 4295 new Type[]{Type.INT}, 4296 new String []{"fieldNo"}, 4297 methodName, 4298 classGen.getClassName(), 4299 il, 4300 constantPoolGen); 4301 4302 int num = getNumOfControlFields(); 4303 if (num == 1) { 4304 il.append(new ALOAD(0)); 4305 il.append(instructionFactory.createGetField(classGen.getClassName(), 4306 getDirtyFieldName(0), 4307 Type.INT)); 4308 il.append(new ICONST(1)); 4309 il.append(new ILOAD(1)); 4310 il.append(new ISHL()); 4311 il.append(new IAND()); 4312 IFNE ifne = new IFNE(null); 4313 il.append(ifne); 4314 il.append(new ICONST(0)); 4315 il.append(new IRETURN()); 4316 InstructionHandle handle = il.append(new ICONST(1)); 4317 ifne.setTarget(handle); 4318 il.append(new IRETURN()); 4319 4320 } else { 4321 il.append(new ILOAD(1)); 4322 for (int i = 0; i < num; i++) { 4323 il.append(new PUSH(constantPoolGen, ((32 * i) + 32))); 4324 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 4325 il.append(if_icmpge); 4326 il.append(new ALOAD(0)); 4327 il.append(instructionFactory.createGetField(classGen.getClassName(), 4328 getDirtyFieldName(i), 4329 Type.INT)); 4330 il.append(new ICONST(1)); 4331 il.append(new ILOAD(1)); 4332 il.append(new ISHL()); 4333 il.append(new IAND()); 4334 IFEQ ifeq = new IFEQ(null); 4335 il.append(ifeq); 4336 il.append(new ICONST(1)); 4337 GOTO aGoto = new GOTO(null); 4338 il.append(aGoto); 4339 InstructionHandle iconst0Handle = il.append(new ICONST(0)); 4340 ifeq.setTarget(iconst0Handle); 4341 InstructionHandle gotoHandle = il.append(new IRETURN()); 4342 aGoto.setTarget(gotoHandle); 4343 InstructionHandle iload1Handle = il.append(new ILOAD(1)); 4344 if_icmpge.setTarget(iload1Handle); 4345 } 4346 InstructionHandle lastHandle = il.getEnd(); 4348 InstructionHandle replaceHandle = il.append(new ICONST(0)); 4349 try { 4350 il.delete(lastHandle); 4351 } catch (TargetLostException e) { 4352 InstructionHandle[] targets = e.getTargets(); 4353 for (int i = 0; i < targets.length; i++) { 4354 InstructionTargeter[] targeters = targets[i].getTargeters(); 4355 for (int j = 0; j < targeters.length; j++) { 4356 targeters[j].updateTarget(targets[i], replaceHandle); 4357 } 4358 } 4359 } 4360 il.append(new IRETURN()); 4361 } 4362 4363 methodGen.setMaxLocals(); 4364 methodGen.setMaxStack(); 4365 classGen.addMethod(methodGen.getMethod()); 4366 il.dispose(); 4367 } 4368 4369 private void addMakeDirtyInt(String methodName) { 4370 4371 InstructionList il = new InstructionList(); 4372 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.VOID, 4374 new Type[]{Type.INT}, 4375 new String []{"fieldNo"}, 4376 methodName, 4377 classGen.getClassName(), 4378 il, 4379 constantPoolGen); 4380 4381 int num = getNumOfControlFields(); 4382 if (num == 1) { 4383 il.append(new ALOAD(0)); 4384 il.append(new DUP()); 4385 il.append(instructionFactory.createGetField(classGen.getClassName(), 4386 getDirtyFieldName(0), 4387 Type.INT)); 4388 4389 il.append(new ICONST(1)); 4390 il.append(new ILOAD(1)); 4391 il.append(new ISHL()); 4392 il.append(new IOR()); 4393 il.append(instructionFactory.createPutField(classGen.getClassName(), 4394 getDirtyFieldName(0), 4395 Type.INT)); 4396 il.append(new RETURN()); 4397 } else { 4398 il.append(new ILOAD(1)); 4399 for (int i = 0; i < num; i++) { 4400 il.append(new PUSH(constantPoolGen, ((32 * i) + 32))); 4401 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 4402 il.append(if_icmpge); 4403 4404 il.append(new ALOAD(0)); 4405 il.append(new DUP()); 4406 il.append(instructionFactory.createGetField(classGen.getClassName(), 4407 getDirtyFieldName(i), 4408 Type.INT)); 4409 il.append(new ICONST(1)); 4410 il.append(new ILOAD(1)); 4411 il.append(new ISHL()); 4412 il.append(new IOR()); 4413 il.append(instructionFactory.createPutField(classGen.getClassName(), 4414 getDirtyFieldName(i), 4415 Type.INT)); 4416 if (i != (num - 1)) { 4417 il.append(new RETURN()); 4418 InstructionHandle iloadHandle = il.append(new ILOAD(1)); 4419 if_icmpge.setTarget(iloadHandle); 4420 } else { 4421 InstructionHandle returnHandle = il.append(new RETURN()); if_icmpge.setTarget(returnHandle); 4423 } 4424 } 4425 4426 } 4427 methodGen.setMaxLocals(); 4428 methodGen.setMaxStack(); 4429 classGen.addMethod(methodGen.getMethod()); 4430 il.dispose(); 4431 } 4432 4433 private void addMakeDirtyString(String methodName) { 4434 4435 InstructionList il = new InstructionList(); 4436 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC, 4437 Type.VOID, 4438 new Type[]{Type.STRING}, 4439 new String []{"fieldName"}, 4440 methodName, 4441 classGen.getClassName(), 4442 il, 4443 constantPoolGen); 4444 4445 ArrayList list = new ArrayList(fieldSet); 4446 Collections.sort(list); 4447 Iterator iter = list.iterator(); 4448 ArrayList gotos = new ArrayList(); 4449 4450 while (iter.hasNext()) { 4451 FieldInfo info = (FieldInfo) iter.next(); 4452 String fieldname = info.getFieldName(); 4453 int fieldNo = info.getFieldNo(); 4454 4455 il.append(new PUSH(constantPoolGen, fieldname)); 4456 il.append(new ALOAD(1)); 4457 il.append(instructionFactory.createInvoke( 4458 "java.lang.String", 4459 "equals", 4460 Type.BOOLEAN, 4461 new Type[]{Type.OBJECT}, 4462 Constants.INVOKEVIRTUAL)); 4463 IFEQ ifeq = new IFEQ(null); il.append(ifeq); 4465 il.append(new ALOAD(0)); 4466 il.append(new PUSH(constantPoolGen, fieldNo)); 4467 il.append(instructionFactory.createInvoke( 4468 classGen.getClassName(), 4469 "versantMakeDirty", 4470 Type.VOID, 4471 new Type[]{Type.INT}, 4472 Constants.INVOKEVIRTUAL)); 4473 GOTO aGoto = new GOTO(null); 4474 gotos.add(aGoto); 4475 il.append(aGoto); 4476 InstructionHandle nopHandle = il.append(new NOP()); 4477 ifeq.setTarget(nopHandle); 4478 } 4479 if (classInfo.getPersistenceCapableSuperclass() != null){ 4481 il.append(new ALOAD(0)); 4482 il.append(new ALOAD(1)); 4483 il.append(instructionFactory.createInvoke( 4484 classInfo.getPersistenceCapableSuperclass(), 4485 "versantMakeDirty", 4486 Type.VOID, 4487 new Type[]{Type.STRING}, 4488 Constants.INVOKESPECIAL)); 4489 } else { 4490 } 4492 4493 4494 4495 InstructionHandle lastHandle = il.append(new RETURN()); 4496 for (Iterator iterator = gotos.iterator(); iterator.hasNext();) { 4497 GOTO aGoto = (GOTO) iterator.next(); 4498 aGoto.setTarget(lastHandle); 4499 } 4500 methodGen.removeNOPs(); 4501 methodGen.setMaxLocals(); 4502 methodGen.setMaxStack(); 4503 classGen.addMethod(methodGen.getMethod()); 4504 il.dispose(); 4505 } 4506 4507 4508 private void addIsDirty(String methodName) { 4509 4510 InstructionList il = new InstructionList(); 4511 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.BOOLEAN, 4513 new Type[]{}, 4514 new String []{}, 4515 methodName, 4516 classGen.getClassName(), 4517 il, 4518 constantPoolGen); 4519 4520 ArrayList list = new ArrayList(); 4521 int num = getNumOfControlFields(); 4522 for (int i = 0; i < num; i++) { 4523 il.append(new ALOAD(0)); 4524 il.append(instructionFactory.createGetField(classGen.getClassName(), 4525 getDirtyFieldName(i), 4526 Type.INT)); 4527 IFNE ifne = new IFNE(null); 4528 list.add(ifne); 4529 il.append(ifne); 4530 } 4531 il.append(new ICONST(0)); 4532 il.append(new IRETURN()); 4533 InstructionHandle ifne_handle = il.append(new ICONST(1)); 4534 for (Iterator iter = list.iterator(); iter.hasNext();) { 4535 IFNE ifne = (IFNE) iter.next(); 4536 ifne.setTarget(ifne_handle); 4537 } 4538 il.append(new IRETURN()); 4539 4540 methodGen.setMaxLocals(); 4541 methodGen.setMaxStack(); 4542 classGen.addMethod(methodGen.getMethod()); 4543 il.dispose(); 4544 } 4545 4546 private void addIsLoadedInt(String methodName) { 4547 4548 InstructionList il = new InstructionList(); 4549 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.BOOLEAN, 4551 new Type[]{Type.INT}, 4552 new String []{"fieldNo"}, 4553 methodName, 4554 classGen.getClassName(), 4555 il, 4556 constantPoolGen); 4557 4558 int num = getNumOfControlFields(); 4559 if (num == 1) { 4560 il.append(new ALOAD(0)); 4561 il.append(instructionFactory.createGetField(classGen.getClassName(), 4562 getLoadedFieldName(0), 4563 Type.INT)); 4564 il.append(new ICONST(1)); 4565 il.append(new ILOAD(1)); 4566 il.append(new ISHL()); 4567 il.append(new IAND()); 4568 IFNE ifne = new IFNE(null); 4569 il.append(ifne); 4570 il.append(new ICONST(0)); 4571 il.append(new IRETURN()); 4572 InstructionHandle handle = il.append(new ICONST(1)); 4573 ifne.setTarget(handle); 4574 il.append(new IRETURN()); 4575 4576 } else { 4577 il.append(new ILOAD(1)); 4578 for (int i = 0; i < num; i++) { 4579 il.append(new PUSH(constantPoolGen, ((32 * i) + 32))); 4580 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 4581 il.append(if_icmpge); 4582 il.append(new ALOAD(0)); 4583 il.append(instructionFactory.createGetField(classGen.getClassName(), 4584 getLoadedFieldName(i), 4585 Type.INT)); 4586 il.append(new ICONST(1)); 4587 il.append(new ILOAD(1)); 4588 il.append(new ISHL()); 4589 il.append(new IAND()); 4590 IFEQ ifeq = new IFEQ(null); 4591 il.append(ifeq); 4592 il.append(new ICONST(1)); 4593 GOTO aGoto = new GOTO(null); 4594 il.append(aGoto); 4595 InstructionHandle iconst0Handle = il.append(new ICONST(0)); 4596 ifeq.setTarget(iconst0Handle); 4597 InstructionHandle gotoHandle = il.append(new IRETURN()); 4598 aGoto.setTarget(gotoHandle); 4599 InstructionHandle iload1Handle = il.append(new ILOAD(1)); 4600 if_icmpge.setTarget(iload1Handle); 4601 } 4602 InstructionHandle lastHandle = il.getEnd(); 4604 InstructionHandle replaceHandle = il.append(new ICONST(0)); 4605 try { 4606 il.delete(lastHandle); 4607 } catch (TargetLostException e) { 4608 InstructionHandle[] targets = e.getTargets(); 4609 for (int i = 0; i < targets.length; i++) { 4610 InstructionTargeter[] targeters = targets[i].getTargeters(); 4611 for (int j = 0; j < targeters.length; j++) { 4612 targeters[j].updateTarget(targets[i], replaceHandle); 4613 } 4614 } 4615 } 4616 il.append(new IRETURN()); 4617 } 4618 4619 methodGen.setMaxLocals(); 4620 methodGen.setMaxStack(); 4621 classGen.addMethod(methodGen.getMethod()); 4622 il.dispose(); 4623 } 4624 4625 private void addSetLoadedInt(String methodName) { 4626 4627 InstructionList il = new InstructionList(); 4628 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.VOID, 4630 new Type[]{Type.INT}, 4631 new String []{"fieldNo"}, 4632 methodName, 4633 classGen.getClassName(), 4634 il, 4635 constantPoolGen); 4636 4637 int num = getNumOfControlFields(); 4638 if (num == 1) { 4639 il.append(new ALOAD(0)); 4640 il.append(new DUP()); 4641 il.append(instructionFactory.createGetField(classGen.getClassName(), 4642 getLoadedFieldName(0), 4643 Type.INT)); 4644 4645 il.append(new ICONST(1)); 4646 il.append(new ILOAD(1)); 4647 il.append(new ISHL()); 4648 il.append(new IOR()); 4649 il.append(instructionFactory.createPutField(classGen.getClassName(), 4650 getLoadedFieldName(0), 4651 Type.INT)); 4652 il.append(new RETURN()); 4653 } else { 4654 il.append(new ILOAD(1)); 4655 for (int i = 0; i < num; i++) { 4656 il.append(new PUSH(constantPoolGen, ((32 * i) + 32))); 4657 IF_ICMPGE if_icmpge = new IF_ICMPGE(null); 4658 il.append(if_icmpge); 4659 4660 il.append(new ALOAD(0)); 4661 il.append(new DUP()); 4662 il.append(instructionFactory.createGetField(classGen.getClassName(), 4663 getLoadedFieldName(i), 4664 Type.INT)); 4665 il.append(new ICONST(1)); 4666 il.append(new ILOAD(1)); 4667 il.append(new ISHL()); 4668 il.append(new IOR()); 4669 il.append(instructionFactory.createPutField(classGen.getClassName(), 4670 getLoadedFieldName(i), 4671 Type.INT)); 4672 if (i != (num - 1)) { 4673 il.append(new RETURN()); 4674 InstructionHandle iloadHandle = il.append(new ILOAD(1)); 4675 if_icmpge.setTarget(iloadHandle); 4676 } else { 4677 InstructionHandle returnHandle = il.append(new RETURN()); if_icmpge.setTarget(returnHandle); 4679 } 4680 } 4681 4682 } 4683 methodGen.setMaxLocals(); 4684 methodGen.setMaxStack(); 4685 classGen.addMethod(methodGen.getMethod()); 4686 il.dispose(); 4687 } 4688 4689 4690 4691 private final int getNumOfControlFields() { 4692 return (totlalManagedFields / 32) + 1; 4693 } 4694 4695 private final String getDirtyFieldName(int index) { 4696 return DIRTY_FIELD_NAME + index; 4697 } 4698 4699 private final String getLoadedFieldName(int index) { 4700 return LOADED_FIELD_NAME + index; 4701 } 4702 4703 private void addFields() { 4704 int num = getNumOfControlFields(); 4705 for (int i = 0; i < num; i++) { 4706 FieldGen fieldGenFilled = new FieldGen( Constants.ACC_PRIVATE , 4708 Type.INT, 4709 LOADED_FIELD_NAME + i, 4710 constantPoolGen); 4711 makeSynthetic(fieldGenFilled); 4712 classGen.addField(fieldGenFilled.getField()); 4713 4714 FieldGen fieldGenDirtyFields = new FieldGen( Constants.ACC_PRIVATE , 4716 Type.INT, 4717 DIRTY_FIELD_NAME + i, 4718 constantPoolGen); 4719 makeSynthetic(fieldGenDirtyFields); 4720 classGen.addField(fieldGenDirtyFields.getField()); 4721 4722 } 4723 4724 FieldGen fieldGenVersionField = new FieldGen( Constants.ACC_PRIVATE , 4726 Type.OBJECT, 4727 VERSION_FIELD_NAME, 4728 constantPoolGen); 4729 makeSynthetic(fieldGenVersionField); 4730 classGen.addField(fieldGenVersionField.getField()); 4731 4732 FieldGen fieldGenOIDField = new FieldGen( Constants.ACC_PRIVATE , 4734 Type.OBJECT, 4735 OID_FIELD_NAME , 4736 constantPoolGen); 4737 makeSynthetic(fieldGenOIDField); 4738 classGen.addField(fieldGenOIDField.getField()); 4739 } 4740 4741 private void addGetOid(String methodName){ 4742 InstructionList il = new InstructionList(); 4743 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.OBJECT, 4745 new Type[]{}, 4746 new String []{}, 4747 methodName, 4748 classGen.getClassName(), 4749 il, 4750 constantPoolGen); 4751 4752 il.append(new ALOAD(0)); 4753 il.append(instructionFactory.createGetField( 4754 classGen.getClassName(), 4755 OID_FIELD_NAME, 4756 Type.OBJECT)); 4757 il.append(new ARETURN()); 4758 4759 methodGen.setMaxLocals(); 4760 methodGen.setMaxStack(); 4761 classGen.addMethod(methodGen.getMethod()); 4762 il.dispose(); 4763 4764 } 4765 4766 private void addSetOid(String methodName) { 4767 InstructionList il = new InstructionList(); 4768 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.VOID, 4770 new Type[]{Type.OBJECT}, 4771 new String []{"oid"}, 4772 methodName, 4773 classGen.getClassName(), 4774 il, 4775 constantPoolGen); 4776 4777 il.append(new ALOAD(0)); 4778 il.append(new ALOAD(1)); 4779 il.append(instructionFactory.createPutField( 4780 classGen.getClassName(), 4781 OID_FIELD_NAME, 4782 Type.OBJECT)); 4783 il.append(new RETURN()); 4784 4785 methodGen.setMaxLocals(); 4786 methodGen.setMaxStack(); 4787 classGen.addMethod(methodGen.getMethod()); 4788 il.dispose(); 4789 } 4790 4791 private void addGetVersion(String methodName) { 4792 InstructionList il = new InstructionList(); 4793 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.OBJECT, 4795 new Type[]{}, 4796 new String []{}, 4797 methodName, 4798 classGen.getClassName(), 4799 il, 4800 constantPoolGen); 4801 4802 il.append(new ALOAD(0)); 4803 il.append(instructionFactory.createGetField( 4804 classGen.getClassName(), 4805 VERSION_FIELD_NAME, 4806 Type.OBJECT)); 4807 il.append(new ARETURN()); 4808 4809 methodGen.setMaxLocals(); 4810 methodGen.setMaxStack(); 4811 classGen.addMethod(methodGen.getMethod()); 4812 il.dispose(); 4813 4814 } 4815 4816 private void addGetStateManager(String methodName) { 4817 InstructionList il = new InstructionList(); 4818 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , new ObjectType(DETACHED_STATE_MANAGER), 4820 new Type[]{}, 4821 new String []{}, 4822 methodName, 4823 classGen.getClassName(), 4824 il, 4825 constantPoolGen); 4826 4827 il.append(new ALOAD(0)); 4828 il.append(instructionFactory.createGetField(classGen.getClassName(), 4829 "jdoStateManager", 4830 new ObjectType(STATE_MANAGER))); 4831 il.append(new INSTANCEOF(constantPoolGen.addClass(DETACHED_STATE_MANAGER))); 4832 IFEQ ifeq = new IFEQ(null); 4833 il.append(ifeq); 4834 il.append(new ALOAD(0)); 4835 il.append(instructionFactory.createGetField(classGen.getClassName(), 4836 "jdoStateManager", 4837 new ObjectType(STATE_MANAGER))); 4838 il.append(instructionFactory.createCheckCast(new ObjectType(DETACHED_STATE_MANAGER))); 4839 il.append(new ARETURN()); 4840 InstructionHandle nullHandle = il.append(new ACONST_NULL()); 4841 ifeq.setTarget(nullHandle); 4842 il.append(new ARETURN()); 4843 4844 methodGen.setMaxLocals(); 4845 methodGen.setMaxStack(); 4846 classGen.addMethod(methodGen.getMethod()); 4847 il.dispose(); 4848 4849 } 4850 4851 private void addSetVersion(String methodName) { 4852 InstructionList il = new InstructionList(); 4853 MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , Type.VOID, 4855 new Type[]{Type.OBJECT}, 4856 new String []{"version"}, 4857 methodName, 4858 classGen.getClassName(), 4859 il, 4860 constantPoolGen); 4861 4862 il.append(new ALOAD(0)); 4863 il.append(new ALOAD(1)); 4864 il.append(instructionFactory.createPutField( 4865 classGen.getClassName(), 4866 VERSION_FIELD_NAME, 4867 Type.OBJECT)); 4868 il.append(new RETURN()); 4869 4870 methodGen.setMaxLocals(); 4871 methodGen.setMaxStack(); 4872 classGen.addMethod(methodGen.getMethod()); 4873 il.dispose(); 4874 } 4875 4876 private void addDetachInterfase() { 4877 classGen.addInterface(DETACHABLE_INTERFASE); 4878 } 4879} 4880 | Popular Tags |