KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > tools > enhancer > ClassEnhancer


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

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 JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.util.*;
31 import java.net.URL JavaDoc;
32
33 /**
34  * This class does the enhancement on class files
35  *
36  */

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 JavaDoc outputDir;
46     private ClassLoader JavaDoc 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 JavaDoc getField = com.versant.lib.bcel.generic.GETFIELD.class.getName();
60     private static final String JavaDoc putField = com.versant.lib.bcel.generic.PUTFIELD.class.getName();
61     private static final String JavaDoc invokeSpecial = com.versant.lib.bcel.generic.INVOKESPECIAL.class.getName();
62     private static final String JavaDoc aload = com.versant.lib.bcel.generic.ALOAD.class.getName();
63     private static final String JavaDoc 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 JavaDoc fileSeparator;
79     private char charfileSeparator; //
80
private static final String JavaDoc VERSANT_STATE_MANAGER = com.versant.core.jdo.VersantStateManager.class.getName();
81
82     private final static String JavaDoc 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 JavaDoc 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 JavaDoc vendorName = "jdoVersant";
91
92     private long currentSerialVersionUID;
93     private static final String JavaDoc DIRTY_FIELD_NAME = "jdoVersantDirty";
94     private static final String JavaDoc LOADED_FIELD_NAME = "jdoVersantLoaded";
95     private static final String JavaDoc OID_FIELD_NAME = "jdoVersantOID";
96     private static final String JavaDoc VERSION_FIELD_NAME = "jdoVersantVersion";
97     private static final String JavaDoc DETACHABLE_INTERFASE = com.versant.core.jdo.VersantDetachable.class.getName();
98     private static final String JavaDoc DETACHED_STATE_MANAGER = com.versant.core.jdo.VersantDetachedStateManager.class.getName();
99     private int totlalManagedFields = 0;
100     private boolean detach;
101     private File JavaDoc 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 // private static final String MAKE_HOLLOW_INTERFASE = com.versant.core.jdo.test.model.versantMakeHollow.class.getName();
119

120     static {
121
122         // Determine the Java version by looking at available classes
123
// java.lang.StrictMath was introduced in JDK 1.3
124
// java.lang.ThreadLocal was introduced in JDK 1.2
125
// java.lang.Void was introduced in JDK 1.1
126
// Count up version until a NoClassDefFoundError ends the try
127

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 // Class.forName("java.lang.StringBuilder");
139
// javaVersion = JAVA_1_5;
140
} catch (ClassNotFoundException JavaDoc cnfe) {
141             // swallow as we've hit the max class version that
142
// we have
143
}
144     }
145
146     public ClassEnhancer(File JavaDoc outputDir, ClassLoader JavaDoc 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 JavaDoc className)throws IOException JavaDoc{
261         String JavaDoc classFileName = className.replace('.','/')+".class";
262         InputStream JavaDoc 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 JavaDoc className) throws IOException JavaDoc {
275         String JavaDoc classFileName = className.replace('.', '/') + ".class";
276         InputStream JavaDoc inputStream = loader.getResourceAsStream(classFileName);
277         URL JavaDoc 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 JavaDoc(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 JavaDoc(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 is used to represent the constant pool of a Classfile ll
310
constantPoolGen = classGen.getConstantPool();
311             // used to create objects representing VM instructions
312
instructionFactory = new InstructionFactory(constantPoolGen);
313
314              if (implementsPC()){ //if the class already implements PC, don't enhance
315
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             //Tasks
327
rewriteStaticConstructor();
328             setDefaultConstructor();
329             setClass$();
330             addSerialVersionUID();
331             addJdoFieldNames();
332             addJdoFieldFlags();
333             if (topClass) addJdoStateManager(); //super
334
if (topClass) addJdoFlags(); //super
335
addJdoInheritedFieldCount();
336             addJdoPersistenceCapableSuperclass();
337             addJdoFieldTypes();
338             addJdoGetManagedFieldCount();
339             if (topClass) addInterrogatives(); //super
340
addFieldGetters();
341             addFieldSetters();
342             addJdoReplaceField();
343             addJdoReplaceFields(); //super??????????????/
344
addJdoProvideField();
345             addJdoProvideFields(); //super??????????????/
346
addJdoCopyFields();
347             addJdoCopyField();
348             if (topClass) addJdoPreSerialize(); //super
349
addWriteObject();
350             addReadObject();
351             addRegisterClass();
352             addJdoNewInstance1();
353             addJdoNewInstance2();
354             if (topClass || appIdentity) addJdoNewObjectIdInstance1();
355             if (topClass || appIdentity) addJdoNewObjectIdInstance2();
356             if (topClass) addJdoGetObjectId(); //super
357
if (topClass) addJdoGetTransactionalObjectId(); //super
358
if (topClass) addJdoReplaceStateManager(); //super
359
if (topClass) addJdoCopyKeyFieldsToObjectId1();
360             if (topClass) addJdoCopyKeyFieldsToObjectId2();
361             if (topClass) addJdoCopyKeyFieldsFromObjectId1();
362             if (topClass) addJdoCopyKeyFieldsFromObjectId2();
363             if (topClass) addJdoReplaceFlags(); //super
364

365
366             addJdoInterface();
367             if (makeFieldsPrivate){
368                 setEnhancedFieldsPrivate();
369             }
370             swapGetterAndSetter();
371             swapClone();
372
373 // addVersantMakeHollow(); // put it in later
374
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"); //public void versantSetLoaded(int i);
384
addIsLoadedInt("versantIsLoaded"); //boolean versantIsLoaded(int i);
385
addIsDirty("versantIsDirty"); //boolean versantIsDirty();
386
addMakeDirtyInt("versantMakeDirty");
387                     addIsDirtyInt("versantIsDirty"); //public boolean versantIsDirty(int fieldNo);
388
addSetOid("versantSetOID"); //public void versantSetOID(Object id);
389
addGetOid("versantGetOID"); //public Object versantGetOID();
390
addGetVersion("versantGetVersion"); //public Object versantGetVersion();
391
addSetVersion("versantSetVersion"); //public void versantSetVersion(Object version);
392
addGetStateManager("versantGetDetachedStateManager"); //StateManager versantGetDetachedStateManager();
393
addDetachInterfase();
394                 }
395                 addMakeDirtyString("versantMakeDirty"); //void versantMakeDirty(String s);// if the names change, change this method.
396
}
397
398             if (didWeAddADefaultConstructor) {
399                 isOurConstructorValid();
400             }
401             dumpClass();
402
403             System.out.println("Persistence Capable = " + classInfo.getClassName());
404
405         } catch (Exception JavaDoc 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         //this gets done only for the least-derived persistence capable class.
417
if (classInfo.getPersistenceCapableSuperclass() != null) {
418             return;
419         }
420         String JavaDoc 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                 // native and abstract methods don't have any code
428
// so continue with next method
429
if (m.isNative() || m.isAbstract()) {
430                     continue;
431                 }
432                 if (m.getName().equals("<init>")) { //is constructor
433
if (m.getSignature().equals("()V")) { //is no args constructor
434
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 JavaDoc e) {
442             // hide exception, this class is not on our classpath
443
}
444     }
445
446     private void addDefaultConstructorToNonPersistantSuperClasses(String JavaDoc superName) {
447         //this gets done only for the least-derived persistence capable class.
448
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 is used to represent the constant pool of a Classfile ll
459
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                 // native and abstract methods don't have any code
465
// so continue with next method
466
if (m.isNative() || m.isAbstract()) {
467                     continue;
468                 }
469
470                 if (m.getName().equals("<init>")) { //is constructor
471
if (m.getSignature().equals("()V")) { //is no args constructor
472
if (m.isPublic()) {
473                             return;
474                         } else { //there is a default constructor but access is wrong
475
m.isPublic(true);
476                             m.isProtected(false); //change access to protected
477
m.isPrivate(false); //take away private access
478
String JavaDoc fileName = classGen.getClassName().replace('.', charfileSeparator) + ".class";
479                             File JavaDoc dumpFile = new File JavaDoc(outputDir, fileName);
480                             try {
481                                 classGen.getJavaClass().dump(dumpFile);
482                             } catch (IOException JavaDoc e) {
483                                 //hide, we could not write out the class
484
}
485                             return;
486                         }
487                     }
488                 }
489             }
490
491             InstructionList il = new InstructionList();
492             il.append(InstructionConstants.THIS); // Push `this'
493
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, // todo this is not to spec it should be protected
499
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 JavaDoc fileName = classGen.getClassName().replace('.', charfileSeparator) + ".class";
512             File JavaDoc dumpFile = new File JavaDoc(outputDir, fileName);
513             boolean error = false;
514             try {
515                 classGen.getJavaClass().dump(dumpFile);
516             } catch (IOException JavaDoc e) {
517                 //hide, we could not write out the class
518
error = true;
519
520             }
521
522             if (!error){
523                 // set our next class
524
// Print warning
525
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 JavaDoc e) {
537             // hide exception, this class is not on our classpath
538
}
539     }
540
541
542     private void swapClone() {
543         // representation of methods in the class
544
Method[] methods = classGen.getMethods();
545         for(int i = 0; i < methods.length; i++) {
546             Method m = methods[i];
547
548             // native and abstract methods don't have any code
549
// so continue with next method
550
if (m.isNative() || m.isAbstract()){
551                 continue;
552             }
553             //we do not want to enhance our enhanced methods
554
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             // get the code in form of an InstructionList object
563
InstructionList il = mg.getInstructionList();
564
565             // get the first instruction
566
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                 // next instruction
584
ih = ih.getNext();
585             }
586             // don't forget to write the code
587
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 // private void addJdogenieMakeHollow() {
630
//
631
// InstructionList il = new InstructionList();
632
// MethodGen methodGen = new MethodGen(
633
// Constants.ACC_PUBLIC ,
634
// Type.VOID,
635
// new Type[]{},
636
// new String[]{},
637
// vendorName+"MakeHollow",
638
// classGen.getClassName(),
639
// il,
640
// constantPoolGen);
641
//
642
// for (Iterator iterator = fieldSet.iterator();iterator.hasNext();) {
643
// FieldInfo fieldInfo = (FieldInfo) iterator.next();
644
// if (fieldInfo.isPrimative() && !fieldInfo.isArray()){
645
// continue;
646
// }
647
// il.append(new ALOAD(0));
648
// il.append(new ACONST_NULL());
649
// il.append(instructionFactory.createPutField(
650
// classGen.getClassName(),
651
// fieldInfo.getFieldName(),
652
// fieldInfo.getType()));
653
//
654
// }
655
// if (classInfo.getPersistenceCapableSuperclass() != null){
656
// il.append(new ALOAD(0));
657
// il.append(instructionFactory.createInvoke(
658
// classInfo.getPersistenceCapableSuperclass() ,
659
// vendorName+"MakeHollow" ,
660
// Type.VOID ,
661
// new Type[]{} ,
662
// Constants.INVOKESPECIAL));
663
// il.append(new RETURN());
664
// } else {
665
// il.append(new RETURN());
666
// }
667
//
668
// methodGen.setMaxLocals();
669
// methodGen.setMaxStack();
670
// classGen.addMethod(methodGen.getMethod());
671
// il.dispose();
672
//// classGen.addInterface(MAKE_HOLLOW_INTERFASE);
673
// }
674

675     private void dumpClass()throws VerifyException{
676         String JavaDoc fileName = classGen.getClassName().replace('.',charfileSeparator)+".class";
677         File JavaDoc dumpFile;
678         if (outputDir != null){
679             dumpFile = new File JavaDoc(outputDir,fileName);
680         } else {
681             dumpFile = currentOutputFile;
682         }
683         try {
684             classGen.getJavaClass().dump(dumpFile);
685         } catch (IOException JavaDoc e) {
686             throw new VerifyException(e);
687         }
688
689     }
690
691
692
693     /** Copy fields to an outside source from the key fields in the ObjectId.
694      * This method is generated in the PersistenceCapable class to generate
695      * a call to the field manager for each key field in the ObjectId. For
696      * example, an ObjectId class that has three key fields (int id,
697      * String name, and Float salary) would have the method generated:
698      * <P>void copyKeyFieldsFromObjectId
699      * <P> (PersistenceCapable oid, ObjectIdFieldManager fm) {
700      * <P> fm.storeIntField (0, oid.id);
701      * <P> fm.storeStringField (1, oid.name);
702      * <P> fm.storeObjectField (2, oid.salary);
703      * <P>}
704      * <P>The implementation is responsible for implementing the
705      * ObjectIdFieldManager to store the values for the key fields.
706      * private void jdoCopyKeyFieldsFromObjectId(PersistenceCapable.ObjectIdFieldReplacer fm, Object oid){
707      */

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 JavaDoc[]{"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 JavaDoc fieldReplacerMethod = null;
733                         if (typeToFieldReplacer.containsKey(info.getType())){
734                             fieldReplacerMethod = (String JavaDoc)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 // makeSynthetic(methodGen);
778
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 JavaDoc[]{"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 // makeSynthetic(methodGen);
843
methodGen.setMaxLocals();
844             methodGen.setMaxStack();
845             classGen.addMethod(methodGen.getMethod());
846             il.dispose();
847         }
848     }
849
850
851
852
853
854     private String JavaDoc 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 JavaDoc[]{},
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 // makeSynthetic(methodGen);
910
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 JavaDoc 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         // representation of methods in the class
940
Method[] methods = classGen.getMethods();
941         for(int i = 0; i < methods.length; i++) {
942             Method m = methods[i];
943
944             // native and abstract methods don't have any code
945
// so continue with next method
946
if (m.isNative() || m.isAbstract()){
947                 continue;
948             }
949             //we do not want to enhance our enhanced methods
950
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             // get the code in form of an InstructionList object
963
InstructionList il = mg.getInstructionList();
964
965             // get the first instruction
966
InstructionHandle ih = il.getStart();
967             while (ih != null) {
968                 Instruction ins = ih.getInstruction();
969                 if (ins.getClass().getName().equals(getField)){//if (ins instanceof GETFIELD)
970
GETFIELD is = (GETFIELD)ins;
971                     String JavaDoc key = is.getClassName(constantPoolGen) +"|"+ is.getFieldName(constantPoolGen);
972                     if (getAndSettersMap.containsKey(key)) {
973                         SwapFieldHelper helper = (SwapFieldHelper)getAndSettersMap.get(key);
974                         // replace it with our static replacement method
975
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)){ // The previos ist was a DUP
990
ih = ih.getPrev();
991                             InstructionHandle prevIhALOAD = ih.getPrev();
992                             Instruction iffyAload = prevIhALOAD.getInstruction();
993                             if (iffyAload.getClass().getName().equals(aload)){ // The ist before that was a ALOAD
994
ALOAD aLoad = (ALOAD)iffyAload;
995                                 ih.setInstruction(aLoad); // Swap ref out
996
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 JavaDoc key = is.getClassName(constantPoolGen) +"|"+ is.getFieldName(constantPoolGen);
1006                    if (getAndSettersMap.containsKey(key)) {
1007                        SwapFieldHelper helper = (SwapFieldHelper)getAndSettersMap.get(key);
1008                        // replace it with our static replacement method
1009
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                // next instruction
1024
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 JavaDoc 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 JavaDoc[]{"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 JavaDoc fieldProviderMethod = null;
1087                        if (typeToFieldProvider.containsKey(info.getType())){
1088                            fieldProviderMethod = (String JavaDoc)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// makeSynthetic(methodGen);
1130
methodGen.setMaxLocals();
1131            methodGen.setMaxStack();
1132            classGen.addMethod(methodGen.getMethod());
1133            il.dispose();
1134        }
1135    }
1136
1137
1138    // not cool, maybe ???????? test
1139
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 JavaDoc[]{"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// makeSynthetic(methodGen);
1178
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 JavaDoc[]{"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 JavaDoc[]{"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 JavaDoc[]{},
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// makeSynthetic(methodGen);
1389
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 JavaDoc[]{},
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// makeSynthetic(methodGen);
1438
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 JavaDoc[]{"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){ // datastore
1470
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 {// this class has application Identity
1495
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// makeSynthetic(methodGen);
1532
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 JavaDoc[]{"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// makeSynthetic(methodGen);
1593
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();//The last instruction of <clinit> will always be the return
1608

1609        String JavaDoc 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            // we must rename this method
1756
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 JavaDoc[]{"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                // we must rename this method
1866
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 JavaDoc[]{"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);//22
1909
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 JavaDoc[]{},
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// makeSynthetic(methodGen);
1979
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 JavaDoc[]{"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// makeSynthetic(methodGen);
2069
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 JavaDoc[]{"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        // Do default
2121
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        // start the lookupSwitch
2148
il.append(new LOOKUPSWITCH(match,targets,defaultHandle));
2149        for (Iterator tempIlIter = tempInsLists.iterator(); tempIlIter.hasNext();) { // add all instructions
2150
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// makeSynthetic(methodGen);
2158
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 JavaDoc[]{"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// makeSynthetic(methodGen);
2203
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 JavaDoc[]{"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// il.insert(new PUSH(constantPoolGen,"fieldNumber"));
2284

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 JavaDoc stateManagerProvidedField = null;
2332                boolean isObject = false;
2333                if (typeToProvidedField.containsKey(fieldInfo.getType())){
2334                    stateManagerProvidedField = (String JavaDoc)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(new PUSH(constantPoolGen,"fieldNumber"));
2422
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// makeSynthetic(methodGen);
2464
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 JavaDoc[]{"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// makeSynthetic(methodGen);
2507
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 JavaDoc[]{"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 JavaDoc stateManagerReplaceField = null;
2579                boolean isObject = false;
2580                if (typeToReplacingField.containsKey(fieldInfo.getType())){
2581                    stateManagerReplaceField = (String JavaDoc)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// makeSynthetic(methodGen);
2686
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 JavaDoc stateManagerGetField = null;
2709            boolean isObject = false;
2710            if (typeToGetField.containsKey(returnType)){
2711                stateManagerGetField = (String JavaDoc)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 JavaDoc[]{"x"},
2727                    fieldInfo.getJdoGetName(),
2728                    classGen.getClassName(),
2729                    il,
2730                    constantPoolGen);
2731
2732
2733            if (fieldInfo.getFlag() == CHECK_READ_WRITE ){// this field is in the default fetch group
2734
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); // null to aload_0 58
2756
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); // null to aload_1 41
2773
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){//if there is a object cast it
2794
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); // null to aload_0 58
2835
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); // null to aload_1 41
2852
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){//if there is a object cast it
2873
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 {//no mediation
2906
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); //25
2917
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 JavaDoc stateManagerSetField = null;
2974            if (typeToSetField.containsKey(fieldType)){
2975                stateManagerSetField = (String JavaDoc)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 JavaDoc[]{"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 ){// this field is in the default fetch group or is transient transactional
3000
il.append(new ALOAD(0));
3001                il.append(instructionFactory.createGetField(
3002                        getTopPCSuperOrCurrentClassName(),
3003                        "jdoFlags",
3004                        Type.BYTE));
3005
3006                il.append(ifne); // 13
3007
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){//if there is a object call it with Object's
3043
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){//if there is a object call it with Object's
3070
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// makeSynthetic(methodGen);
3121
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 ,//| NEW Constants.ACC_FINAL,
3132
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// System.out.println("initialReturnHandle that was deleted = " + initialReturnHandle);
3162
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 Constants.ACC_FINAL,
3183
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 JavaDoc returnType = field.getReturnType();
3215                String JavaDoc 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){//there should never be target for this instruction (DUP)
3254
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 Constants.ACC_FINAL,
3284
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    /**
3351     * Add method
3352     * public PersistenceManager jdoGetPersistenceManager(){
3353     * return jdoStateManager == null ? null : jdoStateManager.getPersistenceManager(this);
3354     * }
3355     */

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// makeSynthetic(methodGen);
3391
methodGen.setMaxLocals();
3392        methodGen.setMaxStack();
3393        classGen.addMethod(methodGen.getMethod());
3394        il.dispose();
3395
3396    }
3397    /**
3398     * Add method
3399     *
3400     * public void jdoMakeDirty(String fieldName){
3401     * if(jdoStateManager==null) return;
3402     * jdoStateManager.makeDirty(this, fieldName);
3403     * }
3404     *
3405     */

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 JavaDoc[]{"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// makeSynthetic(methodGen);
3440
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 Constants.ACC_FINAL,
3449
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// System.out.println("initialReturnHandle that was deleted = " + initialReturnHandle);
3484
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 JavaDoc methodName,String JavaDoc 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// makeSynthetic(methodGen);
3537
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                /**
3557                 * todo add serialVersionUID static constructor to for jdk 1.4
3558                 */

3559            }
3560        }
3561    }
3562    /**
3563     * Check if current class has a serialVersionUID.
3564     *
3565     * @return true if it does have a serialVersionUID, else false.
3566     */

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    /**
3579     * Addes a field jdoPersistenceCapableSuperclass and initializes it to null if there
3580     * is no persistence capable superclass else it initializes it.
3581     *
3582     */

3583    private void addJdoPersistenceCapableSuperclass(){
3584        FieldGen fieldGen = new FieldGen(
3585                Constants.ACC_PRIVATE | Constants.ACC_STATIC ,//| NEW Constants.ACC_FINAL,
3586
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 JavaDoc className = classInfo.getPersistenceCapableSuperclass();
3608            String JavaDoc 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    /**
3660     * All class variables i.e. String.class has a static variable called
3661     * class$java$lang$String of type java.lang.Class, this method creates it if
3662     * it does not exist.
3663     *
3664     * @param className
3665     * @return String fieldName i.e. class$java$lang$String
3666     */

3667    private String JavaDoc getSetClass$Field(String JavaDoc className){
3668        String JavaDoc fullClassName = "class."+className;
3669        String JavaDoc 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    /**
3687     * All class variables i.e. String.class has a static variable called
3688     * class$java$lang$String of type java.lang.Class, this method creates it if
3689     * it does not exist.
3690     *
3691     * @param field
3692     * @return String fieldName i.e. class$java$lang$String
3693     */

3694    private String JavaDoc getSetClass$Field(FieldInfo field){
3695        String JavaDoc 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 JavaDoc 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    /**
3722     * Check if current class implements PersistenceCapable.
3723     *
3724     * @return true if it does implement PersistenceCapable else false.
3725     */

3726    private boolean implementsPC(){
3727        String JavaDoc[] 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    /**
3736     * All class variables i.e. String.class has a static class$ method that check if the class
3737     * exists by doing a class.forname() on the class and throws a NoClassDefFoundError error,
3738     * if the class does not exists
3739     *
3740     */

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        // there is no class$ method so make one
3752
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 JavaDoc[]{"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            // native and abstract methods don't have any code
3805
// so continue with next method
3806
if (m.isNative() || m.isAbstract()) {
3807                continue;
3808            }
3809            if (m.getName().equals("<clinit>")) {//is static constructor
3810
boolean hasChanges = false;
3811                MethodGen mg = new MethodGen(m, classGen.getClassName(), constantPoolGen);
3812
3813                // get the code in form of an InstructionList object
3814
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 JavaDoc 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                            // Fix line numbers
3849
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    /**
3877     * Returns the static constructor if it exists, else it creates it and then
3878     * returns it.
3879     *
3880     */

3881    private Method getStaticConstructor(){
3882        Method[] methods = classGen.getMethods();
3883        for(int i = 0; i < methods.length; i++) {
3884            Method m = methods[i];
3885            // native and abstract methods don't have any code
3886
// so continue with next method
3887
if (m.isNative() || m.isAbstract()){
3888                continue;
3889            }
3890            if (m.getName().equals("<clinit>")){//is static constructor
3891
return m;
3892            }
3893        }
3894        // there is no static constructor so make one
3895
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// makeSynthetic(methodGen);
3908
methodGen.setMaxLocals();
3909        methodGen.setMaxStack();
3910        Method clMethod = methodGen.getMethod();
3911        classGen.addMethod(clMethod);
3912        il.dispose();
3913        return clMethod;
3914
3915    }
3916
3917    /**
3918     * Adds field jdoStateManager it does not need to be initializes.
3919     *
3920     */

3921    private void addJdoStateManager(){
3922        //this field only gets added to the least-derived persistence capable class.
3923
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    /**
3934     * Adds field jdoFlags in the top most persistence capable super class and initializes
3935     * it to javax.jdo.spi.PersistenceCapable.READ_WRITE_OK.
3936     * The initialization needs to occur in all the constructors as it is with all class fields.
3937     *
3938     */

3939    private void addJdoFlags() {
3940        //this field only gets added to the least-derived persistence capable class.
3941
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();//very important to only get these constructors
3950
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                // get the first instruction
3960
InstructionHandle ih = il.getStart();
3961                while (ih != null) {
3962                    Instruction ins = ih.getInstruction();
3963
3964                    if (ins instanceof INVOKESPECIAL) {// found the INVOKESPECIAL call
3965
InstructionList tmpIl = new InstructionList();
3966                        tmpIl.append(new ALOAD(0));
3967                        tmpIl.append(new ICONST(0));//javax.jdo.spi.PersistenceCapable.READ_WRITE_OK
3968
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                    // next instruction
3983
ih = ih.getNext();
3984                }
3985            }
3986        }
3987    }
3988
3989    /**
3990     * Gets a list of all the constructors methods
3991     */

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            // native and abstract methods don't have any code
3998
// so continue with next method
3999
if (m.isNative() || m.isAbstract()){
4000                continue;
4001            }
4002            if (m.getName().equals("<init>")){//is constructor
4003
constuctors.add(m);
4004            }
4005        }
4006        return constuctors;
4007    }
4008    /**
4009     * Sets a default constructor if it needs one or changes the default
4010     * constructor's scope if needed.
4011     */

4012    private void setDefaultConstructor(){
4013// if (classGen.isAbstract())return;
4014
boolean setDefautConstructor = true;
4015        Method[] methods = classGen.getMethods();
4016        for(int i = 0; i < methods.length; i++) {
4017            Method m = methods[i];
4018            // native and abstract methods don't have any code
4019
// so continue with next method
4020
if (m.isNative() || m.isAbstract()){
4021                continue;
4022            }
4023
4024            if (m.getName().equals("<init>")){ //is constructor
4025
if (m.getSignature().equals("()V")){ //is no args constructor
4026
// if (m.isPublic() || m.isProtected()){ //is public or protected
4027
if (m.isPublic() ){
4028                        setDefautConstructor = false; //there is a default constructor with the right access
4029
}else { //there is a default constructor but access is wrong
4030
m.isPublic(true);
4031                        m.isProtected(false); //change access to protected
4032
m.isPrivate(false); //take away private access
4033
setDefautConstructor = false; //now there is a default constructor with the right access
4034
}
4035                }
4036            }
4037        }
4038        if (setDefautConstructor){
4039            InstructionList il = new InstructionList();
4040            il.append(InstructionConstants.THIS); // Push `this'
4041
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, // todo this is not to spec it should be protected
4049
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// classGen.addEmptyConstructor(Constants.ACC_PUBLIC);// todo this is not to spec it should be protected
4062
// If initialization of user-declared field are required use this method
4063
//createDefaultInitializationConstructor();
4064
}
4065    }
4066
4067    /**
4068     * Gets a list of all the initilization constructors methods
4069     */

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            // get the code in form of an InstructionList object
4080
InstructionList il = mg.getInstructionList();
4081
4082            // get the first instruction
4083
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                // next instruction
4094
ih = ih.getNext();
4095            }
4096        }
4097        return initConst;
4098    }
4099
4100
4101    /**
4102     * this method is not needed yet.
4103     */

4104// private void createDefaultInitializationConstructor(){
4105
// List constructors = getInitilizationConstructors();
4106
// Iterator iter = constructors.iterator();
4107
// boolean wasGen = false;
4108
// while (iter.hasNext()){
4109
// Method m = (Method)iter.next();
4110
// MethodGen mg = new MethodGen(m, classInfo.getClassName() ,constantPoolGen);
4111
// LineNumberGen[] lineNumberGen = mg.getLineNumbers();
4112
// int firstLine = 0;
4113
// int nextLine = 10000;
4114
// int nextOffSet = 0;
4115
// InstructionHandle fromIH = null;
4116
// for (int i = 0; i < lineNumberGen.length ; i++){
4117
// int sourceLine = lineNumberGen[i].getSourceLine();
4118
// if (lineNumberGen[i].getLineNumber().getStartPC() == 0){
4119
// firstLine = lineNumberGen[i].getSourceLine();
4120
// }
4121
//
4122
// if (sourceLine > firstLine && sourceLine < nextLine){
4123
// if (lineNumberGen[i].getInstruction().getInstruction() instanceof RETURN) {
4124
// } else {
4125
// fromIH = lineNumberGen[i].getInstruction();
4126
// nextLine = sourceLine;
4127
// nextOffSet = lineNumberGen[i].getLineNumber().getStartPC();
4128
// }
4129
// }
4130
// }
4131
//
4132
// if (nextOffSet > 5){
4133
// InstructionList il = mg.getInstructionList();
4134
// InstructionHandle toIH = il.getEnd().getPrev();
4135
// try{
4136
// if (!fromIH.equals(il.getEnd().getPrev())){
4137
// il.delete(fromIH,il.getEnd().getPrev());
4138
// }
4139
// } catch (TargetLostException e){
4140
// InstructionHandle[] targets = e.getTargets();
4141
// for (int i = 0; i < targets.length ; i++){
4142
// InstructionTargeter[] targeters = targets[i].getTargeters();
4143
// for (int j = 0; j < targeters.length ; j++){
4144
// targeters[j].updateTarget(targets[i], il.getEnd());
4145
// }
4146
// }
4147
// }
4148
//
4149
// MethodGen newCons = new MethodGen( Constants.ACC_PROTECTED,
4150
// Type.VOID,
4151
// new Type[]{},
4152
// null,
4153
// "<init>",
4154
// classInfo.getClassName(),
4155
// il,
4156
// constantPoolGen);
4157
// newCons.getMaxLocals();
4158
// newCons.getMaxStack();
4159
// classGen.addMethod(newCons.getMethod());
4160
// wasGen = true;
4161
// break;
4162
// }
4163
// }
4164
// if (!wasGen){
4165
// classGen.addEmptyConstructor(Constants.ACC_PROTECTED);
4166
// }
4167
// }
4168

4169
4170
4171
4172    /**
4173     * All class variables i.e. String.class has a static variable called
4174     * class$java$lang$String of type java.lang.Class, this method creates it if
4175     * it does not exist.
4176     *
4177     * @param type
4178     * @return String fieldName i.e. class$java$lang$String
4179     */

4180    private InstructionList pushDotClass(Type type) {
4181        InstructionList il = new InstructionList();
4182        String JavaDoc signature = type.getSignature();
4183        String JavaDoc fieldName = null;
4184        String JavaDoc tempFieldName = null;
4185        String JavaDoc 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    /**
4244     * Compute the JVM signature for the class.
4245     */

4246    static String JavaDoc getSignature(Class JavaDoc clazz) {
4247        String JavaDoc type = null;
4248        if (clazz.isArray()) {
4249            Class JavaDoc cl = clazz;
4250            int dimensions = 0;
4251            while (cl.isArray()) {
4252                dimensions++;
4253                cl = cl.getComponentType();
4254            }
4255            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
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    // all the detach suff goes here
4288

4289
4290    private void addIsDirtyInt(String JavaDoc methodName) {
4291
4292        InstructionList il = new InstructionList();
4293        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4294
Type.BOOLEAN,
4295                new Type[]{Type.INT},
4296                new String JavaDoc[]{"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            // take last one and replace with ICONST_0
4347
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 JavaDoc methodName) {
4370
4371        InstructionList il = new InstructionList();
4372        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4373
Type.VOID,
4374                new Type[]{Type.INT},
4375                new String JavaDoc[]{"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()); // last return
4422
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 JavaDoc 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 JavaDoc[]{"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 JavaDoc 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); //17
4464
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        // now we do the else part
4480
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           // todo throw exception or something
4491
}
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 JavaDoc methodName) {
4509
4510        InstructionList il = new InstructionList();
4511        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC , //| NEW Constants.ACC_FINAL,
4512
Type.BOOLEAN,
4513                new Type[]{},
4514                new String JavaDoc[]{},
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 JavaDoc methodName) {
4547
4548        InstructionList il = new InstructionList();
4549        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4550
Type.BOOLEAN,
4551                new Type[]{Type.INT},
4552                new String JavaDoc[]{"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            // take last one and replace with ICONST_0
4603
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 JavaDoc methodName) {
4626
4627        InstructionList il = new InstructionList();
4628        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4629
Type.VOID,
4630                new Type[]{Type.INT},
4631                new String JavaDoc[]{"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()); // last return
4678
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 JavaDoc getDirtyFieldName(int index) {
4696        return DIRTY_FIELD_NAME + index;
4697    }
4698
4699    private final String JavaDoc 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(// Added our int LOADED_FIELD_NAME , to see what has been loaded in
4707
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(// Added our int DIRTY_FIELD_NAME , to see what is dirty
4715
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(// Added our Version field
4725
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(// Added our OID field
4733
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 JavaDoc methodName){
4742        InstructionList il = new InstructionList();
4743        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,// | NEW Constants.ACC_FINAL,
4744
Type.OBJECT,
4745                new Type[]{},
4746                new String JavaDoc[]{},
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 JavaDoc methodName) {
4767        InstructionList il = new InstructionList();
4768        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4769
Type.VOID,
4770                new Type[]{Type.OBJECT},
4771                new String JavaDoc[]{"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 JavaDoc methodName) {
4792        InstructionList il = new InstructionList();
4793        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4794
Type.OBJECT,
4795                new Type[]{},
4796                new String JavaDoc[]{},
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 JavaDoc methodName) {
4817        InstructionList il = new InstructionList();
4818        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4819
new ObjectType(DETACHED_STATE_MANAGER),
4820                new Type[]{},
4821                new String JavaDoc[]{},
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 JavaDoc methodName) {
4852        InstructionList il = new InstructionList();
4853        MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC ,//| NEW Constants.ACC_FINAL,
4854
Type.VOID,
4855                new Type[]{Type.OBJECT},
4856                new String JavaDoc[]{"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