Source Code Cross Referenced for ClassEnhancer.java in  » Testing » PolePosition-0.20 » com » versant » core » jdo » tools » enhancer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » PolePosition 0.20 » com.versant.core.jdo.tools.enhancer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998 - 2005 Versant Corporation
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         * Versant Corporation - initial API and implementation
0010:         */
0011:        package com.versant.core.jdo.tools.enhancer;
0012:
0013:        import com.versant.lib.bcel.Constants;
0014:        import com.versant.lib.bcel.classfile.*;
0015:        import com.versant.lib.bcel.generic.*;
0016:        import com.versant.core.common.Debug;
0017:        import com.versant.core.jdo.tools.enhancer.info.ClassInfo;
0018:        import com.versant.core.jdo.tools.enhancer.info.FieldInfo;
0019:        import com.versant.core.jdo.tools.enhancer.utils.SerialUIDHelper;
0020:        import com.versant.core.jdo.tools.enhancer.utils.SwapFieldHelper;
0021:        import com.versant.core.jdo.tools.enhancer.utils.TableSwitchHelper;
0022:        import com.versant.core.metadata.ClassMetaData;
0023:        import com.versant.core.metadata.MDStatics;
0024:
0025:        import javax.jdo.JDOUserException;
0026:        import java.io.File;
0027:        import java.io.IOException;
0028:        import java.io.InputStream;
0029:        import java.util.*;
0030:        import java.net.URL;
0031:
0032:        /**
0033:         * This class does the enhancement on class files
0034:         *
0035:         */
0036:        public class ClassEnhancer {
0037:
0038:            private ClassGen classGen;
0039:            private ConstantPoolGen constantPoolGen;
0040:            private InstructionFactory instructionFactory;
0041:            private ClassInfo classInfo;
0042:            private Set fieldSet;
0043:            private File outputDir;
0044:            private ClassLoader loader;
0045:            private static int javaVersion;
0046:
0047:            private boolean isEmpty = false;
0048:            private boolean didWeAddADefaultConstructor = false;
0049:
0050:            public static final int JAVA_1_0 = 10;
0051:            public static final int JAVA_1_1 = 11;
0052:            public static final int JAVA_1_2 = 12;
0053:            public static final int JAVA_1_3 = 13;
0054:            public static final int JAVA_1_4 = 14;
0055:            public static final int JAVA_1_5 = 15;
0056:
0057:            private static final String getField = com.versant.lib.bcel.generic.GETFIELD.class
0058:                    .getName();
0059:            private static final String putField = com.versant.lib.bcel.generic.PUTFIELD.class
0060:                    .getName();
0061:            private static final String invokeSpecial = com.versant.lib.bcel.generic.INVOKESPECIAL.class
0062:                    .getName();
0063:            private static final String aload = com.versant.lib.bcel.generic.ALOAD.class
0064:                    .getName();
0065:            private static final String dup = com.versant.lib.bcel.generic.DUP.class
0066:                    .getName();
0067:
0068:            private HashMap getAndSettersMap;
0069:            private HashMap typeToReturnType;
0070:            private HashMap typeToSetField;
0071:            private HashMap typeToFieldProvider;
0072:            private HashMap typeToProvidedField;
0073:            private HashMap typeToReplacingField;
0074:            private HashMap typeToGetField;
0075:            private HashMap typeToLoadType;
0076:            private HashMap typeToFieldReplacer;
0077:
0078:            private HashMap primativeTypesToWrapper;
0079:
0080:            private String fileSeparator;
0081:            private char charfileSeparator; //
0082:            private static final String VERSANT_STATE_MANAGER = com.versant.core.jdo.VersantStateManager.class
0083:                    .getName();
0084:
0085:            private final static String PERSISTENCE_CAPABLE = javax.jdo.spi.PersistenceCapable.class
0086:                    .getName();
0087:            private final static ObjectType PC_OBJECT_TYPE = new ObjectType(
0088:                    PERSISTENCE_CAPABLE);
0089:            private final static String STATE_MANAGER = javax.jdo.spi.StateManager.class
0090:                    .getName();
0091:            private final static ObjectType SM_OBJECT_TYPE = new ObjectType(
0092:                    STATE_MANAGER);
0093:            private int CHECK_WRITE = javax.jdo.spi.PersistenceCapable.CHECK_WRITE;
0094:            private int CHECK_READ_WRITE = javax.jdo.spi.PersistenceCapable.CHECK_READ
0095:                    + javax.jdo.spi.PersistenceCapable.CHECK_WRITE;
0096:            private int MEDIATE_READ_WRITE = javax.jdo.spi.PersistenceCapable.MEDIATE_READ
0097:                    + javax.jdo.spi.PersistenceCapable.MEDIATE_WRITE;
0098:            private int synthetic;
0099:            private String vendorName = "jdoVersant";
0100:
0101:            private long currentSerialVersionUID;
0102:            private static final String DIRTY_FIELD_NAME = "jdoVersantDirty";
0103:            private static final String LOADED_FIELD_NAME = "jdoVersantLoaded";
0104:            private static final String OID_FIELD_NAME = "jdoVersantOID";
0105:            private static final String VERSION_FIELD_NAME = "jdoVersantVersion";
0106:            private static final String DETACHABLE_INTERFASE = com.versant.core.jdo.VersantDetachable.class
0107:                    .getName();
0108:            private static final String DETACHED_STATE_MANAGER = com.versant.core.jdo.VersantDetachedStateManager.class
0109:                    .getName();
0110:            private int totlalManagedFields = 0;
0111:            private boolean detach;
0112:            private File currentOutputFile;
0113:
0114:            public static final ObjectType INTEGER_TYPE = new ObjectType(
0115:                    "java.lang.Integer");
0116:            public static final ObjectType BYTE_TYPE = new ObjectType(
0117:                    "java.lang.Byte");
0118:            public static final ObjectType CHARACTER_TYPE = new ObjectType(
0119:                    "java.lang.Character");
0120:            public static final ObjectType SHORT_TYPE = new ObjectType(
0121:                    "java.lang.Short");
0122:            public static final ObjectType FLOAT_TYPE = new ObjectType(
0123:                    "java.lang.Float");
0124:            public static final ObjectType DOUBLE_TYPE = new ObjectType(
0125:                    "java.lang.Double");
0126:            public static final ObjectType LONG_TYPE = new ObjectType(
0127:                    "java.lang.Long");
0128:            public static final ObjectType BOOLEAN_TYPE = new ObjectType(
0129:                    "java.lang.Boolean");
0130:
0131:            //	private static final String MAKE_HOLLOW_INTERFASE = com.versant.core.jdo.test.model.versantMakeHollow.class.getName();
0132:
0133:            static {
0134:
0135:                // Determine the Java version by looking at available classes
0136:                // java.lang.StrictMath was introduced in JDK 1.3
0137:                // java.lang.ThreadLocal was introduced in JDK 1.2
0138:                // java.lang.Void was introduced in JDK 1.1
0139:                // Count up version until a NoClassDefFoundError ends the try
0140:
0141:                try {
0142:                    javaVersion = JAVA_1_0;
0143:                    Class.forName("java.lang.Void");
0144:                    javaVersion = JAVA_1_1;
0145:                    Class.forName("java.lang.ThreadLocal");
0146:                    javaVersion = JAVA_1_2;
0147:                    Class.forName("java.lang.StrictMath");
0148:                    javaVersion = JAVA_1_3;
0149:                    Class.forName("java.lang.CharSequence");
0150:                    javaVersion = JAVA_1_4;
0151:                    //            Class.forName("java.lang.StringBuilder");
0152:                    //            javaVersion = JAVA_1_5;
0153:                } catch (ClassNotFoundException cnfe) {
0154:                    // swallow as we've hit the max class version that
0155:                    // we have
0156:                }
0157:            }
0158:
0159:            public ClassEnhancer(File outputDir, ClassLoader loader) {
0160:                this .outputDir = outputDir;
0161:                this .loader = loader;
0162:                fileSeparator = System.getProperty("file.separator");
0163:                charfileSeparator = fileSeparator.charAt(0);
0164:
0165:                typeToSetField = new HashMap();
0166:                typeToSetField.put(Type.INT, "setIntField");
0167:                typeToSetField.put(Type.BYTE, "setByteField");
0168:                typeToSetField.put(Type.LONG, "setLongField");
0169:                typeToSetField.put(Type.CHAR, "setCharField");
0170:                typeToSetField.put(Type.SHORT, "setShortField");
0171:                typeToSetField.put(Type.FLOAT, "setFloatField");
0172:                typeToSetField.put(Type.DOUBLE, "setDoubleField");
0173:                typeToSetField.put(Type.STRING, "setStringField");
0174:                typeToSetField.put(Type.BOOLEAN, "setBooleanField");
0175:
0176:                typeToFieldProvider = new HashMap();
0177:                typeToFieldProvider.put(Type.INT, "fetchIntField");
0178:                typeToFieldProvider.put(Type.BYTE, "fetchByteField");
0179:                typeToFieldProvider.put(Type.CHAR, "fetchCharField");
0180:                typeToFieldProvider.put(Type.SHORT, "fetchShortField");
0181:                typeToFieldProvider.put(Type.FLOAT, "fetchFloatField");
0182:                typeToFieldProvider.put(Type.DOUBLE, "fetchDoubleField");
0183:                typeToFieldProvider.put(Type.LONG, "fetchLongField");
0184:                typeToFieldProvider.put(Type.BOOLEAN, "fetchBooleanField");
0185:                typeToFieldProvider.put(Type.STRING, "fetchStringField");
0186:
0187:                typeToProvidedField = new HashMap();
0188:                typeToProvidedField.put(Type.INT, "providedIntField");
0189:                typeToProvidedField.put(Type.BYTE, "providedByteField");
0190:                typeToProvidedField.put(Type.CHAR, "providedCharField");
0191:                typeToProvidedField.put(Type.SHORT, "providedShortField");
0192:                typeToProvidedField.put(Type.FLOAT, "providedFloatField");
0193:                typeToProvidedField.put(Type.DOUBLE, "providedDoubleField");
0194:                typeToProvidedField.put(Type.LONG, "providedLongField");
0195:                typeToProvidedField.put(Type.BOOLEAN, "providedBooleanField");
0196:                typeToProvidedField.put(Type.STRING, "providedStringField");
0197:
0198:                typeToReplacingField = new HashMap();
0199:                typeToReplacingField.put(Type.INT, "replacingIntField");
0200:                typeToReplacingField.put(Type.BYTE, "replacingByteField");
0201:                typeToReplacingField.put(Type.CHAR, "replacingCharField");
0202:                typeToReplacingField.put(Type.SHORT, "replacingShortField");
0203:                typeToReplacingField.put(Type.FLOAT, "replacingFloatField");
0204:                typeToReplacingField.put(Type.DOUBLE, "replacingDoubleField");
0205:                typeToReplacingField.put(Type.LONG, "replacingLongField");
0206:                typeToReplacingField.put(Type.BOOLEAN, "replacingBooleanField");
0207:                typeToReplacingField.put(Type.STRING, "replacingStringField");
0208:
0209:                typeToFieldReplacer = new HashMap();
0210:                typeToFieldReplacer.put(Type.INT, "storeIntField");
0211:                typeToFieldReplacer.put(Type.BYTE, "storeByteField");
0212:                typeToFieldReplacer.put(Type.CHAR, "storeCharField");
0213:                typeToFieldReplacer.put(Type.SHORT, "storeShortField");
0214:                typeToFieldReplacer.put(Type.FLOAT, "storeFloatField");
0215:                typeToFieldReplacer.put(Type.DOUBLE, "storeDoubleField");
0216:                typeToFieldReplacer.put(Type.LONG, "storeLongField");
0217:                typeToFieldReplacer.put(Type.BOOLEAN, "storeBooleanField");
0218:                typeToFieldReplacer.put(Type.STRING, "storeStringField");
0219:
0220:                typeToGetField = new HashMap();
0221:                typeToGetField.put(Type.INT, "getIntField");
0222:                typeToGetField.put(Type.BYTE, "getByteField");
0223:                typeToGetField.put(Type.CHAR, "getCharField");
0224:                typeToGetField.put(Type.SHORT, "getShortField");
0225:                typeToGetField.put(Type.FLOAT, "getFloatField");
0226:                typeToGetField.put(Type.DOUBLE, "getDoubleField");
0227:                typeToGetField.put(Type.LONG, "getLongField");
0228:                typeToGetField.put(Type.BOOLEAN, "getBooleanField");
0229:                typeToGetField.put(Type.STRING, "getStringField");
0230:
0231:                typeToReturnType = new HashMap();
0232:                typeToReturnType.put(Type.INT, new IRETURN());
0233:                typeToReturnType.put(Type.BYTE, new IRETURN());
0234:                typeToReturnType.put(Type.CHAR, new IRETURN());
0235:                typeToReturnType.put(Type.SHORT, new IRETURN());
0236:                typeToReturnType.put(Type.FLOAT, new FRETURN());
0237:                typeToReturnType.put(Type.DOUBLE, new DRETURN());
0238:                typeToReturnType.put(Type.LONG, new LRETURN());
0239:                typeToReturnType.put(Type.BOOLEAN, new IRETURN());
0240:                typeToReturnType.put(Type.STRING, new ARETURN());
0241:
0242:                typeToLoadType = new HashMap();
0243:                typeToLoadType.put(Type.INT, new ILOAD(1));
0244:                typeToLoadType.put(Type.BYTE, new ILOAD(1));
0245:                typeToLoadType.put(Type.CHAR, new ILOAD(1));
0246:                typeToLoadType.put(Type.SHORT, new ILOAD(1));
0247:                typeToLoadType.put(Type.FLOAT, new FLOAD(1));
0248:                typeToLoadType.put(Type.DOUBLE, new DLOAD(1));
0249:                typeToLoadType.put(Type.LONG, new LLOAD(1));
0250:                typeToLoadType.put(Type.BOOLEAN, new ILOAD(1));
0251:                typeToLoadType.put(Type.STRING, new ALOAD(1));
0252:
0253:                primativeTypesToWrapper = new HashMap(8);
0254:                primativeTypesToWrapper.put(Type.INT, INTEGER_TYPE);
0255:                primativeTypesToWrapper.put(Type.BYTE, BYTE_TYPE);
0256:                primativeTypesToWrapper.put(Type.CHAR, CHARACTER_TYPE);
0257:                primativeTypesToWrapper.put(Type.SHORT, SHORT_TYPE);
0258:                primativeTypesToWrapper.put(Type.FLOAT, FLOAT_TYPE);
0259:                primativeTypesToWrapper.put(Type.DOUBLE, DOUBLE_TYPE);
0260:                primativeTypesToWrapper.put(Type.LONG, LONG_TYPE);
0261:                primativeTypesToWrapper.put(Type.BOOLEAN, BOOLEAN_TYPE);
0262:
0263:            }
0264:
0265:            public void setGetAndSettersMap(HashMap map) {
0266:                getAndSettersMap = map;
0267:            }
0268:
0269:            private JavaClass getJavaClass(String className) throws IOException {
0270:                String classFileName = className.replace('.', '/') + ".class";
0271:                InputStream inputStream = loader
0272:                        .getResourceAsStream(classFileName);
0273:                if (inputStream == null) {
0274:                    inputStream = loader.getResourceAsStream("/"
0275:                            + classFileName);
0276:                    if (inputStream == null) {
0277:                        throw new javax.jdo.JDOFatalUserException(
0278:                                "Class not found: " + className);
0279:                    }
0280:                }
0281:                ClassParser parser = new ClassParser(inputStream, classFileName);
0282:                return parser.parse();
0283:            }
0284:
0285:            private JavaClass getOrigJavaClass(String className)
0286:                    throws IOException {
0287:                String classFileName = className.replace('.', '/') + ".class";
0288:                InputStream inputStream = loader
0289:                        .getResourceAsStream(classFileName);
0290:                URL currentFileURL = loader.getResource(classFileName);
0291:                if (currentFileURL.toString().startsWith("jar:")
0292:                        && outputDir == null) {
0293:                    throw new javax.jdo.JDOFatalUserException(
0294:                            "Can not write class "
0295:                                    + className
0296:                                    + " into a jar. Please specify a output directory.");
0297:                }
0298:                currentOutputFile = new File(currentFileURL.getFile());
0299:                if (inputStream == null) {
0300:                    inputStream = loader.getResourceAsStream("/"
0301:                            + classFileName);
0302:                    currentFileURL = loader.getResource("/" + classFileName);
0303:                    if (currentFileURL.toString().startsWith("jar:")
0304:                            && outputDir == null) {
0305:                        throw new javax.jdo.JDOFatalUserException(
0306:                                "Can not write class "
0307:                                        + className
0308:                                        + " into a jar. Please specify a output directory.");
0309:                    }
0310:                    currentOutputFile = new File(currentFileURL.getFile());
0311:                    if (inputStream == null) {
0312:                        throw new javax.jdo.JDOFatalUserException(
0313:                                "Class not found: " + className);
0314:                    }
0315:                }
0316:                ClassParser parser = new ClassParser(inputStream, classFileName);
0317:                return parser.parse();
0318:            }
0319:
0320:            public boolean enhance(ClassInfo classInfo, ClassMetaData cmd,
0321:                    boolean makeFieldsPrivate, boolean detached) {
0322:                try {
0323:                    this .detach = detached;
0324:                    this .classInfo = classInfo;
0325:                    fieldSet = classInfo.getFieldList();
0326:                    if (fieldSet.isEmpty()) {
0327:                        isEmpty = true;
0328:                    } else {
0329:                        isEmpty = false;
0330:                    }
0331:                    JavaClass javaClass = getOrigJavaClass(classInfo
0332:                            .getClassName());
0333:                    classGen = new ClassGen(javaClass);
0334:                    // ConstantPoolGen is used to represent the constant pool of a Classfile            ll
0335:                    constantPoolGen = classGen.getConstantPool();
0336:                    // used to create objects representing VM instructions
0337:                    instructionFactory = new InstructionFactory(constantPoolGen);
0338:
0339:                    if (implements PC()) { //if the class already implements PC, don't enhance
0340:                        return false;
0341:                    }
0342:                    currentSerialVersionUID = SerialUIDHelper
0343:                            .computeSerialVersionUID(javaClass);
0344:                    synthetic = classGen.getConstantPool().addUtf8("Synthetic");
0345:
0346:                    boolean topClass = classInfo.getTopPCSuperClass() == null;
0347:                    boolean appIdentity = classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION;
0348:                    didWeAddADefaultConstructor = false;
0349:
0350:                    //Tasks
0351:                    rewriteStaticConstructor();
0352:                    setDefaultConstructor();
0353:                    setClass$();
0354:                    addSerialVersionUID();
0355:                    addJdoFieldNames();
0356:                    addJdoFieldFlags();
0357:                    if (topClass)
0358:                        addJdoStateManager(); //super
0359:                    if (topClass)
0360:                        addJdoFlags(); //super
0361:                    addJdoInheritedFieldCount();
0362:                    addJdoPersistenceCapableSuperclass();
0363:                    addJdoFieldTypes();
0364:                    addJdoGetManagedFieldCount();
0365:                    if (topClass)
0366:                        addInterrogatives(); //super
0367:                    addFieldGetters();
0368:                    addFieldSetters();
0369:                    addJdoReplaceField();
0370:                    addJdoReplaceFields(); //super??????????????/
0371:                    addJdoProvideField();
0372:                    addJdoProvideFields(); //super??????????????/
0373:                    addJdoCopyFields();
0374:                    addJdoCopyField();
0375:                    if (topClass)
0376:                        addJdoPreSerialize(); //super
0377:                    addWriteObject();
0378:                    addReadObject();
0379:                    addRegisterClass();
0380:                    addJdoNewInstance1();
0381:                    addJdoNewInstance2();
0382:                    if (topClass || appIdentity)
0383:                        addJdoNewObjectIdInstance1();
0384:                    if (topClass || appIdentity)
0385:                        addJdoNewObjectIdInstance2();
0386:                    if (topClass)
0387:                        addJdoGetObjectId(); //super
0388:                    if (topClass)
0389:                        addJdoGetTransactionalObjectId(); //super
0390:                    if (topClass)
0391:                        addJdoReplaceStateManager(); //super
0392:                    if (topClass)
0393:                        addJdoCopyKeyFieldsToObjectId1();
0394:                    if (topClass)
0395:                        addJdoCopyKeyFieldsToObjectId2();
0396:                    if (topClass)
0397:                        addJdoCopyKeyFieldsFromObjectId1();
0398:                    if (topClass)
0399:                        addJdoCopyKeyFieldsFromObjectId2();
0400:                    if (topClass)
0401:                        addJdoReplaceFlags(); //super
0402:
0403:                    addJdoInterface();
0404:                    if (makeFieldsPrivate) {
0405:                        setEnhancedFieldsPrivate();
0406:                    }
0407:                    swapGetterAndSetter();
0408:                    swapClone();
0409:
0410:                    //	        addVersantMakeHollow(); // put it in later
0411:                    totlalManagedFields = 0;
0412:                    if (detach) {
0413:                        if (topClass) {
0414:                            ClassMetaData[] hier = cmd.pcHeirachy;
0415:                            for (int i = 0; i < hier.length; i++) {
0416:                                ClassMetaData classMetaData = hier[i];
0417:                                totlalManagedFields += classMetaData.managedFields.length;
0418:                            }
0419:                            addFields();
0420:                            addSetLoadedInt("versantSetLoaded"); //public void versantSetLoaded(int i);
0421:                            addIsLoadedInt("versantIsLoaded"); //boolean versantIsLoaded(int i);
0422:                            addIsDirty("versantIsDirty"); //boolean versantIsDirty();
0423:                            addMakeDirtyInt("versantMakeDirty");
0424:                            addIsDirtyInt("versantIsDirty"); //public boolean versantIsDirty(int fieldNo);
0425:                            addSetOid("versantSetOID"); //public void versantSetOID(Object id);
0426:                            addGetOid("versantGetOID"); //public Object versantGetOID();
0427:                            addGetVersion("versantGetVersion"); //public Object versantGetVersion();
0428:                            addSetVersion("versantSetVersion"); //public void versantSetVersion(Object version);
0429:                            addGetStateManager("versantGetDetachedStateManager"); //StateManager versantGetDetachedStateManager();
0430:                            addDetachInterfase();
0431:                        }
0432:                        addMakeDirtyString("versantMakeDirty"); //void versantMakeDirty(String s);// if the names change, change this method.
0433:                    }
0434:
0435:                    if (didWeAddADefaultConstructor) {
0436:                        isOurConstructorValid();
0437:                    }
0438:                    dumpClass();
0439:
0440:                    System.out.println("Persistence Capable = "
0441:                            + classInfo.getClassName());
0442:
0443:                } catch (Exception e) {
0444:                    e.printStackTrace();
0445:                    if (Debug.DEBUG) {
0446:                        Debug.ERR.println("Error in Enhancer");
0447:                        e.printStackTrace(Debug.ERR);
0448:                    }
0449:                }
0450:                return true;
0451:            }
0452:
0453:            private void isOurConstructorValid() {
0454:                //this gets done only for the least-derived persistence capable class.
0455:                if (classInfo.getPersistenceCapableSuperclass() != null) {
0456:                    return;
0457:                }
0458:                String super Name = classGen.getSuperclassName();
0459:                try {
0460:                    JavaClass javaClass = getJavaClass(super Name);
0461:                    ClassGen classGen = new ClassGen(javaClass);
0462:                    Method[] methods = classGen.getMethods();
0463:                    for (int i = 0; i < methods.length; i++) {
0464:                        Method m = methods[i];
0465:                        // native and abstract methods don't have any code
0466:                        // so continue with next method
0467:                        if (m.isNative() || m.isAbstract()) {
0468:                            continue;
0469:                        }
0470:                        if (m.getName().equals("<init>")) { //is constructor
0471:                            if (m.getSignature().equals("()V")) { //is no args constructor
0472:                                if (!m.isPrivate()) {
0473:                                    return;
0474:                                }
0475:                            }
0476:                        }
0477:                    }
0478:                    throw new JDOUserException(
0479:                            "Could not create a valid default constructor for class "
0480:                                    + this .classGen.getClassName());
0481:                } catch (IOException e) {
0482:                    // hide exception, this class is not on our classpath
0483:                }
0484:            }
0485:
0486:            private void addDefaultConstructorToNonPersistantSuperClasses(
0487:                    String super Name) {
0488:                //this gets done only for the least-derived persistence capable class.
0489:                if (super Name == null) {
0490:                    if (classInfo.getPersistenceCapableSuperclass() != null) {
0491:                        return;
0492:                    }
0493:                    super Name = classGen.getSuperclassName();
0494:                }
0495:
0496:                try {
0497:                    JavaClass javaClass = getJavaClass(super Name);
0498:                    ClassGen classGen = new ClassGen(javaClass);
0499:                    // ConstantPoolGen is used to represent the constant pool of a Classfile            ll
0500:                    ConstantPoolGen constantPoolGen = classGen
0501:                            .getConstantPool();
0502:
0503:                    Method[] methods = classGen.getMethods();
0504:                    for (int i = 0; i < methods.length; i++) {
0505:                        Method m = methods[i];
0506:                        // native and abstract methods don't have any code
0507:                        // so continue with next method
0508:                        if (m.isNative() || m.isAbstract()) {
0509:                            continue;
0510:                        }
0511:
0512:                        if (m.getName().equals("<init>")) { //is constructor
0513:                            if (m.getSignature().equals("()V")) { //is no args constructor
0514:                                if (m.isPublic()) {
0515:                                    return;
0516:                                } else { //there is a default constructor but access is wrong
0517:                                    m.isPublic(true);
0518:                                    m.isProtected(false); //change access to protected
0519:                                    m.isPrivate(false); //take away private access
0520:                                    String fileName = classGen.getClassName()
0521:                                            .replace('.', charfileSeparator)
0522:                                            + ".class";
0523:                                    File dumpFile = new File(outputDir,
0524:                                            fileName);
0525:                                    try {
0526:                                        classGen.getJavaClass().dump(dumpFile);
0527:                                    } catch (IOException e) {
0528:                                        //hide, we could not write out the class
0529:                                    }
0530:                                    return;
0531:                                }
0532:                            }
0533:                        }
0534:                    }
0535:
0536:                    InstructionList il = new InstructionList();
0537:                    il.append(InstructionConstants.THIS); // Push `this'
0538:                    il.append(new INVOKESPECIAL(constantPoolGen.addMethodref(
0539:                            classGen.getSuperclassName(), "<init>", "()V")));
0540:                    il.append(InstructionConstants.RETURN);
0541:
0542:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC, // todo this is not to spec it should be protected
0543:                            Type.VOID, Type.NO_ARGS, null, "<init>", classGen
0544:                                    .getClassName(), il, constantPoolGen);
0545:                    methodGen.setMaxLocals();
0546:                    methodGen.setMaxStack();
0547:
0548:                    classGen.addMethod(methodGen.getMethod());
0549:
0550:                    String fileName = classGen.getClassName().replace('.',
0551:                            charfileSeparator)
0552:                            + ".class";
0553:                    File dumpFile = new File(outputDir, fileName);
0554:                    boolean error = false;
0555:                    try {
0556:                        classGen.getJavaClass().dump(dumpFile);
0557:                    } catch (IOException e) {
0558:                        //hide, we could not write out the class
0559:                        error = true;
0560:
0561:                    }
0562:
0563:                    if (!error) {
0564:                        // set our next class
0565:                        // Print warning
0566:                        if (this .classGen.getSuperclassName().equals(
0567:                                classGen.getClassName())) {
0568:                            System.out
0569:                                    .println("WARNING: persistence capable class '"
0570:                                            + this .classGen.getClassName()
0571:                                            + "' has a non persistence super class \n'"
0572:                                            + classGen.getClassName()
0573:                                            + "', that does not have a default constructor, will add one.");
0574:                        }
0575:
0576:                        addDefaultConstructorToNonPersistantSuperClasses(classGen
0577:                                .getSuperclassName());
0578:                    }
0579:
0580:                } catch (IOException e) {
0581:                    // hide exception, this class is not on our classpath
0582:                }
0583:            }
0584:
0585:            private void swapClone() {
0586:                // representation of methods in the class
0587:                Method[] methods = classGen.getMethods();
0588:                for (int i = 0; i < methods.length; i++) {
0589:                    Method m = methods[i];
0590:
0591:                    // native and abstract methods don't have any code
0592:                    // so continue with next method
0593:                    if (m.isNative() || m.isAbstract()) {
0594:                        continue;
0595:                    }
0596:                    //we do not want to enhance our enhanced methods
0597:                    if (m.getName().startsWith("<cl")) {
0598:                        continue;
0599:                    }
0600:
0601:                    boolean changed = false;
0602:
0603:                    MethodGen mg = new MethodGen(m, classGen.getClassName(),
0604:                            constantPoolGen);
0605:
0606:                    // get the code in form of an InstructionList object
0607:                    InstructionList il = mg.getInstructionList();
0608:
0609:                    // get the first instruction
0610:                    InstructionHandle ih = il.getStart();
0611:
0612:                    while (ih != null) {
0613:                        Instruction ins = ih.getInstruction();
0614:                        if (ins.getClass().getName().equals(invokeSpecial)) {
0615:                            INVOKESPECIAL is = (INVOKESPECIAL) ins;
0616:                            if (is.getClassName(constantPoolGen).equals(
0617:                                    "java.lang.Object")
0618:                                    && is.getMethodName(constantPoolGen)
0619:                                            .equals("clone")
0620:                                    && is.getSignature(constantPoolGen).equals(
0621:                                            "()Ljava/lang/Object;")) {
0622:
0623:                                il.append(is, getCloneIL());
0624:                                il.setPositions();
0625:                                il.update();
0626:                                changed = true;
0627:
0628:                            }
0629:                        }
0630:                        // next instruction
0631:                        ih = ih.getNext();
0632:                    }
0633:                    // don't forget to write the code
0634:                    if (changed) {
0635:                        il.setPositions();
0636:                        il.update();
0637:                        mg.setMaxLocals();
0638:                        mg.setMaxStack();
0639:                        classGen.replaceMethod(m, mg.getMethod());
0640:                    }
0641:                }
0642:            }
0643:
0644:            private InstructionList getCloneIL() {
0645:                InstructionList il = new InstructionList();
0646:                il.append(new DUP());
0647:                il.append(instructionFactory.createCheckCast(new ObjectType(
0648:                        classGen.getClassName())));
0649:                il.append(new ACONST_NULL());
0650:                if (javaVersion >= JAVA_1_4) {
0651:                    il
0652:                            .append(instructionFactory.createPutField(classGen
0653:                                    .getClassName(), "jdoStateManager",
0654:                                    SM_OBJECT_TYPE));
0655:                } else {
0656:                    il.append(instructionFactory.createPutField(
0657:                            getTopPCSuperOrCurrentClassName(),
0658:                            "jdoStateManager", SM_OBJECT_TYPE));
0659:                }
0660:                il.append(new DUP());
0661:                il.append(instructionFactory.createCheckCast(new ObjectType(
0662:                        classGen.getClassName())));
0663:                il.append(new ICONST(0));
0664:                if (javaVersion >= JAVA_1_4) {
0665:                    il.append(instructionFactory.createPutField(classGen
0666:                            .getClassName(), "jdoFlags", Type.BYTE));
0667:                } else {
0668:                    il.append(instructionFactory.createPutField(
0669:                            getTopPCSuperOrCurrentClassName(), "jdoFlags",
0670:                            Type.BYTE));
0671:                }
0672:                return il;
0673:
0674:            }
0675:
0676:            //	private void addJdogenieMakeHollow() {
0677:            //
0678:            //        InstructionList il = new InstructionList();
0679:            //        MethodGen methodGen = new MethodGen(
0680:            //                Constants.ACC_PUBLIC ,
0681:            //                Type.VOID,
0682:            //                new Type[]{},
0683:            //                new String[]{},
0684:            //                vendorName+"MakeHollow",
0685:            //                classGen.getClassName(),
0686:            //                il,
0687:            //                constantPoolGen);
0688:            //
0689:            //		for (Iterator iterator = fieldSet.iterator();iterator.hasNext();) {
0690:            //			FieldInfo fieldInfo = (FieldInfo) iterator.next();
0691:            //			if (fieldInfo.isPrimative() && !fieldInfo.isArray()){
0692:            //				continue;
0693:            //			}
0694:            //			il.append(new ALOAD(0));
0695:            //			il.append(new ACONST_NULL());
0696:            //			il.append(instructionFactory.createPutField(
0697:            //			        classGen.getClassName(),
0698:            //			        fieldInfo.getFieldName(),
0699:            //			        fieldInfo.getType()));
0700:            //
0701:            //		}
0702:            //		if (classInfo.getPersistenceCapableSuperclass() != null){
0703:            //			il.append(new ALOAD(0));
0704:            //			il.append(instructionFactory.createInvoke(
0705:            //			        classInfo.getPersistenceCapableSuperclass() ,
0706:            //			        vendorName+"MakeHollow" ,
0707:            //			        Type.VOID ,
0708:            //			        new Type[]{} ,
0709:            //			        Constants.INVOKESPECIAL));
0710:            //			il.append(new RETURN());
0711:            //		} else {
0712:            //            il.append(new RETURN());
0713:            //		}
0714:            //
0715:            //        methodGen.setMaxLocals();
0716:            //        methodGen.setMaxStack();
0717:            //        classGen.addMethod(methodGen.getMethod());
0718:            //        il.dispose();
0719:            ////		classGen.addInterface(MAKE_HOLLOW_INTERFASE);
0720:            //    }
0721:
0722:            private void dumpClass() throws VerifyException {
0723:                String fileName = classGen.getClassName().replace('.',
0724:                        charfileSeparator)
0725:                        + ".class";
0726:                File dumpFile;
0727:                if (outputDir != null) {
0728:                    dumpFile = new File(outputDir, fileName);
0729:                } else {
0730:                    dumpFile = currentOutputFile;
0731:                }
0732:                try {
0733:                    classGen.getJavaClass().dump(dumpFile);
0734:                } catch (IOException e) {
0735:                    throw new VerifyException(e);
0736:                }
0737:
0738:            }
0739:
0740:            /** Copy fields to an outside source from the key fields in the ObjectId.
0741:             * This method is generated in the PersistenceCapable class to generate
0742:             * a call to the field manager for each key field in the ObjectId.  For
0743:             * example, an ObjectId class that has three key fields (int id,
0744:             * String name, and Float salary) would have the method generated:
0745:             * <P>void copyKeyFieldsFromObjectId
0746:             * <P>        (PersistenceCapable oid, ObjectIdFieldManager fm) {
0747:             * <P>     fm.storeIntField (0, oid.id);
0748:             * <P>     fm.storeStringField (1, oid.name);
0749:             * <P>     fm.storeObjectField (2, oid.salary);
0750:             * <P>}
0751:             * <P>The implementation is responsible for implementing the
0752:             * ObjectIdFieldManager to store the values for the key fields.
0753:             * private void jdoCopyKeyFieldsFromObjectId(PersistenceCapable.ObjectIdFieldReplacer fm, Object oid){
0754:             */
0755:            private void addJdoCopyKeyFieldsFromObjectId1() {
0756:                if (classInfo.getTopPCSuperClass() == null
0757:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
0758:                                .getObjectidClass() != null)) {
0759:                    InstructionList il = new InstructionList();
0760:                    MethodGen methodGen = new MethodGen(
0761:                            Constants.ACC_PUBLIC,
0762:                            Type.VOID,
0763:                            new Type[] {
0764:                                    new ObjectType(
0765:                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer"),
0766:                                    Type.OBJECT },
0767:                            new String[] { "fc", "oid" },
0768:                            "jdoCopyKeyFieldsFromObjectId", classGen
0769:                                    .getClassName(), il, constantPoolGen);
0770:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
0771:                            && classInfo.getObjectidClass() != null) {
0772:                        Iterator iter = classInfo.getFieldList().iterator();
0773:                        int count = 0;
0774:                        boolean isObject = false;
0775:                        while (iter.hasNext()) {
0776:                            FieldInfo info = (FieldInfo) iter.next();
0777:                            if (info.primaryKey()) {
0778:                                String fieldReplacerMethod = null;
0779:                                if (typeToFieldReplacer.containsKey(info
0780:                                        .getType())) {
0781:                                    fieldReplacerMethod = (String) typeToFieldReplacer
0782:                                            .get(info.getType());
0783:                                    isObject = false;
0784:                                } else {
0785:                                    isObject = true;
0786:                                }
0787:                                il.append(new ALOAD(1));
0788:                                il.append(instructionFactory.createGetStatic(
0789:                                        classGen.getClassName(),
0790:                                        "jdoInheritedFieldCount", Type.INT));
0791:                                il.append(new PUSH(constantPoolGen, count));
0792:                                il.append(new IADD());
0793:                                il.append(new ALOAD(2));
0794:                                il.append(instructionFactory
0795:                                        .createCheckCast(new ObjectType(
0796:                                                classInfo.getObjectidClass())));
0797:                                il
0798:                                        .append(instructionFactory
0799:                                                .createGetField(classInfo
0800:                                                        .getObjectidClass(),
0801:                                                        info.getFieldName(),
0802:                                                        info.getType()));
0803:
0804:                                if (isObject) {
0805:                                    il
0806:                                            .append(instructionFactory
0807:                                                    .createInvoke(
0808:                                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer",
0809:                                                            "storeObjectField",
0810:                                                            Type.VOID,
0811:                                                            new Type[] {
0812:                                                                    Type.INT,
0813:                                                                    Type.OBJECT },
0814:                                                            Constants.INVOKEINTERFACE));
0815:                                } else {
0816:                                    il
0817:                                            .append(instructionFactory
0818:                                                    .createInvoke(
0819:                                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldConsumer",
0820:                                                            fieldReplacerMethod,
0821:                                                            Type.VOID,
0822:                                                            new Type[] {
0823:                                                                    Type.INT,
0824:                                                                    info
0825:                                                                            .getType() },
0826:                                                            Constants.INVOKEINTERFACE));
0827:                                }
0828:                            }
0829:                            count++;
0830:                        }
0831:                    }
0832:                    il.append(new RETURN());
0833:                    //            makeSynthetic(methodGen);
0834:                    methodGen.setMaxLocals();
0835:                    methodGen.setMaxStack();
0836:                    classGen.addMethod(methodGen.getMethod());
0837:                    il.dispose();
0838:                }
0839:            }
0840:
0841:            private void addJdoCopyKeyFieldsFromObjectId2() {
0842:                if (classInfo.getTopPCSuperClass() == null
0843:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
0844:                                .getObjectidClass() != null)) {
0845:
0846:                    InstructionList il = new InstructionList();
0847:                    MethodGen methodGen = new MethodGen(
0848:                            Constants.ACC_PROTECTED, Type.VOID,
0849:                            new Type[] { Type.OBJECT }, new String[] { "oid" },
0850:                            "jdoCopyKeyFieldsFromObjectId", classGen
0851:                                    .getClassName(), il, constantPoolGen);
0852:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
0853:                            && classInfo.getObjectidClass() != null) {
0854:
0855:                        il.append(new ALOAD(1));
0856:                        il.append(instructionFactory
0857:                                .createCheckCast(new ObjectType(classInfo
0858:                                        .getObjectidClass())));
0859:                        il.append(new ASTORE(2));
0860:                        InstructionHandle pckStartHandle = null;
0861:                        boolean first = true;
0862:                        ClassInfo currentClass = getTopPCSuperOrCurrentClass();
0863:                        Iterator iter = currentClass.getFieldList().iterator();
0864:                        while (iter.hasNext()) {
0865:                            FieldInfo info = (FieldInfo) iter.next();
0866:                            if (info.primaryKey()) {
0867:                                if (first) {
0868:                                    pckStartHandle = il.append(new ALOAD(0));
0869:                                    first = false;
0870:                                } else {
0871:                                    il.append(new ALOAD(0));
0872:                                }
0873:                                il.append(new ALOAD(2));
0874:                                il
0875:                                        .append(instructionFactory
0876:                                                .createGetField(classInfo
0877:                                                        .getObjectidClass(),
0878:                                                        info.getFieldName(),
0879:                                                        info.getType()));
0880:                                il
0881:                                        .append(instructionFactory
0882:                                                .createPutField(classInfo
0883:                                                        .getClassName(), info
0884:                                                        .getFieldName(), info
0885:                                                        .getType()));
0886:                            }
0887:                        }
0888:                        il.append(new RETURN());
0889:                        methodGen.addLocalVariable("pck", new ObjectType(
0890:                                classInfo.getObjectidClass()), 2,
0891:                                pckStartHandle, il.getEnd());
0892:                    } else {
0893:                        il.append(new RETURN());
0894:                    }
0895:                    //            makeSynthetic(methodGen);
0896:                    methodGen.setMaxLocals();
0897:                    methodGen.setMaxStack();
0898:                    classGen.addMethod(methodGen.getMethod());
0899:                    il.dispose();
0900:                }
0901:            }
0902:
0903:            private String getTopPCSuperOrCurrentClassName() {
0904:                if (classInfo.getTopPCSuperClass() == null) {
0905:                    return classInfo.getClassName();
0906:                } else {
0907:                    return classInfo.getTopPCSuperClass().getClassName();
0908:                }
0909:            }
0910:
0911:            private ClassInfo getTopPCSuperOrCurrentClass() {
0912:                if (classInfo.getTopPCSuperClass() == null) {
0913:                    return classInfo;
0914:                } else {
0915:                    return classInfo.getTopPCSuperClass();
0916:                }
0917:            }
0918:
0919:            private void addJdoReplaceFlags() {
0920:                if (classInfo.getTopPCSuperClass() == null) {
0921:                    InstructionList il = new InstructionList();
0922:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
0923:                            Type.VOID, new Type[] {}, new String[] {},
0924:                            "jdoReplaceFlags", classGen.getClassName(), il,
0925:                            constantPoolGen);
0926:
0927:                    il.append(new ALOAD(0));
0928:                    il.append(instructionFactory.createGetField(
0929:                            getTopPCSuperOrCurrentClassName(),
0930:                            "jdoStateManager", SM_OBJECT_TYPE));
0931:                    IFNULL ifnull = new IFNULL(null);
0932:                    il.append(ifnull);
0933:                    il.append(new ALOAD(0));
0934:                    il.append(new ALOAD(0));
0935:                    il.append(instructionFactory.createGetField(
0936:                            getTopPCSuperOrCurrentClassName(),
0937:                            "jdoStateManager", SM_OBJECT_TYPE));
0938:                    il.append(new ALOAD(0));
0939:                    il.append(instructionFactory.createInvoke(STATE_MANAGER,
0940:                            "replacingFlags", Type.BYTE,
0941:                            new Type[] { PC_OBJECT_TYPE },
0942:                            Constants.INVOKEINTERFACE));
0943:                    il.append(instructionFactory.createPutField(
0944:                            getTopPCSuperOrCurrentClassName(), "jdoFlags",
0945:                            Type.BYTE));
0946:                    InstructionHandle handle = il.append(new RETURN());
0947:                    ifnull.setTarget(handle);
0948:                    //            makeSynthetic(methodGen);
0949:                    methodGen.setMaxLocals();
0950:                    methodGen.setMaxStack();
0951:
0952:                    classGen.addMethod(methodGen.getMethod());
0953:                    il.dispose();
0954:                }
0955:            }
0956:
0957:            private boolean mustEnhance(Method m) {
0958:                String name = m.getName();
0959:                if (name.startsWith(vendorName + "MakeHollow")) {
0960:                    return false;
0961:                }
0962:                if (name.startsWith(vendorName)) {
0963:                    return true;
0964:                } else if (name.startsWith("jdo")) {
0965:                    if (classInfo.isInstanceCallbacks()
0966:                            && (name.equals("jdoPreStore") || name
0967:                                    .equals("jdoPreDelete"))
0968:                            && m.getSignature().equals("()V")) {
0969:                        return true;
0970:                    }
0971:                } else {
0972:                    return true;
0973:                }
0974:                return false;
0975:            }
0976:
0977:            private void swapGetterAndSetter() {
0978:
0979:                // representation of methods in the class
0980:                Method[] methods = classGen.getMethods();
0981:                for (int i = 0; i < methods.length; i++) {
0982:                    Method m = methods[i];
0983:
0984:                    // native and abstract methods don't have any code
0985:                    // so continue with next method
0986:                    if (m.isNative() || m.isAbstract()) {
0987:                        continue;
0988:                    }
0989:                    //we do not want to enhance our enhanced methods
0990:                    if (m.getName().startsWith("<cl")) {
0991:                        continue;
0992:                    }
0993:
0994:                    if (!mustEnhance(m)) {
0995:                        continue;
0996:                    }
0997:
0998:                    boolean changed = false;
0999:
1000:                    MethodGen mg = new MethodGen(m, classGen.getClassName(),
1001:                            constantPoolGen);
1002:
1003:                    // get the code in form of an InstructionList object
1004:                    InstructionList il = mg.getInstructionList();
1005:
1006:                    // get the first instruction
1007:                    InstructionHandle ih = il.getStart();
1008:                    while (ih != null) {
1009:                        Instruction ins = ih.getInstruction();
1010:                        if (ins.getClass().getName().equals(getField)) {//if (ins instanceof GETFIELD)
1011:                            GETFIELD is = (GETFIELD) ins;
1012:                            String key = is.getClassName(constantPoolGen) + "|"
1013:                                    + is.getFieldName(constantPoolGen);
1014:                            if (getAndSettersMap.containsKey(key)) {
1015:                                SwapFieldHelper helper = (SwapFieldHelper) getAndSettersMap
1016:                                        .get(key);
1017:                                // replace it with our static replacement method
1018:                                ih.setInstruction(instructionFactory
1019:                                        .createInvoke(helper.className,
1020:                                                helper.jdoGetName, helper.type,
1021:                                                new Type[] { new ObjectType(
1022:                                                        helper.className) },
1023:                                                Constants.INVOKESTATIC));
1024:                                il.setPositions();
1025:                                il.update();
1026:
1027:                                changed = true;
1028:                                InstructionHandle prevIhDUP = ih.getPrev();
1029:                                Instruction iffyDup = prevIhDUP
1030:                                        .getInstruction();
1031:                                if (iffyDup.getClass().getName().equals(dup)) { // The previos ist was a DUP
1032:                                    ih = ih.getPrev();
1033:                                    InstructionHandle prevIhALOAD = ih
1034:                                            .getPrev();
1035:                                    Instruction iffyAload = prevIhALOAD
1036:                                            .getInstruction();
1037:                                    if (iffyAload.getClass().getName().equals(
1038:                                            aload)) { // The ist before that was a ALOAD
1039:                                        ALOAD aLoad = (ALOAD) iffyAload;
1040:                                        ih.setInstruction(aLoad); // Swap ref out
1041:                                        il.setPositions();
1042:                                        il.update();
1043:                                    } else {
1044:                                        ih = ih.getNext();
1045:                                    }
1046:                                }
1047:                            }
1048:                        } else if (ins.getClass().getName().equals(putField)) {
1049:                            PUTFIELD is = (PUTFIELD) ins;
1050:                            String key = is.getClassName(constantPoolGen) + "|"
1051:                                    + is.getFieldName(constantPoolGen);
1052:                            if (getAndSettersMap.containsKey(key)) {
1053:                                SwapFieldHelper helper = (SwapFieldHelper) getAndSettersMap
1054:                                        .get(key);
1055:                                // replace it with our static replacement method
1056:                                ih
1057:                                        .setInstruction(instructionFactory
1058:                                                .createInvoke(
1059:                                                        helper.className,
1060:                                                        helper.jdoSetName,
1061:                                                        Type.VOID,
1062:                                                        new Type[] {
1063:                                                                new ObjectType(
1064:                                                                        helper.className),
1065:                                                                helper.type },
1066:                                                        Constants.INVOKESTATIC));
1067:                                il.setPositions();
1068:                                il.update();
1069:                                changed = true;
1070:                            }
1071:                        }
1072:                        // next instruction
1073:                        ih = ih.getNext();
1074:                    }
1075:                    if (changed) {
1076:                        il.setPositions();
1077:                        il.update();
1078:                        mg.setMaxLocals();
1079:                        mg.setMaxStack();
1080:                        Method method = mg.getMethod();
1081:                        classGen.replaceMethod(m, method);
1082:                    }
1083:                }
1084:            }
1085:
1086:            private void setEnhancedFieldsPrivate() {
1087:                Field[] fields = classGen.getFields();
1088:                Iterator iter = fieldSet.iterator();
1089:                while (iter.hasNext()) {
1090:                    FieldInfo info = (FieldInfo) iter.next();
1091:                    String fieldname = info.getFieldName();
1092:                    for (int i = 0; i < fields.length; i++) {
1093:                        Field f = fields[i];
1094:                        if (f.getName().equals(fieldname)) {
1095:                            if (!f.isPrivate()) {
1096:                                f.isProtected(false);
1097:                                f.isPublic(false);
1098:                                f.isPrivate(true);
1099:                            }
1100:                        }
1101:                    }
1102:                }
1103:            }
1104:
1105:            private void addJdoInterface() {
1106:                classGen.addInterface(PERSISTENCE_CAPABLE);
1107:            }
1108:
1109:            private void addJdoCopyKeyFieldsToObjectId2() {
1110:                if (classInfo.getTopPCSuperClass() == null
1111:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
1112:                                .getObjectidClass() != null)) {
1113:                    InstructionList il = new InstructionList();
1114:                    MethodGen methodGen = new MethodGen(
1115:                            Constants.ACC_PUBLIC,
1116:                            Type.VOID,
1117:                            new Type[] {
1118:                                    new ObjectType(
1119:                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier"),
1120:                                    Type.OBJECT },
1121:                            new String[] { "fs", "oid" },
1122:                            "jdoCopyKeyFieldsToObjectId", classGen
1123:                                    .getClassName(), il, constantPoolGen);
1124:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
1125:                            && classInfo.getObjectidClass() != null) {
1126:                        Iterator iter = classInfo.getFieldList().iterator();
1127:                        int count = 0;
1128:                        boolean isObject = false;
1129:                        while (iter.hasNext()) {
1130:                            FieldInfo info = (FieldInfo) iter.next();
1131:                            if (info.primaryKey()) {
1132:                                String fieldProviderMethod = null;
1133:                                if (typeToFieldProvider.containsKey(info
1134:                                        .getType())) {
1135:                                    fieldProviderMethod = (String) typeToFieldProvider
1136:                                            .get(info.getType());
1137:                                    isObject = false;
1138:                                } else {
1139:                                    isObject = true;
1140:                                }
1141:                                il.append(new ALOAD(2));
1142:                                il.append(instructionFactory
1143:                                        .createCheckCast(new ObjectType(
1144:                                                classInfo.getObjectidClass())));
1145:                                il.append(new ALOAD(1));
1146:                                il.append(instructionFactory.createGetStatic(
1147:                                        classGen.getClassName(),
1148:                                        "jdoInheritedFieldCount", Type.INT));
1149:                                il.append(new PUSH(constantPoolGen, count));
1150:                                il.append(new IADD());
1151:                                if (isObject) {
1152:                                    il
1153:                                            .append(instructionFactory
1154:                                                    .createInvoke(
1155:                                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier",
1156:                                                            "fetchObjectField",
1157:                                                            Type.OBJECT,
1158:                                                            new Type[] { Type.INT },
1159:                                                            Constants.INVOKEINTERFACE));
1160:                                    il
1161:                                            .append(instructionFactory
1162:                                                    .createCheckCast((ReferenceType) info
1163:                                                            .getType()));
1164:                                } else {
1165:                                    il
1166:                                            .append(instructionFactory
1167:                                                    .createInvoke(
1168:                                                            "javax.jdo.spi.PersistenceCapable$ObjectIdFieldSupplier",
1169:                                                            fieldProviderMethod,
1170:                                                            info.getType(),
1171:                                                            new Type[] { Type.INT },
1172:                                                            Constants.INVOKEINTERFACE));
1173:
1174:                                }
1175:                                il
1176:                                        .append(instructionFactory
1177:                                                .createPutField(classInfo
1178:                                                        .getObjectidClass(),
1179:                                                        info.getFieldName(),
1180:                                                        info.getType()));
1181:
1182:                            }
1183:                            count++;
1184:                        }
1185:                    }
1186:                    il.append(new RETURN());
1187:
1188:                    //            makeSynthetic(methodGen);
1189:                    methodGen.setMaxLocals();
1190:                    methodGen.setMaxStack();
1191:                    classGen.addMethod(methodGen.getMethod());
1192:                    il.dispose();
1193:                }
1194:            }
1195:
1196:            // not cool, maybe ???????? test
1197:            private void addJdoCopyKeyFieldsToObjectId1() {
1198:                if (classInfo.getTopPCSuperClass() == null
1199:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
1200:                                .getObjectidClass() != null)) {
1201:                    InstructionList il = new InstructionList();
1202:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1203:                            Type.VOID, new Type[] { Type.OBJECT },
1204:                            new String[] { "oid" },
1205:                            "jdoCopyKeyFieldsToObjectId", classGen
1206:                                    .getClassName(), il, constantPoolGen);
1207:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
1208:                            && classInfo.getObjectidClass() != null) {
1209:                        Iterator iter = classInfo.getFieldList().iterator();
1210:                        while (iter.hasNext()) {
1211:                            FieldInfo info = (FieldInfo) iter.next();
1212:                            if (info.primaryKey()) {
1213:                                il.append(new ALOAD(1));
1214:                                il.append(instructionFactory
1215:                                        .createCheckCast(new ObjectType(
1216:                                                classInfo.getObjectidClass())));
1217:                                il.append(new ALOAD(0));
1218:                                il
1219:                                        .append(instructionFactory
1220:                                                .createGetField(classInfo
1221:                                                        .getClassName(), info
1222:                                                        .getFieldName(), info
1223:                                                        .getType()));
1224:                                il
1225:                                        .append(instructionFactory
1226:                                                .createPutField(classInfo
1227:                                                        .getObjectidClass(),
1228:                                                        info.getFieldName(),
1229:                                                        info.getType()));
1230:                            }
1231:                        }
1232:                    }
1233:                    il.append(new RETURN());
1234:                    //            makeSynthetic(methodGen);
1235:                    methodGen.setMaxLocals();
1236:                    methodGen.setMaxStack();
1237:                    classGen.addMethod(methodGen.getMethod());
1238:                    il.dispose();
1239:                }
1240:            }
1241:
1242:            private void addJdoNewObjectIdInstance1() {
1243:                if (classInfo.getTopPCSuperClass() == null
1244:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
1245:                                .getObjectidClass() != null)) {
1246:                    InstructionList il = new InstructionList();
1247:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1248:                            Type.OBJECT, null, null, "jdoNewObjectIdInstance",
1249:                            classGen.getClassName(), il, constantPoolGen);
1250:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
1251:                            && classInfo.getObjectidClass() != null) {
1252:                        il.append(instructionFactory.createNew(classInfo
1253:                                .getObjectidClass()));
1254:                        il.append(new DUP());
1255:                        il.append(instructionFactory.createInvoke(classInfo
1256:                                .getObjectidClass(), "<init>", Type.VOID,
1257:                                new Type[] {}, Constants.INVOKESPECIAL));
1258:                    } else {
1259:                        il.append(new ACONST_NULL());
1260:                    }
1261:                    il.append(new ARETURN());
1262:
1263:                    methodGen.setMaxLocals();
1264:                    methodGen.setMaxStack();
1265:                    classGen.addMethod(methodGen.getMethod());
1266:                    il.dispose();
1267:                }
1268:            }
1269:
1270:            private void addJdoNewObjectIdInstance2() {
1271:                if (classInfo.getTopPCSuperClass() == null
1272:                        || (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION && classInfo
1273:                                .getObjectidClass() != null)) {
1274:                    InstructionList il = new InstructionList();
1275:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1276:                            Type.OBJECT, new Type[] { Type.STRING },
1277:                            new String[] { "str" }, "jdoNewObjectIdInstance",
1278:                            classGen.getClassName(), il, constantPoolGen);
1279:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION
1280:                            && classInfo.getObjectidClass() != null) {
1281:                        il.append(instructionFactory.createNew(classInfo
1282:                                .getObjectidClass()));
1283:                        il.append(new DUP());
1284:                        il.append(new ALOAD(1));
1285:                        il.append(instructionFactory.createInvoke(classInfo
1286:                                .getObjectidClass(), "<init>", Type.VOID,
1287:                                new Type[] { Type.STRING },
1288:                                Constants.INVOKESPECIAL));
1289:                    } else {
1290:                        il.append(new ACONST_NULL());
1291:                    }
1292:                    il.append(new ARETURN());
1293:
1294:                    methodGen.setMaxLocals();
1295:                    methodGen.setMaxStack();
1296:                    classGen.addMethod(methodGen.getMethod());
1297:                    il.dispose();
1298:                }
1299:            }
1300:
1301:            private void addJdoReplaceStateManager() {
1302:                if (classInfo.getTopPCSuperClass() == null) {
1303:                    InstructionList il = new InstructionList();
1304:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC
1305:                            | Constants.ACC_SYNCHRONIZED, Type.VOID,
1306:                            new Type[] { SM_OBJECT_TYPE },
1307:                            new String[] { "sm" }, "jdoReplaceStateManager",
1308:                            classGen.getClassName(), il, constantPoolGen);
1309:
1310:                    il.append(new ALOAD(0));
1311:                    il.append(instructionFactory.createGetField(
1312:                            getTopPCSuperOrCurrentClassName(),
1313:                            "jdoStateManager", SM_OBJECT_TYPE));
1314:                    IFNULL ifnullInst1 = new IFNULL(null);
1315:                    il.append(ifnullInst1);
1316:                    il.append(new ALOAD(0));
1317:                    il.append(new ALOAD(0));
1318:                    il.append(instructionFactory.createGetField(
1319:                            getTopPCSuperOrCurrentClassName(),
1320:                            "jdoStateManager", SM_OBJECT_TYPE));
1321:                    il.append(new ALOAD(0));
1322:                    il.append(new ALOAD(1));
1323:                    il.append(instructionFactory.createInvoke(STATE_MANAGER,
1324:                            "replacingStateManager", SM_OBJECT_TYPE,
1325:                            new Type[] { PC_OBJECT_TYPE, SM_OBJECT_TYPE },
1326:                            Constants.INVOKEINTERFACE));
1327:                    il.append(instructionFactory.createPutField(
1328:                            getTopPCSuperOrCurrentClassName(),
1329:                            "jdoStateManager", SM_OBJECT_TYPE));
1330:                    GOTO gotoInst = new GOTO(null);
1331:                    il.append(gotoInst);
1332:                    InstructionHandle secManHandle = il
1333:                            .append(instructionFactory
1334:                                    .createInvoke(
1335:                                            "java.lang.System",
1336:                                            "getSecurityManager",
1337:                                            new ObjectType(
1338:                                                    "java.lang.SecurityManager"),
1339:                                            new Type[] {},
1340:                                            Constants.INVOKESTATIC));
1341:                    ifnullInst1.setTarget(secManHandle);
1342:                    il.append(new ASTORE(2));
1343:                    InstructionHandle startSecHandle = il.append(new ALOAD(2));
1344:                    IFNULL ifnullInst2 = new IFNULL(null);
1345:                    il.append(ifnullInst2);
1346:                    il.append(new ALOAD(2));
1347:                    il.append(instructionFactory.createGetStatic(
1348:                            "javax.jdo.spi.JDOPermission", "SET_STATE_MANAGER",
1349:                            new ObjectType("javax.jdo.spi.JDOPermission")));
1350:                    il.append(instructionFactory.createInvoke(
1351:                            "java.lang.SecurityManager", "checkPermission",
1352:                            Type.VOID, new Type[] { new ObjectType(
1353:                                    "java.security.Permission") },
1354:                            Constants.INVOKEVIRTUAL));
1355:                    InstructionHandle ifnullHandle = il.append(new ALOAD(0));
1356:                    ifnullInst2.setTarget(ifnullHandle);
1357:                    il.append(new ALOAD(1));
1358:                    il.append(instructionFactory.createPutField(
1359:                            getTopPCSuperOrCurrentClassName(),
1360:                            "jdoStateManager", SM_OBJECT_TYPE));
1361:                    InstructionHandle gotoHandle = il.append(new RETURN());
1362:                    gotoInst.setTarget(gotoHandle);
1363:                    methodGen.addLocalVariable("sec", new ObjectType(
1364:                            "java.lang.SecurityManager"), 2, startSecHandle, il
1365:                            .getEnd());
1366:
1367:                    methodGen.setMaxLocals();
1368:                    methodGen.setMaxStack();
1369:                    classGen.addMethod(methodGen.getMethod());
1370:                    il.dispose();
1371:                }
1372:
1373:            }
1374:
1375:            private void addJdoGetTransactionalObjectId() {
1376:                if (classInfo.getTopPCSuperClass() == null) {
1377:                    InstructionList il = new InstructionList();
1378:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1379:                            Type.OBJECT, new Type[] {}, new String[] {},
1380:                            "jdoGetTransactionalObjectId", classGen
1381:                                    .getClassName(), il, constantPoolGen);
1382:                    il.append(new ALOAD(0));
1383:                    il.append(instructionFactory.createGetField(
1384:                            getTopPCSuperOrCurrentClassName(),
1385:                            "jdoStateManager", SM_OBJECT_TYPE));
1386:                    IFNONNULL ifnonnullInst = new IFNONNULL(null);
1387:                    il.append(ifnonnullInst);
1388:                    il.append(new ACONST_NULL());
1389:                    GOTO gotoInst = new GOTO(null);
1390:                    il.append(gotoInst);
1391:                    InstructionHandle ifnonnullHandle = il.append(new ALOAD(0));
1392:                    il.append(instructionFactory.createGetField(
1393:                            getTopPCSuperOrCurrentClassName(),
1394:                            "jdoStateManager", SM_OBJECT_TYPE));
1395:                    il.append(new ALOAD(0));
1396:                    il.append(instructionFactory.createInvoke(STATE_MANAGER,
1397:                            "getTransactionalObjectId", Type.OBJECT,
1398:                            new Type[] { PC_OBJECT_TYPE },
1399:                            Constants.INVOKEINTERFACE));
1400:                    InstructionHandle gotoHandle = il.append(new ARETURN());
1401:                    gotoInst.setTarget(gotoHandle);
1402:                    ifnonnullInst.setTarget(ifnonnullHandle);
1403:
1404:                    //            makeSynthetic(methodGen);
1405:                    methodGen.setMaxLocals();
1406:                    methodGen.setMaxStack();
1407:                    classGen.addMethod(methodGen.getMethod());
1408:                    il.dispose();
1409:                }
1410:            }
1411:
1412:            private void addJdoGetObjectId() {
1413:                if (classInfo.getTopPCSuperClass() == null) {
1414:                    InstructionList il = new InstructionList();
1415:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1416:                            Type.OBJECT, new Type[] {}, new String[] {},
1417:                            "jdoGetObjectId", classGen.getClassName(), il,
1418:                            constantPoolGen);
1419:
1420:                    il.append(new ALOAD(0));
1421:                    il.append(instructionFactory.createGetField(
1422:                            getTopPCSuperOrCurrentClassName(),
1423:                            "jdoStateManager", SM_OBJECT_TYPE));
1424:                    IFNONNULL ifnonnullInst = new IFNONNULL(null);
1425:                    il.append(ifnonnullInst);
1426:                    il.append(new ACONST_NULL());
1427:                    GOTO gotoInst = new GOTO(null);
1428:                    il.append(gotoInst);
1429:                    InstructionHandle ifnonnullHandle = il.append(new ALOAD(0));
1430:                    il.append(instructionFactory.createGetField(
1431:                            getTopPCSuperOrCurrentClassName(),
1432:                            "jdoStateManager", SM_OBJECT_TYPE));
1433:                    il.append(new ALOAD(0));
1434:                    il.append(instructionFactory.createInvoke(STATE_MANAGER,
1435:                            "getObjectId", Type.OBJECT,
1436:                            new Type[] { PC_OBJECT_TYPE },
1437:                            Constants.INVOKEINTERFACE));
1438:                    InstructionHandle gotoHandle = il.append(new ARETURN());
1439:                    gotoInst.setTarget(gotoHandle);
1440:                    ifnonnullInst.setTarget(ifnonnullHandle);
1441:
1442:                    //            makeSynthetic(methodGen);
1443:                    methodGen.setMaxLocals();
1444:                    methodGen.setMaxStack();
1445:                    classGen.addMethod(methodGen.getMethod());
1446:                    il.dispose();
1447:                }
1448:            }
1449:
1450:            private void addJdoNewInstance2() {
1451:                InstructionList il = new InstructionList();
1452:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1453:                        PC_OBJECT_TYPE, new Type[] { SM_OBJECT_TYPE,
1454:                                Type.OBJECT }, new String[] { "sm", "oid" },
1455:                        "jdoNewInstance", classGen.getClassName(), il,
1456:                        constantPoolGen);
1457:                if (classGen.isAbstract()) {
1458:                    il.append(instructionFactory
1459:                            .createNew("javax.jdo.JDOFatalInternalException"));
1460:                    il.append(new DUP());
1461:                    il.append(instructionFactory.createInvoke(
1462:                            "javax.jdo.JDOFatalInternalException", "<init>",
1463:                            Type.VOID, new Type[] {}, Constants.INVOKESPECIAL));
1464:                    il.append(new ATHROW());
1465:
1466:                } else {
1467:                    if (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_DATASTORE) { // datastore
1468:                        il.append(instructionFactory.createNew(classGen
1469:                                .getClassName()));
1470:                        il.append(new DUP());
1471:                        il.append(instructionFactory.createInvoke(classGen
1472:                                .getClassName(), "<init>", Type.VOID,
1473:                                new Type[] {}, Constants.INVOKESPECIAL));
1474:                        il.append(new ASTORE(3));
1475:                        InstructionHandle pcStartHandle = il
1476:                                .append(new ALOAD(3));
1477:                        il.append(new ALOAD(1));
1478:                        il.append(instructionFactory.createPutField(
1479:                                getTopPCSuperOrCurrentClassName(),
1480:                                "jdoStateManager", SM_OBJECT_TYPE));
1481:                        il.append(new ALOAD(3));
1482:                        il.append(new ICONST(1));
1483:                        il.append(instructionFactory.createPutField(
1484:                                getTopPCSuperOrCurrentClassName(), "jdoFlags",
1485:                                Type.BYTE));
1486:                        il.append(new ALOAD(3));
1487:                        InstructionHandle returnHandle = il
1488:                                .append(new ARETURN());
1489:                        methodGen.addLocalVariable("pc", new ObjectType(
1490:                                classGen.getClassName()), 3, pcStartHandle,
1491:                                returnHandle);
1492:                    } else {// this class has application Identity
1493:                        il.append(instructionFactory.createNew(classGen
1494:                                .getClassName()));
1495:                        il.append(new DUP());
1496:                        il.append(instructionFactory.createInvoke(classGen
1497:                                .getClassName(), "<init>", Type.VOID,
1498:                                new Type[] {}, Constants.INVOKESPECIAL));
1499:                        il.append(new ASTORE(3));
1500:                        InstructionHandle pcStartHandle = il
1501:                                .append(new ALOAD(3));
1502:                        il.append(new ALOAD(1));
1503:                        il.append(instructionFactory.createPutField(
1504:                                getTopPCSuperOrCurrentClassName(),
1505:                                "jdoStateManager", SM_OBJECT_TYPE));
1506:                        il.append(new ALOAD(3));
1507:                        il.append(new ICONST(1));
1508:                        il.append(instructionFactory.createPutField(
1509:                                getTopPCSuperOrCurrentClassName(), "jdoFlags",
1510:                                Type.BYTE));
1511:                        il.append(new ALOAD(0));
1512:                        il.append(new ALOAD(2));
1513:                        il.append(instructionFactory.createInvoke(
1514:                                getTopPCSuperOrCurrentClass().getClassName(),
1515:                                "jdoCopyKeyFieldsFromObjectId", Type.VOID,
1516:                                new Type[] { Type.OBJECT },
1517:                                Constants.INVOKEVIRTUAL));
1518:
1519:                        il.append(new ALOAD(3));
1520:                        il.append(new ARETURN());
1521:                        methodGen.addLocalVariable("pc", new ObjectType(
1522:                                classGen.getClassName()), 3, pcStartHandle, il
1523:                                .getEnd());
1524:                    }
1525:                }
1526:
1527:                //        makeSynthetic(methodGen);
1528:                methodGen.setMaxLocals();
1529:                methodGen.setMaxStack();
1530:                classGen.addMethod(methodGen.getMethod());
1531:                il.dispose();
1532:            }
1533:
1534:            private void addJdoNewInstance1() {
1535:                InstructionList il = new InstructionList();
1536:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1537:                        PC_OBJECT_TYPE, new Type[] { SM_OBJECT_TYPE },
1538:                        new String[] { "sm" }, "jdoNewInstance", classGen
1539:                                .getClassName(), il, constantPoolGen);
1540:                if (classGen.isAbstract()) {
1541:                    il.append(instructionFactory
1542:                            .createNew("javax.jdo.JDOFatalInternalException"));
1543:                    il.append(new DUP());
1544:                    il.append(instructionFactory.createInvoke(
1545:                            "javax.jdo.JDOFatalInternalException", "<init>",
1546:                            Type.VOID, new Type[] {}, Constants.INVOKESPECIAL));
1547:                    il.append(new ATHROW());
1548:                } else {
1549:                    il.append(instructionFactory.createNew(classGen
1550:                            .getClassName()));
1551:                    il.append(new DUP());
1552:                    il.append(instructionFactory.createInvoke(classGen
1553:                            .getClassName(), "<init>", Type.VOID,
1554:                            new Type[] {}, Constants.INVOKESPECIAL));
1555:                    il.append(new ASTORE(2));
1556:                    InstructionHandle pcStartHandle = il.append(new ALOAD(2));
1557:                    il.append(new ALOAD(1));
1558:                    il.append(instructionFactory.createPutField(
1559:                            getTopPCSuperOrCurrentClassName(),
1560:                            "jdoStateManager", SM_OBJECT_TYPE));
1561:                    il.append(new ALOAD(2));
1562:                    il.append(new ICONST(1));
1563:                    il.append(instructionFactory.createPutField(
1564:                            getTopPCSuperOrCurrentClassName(), "jdoFlags",
1565:                            Type.BYTE));
1566:                    il.append(new ALOAD(2));
1567:                    InstructionHandle returnHandle = il.append(new ARETURN());
1568:                    methodGen.addLocalVariable("pc", new ObjectType(classGen
1569:                            .getClassName()), 2, pcStartHandle, returnHandle);
1570:                }
1571:
1572:                //        makeSynthetic(methodGen);
1573:                methodGen.setMaxLocals();
1574:                methodGen.setMaxStack();
1575:                classGen.addMethod(methodGen.getMethod());
1576:                il.dispose();
1577:            }
1578:
1579:            private void addRegisterClass() {
1580:                Method m = getStaticConstructor();
1581:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
1582:                        constantPoolGen);
1583:                InstructionList il = methodGen.getInstructionList();
1584:                InstructionHandle returnHandle = il.getEnd();//The last instruction of <clinit> will always be the return
1585:
1586:                String className = getSetClass$Field(classGen.getClassName());
1587:                InstructionHandle nopTarget = il.append(new NOP());
1588:                il.append(instructionFactory.createGetStatic(classGen
1589:                        .getClassName(), className, new ObjectType(
1590:                        "java.lang.Class")));
1591:                IFNONNULL ifnonnull = new IFNONNULL(null);
1592:                il.append(ifnonnull);
1593:                il.append(new PUSH(constantPoolGen, classGen.getClassName()));
1594:                il.append(instructionFactory.createInvoke(classGen
1595:                        .getClassName(), "class$", new ObjectType(
1596:                        "java.lang.Class"), new Type[] { Type.STRING },
1597:                        Constants.INVOKESTATIC));
1598:                il.append(new DUP());
1599:                il.append(instructionFactory.createPutStatic(classGen
1600:                        .getClassName(), className, new ObjectType(
1601:                        "java.lang.Class")));
1602:                GOTO gotoIns = new GOTO(null);
1603:                il.append(gotoIns);
1604:                InstructionHandle ifnonnullHandle = il
1605:                        .append(instructionFactory.createGetStatic(classGen
1606:                                .getClassName(), className, new ObjectType(
1607:                                "java.lang.Class")));
1608:                ifnonnull.setTarget(ifnonnullHandle);
1609:                InstructionHandle gotoHandle = il.append(instructionFactory
1610:                        .createGetStatic(classGen.getClassName(),
1611:                                "jdoFieldNames", new ArrayType(
1612:                                        "java.lang.String", 1)));
1613:                gotoIns.setTarget(gotoHandle);
1614:                il.append(instructionFactory.createGetStatic(classGen
1615:                        .getClassName(), "jdoFieldTypes", new ArrayType(
1616:                        "java.lang.Class", 1)));
1617:                il.append(instructionFactory.createGetStatic(classGen
1618:                        .getClassName(), "jdoFieldFlags", new ArrayType(
1619:                        Type.BYTE, 1)));
1620:                il.append(instructionFactory.createGetStatic(classGen
1621:                        .getClassName(), "jdoPersistenceCapableSuperclass",
1622:                        new ObjectType("java.lang.Class")));
1623:                if (classGen.isAbstract()) {
1624:                    il.append(new ACONST_NULL());
1625:                } else {
1626:                    il.append(instructionFactory.createNew(classGen
1627:                            .getClassName()));
1628:                    il.append(new DUP());
1629:                    il.append(instructionFactory.createInvoke(classGen
1630:                            .getClassName(), "<init>", Type.VOID,
1631:                            new Type[] {}, Constants.INVOKESPECIAL));
1632:                }
1633:                il.append(instructionFactory.createInvoke(
1634:                        "javax.jdo.spi.JDOImplHelper", "registerClass",
1635:                        Type.VOID, new Type[] {
1636:                                new ObjectType("java.lang.Class"),
1637:                                new ArrayType(Type.STRING, 1),
1638:                                new ArrayType("java.lang.Class", 1),
1639:                                new ArrayType(Type.BYTE, 1),
1640:                                new ObjectType("java.lang.Class"),
1641:                                PC_OBJECT_TYPE }, Constants.INVOKESTATIC));
1642:                il.append(new RETURN());
1643:                try {
1644:                    il.delete(returnHandle);
1645:                } catch (TargetLostException e) {
1646:                    InstructionHandle[] targets = e.getTargets();
1647:                    for (int i = 0; i < targets.length; i++) {
1648:                        InstructionTargeter[] targeters = targets[i]
1649:                                .getTargeters();
1650:                        for (int j = 0; j < targeters.length; j++) {
1651:                            targeters[j].updateTarget(targets[i], nopTarget);
1652:                        }
1653:                    }
1654:                }
1655:                methodGen.removeNOPs();
1656:                methodGen.setMaxLocals();
1657:                methodGen.setMaxStack();
1658:                classGen.replaceMethod(m, methodGen.getMethod());
1659:                il.dispose();
1660:            }
1661:
1662:            private boolean writeObjectExist() {
1663:                Method[] methods = classGen.getMethods();
1664:                for (int i = 0; i < methods.length; i++) {
1665:                    Method m = methods[i];
1666:                    if (m.getName().equals("writeObject")
1667:                            && m.getSignature().equals(
1668:                                    "(Ljava/io/ObjectOutputStream;)V")) {
1669:                        return true;
1670:                    }
1671:                }
1672:                return false;
1673:
1674:            }
1675:
1676:            private Method getWriteObject() {
1677:                Method[] methods = classGen.getMethods();
1678:                for (int i = 0; i < methods.length; i++) {
1679:                    Method m = methods[i];
1680:                    if (m.getName().equals("writeObject")
1681:                            && m.getSignature().equals(
1682:                                    "(Ljava/io/ObjectOutputStream;)V")) {
1683:                        return m;
1684:                    }
1685:                }
1686:                return null;
1687:
1688:            }
1689:
1690:            private boolean readObjectExist() {
1691:                Method[] methods = classGen.getMethods();
1692:                for (int i = 0; i < methods.length; i++) {
1693:                    Method m = methods[i];
1694:                    if (m.getName().equals("readObject")
1695:                            && m.getSignature().equals(
1696:                                    "(Ljava/io/ObjectInputStream;)V")) {
1697:                        return true;
1698:                    }
1699:                }
1700:                return false;
1701:
1702:            }
1703:
1704:            private Method getReadObject() {
1705:                Method[] methods = classGen.getMethods();
1706:                for (int i = 0; i < methods.length; i++) {
1707:                    Method m = methods[i];
1708:                    if (m.getName().equals("readObject")
1709:                            && m.getSignature().equals(
1710:                                    "(Ljava/io/ObjectInputStream;)V")) {
1711:                        return m;
1712:                    }
1713:                }
1714:                return null;
1715:
1716:            }
1717:
1718:            private void addWriteObject() {
1719:                boolean rename = false;
1720:                if (writeObjectExist()
1721:                        && classInfo.getTopPCSuperClass() == null) {
1722:                    // we must rename this method
1723:                    Method m = getWriteObject();
1724:                    MethodGen mg = new MethodGen(m, classGen.getClassName(),
1725:                            constantPoolGen);
1726:                    mg.setName("versantWriteObject");
1727:                    classGen.replaceMethod(m, mg.getMethod());
1728:                    rename = true;
1729:                } else if (writeObjectExist()
1730:                        && classInfo.getTopPCSuperClass() != null) {
1731:                    return;
1732:                }
1733:                InstructionList il = new InstructionList();
1734:                MethodGen methodGen = new MethodGen(Constants.ACC_PRIVATE,
1735:                        Type.VOID, new Type[] { new ObjectType(
1736:                                "java.io.ObjectOutputStream") },
1737:                        new String[] { "out" }, "writeObject", classGen
1738:                                .getClassName(), il, constantPoolGen);
1739:                if (classInfo.getTopPCSuperClass() == null) {
1740:                    il.append(new ALOAD(0));
1741:                    il.append(instructionFactory.createInvoke(
1742:                            getTopPCSuperOrCurrentClass().getClassName(),
1743:                            "jdoPreSerialize", Type.VOID, new Type[] {},
1744:                            Constants.INVOKESPECIAL));
1745:                }
1746:                if (rename) {
1747:                    il.append(new ALOAD(0));
1748:                    il.append(new ALOAD(1));
1749:                    il.append(instructionFactory.createInvoke(classGen
1750:                            .getClassName(), "versantWriteObject", Type.VOID,
1751:                            new Type[] { new ObjectType(
1752:                                    "java.io.ObjectOutputStream") },
1753:                            Constants.INVOKESPECIAL));
1754:                } else {
1755:                    il.append(new ALOAD(1));
1756:                    il.append(instructionFactory.createInvoke(
1757:                            "java.io.ObjectOutputStream", "defaultWriteObject",
1758:                            Type.VOID, new Type[] {}, Constants.INVOKEVIRTUAL));
1759:                }
1760:
1761:                if (classInfo.getTopPCSuperClass() == null && detach) {
1762:                    il.append(new ALOAD(0));
1763:                    il.append(instructionFactory.createGetField(classGen
1764:                            .getClassName(), "jdoStateManager", new ObjectType(
1765:                            STATE_MANAGER)));
1766:                    il.append(new INSTANCEOF(constantPoolGen
1767:                            .addClass(DETACHED_STATE_MANAGER)));
1768:                    IFEQ ifeq = new IFEQ(null);
1769:                    il.append(ifeq);
1770:                    il.append(new ALOAD(1));
1771:                    il.append(new ICONST(1));
1772:                    il.append(instructionFactory.createInvoke(
1773:                            "java.io.ObjectOutputStream", "writeBoolean",
1774:                            Type.VOID, new Type[] { Type.BOOLEAN },
1775:                            Constants.INVOKEVIRTUAL));
1776:                    il.append(new ALOAD(1));
1777:                    il.append(new ALOAD(0));
1778:                    il.append(instructionFactory.createGetField(classGen
1779:                            .getClassName(), "jdoStateManager", new ObjectType(
1780:                            STATE_MANAGER)));
1781:                    il.append(instructionFactory.createInvoke(
1782:                            "java.io.ObjectOutputStream", "writeObject",
1783:                            Type.VOID, new Type[] { Type.OBJECT },
1784:                            Constants.INVOKEVIRTUAL));
1785:                    il.append(new ALOAD(1));
1786:                    il.append(new ALOAD(0));
1787:                    il.append(instructionFactory.createGetField(classGen
1788:                            .getClassName(), "jdoFlags", Type.BYTE));
1789:                    il.append(instructionFactory.createInvoke(
1790:                            "java.io.ObjectOutputStream", "writeByte",
1791:                            Type.VOID, new Type[] { Type.INT },
1792:                            Constants.INVOKEVIRTUAL));
1793:                    GOTO aGoto = new GOTO(null);
1794:                    il.append(aGoto);
1795:                    InstructionHandle aload1Handle = il.append(new ALOAD(1));
1796:                    ifeq.setTarget(aload1Handle);
1797:                    il.append(new ICONST(0));
1798:                    il.append(instructionFactory.createInvoke(
1799:                            "java.io.ObjectOutputStream", "writeBoolean",
1800:                            Type.VOID, new Type[] { Type.BOOLEAN },
1801:                            Constants.INVOKEVIRTUAL));
1802:                    InstructionHandle returnHandle = il.append(new RETURN());
1803:                    aGoto.setTarget(returnHandle);
1804:                } else {
1805:                    il.append(new RETURN());
1806:                }
1807:
1808:                methodGen.addException("java.io.IOException");
1809:                methodGen.setMaxLocals();
1810:                methodGen.setMaxStack();
1811:                classGen.addMethod(methodGen.getMethod());
1812:                il.dispose();
1813:
1814:            }
1815:
1816:            private void addReadObject() {
1817:                if (classInfo.getTopPCSuperClass() == null && detach) {
1818:                    boolean rename = false;
1819:                    if (readObjectExist()) {
1820:                        // we must rename this method
1821:                        Method m = getReadObject();
1822:                        MethodGen mg = new MethodGen(m,
1823:                                classGen.getClassName(), constantPoolGen);
1824:                        mg.setName("versantReadObject");
1825:                        classGen.replaceMethod(m, mg.getMethod());
1826:                        rename = true;
1827:                    }
1828:
1829:                    InstructionList il = new InstructionList();
1830:                    MethodGen methodGen = new MethodGen(Constants.ACC_PRIVATE,
1831:                            Type.VOID, new Type[] { new ObjectType(
1832:                                    "java.io.ObjectInputStream") },
1833:                            new String[] { "in" }, "readObject", classGen
1834:                                    .getClassName(), il, constantPoolGen);
1835:
1836:                    if (rename) {
1837:                        il.append(new ALOAD(0));
1838:                        il.append(new ALOAD(1));
1839:                        il.append(instructionFactory.createInvoke(classGen
1840:                                .getClassName(), "versantReadObject",
1841:                                Type.VOID, new Type[] { new ObjectType(
1842:                                        "java.io.ObjectInputStream") },
1843:                                Constants.INVOKESPECIAL));
1844:
1845:                    } else {
1846:                        il.append(new ALOAD(1));
1847:                        il.append(instructionFactory.createInvoke(
1848:                                "java.io.ObjectInputStream",
1849:                                "defaultReadObject", Type.VOID, new Type[] {},
1850:                                Constants.INVOKEVIRTUAL));
1851:                    }
1852:                    il.append(new ALOAD(1));
1853:                    il.append(instructionFactory.createInvoke(
1854:                            "java.io.ObjectInputStream", "readBoolean",
1855:                            Type.BOOLEAN, new Type[] {},
1856:                            Constants.INVOKEVIRTUAL));
1857:                    IFEQ ifeq = new IFEQ(null);
1858:                    il.append(ifeq);//22
1859:                    il.append(new ALOAD(0));
1860:                    il.append(new ALOAD(1));
1861:                    il.append(instructionFactory
1862:                            .createInvoke("java.io.ObjectInputStream",
1863:                                    "readObject", Type.OBJECT, new Type[] {},
1864:                                    Constants.INVOKEVIRTUAL));
1865:                    il.append(instructionFactory
1866:                            .createCheckCast(new ObjectType(
1867:                                    DETACHED_STATE_MANAGER)));
1868:                    il.append(instructionFactory.createPutField(classGen
1869:                            .getClassName(), "jdoStateManager", new ObjectType(
1870:                            STATE_MANAGER)));
1871:                    il.append(new ALOAD(0));
1872:                    il.append(new ALOAD(1));
1873:                    il.append(instructionFactory.createInvoke(
1874:                            "java.io.ObjectInputStream", "readByte", Type.BYTE,
1875:                            new Type[] {}, Constants.INVOKEVIRTUAL));
1876:                    il.append(instructionFactory.createPutField(classGen
1877:                            .getClassName(), "jdoFlags", Type.BYTE));
1878:
1879:                    InstructionHandle returnHandle = il.append(new RETURN());
1880:                    ifeq.setTarget(returnHandle);
1881:
1882:                    methodGen.addException("java.io.IOException");
1883:                    methodGen.addException("java.lang.ClassNotFoundException");
1884:                    methodGen.setMaxLocals();
1885:                    methodGen.setMaxStack();
1886:                    classGen.addMethod(methodGen.getMethod());
1887:                    il.dispose();
1888:                }
1889:            }
1890:
1891:            private void addJdoPreSerialize() {
1892:                if (classInfo.getTopPCSuperClass() == null) {
1893:                    InstructionList il = new InstructionList();
1894:                    MethodGen methodGen = new MethodGen(Constants.ACC_PRIVATE,
1895:                            Type.VOID, new Type[] {}, new String[] {},
1896:                            "jdoPreSerialize", classGen.getClassName(), il,
1897:                            constantPoolGen);
1898:
1899:                    InstructionHandle returnHandle = il.insert(new RETURN());
1900:                    il.insert(instructionFactory.createInvoke(STATE_MANAGER,
1901:                            "preSerialize", Type.VOID,
1902:                            new Type[] { PC_OBJECT_TYPE },
1903:                            Constants.INVOKEINTERFACE));
1904:                    il.insert(new ALOAD(0));
1905:                    il.insert(instructionFactory.createGetField(
1906:                            getTopPCSuperOrCurrentClassName(),
1907:                            "jdoStateManager", SM_OBJECT_TYPE));
1908:                    il.insert(new ALOAD(0));
1909:                    il.insert(new IFNULL(returnHandle));
1910:                    il.insert(instructionFactory.createGetField(
1911:                            getTopPCSuperOrCurrentClassName(),
1912:                            "jdoStateManager", SM_OBJECT_TYPE));
1913:                    il.insert(new ALOAD(0));
1914:
1915:                    //            makeSynthetic(methodGen);
1916:                    methodGen.setMaxLocals();
1917:                    methodGen.setMaxStack();
1918:                    classGen.addMethod(methodGen.getMethod());
1919:                    il.dispose();
1920:                }
1921:            }
1922:
1923:            private void addJdoCopyFields() {
1924:                InstructionList il = new InstructionList();
1925:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
1926:                        Type.VOID, new Type[] { Type.OBJECT,
1927:                                new ArrayType(Type.INT, 1) }, new String[] {
1928:                                "pc", "fieldNumbers" }, "jdoCopyFields",
1929:                        classGen.getClassName(), il, constantPoolGen);
1930:
1931:                il.append(new ALOAD(1));
1932:                il.append(instructionFactory.createCheckCast(new ObjectType(
1933:                        classGen.getClassName())));
1934:                il.append(new ASTORE(3));
1935:                InstructionHandle otherStartHandle = il.append(new ALOAD(3));
1936:                il.append(instructionFactory.createGetField(
1937:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
1938:                        SM_OBJECT_TYPE));
1939:                il.append(new ALOAD(0));
1940:                il.append(instructionFactory.createGetField(
1941:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
1942:                        SM_OBJECT_TYPE));
1943:                IF_ACMPEQ if_acmpeq = new IF_ACMPEQ(null);
1944:                il.append(if_acmpeq);
1945:                il.append(instructionFactory
1946:                        .createNew("java.lang.IllegalArgumentException"));
1947:                il.append(new DUP());
1948:                il.append(new PUSH(constantPoolGen,
1949:                        "this.jdoStateManager != other.jdoStateManager"));
1950:                il.append(instructionFactory.createInvoke(
1951:                        "java.lang.IllegalArgumentException", "<init>",
1952:                        Type.VOID, new Type[] { Type.STRING },
1953:                        Constants.INVOKESPECIAL));
1954:                il.append(new ATHROW());
1955:                InstructionHandle if_acmpeqHandle = il.append(new ALOAD(0));
1956:                if_acmpeq.setTarget(if_acmpeqHandle);
1957:                il.append(instructionFactory.createGetField(
1958:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
1959:                        SM_OBJECT_TYPE));
1960:                IFNONNULL ifnonnull = new IFNONNULL(null);
1961:                il.append(ifnonnull);
1962:                il.append(instructionFactory
1963:                        .createNew("java.lang.IllegalArgumentException"));
1964:                il.append(new DUP());
1965:                il.append(new PUSH(constantPoolGen,
1966:                        "this.jdoStateManager == null"));
1967:                il.append(instructionFactory.createInvoke(
1968:                        "java.lang.IllegalArgumentException", "<init>",
1969:                        Type.VOID, new Type[] { Type.STRING },
1970:                        Constants.INVOKESPECIAL));
1971:                il.append(new ATHROW());
1972:                InstructionHandle ifnonnullHandle = il.append(new ICONST(0));
1973:                ifnonnull.setTarget(ifnonnullHandle);
1974:                il.append(new ISTORE(4));
1975:                GOTO aGoto = new GOTO(null);
1976:                InstructionHandle iStartHandle = il.append(aGoto);
1977:                InstructionHandle if_icmpltHandle = il.append(new ALOAD(0));
1978:                il.append(new ALOAD(3));
1979:                il.append(new ALOAD(2));
1980:                il.append(new ILOAD(4));
1981:                il.append(new IALOAD());
1982:                il.append(instructionFactory.createInvoke(classGen
1983:                        .getClassName(), "jdoCopyField", Type.VOID, new Type[] {
1984:                        new ObjectType(classGen.getClassName()), Type.INT },
1985:                        Constants.INVOKEVIRTUAL));
1986:                il.append(new IINC(4, 1));
1987:                InstructionHandle aGotoHandle = il.append(new ILOAD(4));
1988:                aGoto.setTarget(aGotoHandle);
1989:                il.append(new ALOAD(2));
1990:                il.append(new ARRAYLENGTH());
1991:                il.append(new IF_ICMPLT(if_icmpltHandle));
1992:                il.append(new RETURN());
1993:
1994:                methodGen.addLocalVariable("other", new ObjectType(classGen
1995:                        .getClassName()), 3, otherStartHandle, il.getEnd());
1996:                methodGen.addLocalVariable("i", Type.INT, 4, iStartHandle, il
1997:                        .getEnd());
1998:                //        makeSynthetic(methodGen);
1999:                methodGen.setMaxLocals();
2000:                methodGen.setMaxStack();
2001:                classGen.addMethod(methodGen.getMethod());
2002:                il.dispose();
2003:            }
2004:
2005:            private void addJdoCopyField() {
2006:                InstructionList il = new InstructionList();
2007:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
2008:                        Type.VOID, new Type[] {
2009:                                new ObjectType(classGen.getClassName()),
2010:                                Type.INT }, new String[] { "other",
2011:                                "fieldNumber" }, "jdoCopyField", classGen
2012:                                .getClassName(), il, constantPoolGen);
2013:
2014:                il.append(new ILOAD(2));
2015:                il.append(instructionFactory.createGetStatic(classGen
2016:                        .getClassName(), "jdoInheritedFieldCount", Type.INT));
2017:                il.append(new ISUB());
2018:                il.append(new ISTORE(3));
2019:                InstructionHandle relativeFieldStartHandle = il
2020:                        .append(new ILOAD(3));
2021:
2022:                int switchCount = fieldSet.size();
2023:                int[] match = new int[switchCount];
2024:                InstructionHandle[] targets = new InstructionHandle[switchCount];
2025:                ArrayList tempInsLists = new ArrayList(switchCount + 1);
2026:                int i = 0;
2027:                ArrayList tempList = new ArrayList(fieldSet);
2028:                for (Iterator fieldIter = tempList.iterator(); fieldIter
2029:                        .hasNext(); i++) {
2030:                    FieldInfo fieldInfo = (FieldInfo) fieldIter.next();
2031:                    InstructionList tempIL = new InstructionList();
2032:                    match[i] = fieldInfo.getFieldNo();
2033:                    targets[i] = tempIL.append(new ALOAD(0));
2034:                    tempIL.append(new ALOAD(1));
2035:                    tempIL.append(instructionFactory.createGetField(classGen
2036:                            .getClassName(), fieldInfo.getFieldName(),
2037:                            fieldInfo.getType()));
2038:                    tempIL.append(instructionFactory.createPutField(classGen
2039:                            .getClassName(), fieldInfo.getFieldName(),
2040:                            fieldInfo.getType()));
2041:                    tempIL.append(new RETURN());
2042:                    tempInsLists.add(tempIL);
2043:                }
2044:                // Do default
2045:                InstructionList tempIL = new InstructionList();
2046:                InstructionHandle defaultHandle = null;
2047:                if (classInfo.getTopPCSuperClass() == null) {
2048:                    defaultHandle = tempIL.append(instructionFactory
2049:                            .createNew("java.lang.IllegalArgumentException"));
2050:                    tempIL.append(new DUP());
2051:                    tempIL.append(new PUSH(constantPoolGen, "fieldNumber"));
2052:                    tempIL.append(instructionFactory.createInvoke(
2053:                            "java.lang.IllegalArgumentException", "<init>",
2054:                            Type.VOID, new Type[] { Type.STRING },
2055:                            Constants.INVOKESPECIAL));
2056:                    tempIL.append(new ATHROW());
2057:                } else {
2058:                    defaultHandle = tempIL.append(new ALOAD(0));
2059:                    tempIL.append(new ALOAD(1));
2060:                    tempIL.append(new ILOAD(2));
2061:                    tempIL.append(instructionFactory.createInvoke(classInfo
2062:                            .getTopPCSuperClass().getClassName(),
2063:                            "jdoCopyField", Type.VOID, new Type[] {
2064:                                    new ObjectType(classInfo
2065:                                            .getTopPCSuperClass()
2066:                                            .getClassName()), Type.INT },
2067:                            Constants.INVOKESPECIAL));
2068:                }
2069:                tempInsLists.add(tempIL);
2070:                // start the lookupSwitch
2071:                il.append(new LOOKUPSWITCH(match, targets, defaultHandle));
2072:                for (Iterator tempIlIter = tempInsLists.iterator(); tempIlIter
2073:                        .hasNext();) { // add all instructions
2074:                    InstructionList list = (InstructionList) tempIlIter.next();
2075:                    il.append(list);
2076:                }
2077:                il.append(new RETURN());
2078:
2079:                methodGen.addLocalVariable("relativeField", Type.INT, 3,
2080:                        relativeFieldStartHandle, il.getEnd());
2081:
2082:                //        makeSynthetic(methodGen);
2083:                methodGen.setMaxLocals();
2084:                methodGen.setMaxStack();
2085:                classGen.addMethod(methodGen.getMethod());
2086:                il.dispose();
2087:            }
2088:
2089:            private void addJdoProvideFields() {
2090:
2091:                InstructionList il = new InstructionList();
2092:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
2093:                        Type.VOID, new Type[] { new ArrayType(Type.INT, 1) },
2094:                        new String[] { "fieldNumbers" }, "jdoProvideFields",
2095:                        classGen.getClassName(), il, constantPoolGen);
2096:                il.append(new ICONST(0));
2097:                il.append(new ISTORE(2));
2098:                InstructionHandle iloadHandle = il.append(new ILOAD(2));
2099:                il.append(new ALOAD(1));
2100:                il.append(new ARRAYLENGTH());
2101:                IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
2102:                il.append(if_icmpge);
2103:                il.append(new ALOAD(1));
2104:                il.append(new ILOAD(2));
2105:                il.append(new IALOAD());
2106:                il.append(new ISTORE(3));
2107:                InstructionHandle aloadHandle = il.append(new ALOAD(0));
2108:                il.append(new ILOAD(3));
2109:                il.append(instructionFactory.createInvoke(classGen
2110:                        .getClassName(), "jdoProvideField", Type.VOID,
2111:                        new Type[] { Type.INT }, Constants.INVOKEVIRTUAL));
2112:                InstructionHandle iincHandle = il.append(new IINC(2, 1));
2113:                il.append(new GOTO(iloadHandle));
2114:                InstructionHandle returnHandle = il.append(new RETURN());
2115:                if_icmpge.setTarget(returnHandle);
2116:                methodGen.addLocalVariable("i", Type.INT, 2, iloadHandle,
2117:                        returnHandle);
2118:                methodGen.addLocalVariable("fieldNumber", Type.INT, 3,
2119:                        aloadHandle, iincHandle);
2120:                //        makeSynthetic(methodGen);
2121:                methodGen.setMaxLocals();
2122:                methodGen.setMaxStack();
2123:                classGen.addMethod(methodGen.getMethod());
2124:                il.dispose();
2125:            }
2126:
2127:            private void addJdoProvideField() {
2128:
2129:                ArrayList myList = new ArrayList(fieldSet);
2130:                ListIterator fieldIter = myList.listIterator();
2131:
2132:                while (fieldIter.hasNext()) {
2133:                    fieldIter.next();
2134:                }
2135:
2136:                InstructionList il = new InstructionList();
2137:
2138:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
2139:                        Type.VOID, new Type[] { Type.INT },
2140:                        new String[] { "fieldNumber" }, "jdoProvideField",
2141:                        classGen.getClassName(), il, constantPoolGen);
2142:
2143:                if (!isEmpty) {
2144:                    int size = fieldSet.size();
2145:                    int[] match = new int[size];
2146:                    int fieldNum = size;
2147:                    InstructionHandle[] targets = new InstructionHandle[size];
2148:                    InstructionHandle defaultHandle = null;
2149:                    InstructionHandle returnHandel = null;
2150:                    Set switchList = new TreeSet();
2151:                    if (classInfo.getPersistenceCapableSuperclass() == null) {
2152:                        defaultHandle = il
2153:                                .append(instructionFactory
2154:                                        .createNew("java.lang.IllegalArgumentException"));
2155:                        il.append(new DUP());
2156:
2157:                        il.append(instructionFactory
2158:                                .createNew("java.lang.StringBuffer"));
2159:                        il.append(new DUP());
2160:                        il.append(instructionFactory.createInvoke(
2161:                                "java.lang.StringBuffer", "<init>", Type.VOID,
2162:                                new Type[] {}, Constants.INVOKESPECIAL));
2163:                        il.append(new PUSH(constantPoolGen, "Class "
2164:                                + classGen.getClassName()
2165:                                + " called with invalid fieldNumber = "));
2166:                        il.append(instructionFactory.createInvoke(
2167:                                "java.lang.StringBuffer", "append",
2168:                                Type.STRINGBUFFER, new Type[] { Type.STRING },
2169:                                Constants.INVOKEVIRTUAL));
2170:                        il.append(new ILOAD(1));
2171:                        il.append(instructionFactory.createInvoke(
2172:                                "java.lang.StringBuffer", "append",
2173:                                Type.STRINGBUFFER, new Type[] { Type.INT },
2174:                                Constants.INVOKEVIRTUAL));
2175:                        il.append(instructionFactory.createInvoke(
2176:                                "java.lang.StringBuffer", "toString",
2177:                                Type.STRING, new Type[] {},
2178:                                Constants.INVOKEVIRTUAL));
2179:
2180:                        il.append(instructionFactory.createInvoke(
2181:                                "java.lang.IllegalArgumentException", "<init>",
2182:                                Type.VOID, new Type[] { Type.STRING },
2183:                                Constants.INVOKESPECIAL));
2184:                        il.append(new ATHROW());
2185:                        returnHandel = il.append(new RETURN());
2186:                    } else {
2187:                        returnHandel = il.insert(new RETURN());
2188:                        il.insert(new ATHROW());
2189:                        il.insert(instructionFactory.createInvoke(
2190:                                "java.lang.IllegalArgumentException", "<init>",
2191:                                Type.VOID, new Type[] { Type.STRING },
2192:                                Constants.INVOKESPECIAL));
2193:                        //				il.insert(new PUSH(constantPoolGen,"fieldNumber"));
2194:
2195:                        il.insert(instructionFactory.createInvoke(
2196:                                "java.lang.StringBuffer", "toString",
2197:                                Type.STRING, new Type[] {},
2198:                                Constants.INVOKEVIRTUAL));
2199:                        il.insert(instructionFactory.createInvoke(
2200:                                "java.lang.StringBuffer", "append",
2201:                                Type.STRINGBUFFER, new Type[] { Type.INT },
2202:                                Constants.INVOKEVIRTUAL));
2203:                        il.insert(new ILOAD(1));
2204:                        il.insert(instructionFactory.createInvoke(
2205:                                "java.lang.StringBuffer", "append",
2206:                                Type.STRINGBUFFER, new Type[] { Type.STRING },
2207:                                Constants.INVOKEVIRTUAL));
2208:                        il.insert(new PUSH(constantPoolGen, "Class "
2209:                                + classGen.getClassName()
2210:                                + " called with invalid fieldNumber = "));
2211:                        il.insert(instructionFactory.createInvoke(
2212:                                "java.lang.StringBuffer", "<init>", Type.VOID,
2213:                                new Type[] {}, Constants.INVOKESPECIAL));
2214:                        il.insert(new DUP());
2215:                        il.insert(instructionFactory
2216:                                .createNew("java.lang.StringBuffer"));
2217:
2218:                        il.insert(new DUP());
2219:                        InstructionHandle newHandel = il
2220:                                .insert(instructionFactory
2221:                                        .createNew("java.lang.IllegalArgumentException"));
2222:                        il.insert(new GOTO(returnHandel));
2223:                        il.insert(instructionFactory.createInvoke(classInfo
2224:                                .getPersistenceCapableSuperclass(),
2225:                                "jdoProvideField", Type.VOID,
2226:                                new Type[] { Type.INT },
2227:                                Constants.INVOKESPECIAL));
2228:                        il.insert(new ILOAD(1));
2229:                        il.insert(new ALOAD(0));
2230:                        il.insert(new IFGE(newHandel));
2231:                        defaultHandle = il.insert(new ILOAD(2));
2232:                    }
2233:
2234:                    while (fieldIter.hasPrevious()) {
2235:                        FieldInfo fieldInfo = (FieldInfo) fieldIter.previous();
2236:                        fieldNum--;
2237:                        Type fieldType = fieldInfo.getType();
2238:                        String stateManagerProvidedField = null;
2239:                        boolean isObject = false;
2240:                        if (typeToProvidedField
2241:                                .containsKey(fieldInfo.getType())) {
2242:                            stateManagerProvidedField = (String) typeToProvidedField
2243:                                    .get(fieldInfo.getType());
2244:                            isObject = false;
2245:                        } else {
2246:                            isObject = true;
2247:                        }
2248:
2249:                        il.insert(new GOTO(returnHandel));
2250:
2251:                        if (isObject) {
2252:                            il.insert(instructionFactory.createInvoke(
2253:                                    STATE_MANAGER, "providedObjectField",
2254:                                    Type.VOID, new Type[] { PC_OBJECT_TYPE,
2255:                                            Type.INT, Type.OBJECT },
2256:                                    Constants.INVOKEINTERFACE));
2257:                        } else {
2258:                            il.insert(instructionFactory.createInvoke(
2259:                                    STATE_MANAGER, stateManagerProvidedField,
2260:                                    Type.VOID, new Type[] { PC_OBJECT_TYPE,
2261:                                            Type.INT, fieldType },
2262:                                    Constants.INVOKEINTERFACE));
2263:                        }
2264:                        il.insert(instructionFactory.createGetField(classGen
2265:                                .getClassName(), fieldInfo.getFieldName(),
2266:                                fieldType));
2267:
2268:                        il.insert(new ALOAD(0));
2269:                        il.insert(new ILOAD(1));
2270:                        il.insert(new ALOAD(0));
2271:                        il.insert(instructionFactory.createGetField(
2272:                                getTopPCSuperOrCurrentClassName(),
2273:                                "jdoStateManager", SM_OBJECT_TYPE));
2274:                        InstructionHandle switchHandel = il
2275:                                .insert(new ALOAD(0));
2276:                        TableSwitchHelper tsh = new TableSwitchHelper();
2277:                        tsh.match = fieldNum;
2278:                        tsh.target = switchHandel;
2279:                        switchList.add(tsh);
2280:
2281:                    }
2282:                    Iterator sIter = switchList.iterator();
2283:                    int count = 0;
2284:                    while (sIter.hasNext()) {
2285:                        TableSwitchHelper tsh = (TableSwitchHelper) sIter
2286:                                .next();
2287:                        match[count] = tsh.match;
2288:                        targets[count] = tsh.target;
2289:                        count++;
2290:                    }
2291:
2292:                    il.insert(new TABLESWITCH(match, targets, defaultHandle));
2293:                    InstructionHandle relativeFieldFromHandle = il
2294:                            .insert(new ILOAD(2));
2295:                    il.insert(new ISTORE(2));
2296:                    il.insert(new ISUB());
2297:                    il.insert(instructionFactory
2298:                            .createGetStatic(classGen.getClassName(),
2299:                                    "jdoInheritedFieldCount", Type.INT));
2300:                    il.insert(new ILOAD(1));
2301:                    methodGen.addLocalVariable("relativeField", Type.INT, 2,
2302:                            relativeFieldFromHandle, returnHandel);
2303:                } else if (classInfo.getPersistenceCapableSuperclass() != null) {
2304:
2305:                    il.append(new ILOAD(1));
2306:                    il.append(instructionFactory
2307:                            .createGetStatic(classGen.getClassName(),
2308:                                    "jdoInheritedFieldCount", Type.INT));
2309:                    il.append(new ISUB());
2310:                    il.append(new ISTORE(2));
2311:                    InstructionHandle relativeField_Start = il
2312:                            .append(new ILOAD(2));
2313:                    IFGE ifge = new IFGE(null);
2314:                    il.append(ifge);
2315:                    il.append(new ALOAD(0));
2316:                    il.append(new ILOAD(1));
2317:                    il.append(instructionFactory.createInvoke(classInfo
2318:                            .getPersistenceCapableSuperclass(),
2319:                            "jdoProvideField", Type.VOID,
2320:                            new Type[] { Type.INT }, Constants.INVOKESPECIAL));
2321:                    GOTO aGoto = new GOTO(null);
2322:                    il.append(aGoto);
2323:                    InstructionHandle newHandel = il.append(instructionFactory
2324:                            .createNew("java.lang.IllegalArgumentException"));
2325:                    ifge.setTarget(newHandel);
2326:                    il.append(new DUP());
2327:                    //			il.append(new PUSH(constantPoolGen,"fieldNumber"));
2328:                    il.append(instructionFactory
2329:                            .createNew("java.lang.StringBuffer"));
2330:                    il.append(new DUP());
2331:                    il.append(instructionFactory.createInvoke(
2332:                            "java.lang.StringBuffer", "<init>", Type.VOID,
2333:                            new Type[] {}, Constants.INVOKESPECIAL));
2334:                    il.append(new PUSH(constantPoolGen, "Class "
2335:                            + classGen.getClassName()
2336:                            + " called with invalid fieldNumber = "));
2337:                    il.append(instructionFactory.createInvoke(
2338:                            "java.lang.StringBuffer", "append",
2339:                            Type.STRINGBUFFER, new Type[] { Type.STRING },
2340:                            Constants.INVOKEVIRTUAL));
2341:                    il.append(new ILOAD(1));
2342:                    il.append(instructionFactory.createInvoke(
2343:                            "java.lang.StringBuffer", "append",
2344:                            Type.STRINGBUFFER, new Type[] { Type.INT },
2345:                            Constants.INVOKEVIRTUAL));
2346:                    il.append(instructionFactory.createInvoke(
2347:                            "java.lang.StringBuffer", "toString", Type.STRING,
2348:                            new Type[] {}, Constants.INVOKEVIRTUAL));
2349:
2350:                    il.append(instructionFactory.createInvoke(
2351:                            "java.lang.IllegalArgumentException", "<init>",
2352:                            Type.VOID, new Type[] { Type.STRING },
2353:                            Constants.INVOKESPECIAL));
2354:                    il.append(new ATHROW());
2355:                    il.append(new RETURN());
2356:                    aGoto.setTarget(il.getEnd());
2357:
2358:                    methodGen.addLocalVariable("relativeField", Type.INT, 2,
2359:                            relativeField_Start, il.getEnd());
2360:
2361:                } else {
2362:                    il.append(new RETURN());
2363:                }
2364:                //        makeSynthetic(methodGen);
2365:                methodGen.setMaxLocals();
2366:                methodGen.setMaxStack();
2367:                classGen.addMethod(methodGen.getMethod());
2368:                il.dispose();
2369:            }
2370:
2371:            private void addJdoReplaceFields() {
2372:                InstructionList il = new InstructionList();
2373:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
2374:                        Type.VOID, new Type[] { new ArrayType(Type.INT, 1) },
2375:                        new String[] { "fieldNumbers" }, "jdoReplaceFields",
2376:                        classGen.getClassName(), il, constantPoolGen);
2377:                il.append(new ICONST(0));
2378:                il.append(new ISTORE(2));
2379:                InstructionHandle iloadHandle = il.append(new ILOAD(2));
2380:                il.append(new ALOAD(1));
2381:                il.append(new ARRAYLENGTH());
2382:                IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
2383:                il.append(if_icmpge);
2384:                il.append(new ALOAD(1));
2385:                il.append(new ILOAD(2));
2386:                il.append(new IALOAD());
2387:                il.append(new ISTORE(3));
2388:                InstructionHandle aloadHandle = il.append(new ALOAD(0));
2389:                il.append(new ILOAD(3));
2390:                il.append(instructionFactory.createInvoke(classGen
2391:                        .getClassName(), "jdoReplaceField", Type.VOID,
2392:                        new Type[] { Type.INT }, Constants.INVOKEVIRTUAL));
2393:                InstructionHandle iincHandle = il.append(new IINC(2, 1));
2394:                il.append(new GOTO(iloadHandle));
2395:                InstructionHandle returnHandle = il.append(new RETURN());
2396:                if_icmpge.setTarget(returnHandle);
2397:                methodGen.addLocalVariable("i", Type.INT, 2, iloadHandle,
2398:                        returnHandle);
2399:                methodGen.addLocalVariable("fieldNumber", Type.INT, 3,
2400:                        aloadHandle, iincHandle);
2401:                //        makeSynthetic(methodGen);
2402:                methodGen.setMaxLocals();
2403:                methodGen.setMaxStack();
2404:                classGen.addMethod(methodGen.getMethod());
2405:                il.dispose();
2406:            }
2407:
2408:            private void addJdoReplaceField() {
2409:
2410:                int size = fieldSet.size();
2411:                int[] match = new int[size];
2412:                InstructionHandle[] targets = new InstructionHandle[size];
2413:                InstructionHandle defaultHandle = null;
2414:                InstructionHandle returnHandel = null;
2415:                Set switchList = new TreeSet();
2416:                ArrayList myList = new ArrayList(fieldSet);
2417:                ListIterator fieldIter = myList.listIterator();
2418:                int fieldNum = size;
2419:                while (fieldIter.hasNext()) {
2420:                    fieldIter.next();
2421:                }
2422:                InstructionList il = new InstructionList();
2423:
2424:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
2425:                        Type.VOID, new Type[] { Type.INT },
2426:                        new String[] { "fieldNumber" }, "jdoReplaceField",
2427:                        classGen.getClassName(), il, constantPoolGen);
2428:                if (!isEmpty) {
2429:                    if (classInfo.getPersistenceCapableSuperclass() == null) {
2430:                        defaultHandle = il
2431:                                .append(instructionFactory
2432:                                        .createNew("java.lang.IllegalArgumentException"));
2433:                        il.append(new DUP());
2434:                        il.append(new PUSH(constantPoolGen, "fieldNumber"));
2435:                        il.append(instructionFactory.createInvoke(
2436:                                "java.lang.IllegalArgumentException", "<init>",
2437:                                Type.VOID, new Type[] { Type.STRING },
2438:                                Constants.INVOKESPECIAL));
2439:                        il.append(new ATHROW());
2440:                        returnHandel = il.append(new RETURN());
2441:                    } else {
2442:                        returnHandel = il.insert(new RETURN());
2443:                        il.insert(new ATHROW());
2444:                        il.insert(instructionFactory.createInvoke(
2445:                                "java.lang.IllegalArgumentException", "<init>",
2446:                                Type.VOID, new Type[] { Type.STRING },
2447:                                Constants.INVOKESPECIAL));
2448:                        il.insert(new PUSH(constantPoolGen, "fieldNumber"));
2449:                        il.insert(new DUP());
2450:                        InstructionHandle newHandel = il
2451:                                .insert(instructionFactory
2452:                                        .createNew("java.lang.IllegalArgumentException"));
2453:                        il.insert(new GOTO(returnHandel));
2454:                        il.insert(instructionFactory.createInvoke(classInfo
2455:                                .getPersistenceCapableSuperclass(),
2456:                                "jdoReplaceField", Type.VOID,
2457:                                new Type[] { Type.INT },
2458:                                Constants.INVOKESPECIAL));
2459:                        il.insert(new ILOAD(1));
2460:                        il.insert(new ALOAD(0));
2461:                        il.insert(new IFGE(newHandel));
2462:                        defaultHandle = il.insert(new ILOAD(2));
2463:                    }
2464:
2465:                    while (fieldIter.hasPrevious()) {
2466:                        FieldInfo fieldInfo = (FieldInfo) fieldIter.previous();
2467:                        fieldNum--;
2468:                        Type fieldType = fieldInfo.getType();
2469:                        String stateManagerReplaceField = null;
2470:                        boolean isObject = false;
2471:                        if (typeToReplacingField.containsKey(fieldInfo
2472:                                .getType())) {
2473:                            stateManagerReplaceField = (String) typeToReplacingField
2474:                                    .get(fieldInfo.getType());
2475:                            isObject = false;
2476:                        } else {
2477:                            isObject = true;
2478:                        }
2479:
2480:                        il.insert(new GOTO(returnHandel));
2481:                        il.insert(instructionFactory.createPutField(classGen
2482:                                .getClassName(), fieldInfo.getFieldName(),
2483:                                fieldType));
2484:                        if (isObject) {
2485:                            if (fieldInfo.isArray()) {
2486:                                il.insert(instructionFactory
2487:                                        .createCheckCast(new ObjectType(
2488:                                                fieldInfo.getSignature())));
2489:                            } else {
2490:                                il.insert(instructionFactory
2491:                                        .createCheckCast(new ObjectType(
2492:                                                fieldInfo.getReturnType())));
2493:                            }
2494:                            il.insert(instructionFactory.createInvoke(
2495:                                    STATE_MANAGER, "replacingObjectField",
2496:                                    Type.OBJECT, new Type[] { PC_OBJECT_TYPE,
2497:                                            Type.INT },
2498:                                    Constants.INVOKEINTERFACE));
2499:                        } else {
2500:                            il.insert(instructionFactory.createInvoke(
2501:                                    STATE_MANAGER, stateManagerReplaceField,
2502:                                    fieldType, new Type[] { PC_OBJECT_TYPE,
2503:                                            Type.INT },
2504:                                    Constants.INVOKEINTERFACE));
2505:                        }
2506:                        il.insert(new ILOAD(1));
2507:                        il.insert(new ALOAD(0));
2508:                        il.insert(instructionFactory.createGetField(
2509:                                getTopPCSuperOrCurrentClassName(),
2510:                                "jdoStateManager", SM_OBJECT_TYPE));
2511:                        il.insert(new ALOAD(0));
2512:                        InstructionHandle switchHandel = il
2513:                                .insert(new ALOAD(0));
2514:                        TableSwitchHelper tsh = new TableSwitchHelper();
2515:                        tsh.match = fieldNum;
2516:                        tsh.target = switchHandel;
2517:                        switchList.add(tsh);
2518:                    }
2519:                    Iterator sIter = switchList.iterator();
2520:                    int count = 0;
2521:                    while (sIter.hasNext()) {
2522:                        TableSwitchHelper tsh = (TableSwitchHelper) sIter
2523:                                .next();
2524:                        match[count] = tsh.match;
2525:                        targets[count] = tsh.target;
2526:                        count++;
2527:                    }
2528:
2529:                    il.insert(new TABLESWITCH(match, targets, defaultHandle));
2530:                    InstructionHandle relativeFieldFromHandle = il
2531:                            .insert(new ILOAD(2));
2532:                    il.insert(new ISTORE(2));
2533:                    il.insert(new ISUB());
2534:                    il.insert(instructionFactory
2535:                            .createGetStatic(classGen.getClassName(),
2536:                                    "jdoInheritedFieldCount", Type.INT));
2537:                    il.insert(new ILOAD(1));
2538:                    methodGen.addLocalVariable("relativeField", Type.INT, 2,
2539:                            relativeFieldFromHandle, returnHandel);
2540:                } else if (classInfo.getPersistenceCapableSuperclass() != null) {
2541:                    il.append(new ILOAD(1));
2542:                    il.append(instructionFactory
2543:                            .createGetStatic(classGen.getClassName(),
2544:                                    "jdoInheritedFieldCount", Type.INT));
2545:                    il.append(new ISUB());
2546:                    il.append(new ISTORE(2));
2547:                    InstructionHandle relativeField_Start = il
2548:                            .append(new ILOAD(2));
2549:                    IFGE ifge = new IFGE(null);
2550:                    il.append(ifge);
2551:                    il.append(new ALOAD(0));
2552:                    il.append(new ILOAD(1));
2553:
2554:                    il.append(instructionFactory.createInvoke(classInfo
2555:                            .getPersistenceCapableSuperclass(),
2556:                            "jdoReplaceField", Type.VOID,
2557:                            new Type[] { Type.INT }, Constants.INVOKESPECIAL));
2558:                    GOTO aGoto = new GOTO(null);
2559:                    il.append(aGoto);
2560:                    InstructionHandle newHandel = il.append(instructionFactory
2561:                            .createNew("java.lang.IllegalArgumentException"));
2562:                    ifge.setTarget(newHandel);
2563:                    il.append(new DUP());
2564:                    il.append(new PUSH(constantPoolGen, "fieldNumber"));
2565:                    il.append(instructionFactory.createInvoke(
2566:                            "java.lang.IllegalArgumentException", "<init>",
2567:                            Type.VOID, new Type[] { Type.STRING },
2568:                            Constants.INVOKESPECIAL));
2569:                    il.append(new ATHROW());
2570:                    il.append(new RETURN());
2571:                    aGoto.setTarget(il.getEnd());
2572:
2573:                    methodGen.addLocalVariable("relativeField", Type.INT, 2,
2574:                            relativeField_Start, il.getEnd());
2575:                } else {
2576:                    il.append(new RETURN());
2577:                }
2578:
2579:                //        makeSynthetic(methodGen);
2580:                methodGen.setMaxLocals();
2581:                methodGen.setMaxStack();
2582:                classGen.addMethod(methodGen.getMethod());
2583:                il.dispose();
2584:            }
2585:
2586:            private void addFieldGetters() {
2587:                Iterator fieldIter = fieldSet.iterator();
2588:                int fieldNum = 0;
2589:
2590:                while (fieldIter.hasNext()) {
2591:                    FieldInfo fieldInfo = (FieldInfo) fieldIter.next();
2592:                    int acc = Constants.ACC_STATIC
2593:                            | (fieldInfo.isPrivate() ? Constants.ACC_PRIVATE
2594:                                    : (short) 0)
2595:                            | (fieldInfo.isProtected() ? Constants.ACC_PROTECTED
2596:                                    : (short) 0)
2597:                            | (fieldInfo.isPublic() ? Constants.ACC_PUBLIC
2598:                                    : (short) 0);
2599:                    Type returnType = fieldInfo.getType();
2600:                    ReturnInstruction returnInstruction;
2601:                    String stateManagerGetField = null;
2602:                    boolean isObject = false;
2603:                    if (typeToGetField.containsKey(returnType)) {
2604:                        stateManagerGetField = (String) typeToGetField
2605:                                .get(returnType);
2606:                        returnInstruction = (ReturnInstruction) typeToReturnType
2607:                                .get(returnType);
2608:                        isObject = false;
2609:                    } else {
2610:                        stateManagerGetField = "getObjectField";
2611:                        returnInstruction = new ARETURN();
2612:                        isObject = true;
2613:                    }
2614:
2615:                    InstructionList il = new InstructionList();
2616:
2617:                    MethodGen methodGen = new MethodGen(
2618:                            acc,
2619:                            returnType,
2620:                            new Type[] { new ObjectType(classGen.getClassName()) },
2621:                            new String[] { "x" }, fieldInfo.getJdoGetName(),
2622:                            classGen.getClassName(), il, constantPoolGen);
2623:
2624:                    if (fieldInfo.getFlag() == CHECK_READ_WRITE) {// this field is in the default fetch group
2625:                        il.append(new ALOAD(0));
2626:                        il.append(instructionFactory.createGetField(
2627:                                getTopPCSuperOrCurrentClassName(), "jdoFlags",
2628:                                Type.BYTE));
2629:                        IFGT ifgt = new IFGT(null);
2630:                        il.append(ifgt);
2631:                        il.append(new ALOAD(0));
2632:                        il.append(instructionFactory.createGetField(classGen
2633:                                .getClassName(), fieldInfo.getFieldName(),
2634:                                returnType));
2635:                        il.append(returnInstruction);
2636:                        InstructionHandle ifgtHandel = il.append(new ALOAD(0));
2637:                        ifgt.setTarget(ifgtHandel);
2638:                        il.append(instructionFactory.createGetField(
2639:                                getTopPCSuperOrCurrentClassName(),
2640:                                "jdoStateManager", SM_OBJECT_TYPE));
2641:                        il.append(new ASTORE(1));
2642:                        InstructionHandle smHandle = il.append(new ALOAD(1));
2643:                        IFNULL ifnull = new IFNULL(null); // null to aload_0 58
2644:                        il.append(ifnull);
2645:                        il.append(new ALOAD(1));
2646:                        il.append(new ALOAD(0));
2647:                        il.append(instructionFactory.createGetStatic(classGen
2648:                                .getClassName(), "jdoInheritedFieldCount",
2649:                                Type.INT));
2650:                        il.append(new PUSH(constantPoolGen, fieldNum));
2651:                        il.append(new IADD());
2652:                        il.append(instructionFactory.createInvoke(
2653:                                STATE_MANAGER, "isLoaded", Type.BOOLEAN,
2654:                                new Type[] { PC_OBJECT_TYPE, Type.INT },
2655:                                Constants.INVOKEINTERFACE));
2656:                        IFEQ ifeq = new IFEQ(null);
2657:                        il.append(ifeq); // null to aload_1 41
2658:                        il.append(new ALOAD(0));
2659:                        il.append(instructionFactory.createGetField(classGen
2660:                                .getClassName(), fieldInfo.getFieldName(),
2661:                                returnType));
2662:                        il.append(returnInstruction);
2663:                        InstructionHandle ifeqHandel = il.append(new ALOAD(1));
2664:                        ifeq.setTarget(ifeqHandel);
2665:                        il.append(new ALOAD(0));
2666:                        il.append(instructionFactory.createGetStatic(classGen
2667:                                .getClassName(), "jdoInheritedFieldCount",
2668:                                Type.INT));
2669:                        il.append(new PUSH(constantPoolGen, fieldNum));
2670:                        il.append(new IADD());
2671:                        il.append(new ALOAD(0));
2672:                        il.append(instructionFactory.createGetField(classGen
2673:                                .getClassName(), fieldInfo.getFieldName(),
2674:                                returnType));
2675:                        if (isObject) {//if there is a object cast it
2676:                            il.append(instructionFactory.createInvoke(
2677:                                    STATE_MANAGER, stateManagerGetField,
2678:                                    Type.OBJECT, new Type[] { PC_OBJECT_TYPE,
2679:                                            Type.INT, Type.OBJECT },
2680:                                    Constants.INVOKEINTERFACE));
2681:                            il.append(instructionFactory
2682:                                    .createCheckCast((ReferenceType) fieldInfo
2683:                                            .getType()));
2684:                        } else {
2685:                            il.append(instructionFactory.createInvoke(
2686:                                    STATE_MANAGER, stateManagerGetField,
2687:                                    returnType, new Type[] { PC_OBJECT_TYPE,
2688:                                            Type.INT, returnType },
2689:                                    Constants.INVOKEINTERFACE));
2690:                        }
2691:                        il.append(returnInstruction);
2692:                        InstructionHandle ifNullHandle = il
2693:                                .append(new ALOAD(0));
2694:                        ifnull.setTarget(ifNullHandle);
2695:                        il.append(instructionFactory.createGetField(classGen
2696:                                .getClassName(), fieldInfo.getFieldName(),
2697:                                returnType));
2698:                        il.append(returnInstruction);
2699:                        methodGen.addLocalVariable("sm", SM_OBJECT_TYPE, 1,
2700:                                smHandle, il.getEnd());
2701:
2702:                    } else if (fieldInfo.getFlag() == MEDIATE_READ_WRITE) {
2703:
2704:                        il.append(new ALOAD(0));
2705:                        il.append(instructionFactory.createGetField(
2706:                                getTopPCSuperOrCurrentClassName(),
2707:                                "jdoStateManager", SM_OBJECT_TYPE));
2708:                        il.append(new ASTORE(1));
2709:                        InstructionHandle smHandle = il.append(new ALOAD(1));
2710:                        IFNULL ifnull = new IFNULL(null); // null to aload_0 58
2711:                        il.append(ifnull);
2712:                        il.append(new ALOAD(1));
2713:                        il.append(new ALOAD(0));
2714:                        il.append(instructionFactory.createGetStatic(classGen
2715:                                .getClassName(), "jdoInheritedFieldCount",
2716:                                Type.INT));
2717:                        il.append(new PUSH(constantPoolGen, fieldNum));
2718:                        il.append(new IADD());
2719:                        il.append(instructionFactory.createInvoke(
2720:                                STATE_MANAGER, "isLoaded", Type.BOOLEAN,
2721:                                new Type[] { PC_OBJECT_TYPE, Type.INT },
2722:                                Constants.INVOKEINTERFACE));
2723:                        IFEQ ifeq = new IFEQ(null);
2724:                        il.append(ifeq); // null to aload_1 41
2725:                        il.append(new ALOAD(0));
2726:                        il.append(instructionFactory.createGetField(classGen
2727:                                .getClassName(), fieldInfo.getFieldName(),
2728:                                returnType));
2729:                        il.append(returnInstruction);
2730:                        InstructionHandle ifeqHandel = il.append(new ALOAD(1));
2731:                        ifeq.setTarget(ifeqHandel);
2732:                        il.append(new ALOAD(0));
2733:                        il.append(instructionFactory.createGetStatic(classGen
2734:                                .getClassName(), "jdoInheritedFieldCount",
2735:                                Type.INT));
2736:                        il.append(new PUSH(constantPoolGen, fieldNum));
2737:                        il.append(new IADD());
2738:                        il.append(new ALOAD(0));
2739:                        il.append(instructionFactory.createGetField(classGen
2740:                                .getClassName(), fieldInfo.getFieldName(),
2741:                                returnType));
2742:                        if (isObject) {//if there is a object cast it
2743:                            il.append(instructionFactory.createInvoke(
2744:                                    STATE_MANAGER, stateManagerGetField,
2745:                                    Type.OBJECT, new Type[] { PC_OBJECT_TYPE,
2746:                                            Type.INT, Type.OBJECT },
2747:                                    Constants.INVOKEINTERFACE));
2748:                            il.append(instructionFactory
2749:                                    .createCheckCast((ReferenceType) fieldInfo
2750:                                            .getType()));
2751:                        } else {
2752:                            il.append(instructionFactory.createInvoke(
2753:                                    STATE_MANAGER, stateManagerGetField,
2754:                                    returnType, new Type[] { PC_OBJECT_TYPE,
2755:                                            Type.INT, returnType },
2756:                                    Constants.INVOKEINTERFACE));
2757:                        }
2758:                        il.append(returnInstruction);
2759:                        InstructionHandle ifNullHandle = il
2760:                                .append(new ALOAD(0));
2761:                        ifnull.setTarget(ifNullHandle);
2762:                        il.append(instructionFactory.createGetField(classGen
2763:                                .getClassName(), fieldInfo.getFieldName(),
2764:                                returnType));
2765:                        il.append(returnInstruction);
2766:                        methodGen.addLocalVariable("sm", SM_OBJECT_TYPE, 1,
2767:                                smHandle, il.getEnd());
2768:
2769:                    } else {//no mediation
2770:                        if (fieldInfo.primaryKey()
2771:                                && (classInfo.getIdentityType() == MDStatics.IDENTITY_TYPE_APPLICATION)
2772:                                && classInfo.isKeyGen()) {
2773:
2774:                            il.append(new ALOAD(0));
2775:                            il
2776:                                    .append(instructionFactory
2777:                                            .createGetField(
2778:                                                    classGen.getClassName(),
2779:                                                    "jdoStateManager",
2780:                                                    new ObjectType(
2781:                                                            "javax.jdo.spi.StateManager")));
2782:                            il.append(new INSTANCEOF(constantPoolGen
2783:                                    .addClass(VERSANT_STATE_MANAGER)));
2784:                            IFEQ ifeq = new IFEQ(null);
2785:                            il.append(ifeq); //25
2786:                            il.append(new ALOAD(0));
2787:                            il
2788:                                    .append(instructionFactory
2789:                                            .createGetField(
2790:                                                    classGen.getClassName(),
2791:                                                    "jdoStateManager",
2792:                                                    new ObjectType(
2793:                                                            "javax.jdo.spi.StateManager")));
2794:                            il.append(instructionFactory
2795:                                    .createCheckCast(new ObjectType(
2796:                                            VERSANT_STATE_MANAGER)));
2797:                            il.append(instructionFactory.createGetStatic(
2798:                                    classGen.getClassName(),
2799:                                    "jdoInheritedFieldCount", Type.INT));
2800:                            il.append(new PUSH(constantPoolGen, fieldInfo
2801:                                    .getFieldNo()));
2802:                            il.append(new IADD());
2803:                            il.append(instructionFactory.createInvoke(
2804:                                    VERSANT_STATE_MANAGER, "fillNewAppPKField",
2805:                                    Type.VOID, new Type[] { Type.INT },
2806:                                    Constants.INVOKEINTERFACE));
2807:                            InstructionHandle nopHandle = il.append(new NOP());
2808:                            ifeq.setTarget(nopHandle);
2809:                        }
2810:                        il.append(new ALOAD(0));
2811:                        il.append(instructionFactory.createGetField(classGen
2812:                                .getClassName(), fieldInfo.getFieldName(),
2813:                                returnType));
2814:                        il.append(returnInstruction);
2815:                    }
2816:                    methodGen.removeNOPs();
2817:                    makeSynthetic(methodGen);
2818:                    methodGen.setMaxLocals();
2819:                    methodGen.setMaxStack();
2820:                    classGen.addMethod(methodGen.getMethod());
2821:                    il.dispose();
2822:                    fieldNum++;
2823:
2824:                }
2825:
2826:            }
2827:
2828:            private void makeSynthetic(FieldGenOrMethodGen gen) {
2829:                gen.addAttribute(new Synthetic(synthetic, 0, null, gen
2830:                        .getConstantPool().getConstantPool()));
2831:            }
2832:
2833:            private void addFieldSetters() {
2834:                Iterator fieldIter = fieldSet.iterator();
2835:                int fieldNum = 0;
2836:
2837:                while (fieldIter.hasNext()) {
2838:                    FieldInfo fieldInfo = (FieldInfo) fieldIter.next();
2839:
2840:                    int acc = Constants.ACC_STATIC
2841:                            | (fieldInfo.isPrivate() ? Constants.ACC_PRIVATE
2842:                                    : (short) 0)
2843:                            | (fieldInfo.isProtected() ? Constants.ACC_PROTECTED
2844:                                    : (short) 0)
2845:                            | (fieldInfo.isPublic() ? Constants.ACC_PUBLIC
2846:                                    : (short) 0);
2847:
2848:                    Type fieldType = fieldInfo.getType();
2849:                    boolean isObject = false;
2850:                    String stateManagerSetField = null;
2851:                    if (typeToSetField.containsKey(fieldType)) {
2852:                        stateManagerSetField = (String) typeToSetField
2853:                                .get(fieldType);
2854:                        isObject = false;
2855:                    } else {
2856:                        stateManagerSetField = "setObjectField";
2857:                        isObject = true;
2858:                    }
2859:
2860:                    InstructionList il = new InstructionList();
2861:                    MethodGen methodGen = new MethodGen(acc, Type.VOID,
2862:                            new Type[] {
2863:                                    new ObjectType(classGen.getClassName()),
2864:                                    fieldType },
2865:                            new String[] { "x", "newValue" }, fieldInfo
2866:                                    .getJdoSetName(), classGen.getClassName(),
2867:                            il, constantPoolGen);
2868:
2869:                    int flags = fieldInfo.getFlag();
2870:                    boolean isLorD = false;
2871:                    if (fieldType.equals(Type.LONG)
2872:                            || fieldType.equals(Type.DOUBLE))
2873:                        isLorD = true;
2874:                    IFNE ifne = new IFNE(null);
2875:                    if (flags == CHECK_READ_WRITE || flags == CHECK_WRITE) {// this field is in the default fetch group or is transient transactional
2876:                        il.append(new ALOAD(0));
2877:                        il.append(instructionFactory.createGetField(
2878:                                getTopPCSuperOrCurrentClassName(), "jdoFlags",
2879:                                Type.BYTE));
2880:
2881:                        il.append(ifne); // 13
2882:                        il.append(new ALOAD(0));
2883:                        if (isObject) {
2884:                            il.append(new ALOAD(1));
2885:                        } else {
2886:                            il.append((LoadInstruction) typeToLoadType
2887:                                    .get(fieldType));
2888:                        }
2889:                        il.append(instructionFactory.createPutField(classGen
2890:                                .getClassName(), fieldInfo.getFieldName(),
2891:                                fieldType));
2892:                        il.append(new RETURN());
2893:                    }
2894:                    InstructionHandle ifneHandel = il.append(new ALOAD(0));
2895:                    ifne.setTarget(ifneHandel);
2896:                    il.append(instructionFactory.createGetField(
2897:                            getTopPCSuperOrCurrentClassName(),
2898:                            "jdoStateManager", SM_OBJECT_TYPE));
2899:                    il.append(new ASTORE((isLorD ? 3 : 2)));
2900:                    InstructionHandle smStartHandle = il.append(new ALOAD(
2901:                            (isLorD ? 3 : 2)));
2902:                    IFNULL ifnull = new IFNULL(null);
2903:                    il.append(ifnull);
2904:                    il.append(new ALOAD((isLorD ? 3 : 2)));
2905:                    il.append(new ALOAD(0));
2906:                    il.append(instructionFactory
2907:                            .createGetStatic(classGen.getClassName(),
2908:                                    "jdoInheritedFieldCount", Type.INT));
2909:                    il.append(new PUSH(constantPoolGen, fieldNum));
2910:                    il.append(new IADD());
2911:                    il.append(new ALOAD(0));
2912:                    il.append(instructionFactory.createGetField(classGen
2913:                            .getClassName(), fieldInfo.getFieldName(),
2914:                            fieldType));
2915:                    if (isObject) {//if there is a object call it with Object's
2916:                        il.append(new ALOAD(1));
2917:                        il.append(instructionFactory.createInvoke(
2918:                                STATE_MANAGER, stateManagerSetField, Type.VOID,
2919:                                new Type[] { PC_OBJECT_TYPE, Type.INT,
2920:                                        Type.OBJECT, Type.OBJECT },
2921:                                Constants.INVOKEINTERFACE));
2922:                    } else {
2923:                        il.append((LoadInstruction) typeToLoadType
2924:                                .get(fieldType));
2925:                        il.append(instructionFactory.createInvoke(
2926:                                STATE_MANAGER, stateManagerSetField, Type.VOID,
2927:                                new Type[] { PC_OBJECT_TYPE, Type.INT,
2928:                                        fieldType, fieldType },
2929:                                Constants.INVOKEINTERFACE));
2930:                    }
2931:                    GOTO aGoto = new GOTO(null);
2932:                    il.append(aGoto);
2933:                    InstructionHandle ifnullHandle = il.append(new ALOAD(0));
2934:                    ifnull.setTarget(ifnullHandle);
2935:                    if (isObject) {//if there is a object call it with Object's
2936:                        il.append(new ALOAD(1));
2937:                    } else {
2938:                        il.append((LoadInstruction) typeToLoadType
2939:                                .get(fieldType));
2940:                    }
2941:                    il.append(instructionFactory.createPutField(classGen
2942:                            .getClassName(), fieldInfo.getFieldName(),
2943:                            fieldType));
2944:                    InstructionHandle lastHandle = il.append(new RETURN());
2945:                    aGoto.setTarget(lastHandle);
2946:
2947:                    methodGen.addLocalVariable("sm", SM_OBJECT_TYPE,
2948:                            (isLorD ? 3 : 2), smStartHandle, il.getEnd());
2949:
2950:                    makeSynthetic(methodGen);
2951:                    methodGen.setMaxLocals();
2952:                    methodGen.setMaxStack();
2953:                    classGen.addMethod(methodGen.getMethod());
2954:                    il.dispose();
2955:                    fieldNum++;
2956:
2957:                }
2958:
2959:            }
2960:
2961:            private void addJdoGetManagedFieldCount() {
2962:                InstructionList il = new InstructionList();
2963:                MethodGen methodGen = new MethodGen(Constants.ACC_STATIC
2964:                        | Constants.ACC_PROTECTED, Type.INT, null, null,
2965:                        "jdoGetManagedFieldCount", classGen.getClassName(), il,
2966:                        constantPoolGen);
2967:                il.append(instructionFactory.createGetStatic(classGen
2968:                        .getClassName(), "jdoInheritedFieldCount", Type.INT));
2969:                il.append(new PUSH(constantPoolGen, fieldSet.size()));
2970:                il.append(new IADD());
2971:                il.append(new IRETURN());
2972:
2973:                //        makeSynthetic(methodGen);
2974:                methodGen.setMaxLocals();
2975:                methodGen.setMaxStack();
2976:                classGen.addMethod(methodGen.getMethod());
2977:                il.dispose();
2978:            }
2979:
2980:            private void addJdoInheritedFieldCount() {
2981:                FieldGen fieldGen = new FieldGen(Constants.ACC_PRIVATE
2982:                        | Constants.ACC_STATIC,//| NEW Constants.ACC_FINAL,
2983:                        Type.INT, "jdoInheritedFieldCount", constantPoolGen);
2984:                makeSynthetic(fieldGen);
2985:                classGen.addField(fieldGen.getField());
2986:                Method m = getStaticConstructor();
2987:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
2988:                        constantPoolGen);
2989:                InstructionList il = methodGen.getInstructionList();
2990:                InstructionHandle initialReturnHandle = il.getEnd();
2991:                InstructionHandle nopTarget = il.append(new NOP());
2992:                if (classInfo.getPersistenceCapableSuperclass() == null) {
2993:                    il.append(new ICONST(0));
2994:                } else {
2995:                    il.append(instructionFactory.createInvoke(classInfo
2996:                            .getPersistenceCapableSuperclass(),
2997:                            "jdoGetManagedFieldCount", Type.INT, new Type[] {},
2998:                            Constants.INVOKESTATIC));
2999:                }
3000:                il.append(instructionFactory.createPutStatic(classGen
3001:                        .getClassName(), "jdoInheritedFieldCount", Type.INT));
3002:                il.append(new RETURN());
3003:                try {
3004:                    //            System.out.println("initialReturnHandle that was deleted = " + initialReturnHandle);
3005:                    il.delete(initialReturnHandle);
3006:                } catch (TargetLostException e) {
3007:                    InstructionHandle[] targets = e.getTargets();
3008:                    for (int i = 0; i < targets.length; i++) {
3009:                        InstructionTargeter[] targeters = targets[i]
3010:                                .getTargeters();
3011:                        for (int j = 0; j < targeters.length; j++) {
3012:                            targeters[j].updateTarget(targets[i], nopTarget);
3013:                        }
3014:                    }
3015:                }
3016:
3017:                methodGen.removeNOPs();
3018:                methodGen.setMaxLocals();
3019:                methodGen.setMaxStack();
3020:                classGen.replaceMethod(m, methodGen.getMethod());
3021:                il.dispose();
3022:            }
3023:
3024:            private void addJdoFieldTypes() {
3025:                FieldGen fieldGen = new FieldGen(
3026:                        Constants.ACC_PRIVATE | Constants.ACC_STATIC,//| NEW Constants.ACC_FINAL,
3027:                        new ArrayType("java.lang.Class", 1), "jdoFieldTypes",
3028:                        constantPoolGen);
3029:                makeSynthetic(fieldGen);
3030:                classGen.addField(fieldGen.getField());
3031:                Method m = getStaticConstructor();
3032:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
3033:                        constantPoolGen);
3034:                InstructionList il = methodGen.getInstructionList();
3035:
3036:                InstructionHandle initialReturnHandle = il.getEnd();
3037:                InstructionHandle nopTarget = il.append(new NOP());
3038:                il.append(new PUSH(constantPoolGen, fieldSet.size()));
3039:                il.append(new ANEWARRAY(constantPoolGen
3040:                        .addClass(new ObjectType("java.lang.Class"))));
3041:                il.append(new DUP());
3042:                Iterator iter = fieldSet.iterator();
3043:                int push = 0;
3044:                while (iter.hasNext()) {
3045:                    FieldInfo field = (FieldInfo) iter.next();
3046:                    if (field.isPrimative()) {
3047:                        il.append(new PUSH(constantPoolGen, push));
3048:                        il.append(instructionFactory.createGetStatic(field
3049:                                .getPrimativeTypeObject(), "TYPE",
3050:                                new ObjectType("java.lang.Class")));
3051:                        il.append(new AASTORE());
3052:                        il.append(new DUP());
3053:                    } else {
3054:                        InstructionList tempIl = new InstructionList();
3055:                        String returnType = field.getReturnType();
3056:                        String fieldName = getSetClass$Field(field);
3057:                        tempIl.insert(new DUP());
3058:                        InstructionHandle gotoAASTORE = tempIl
3059:                                .insert(new AASTORE());
3060:                        InstructionHandle gotoGetStatic = tempIl
3061:                                .insert(instructionFactory.createGetStatic(
3062:                                        classGen.getClassName(), fieldName,
3063:                                        new ObjectType("java.lang.Class")));
3064:                        tempIl.insert(new GOTO(gotoAASTORE));
3065:                        tempIl.insert(instructionFactory.createPutStatic(
3066:                                classGen.getClassName(), fieldName,
3067:                                new ObjectType("java.lang.Class")));
3068:                        tempIl.insert(new DUP());
3069:                        tempIl.insert(instructionFactory
3070:                                .createInvoke(classGen.getClassName(),
3071:                                        "class$", new ObjectType(
3072:                                                "java.lang.Class"),
3073:                                        new Type[] { new ObjectType(
3074:                                                "java.lang.String") },
3075:                                        Constants.INVOKESTATIC));
3076:                        if (field.isArray()) {
3077:                            tempIl.insert(new PUSH(constantPoolGen, field
3078:                                    .getSignature().replace('/', '.')));
3079:                        } else {
3080:                            tempIl
3081:                                    .insert(new PUSH(constantPoolGen,
3082:                                            returnType));
3083:                        }
3084:
3085:                        tempIl.insert(new IFNONNULL(gotoGetStatic));
3086:                        tempIl.insert(instructionFactory.createGetStatic(
3087:                                classGen.getClassName(), fieldName,
3088:                                new ObjectType("java.lang.Class")));
3089:                        tempIl.insert(new PUSH(constantPoolGen, push));
3090:
3091:                        il.append(tempIl);
3092:                    }
3093:                    push++;
3094:                }
3095:                try {
3096:                    il.delete(il.getEnd());
3097:                } catch (TargetLostException e) {//there should never be target for this instruction (DUP)
3098:                    e.printStackTrace();
3099:                }
3100:
3101:                il.append(instructionFactory.createPutStatic(classGen
3102:                        .getClassName(), "jdoFieldTypes", new ArrayType(
3103:                        new ObjectType("java.lang.Class"), 1)));
3104:                il.append(new RETURN());
3105:                try {
3106:                    il.delete(initialReturnHandle);
3107:                } catch (TargetLostException e) {
3108:                    InstructionHandle[] targets = e.getTargets();
3109:                    for (int i = 0; i < targets.length; i++) {
3110:                        InstructionTargeter[] targeters = targets[i]
3111:                                .getTargeters();
3112:                        for (int j = 0; j < targeters.length; j++) {
3113:                            targeters[j].updateTarget(targets[i], nopTarget);
3114:                        }
3115:                    }
3116:                }
3117:                methodGen.removeNOPs();
3118:                methodGen.setMaxLocals();
3119:                methodGen.setMaxStack();
3120:                classGen.replaceMethod(m, methodGen.getMethod());
3121:                il.dispose();
3122:            }
3123:
3124:            private void addJdoFieldFlags() {
3125:                FieldGen fieldGen = new FieldGen(
3126:                        Constants.ACC_PRIVATE | Constants.ACC_STATIC,//| NEW Constants.ACC_FINAL,
3127:                        new ArrayType(Type.BYTE, 1), "jdoFieldFlags",
3128:                        constantPoolGen);
3129:
3130:                makeSynthetic(fieldGen);
3131:                classGen.addField(fieldGen.getField());
3132:                Method m = getStaticConstructor();
3133:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
3134:                        constantPoolGen);
3135:                InstructionList il = methodGen.getInstructionList();
3136:
3137:                InstructionHandle initialReturnHandle = il.getEnd();
3138:                InstructionHandle nopTarget = il.append(new NOP());
3139:                il.append(new PUSH(constantPoolGen, fieldSet.size()));
3140:                il.append(new NEWARRAY((Type.BYTE).getType()));
3141:                Iterator iter = fieldSet.iterator();
3142:                int push = 0;
3143:                while (iter.hasNext()) {
3144:                    FieldInfo field = (FieldInfo) iter.next();
3145:                    il.append(new DUP());
3146:                    il.append(new PUSH(constantPoolGen, push));
3147:                    il.append(new PUSH(constantPoolGen, field.getFlag()));
3148:                    il.append(new BASTORE());
3149:                    push++;
3150:                }
3151:                il.append(instructionFactory.createPutStatic(classGen
3152:                        .getClassName(), "jdoFieldFlags", new ArrayType(
3153:                        Type.BYTE, 1)));
3154:                il.append(new RETURN());
3155:                try {
3156:                    il.delete(initialReturnHandle);
3157:                } catch (TargetLostException e) {
3158:                    InstructionHandle[] targets = e.getTargets();
3159:                    for (int i = 0; i < targets.length; i++) {
3160:                        InstructionTargeter[] targeters = targets[i]
3161:                                .getTargeters();
3162:                        for (int j = 0; j < targeters.length; j++) {
3163:                            targeters[j].updateTarget(targets[i], nopTarget);
3164:                        }
3165:                    }
3166:                }
3167:                methodGen.removeNOPs();
3168:                methodGen.setMaxLocals();
3169:                methodGen.setMaxStack();
3170:                classGen.replaceMethod(m, methodGen.getMethod());
3171:                il.dispose();
3172:
3173:            }
3174:
3175:            private void addInterrogatives() {
3176:                if (classInfo.getTopPCSuperClass() == null) {
3177:                    setInterrogative("jdoIsPersistent", "isPersistent");
3178:                    setInterrogative("jdoIsTransactional", "isTransactional");
3179:                    setInterrogative("jdoIsNew", "isNew");
3180:                    setInterrogative("jdoIsDirty", "isDirty");
3181:                    setInterrogative("jdoIsDeleted", "isDeleted");
3182:                    setJdoGetPersistanceManager();
3183:                    setJdoMakeDirty();
3184:                }
3185:            }
3186:
3187:            /**
3188:             * Add method
3189:             * public PersistenceManager jdoGetPersistenceManager(){
3190:             *     return jdoStateManager == null ? null : jdoStateManager.getPersistenceManager(this);
3191:             * }
3192:             */
3193:            private void setJdoGetPersistanceManager() {
3194:                InstructionList il = new InstructionList();
3195:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
3196:                        new ObjectType("javax.jdo.PersistenceManager"), null,
3197:                        null, "jdoGetPersistenceManager", classGen
3198:                                .getClassName(), il, constantPoolGen);
3199:
3200:                InstructionHandle ireturnHandle = il.insert(new ARETURN());
3201:                il.insert(instructionFactory.createInvoke(STATE_MANAGER,
3202:                        "getPersistenceManager", new ObjectType(
3203:                                "javax.jdo.PersistenceManager"),
3204:                        new Type[] { PC_OBJECT_TYPE },
3205:                        Constants.INVOKEINTERFACE));
3206:                il.insert(new ALOAD(0));
3207:                il.insert(instructionFactory.createGetField(
3208:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3209:                        SM_OBJECT_TYPE));
3210:                InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0));
3211:                il.insert(new GOTO(ireturnHandle));
3212:                il.insert(new ACONST_NULL());
3213:                il.insert(new IFNONNULL(ifNonNullHandle));
3214:                il.insert(instructionFactory.createGetField(
3215:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3216:                        SM_OBJECT_TYPE));
3217:                il.insert(new ALOAD(0));
3218:
3219:                //        makeSynthetic(methodGen);
3220:                methodGen.setMaxLocals();
3221:                methodGen.setMaxStack();
3222:                classGen.addMethod(methodGen.getMethod());
3223:                il.dispose();
3224:
3225:            }
3226:
3227:            /**
3228:             * Add method
3229:             *
3230:             *  public void jdoMakeDirty(String fieldName){
3231:             *      if(jdoStateManager==null) return;
3232:             *      jdoStateManager.makeDirty(this, fieldName);
3233:             *  }
3234:             *
3235:             */
3236:            private void setJdoMakeDirty() {
3237:                InstructionList il = new InstructionList();
3238:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
3239:                        Type.VOID, new Type[] { Type.STRING },
3240:                        new String[] { "fieldName" }, "jdoMakeDirty", classGen
3241:                                .getClassName(), il, constantPoolGen);
3242:                il.insert(new RETURN());
3243:                il.insert(instructionFactory.createInvoke(STATE_MANAGER,
3244:                        "makeDirty", Type.VOID, new Type[] { PC_OBJECT_TYPE,
3245:                                Type.STRING }, Constants.INVOKEINTERFACE));
3246:                il.insert(new ALOAD(1));
3247:                il.insert(new ALOAD(0));
3248:                il.insert(instructionFactory.createGetField(
3249:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3250:                        SM_OBJECT_TYPE));
3251:                InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0));
3252:                il.insert(new RETURN());
3253:                il.insert(new IFNONNULL(ifNonNullHandle));
3254:                il.insert(instructionFactory.createGetField(
3255:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3256:                        SM_OBJECT_TYPE));
3257:                il.insert(new ALOAD(0));
3258:
3259:                //        makeSynthetic(methodGen);
3260:                methodGen.setMaxLocals();
3261:                methodGen.setMaxStack();
3262:                classGen.addMethod(methodGen.getMethod());
3263:                il.dispose();
3264:            }
3265:
3266:            private void addJdoFieldNames() {
3267:                FieldGen fieldGen = new FieldGen(
3268:                        Constants.ACC_PRIVATE | Constants.ACC_STATIC,// | NEW Constants.ACC_FINAL,
3269:                        new ArrayType(Type.STRING, 1), "jdoFieldNames",
3270:                        constantPoolGen);
3271:                makeSynthetic(fieldGen);
3272:                classGen.addField(fieldGen.getField());
3273:                Method m = getStaticConstructor();
3274:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
3275:                        constantPoolGen);
3276:                InstructionList il = methodGen.getInstructionList();
3277:
3278:                InstructionHandle initialReturnHandle = il.getEnd();
3279:
3280:                InstructionHandle nopTarget = il.append(new NOP());
3281:                il.append(new PUSH(constantPoolGen, fieldSet.size()));
3282:                il.append(new ANEWARRAY(constantPoolGen.addClass(Type.STRING)));
3283:
3284:                Iterator iter = fieldSet.iterator();
3285:                int push = 0;
3286:                while (iter.hasNext()) {
3287:                    FieldInfo field = (FieldInfo) iter.next();
3288:                    il.append(new DUP());
3289:                    il.append(new PUSH(constantPoolGen, push));
3290:                    il.append(new PUSH(constantPoolGen, field.getFieldName()));
3291:                    il.append(new AASTORE());
3292:                    push++;
3293:                }
3294:                il.append(instructionFactory.createPutStatic(classGen
3295:                        .getClassName(), "jdoFieldNames", new ArrayType(
3296:                        Type.STRING, 1)));
3297:                il.append(new RETURN());
3298:                try {
3299:                    //            System.out.println("initialReturnHandle that was deleted = " + initialReturnHandle);
3300:                    il.delete(initialReturnHandle);
3301:                } catch (TargetLostException e) {
3302:                    InstructionHandle[] targets = e.getTargets();
3303:                    for (int i = 0; i < targets.length; i++) {
3304:                        InstructionTargeter[] targeters = targets[i]
3305:                                .getTargeters();
3306:                        for (int j = 0; j < targeters.length; j++) {
3307:                            targeters[j].updateTarget(targets[i], nopTarget);
3308:                        }
3309:                    }
3310:                }
3311:
3312:                methodGen.removeNOPs();
3313:                methodGen.setMaxLocals();
3314:                methodGen.setMaxStack();
3315:                classGen.replaceMethod(m, methodGen.getMethod());
3316:                il.dispose();
3317:            }
3318:
3319:            private void setInterrogative(String methodName,
3320:                    String callingMethodName) {
3321:                InstructionList il = new InstructionList();
3322:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
3323:                        Type.BOOLEAN, null, null, methodName, classGen
3324:                                .getClassName(), il, constantPoolGen);
3325:                InstructionHandle ireturnHandle = il.insert(new IRETURN());
3326:                il.insert(instructionFactory.createInvoke(STATE_MANAGER,
3327:                        callingMethodName, Type.BOOLEAN,
3328:                        new Type[] { PC_OBJECT_TYPE },
3329:                        Constants.INVOKEINTERFACE));
3330:                il.insert(new ALOAD(0));
3331:                il.insert(instructionFactory.createGetField(
3332:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3333:                        SM_OBJECT_TYPE));
3334:                InstructionHandle ifNonNullHandle = il.insert(new ALOAD(0));
3335:                il.insert(new GOTO(ireturnHandle));
3336:                il.insert(new ICONST(0));
3337:                il.insert(new IFNONNULL(ifNonNullHandle));
3338:                il.insert(instructionFactory.createGetField(
3339:                        getTopPCSuperOrCurrentClassName(), "jdoStateManager",
3340:                        SM_OBJECT_TYPE));
3341:                il.insert(new ALOAD(0));
3342:
3343:                //        makeSynthetic(methodGen);
3344:                methodGen.setMaxLocals();
3345:                methodGen.setMaxStack();
3346:                classGen.addMethod(methodGen.getMethod());
3347:                il.dispose();
3348:
3349:            }
3350:
3351:            private void addSerialVersionUID() {
3352:                if (!hasSerialVersionUID()) {
3353:                    FieldGen fieldGen = new FieldGen(Constants.ACC_PRIVATE
3354:                            | Constants.ACC_STATIC | Constants.ACC_FINAL,
3355:                            Type.LONG, "serialVersionUID", constantPoolGen);
3356:                    fieldGen.setInitValue(currentSerialVersionUID);
3357:                    makeSynthetic(fieldGen);
3358:                    classGen.addField(fieldGen.getField());
3359:
3360:                    if (javaVersion >= JAVA_1_4) {
3361:                        /**
3362:                         * todo add serialVersionUID static constructor to for jdk 1.4
3363:                         */
3364:                    }
3365:                }
3366:            }
3367:
3368:            /**
3369:             * Check if current class has a serialVersionUID.
3370:             *
3371:             * @return true if it does have a serialVersionUID, else false.
3372:             */
3373:            private boolean hasSerialVersionUID() {
3374:                Field[] fields = classGen.getFields();
3375:                for (int i = 0; i < fields.length; i++) {
3376:                    Field f = fields[i];
3377:                    if (f.getName().equals("serialVersionUID")) {
3378:                        return true;
3379:                    }
3380:                }
3381:                return false;
3382:            }
3383:
3384:            /**
3385:             * Addes a field jdoPersistenceCapableSuperclass and initializes it to null if there
3386:             * is no persistence capable superclass else it initializes it.
3387:             *
3388:             */
3389:            private void addJdoPersistenceCapableSuperclass() {
3390:                FieldGen fieldGen = new FieldGen(
3391:                        Constants.ACC_PRIVATE | Constants.ACC_STATIC,//| NEW Constants.ACC_FINAL,
3392:                        new ObjectType("java.lang.Class"),
3393:                        "jdoPersistenceCapableSuperclass", constantPoolGen);
3394:                makeSynthetic(fieldGen);
3395:                classGen.addField(fieldGen.getField());
3396:                Method m = getStaticConstructor();
3397:                MethodGen methodGen = new MethodGen(m, classGen.getClassName(),
3398:                        constantPoolGen);
3399:                InstructionList il = methodGen.getInstructionList();
3400:                InstructionHandle initialReturnHandle = il.getEnd();
3401:                InstructionHandle nopTarget = il.append(new NOP());
3402:                if (classInfo.getPersistenceCapableSuperclass() == null) {
3403:                    il.append(InstructionConstants.ACONST_NULL);
3404:                    il.append(instructionFactory.createPutStatic(classGen
3405:                            .getClassName(), "jdoPersistenceCapableSuperclass",
3406:                            new ObjectType("java.lang.Class")));
3407:                } else {
3408:
3409:                    String className = classInfo
3410:                            .getPersistenceCapableSuperclass();
3411:                    String fieldName = getSetClass$Field(className);
3412:
3413:                    il.append(instructionFactory.createGetStatic(classGen
3414:                            .getClassName(), fieldName, new ObjectType(
3415:                            "java.lang.Class")));
3416:                    IFNONNULL ifNonNull = new IFNONNULL(null);
3417:                    il.append(ifNonNull);
3418:                    il.append(new PUSH(constantPoolGen, className));
3419:                    il.append(instructionFactory.createInvoke(classGen
3420:                            .getClassName(), "class$", new ObjectType(
3421:                            "java.lang.Class"), new Type[] { new ObjectType(
3422:                            "java.lang.String") }, Constants.INVOKESTATIC));
3423:                    il.append(new DUP());
3424:                    il.append(instructionFactory.createPutStatic(classGen
3425:                            .getClassName(), fieldName, new ObjectType(
3426:                            "java.lang.Class")));
3427:                    GOTO gotoInst = new GOTO(null);
3428:                    il.append(gotoInst);
3429:                    InstructionHandle ifNonNullHandle = il
3430:                            .append(instructionFactory.createGetStatic(classGen
3431:                                    .getClassName(), fieldName, new ObjectType(
3432:                                    "java.lang.Class")));
3433:                    ifNonNull.setTarget(ifNonNullHandle);
3434:                    InstructionHandle gotoHandle = il.append(instructionFactory
3435:                            .createPutStatic(classGen.getClassName(),
3436:                                    "jdoPersistenceCapableSuperclass",
3437:                                    new ObjectType("java.lang.Class")));
3438:                    gotoInst.setTarget(gotoHandle);
3439:                }
3440:                il.append(new RETURN());
3441:                try {
3442:                    il.delete(initialReturnHandle);
3443:                } catch (TargetLostException e) {
3444:                    InstructionHandle[] targets = e.getTargets();
3445:                    for (int i = 0; i < targets.length; i++) {
3446:                        InstructionTargeter[] targeters = targets[i]
3447:                                .getTargeters();
3448:                        for (int j = 0; j < targeters.length; j++) {
3449:                            targeters[j].updateTarget(targets[i], nopTarget);
3450:                        }
3451:                    }
3452:                }
3453:                methodGen.removeNOPs();
3454:                methodGen.setMaxLocals();
3455:                methodGen.setMaxStack();
3456:                classGen.replaceMethod(m, methodGen.getMethod());
3457:                il.dispose();
3458:            }
3459:
3460:            /**
3461:             * All class variables i.e. String.class has a static variable called
3462:             * class$java$lang$String of type java.lang.Class, this method creates it if
3463:             * it does not exist.
3464:             *
3465:             * @param  className
3466:             * @return String fieldName i.e. class$java$lang$String
3467:             */
3468:            private String getSetClass$Field(String className) {
3469:                String fullClassName = "class." + className;
3470:                String fieldName = fullClassName.replace('.', '$');
3471:                Field[] fields = classGen.getFields();
3472:                for (int i = 0; i < fields.length; i++) {
3473:                    Field f = fields[i];
3474:                    if (f.getName().equals(fieldName)) {
3475:                        return fieldName;
3476:                    }
3477:                }
3478:                FieldGen fieldGen = new FieldGen(Constants.ACC_STATIC,
3479:                        new ObjectType("java.lang.Class"), fieldName,
3480:                        constantPoolGen);
3481:                classGen.addField(fieldGen.getField());
3482:                return fieldName;
3483:
3484:            }
3485:
3486:            /**
3487:             * All class variables i.e. String.class has a static variable called
3488:             * class$java$lang$String of type java.lang.Class, this method creates it if
3489:             * it does not exist.
3490:             *
3491:             * @param field
3492:             * @return String fieldName i.e. class$java$lang$String
3493:             */
3494:            private String getSetClass$Field(FieldInfo field) {
3495:                String fullClassName = null;
3496:                if (field.isArray()) {
3497:                    fullClassName = ("array" + field.getSignature()).replace(
3498:                            '/', '$');
3499:                    fullClassName = fullClassName.replace('[', '$');
3500:                    fullClassName = (fullClassName.replace(';', ' ')).trim();
3501:                } else {
3502:                    fullClassName = "class." + field.getReturnType();
3503:                }
3504:                String fieldName = fullClassName.replace('.', '$');
3505:                Field[] fields = classGen.getFields();
3506:                for (int i = 0; i < fields.length; i++) {
3507:                    Field f = fields[i];
3508:                    if (f.getName().equals(fieldName)) {
3509:                        return fieldName;
3510:                    }
3511:                }
3512:                FieldGen fieldGen = new FieldGen(Constants.ACC_STATIC,
3513:                        new ObjectType("java.lang.Class"), fieldName,
3514:                        constantPoolGen);
3515:                makeSynthetic(fieldGen);
3516:                classGen.addField(fieldGen.getField());
3517:                return fieldName;
3518:
3519:            }
3520:
3521:            /**
3522:             * Check if current class implements PersistenceCapable.
3523:             *
3524:             * @return true if it does implement PersistenceCapable else false.
3525:             */
3526:            private boolean implements PC() {
3527:                String[] interfaceNames = classGen.getInterfaceNames();
3528:                for (int i = 0; i < interfaceNames.length; i++) {
3529:                    if (interfaceNames[i].equals(PERSISTENCE_CAPABLE)) {
3530:                        return true;
3531:                    }
3532:                }
3533:                return false;
3534:            }
3535:
3536:            /**
3537:             * All class variables i.e. String.class has a static class$ method that check if the class
3538:             * exists by doing a class.forname() on the class and throws a NoClassDefFoundError error,
3539:             * if the class does not exists
3540:             *
3541:             */
3542:            private void setClass$() {
3543:                Method[] methods = classGen.getMethods();
3544:                for (int i = 0; i < methods.length; i++) {
3545:                    Method m = methods[i];
3546:
3547:                    if (m.getName().equals("class$")
3548:                            && "(Ljava/lang/String;)Ljava/lang/Class;".equals(m
3549:                                    .getSignature())) {
3550:                        return;
3551:                    }
3552:                }
3553:                // there is no class$ method so make one
3554:                InstructionList il = new InstructionList();
3555:                MethodGen methodGen = new MethodGen(Constants.ACC_STATIC,
3556:                        new ObjectType("java.lang.Class"),
3557:                        new Type[] { new ObjectType("java.lang.String") },
3558:                        new String[] { "x0" }, "class$", classGen
3559:                                .getClassName(), il, constantPoolGen);
3560:
3561:                InstructionHandle tryStart = il.append(new ALOAD(0));
3562:                il.append(instructionFactory.createInvoke("java.lang.Class",
3563:                        "forName", new ObjectType("java.lang.Class"),
3564:                        new Type[] { new ObjectType("java.lang.String") },
3565:                        Constants.INVOKESTATIC));
3566:                InstructionHandle tryEnd = il.append(new ARETURN());
3567:                InstructionHandle handler = il.append(new ASTORE(1));
3568:                InstructionHandle varStart = il.append(instructionFactory
3569:                        .createNew("java.lang.NoClassDefFoundError"));
3570:                il.append(new DUP());
3571:                il.append(new ALOAD(1));
3572:                il.append(instructionFactory.createInvoke(
3573:                        "java.lang.Throwable", "getMessage", new ObjectType(
3574:                                "java.lang.String"), new Type[] {},
3575:                        Constants.INVOKEVIRTUAL));
3576:                il.append(instructionFactory.createInvoke(
3577:                        "java.lang.NoClassDefFoundError", "<init>", Type.VOID,
3578:                        new Type[] { new ObjectType("java.lang.String") },
3579:                        Constants.INVOKESPECIAL));
3580:                InstructionHandle varEnd = il.append(new ATHROW());
3581:                methodGen.addLocalVariable("x1", new ObjectType(
3582:                        "java.lang.ClassNotFoundException"), varStart, varEnd);
3583:                methodGen.addExceptionHandler(tryStart, tryEnd, handler,
3584:                        new ObjectType("java.lang.ClassNotFoundException"));
3585:                makeSynthetic(methodGen);
3586:                methodGen.setMaxLocals();
3587:                methodGen.setMaxStack();
3588:                Method class$Method = methodGen.getMethod();
3589:                classGen.addMethod(class$Method);
3590:                il.dispose();
3591:                return;
3592:
3593:            }
3594:
3595:            private void rewriteStaticConstructor() {
3596:                Method[] methods = classGen.getMethods();
3597:                for (int k = 0; k < methods.length; k++) {
3598:                    Method m = methods[k];
3599:                    // native and abstract methods don't have any code
3600:                    // so continue with next method
3601:                    if (m.isNative() || m.isAbstract()) {
3602:                        continue;
3603:                    }
3604:                    if (m.getName().equals("<clinit>")) {//is static constructor
3605:                        boolean hasChanges = false;
3606:                        MethodGen mg = new MethodGen(m,
3607:                                classGen.getClassName(), constantPoolGen);
3608:
3609:                        // get the code in form of an InstructionList object
3610:                        InstructionList il = mg.getInstructionList();
3611:                        Instruction ins;
3612:                        InstructionHandle ih = il.getStart();
3613:                        while (ih != null) {
3614:                            ins = ih.getInstruction();
3615:                            if (ins instanceof  LDC) {
3616:                                LDC ldc = (LDC) ins;
3617:                                Constant c = constantPoolGen.getConstantPool()
3618:                                        .getConstant(ldc.getIndex());
3619:                                if (c.getTag() == Constants.CONSTANT_Class) {
3620:                                    hasChanges = true;
3621:                                    String name = constantPoolGen
3622:                                            .getConstantPool()
3623:                                            .getConstantString(ldc.getIndex(),
3624:                                                    Constants.CONSTANT_Class);
3625:
3626:                                    if (!name.startsWith("[")) {
3627:                                        name = "L" + name + ";";
3628:                                    }
3629:
3630:                                    Type type = Type.getType(name);
3631:                                    InstructionList tempIl = pushDotClass(type);
3632:                                    InstructionHandle startTarget = tempIl
3633:                                            .getStart();
3634:                                    InstructionHandle newTarget = tempIl
3635:                                            .getEnd();
3636:                                    il.append(ih, tempIl);
3637:                                    try {
3638:                                        il.delete(ih);
3639:                                    } catch (TargetLostException e) {
3640:                                        InstructionHandle[] targets = e
3641:                                                .getTargets();
3642:                                        for (int i = 0; i < targets.length; i++) {
3643:                                            InstructionTargeter[] targeters = targets[i]
3644:                                                    .getTargeters();
3645:                                            for (int j = 0; j < targeters.length; j++) {
3646:                                                targeters[j].updateTarget(
3647:                                                        targets[i], newTarget);
3648:                                            }
3649:                                        }
3650:                                    }
3651:                                    il.setPositions();
3652:                                    il.update();
3653:                                    // Fix line numbers
3654:                                    LineNumberGen[] numbersGen = mg
3655:                                            .getLineNumbers();
3656:                                    if (numbersGen != null) {
3657:                                        for (int i = 0; i < numbersGen.length; i++) {
3658:                                            LineNumberGen lineNumberGen = numbersGen[i];
3659:                                            if (lineNumberGen
3660:                                                    .containsTarget(newTarget)) {
3661:                                                lineNumberGen
3662:                                                        .setInstruction(startTarget);
3663:                                            }
3664:                                        }
3665:                                    }
3666:
3667:                                    ih = il.getStart();
3668:
3669:                                }
3670:                            }
3671:                            ih = ih.getNext();
3672:                        }
3673:                        if (hasChanges) {
3674:                            il.setPositions();
3675:                            il.update();
3676:                            mg.removeNOPs();
3677:                            mg.setMaxLocals();
3678:                            mg.setMaxStack();
3679:                            classGen.replaceMethod(m, mg.getMethod());
3680:                        }
3681:                    }
3682:                }
3683:            }
3684:
3685:            /**
3686:             * Returns the static constructor if it exists, else it creates it and then
3687:             * returns it.
3688:             *
3689:             */
3690:            private Method getStaticConstructor() {
3691:                Method[] methods = classGen.getMethods();
3692:                for (int i = 0; i < methods.length; i++) {
3693:                    Method m = methods[i];
3694:                    // native and abstract methods don't have any code
3695:                    // so continue with next method
3696:                    if (m.isNative() || m.isAbstract()) {
3697:                        continue;
3698:                    }
3699:                    if (m.getName().equals("<clinit>")) {//is static constructor
3700:                        return m;
3701:                    }
3702:                }
3703:                // there is no static constructor so make one
3704:                InstructionList il = new InstructionList();
3705:                MethodGen methodGen = new MethodGen(Constants.ACC_STATIC,
3706:                        Type.VOID, null, null, "<clinit>", classGen
3707:                                .getClassName(), il, constantPoolGen);
3708:
3709:                il.append(new RETURN());
3710:                //        makeSynthetic(methodGen);
3711:                methodGen.setMaxLocals();
3712:                methodGen.setMaxStack();
3713:                Method clMethod = methodGen.getMethod();
3714:                classGen.addMethod(clMethod);
3715:                il.dispose();
3716:                return clMethod;
3717:
3718:            }
3719:
3720:            /**
3721:             * Adds field jdoStateManager it does not need to be initializes.
3722:             *
3723:             */
3724:            private void addJdoStateManager() {
3725:                //this field only gets added to the least-derived persistence capable class.
3726:                if (classInfo.getPersistenceCapableSuperclass() == null) {
3727:                    FieldGen fieldGen = new FieldGen(Constants.ACC_PROTECTED
3728:                            | Constants.ACC_TRANSIENT, SM_OBJECT_TYPE,
3729:                            "jdoStateManager", constantPoolGen);
3730:                    makeSynthetic(fieldGen);
3731:                    classGen.addField(fieldGen.getField());
3732:                }
3733:            }
3734:
3735:            /**
3736:             * Adds field jdoFlags in the top most persistence capable super class and initializes
3737:             * it to javax.jdo.spi.PersistenceCapable.READ_WRITE_OK.
3738:             * The initialization needs to occur in all the constructors as it is with all class fields.
3739:             *
3740:             */
3741:            private void addJdoFlags() {
3742:                //this field only gets added to the least-derived persistence capable class.
3743:                if (classInfo.getPersistenceCapableSuperclass() == null) {
3744:                    FieldGen fieldGen = new FieldGen(Constants.ACC_PROTECTED
3745:                            | Constants.ACC_TRANSIENT, Type.BYTE, "jdoFlags",
3746:                            constantPoolGen);
3747:                    makeSynthetic(fieldGen);
3748:                    classGen.addField(fieldGen.getField());
3749:                    List constructors = getInitilizationConstructors();//very important to only get these constructors
3750:                    Iterator iter = constructors.iterator();
3751:                    while (iter.hasNext()) {
3752:                        Method constructor = (Method) iter.next();
3753:                        MethodGen mg = new MethodGen(constructor, classInfo
3754:                                .getClassName(), constantPoolGen);
3755:
3756:                        InstructionList il = mg.getInstructionList();
3757:                        // get the first instruction
3758:                        InstructionHandle ih = il.getStart();
3759:                        while (ih != null) {
3760:                            Instruction ins = ih.getInstruction();
3761:
3762:                            if (ins instanceof  INVOKESPECIAL) {// found the INVOKESPECIAL call
3763:                                InstructionList tmpIl = new InstructionList();
3764:                                tmpIl.append(new ALOAD(0));
3765:                                tmpIl.append(new ICONST(0));//javax.jdo.spi.PersistenceCapable.READ_WRITE_OK
3766:                                tmpIl.append(instructionFactory.createPutField(
3767:                                        classInfo.getClassName(), "jdoFlags",
3768:                                        Type.BYTE));
3769:                                il.append(ih, tmpIl);
3770:                                il.setPositions();
3771:                                il.update();
3772:
3773:                                mg.setInstructionList(il);
3774:                                mg.setMaxLocals();
3775:                                mg.setMaxStack();
3776:                                classGen.replaceMethod(constructor, mg
3777:                                        .getMethod());
3778:                                il.dispose();
3779:                                break;
3780:                            }
3781:                            // next instruction
3782:                            ih = ih.getNext();
3783:                        }
3784:                    }
3785:                }
3786:            }
3787:
3788:            /**
3789:             * Gets a list of all the constructors methods
3790:             */
3791:            private List getConstructors() {
3792:                ArrayList constuctors = new ArrayList();
3793:                Method[] methods = classGen.getMethods();
3794:                for (int i = 0; i < methods.length; i++) {
3795:                    Method m = methods[i];
3796:                    // native and abstract methods don't have any code
3797:                    // so continue with next method
3798:                    if (m.isNative() || m.isAbstract()) {
3799:                        continue;
3800:                    }
3801:                    if (m.getName().equals("<init>")) {//is constructor
3802:                        constuctors.add(m);
3803:                    }
3804:                }
3805:                return constuctors;
3806:            }
3807:
3808:            /**
3809:             * Sets a default constructor if it needs one or changes the default
3810:             * constructor's scope if needed.
3811:             */
3812:            private void setDefaultConstructor() {
3813:                //        if (classGen.isAbstract())return;
3814:                boolean setDefautConstructor = true;
3815:                Method[] methods = classGen.getMethods();
3816:                for (int i = 0; i < methods.length; i++) {
3817:                    Method m = methods[i];
3818:                    // native and abstract methods don't have any code
3819:                    // so continue with next method
3820:                    if (m.isNative() || m.isAbstract()) {
3821:                        continue;
3822:                    }
3823:
3824:                    if (m.getName().equals("<init>")) { //is constructor
3825:                        if (m.getSignature().equals("()V")) { //is no args constructor
3826:                        //                  if (m.isPublic() || m.isProtected()){   //is public or protected
3827:                            if (m.isPublic()) {
3828:                                setDefautConstructor = false; //there is a default constructor with the right access
3829:                            } else { //there is a default constructor but access is wrong
3830:                                m.isPublic(true);
3831:                                m.isProtected(false); //change access to protected
3832:                                m.isPrivate(false); //take away private access
3833:                                setDefautConstructor = false; //now there is a default constructor with the right access
3834:                            }
3835:                        }
3836:                    }
3837:                }
3838:                if (setDefautConstructor) {
3839:                    InstructionList il = new InstructionList();
3840:                    il.append(InstructionConstants.THIS); // Push `this'
3841:                    il.append(new INVOKESPECIAL(constantPoolGen.addMethodref(
3842:                            classGen.getSuperclassName(), "<init>", "()V")));
3843:                    il.append(InstructionConstants.RETURN);
3844:
3845:                    MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC, // todo this is not to spec it should be protected
3846:                            Type.VOID, Type.NO_ARGS, null, "<init>", classGen
3847:                                    .getClassName(), il, constantPoolGen);
3848:                    methodGen.setMaxLocals();
3849:                    methodGen.setMaxStack();
3850:
3851:                    classGen.addMethod(methodGen.getMethod());
3852:                    didWeAddADefaultConstructor = true;
3853:                    //            classGen.addEmptyConstructor(Constants.ACC_PUBLIC);// todo this is not to spec it should be protected
3854:                    // If initialization of user-declared field are required use this method
3855:                    //createDefaultInitializationConstructor();
3856:                }
3857:            }
3858:
3859:            /**
3860:             * Gets a list of all the initilization constructors methods
3861:             */
3862:            private List getInitilizationConstructors() {
3863:                ArrayList initConst = new ArrayList();
3864:                List list = getConstructors();
3865:                Iterator iter = list.iterator();
3866:                while (iter.hasNext()) {
3867:                    Method m = (Method) iter.next();
3868:
3869:                    MethodGen mg = new MethodGen(m, classGen.getClassName(),
3870:                            constantPoolGen);
3871:
3872:                    // get the code in form of an InstructionList object
3873:                    InstructionList il = mg.getInstructionList();
3874:
3875:                    // get the first instruction
3876:                    InstructionHandle ih = il.getStart();
3877:                    while (ih != null) {
3878:                        Instruction ins = ih.getInstruction();
3879:                        if (ins.getClass().getName().equals(invokeSpecial)) {
3880:                            INVOKESPECIAL is = (INVOKESPECIAL) ins;
3881:                            if (is.getClassName(constantPoolGen).equals(
3882:                                    classGen.getSuperclassName())
3883:                                    && is.getMethodName(constantPoolGen)
3884:                                            .equals("<init>")) {
3885:                                initConst.add(m);
3886:                            }
3887:                        }
3888:                        // next instruction
3889:                        ih = ih.getNext();
3890:                    }
3891:                }
3892:                return initConst;
3893:            }
3894:
3895:            /**
3896:             * this method is not needed yet.
3897:             */
3898:            //    private void createDefaultInitializationConstructor(){
3899:            //        List constructors = getInitilizationConstructors();
3900:            //        Iterator iter = constructors.iterator();
3901:            //        boolean wasGen = false;
3902:            //        while (iter.hasNext()){
3903:            //            Method m = (Method)iter.next();
3904:            //            MethodGen mg = new MethodGen(m, classInfo.getClassName() ,constantPoolGen);
3905:            //            LineNumberGen[] lineNumberGen = mg.getLineNumbers();
3906:            //            int firstLine = 0;
3907:            //            int nextLine = 10000;
3908:            //            int nextOffSet = 0;
3909:            //            InstructionHandle fromIH = null;
3910:            //            for (int i = 0; i < lineNumberGen.length ; i++){
3911:            //                int sourceLine = lineNumberGen[i].getSourceLine();
3912:            //                if (lineNumberGen[i].getLineNumber().getStartPC() == 0){
3913:            //                    firstLine = lineNumberGen[i].getSourceLine();
3914:            //                }
3915:            //
3916:            //                if (sourceLine > firstLine && sourceLine < nextLine){
3917:            //                    if (lineNumberGen[i].getInstruction().getInstruction() instanceof RETURN) {
3918:            //                    } else {
3919:            //                        fromIH = lineNumberGen[i].getInstruction();
3920:            //                        nextLine = sourceLine;
3921:            //                        nextOffSet = lineNumberGen[i].getLineNumber().getStartPC();
3922:            //                    }
3923:            //                }
3924:            //            }
3925:            //
3926:            //            if (nextOffSet > 5){
3927:            //                InstructionList il = mg.getInstructionList();
3928:            //                InstructionHandle toIH = il.getEnd().getPrev();
3929:            //                try{
3930:            //                    if (!fromIH.equals(il.getEnd().getPrev())){
3931:            //                        il.delete(fromIH,il.getEnd().getPrev());
3932:            //                    }
3933:            //                } catch (TargetLostException e){
3934:            //                    InstructionHandle[] targets = e.getTargets();
3935:            //                    for (int i = 0; i < targets.length ; i++){
3936:            //                        InstructionTargeter[] targeters = targets[i].getTargeters();
3937:            //                        for (int j = 0; j < targeters.length ; j++){
3938:            //                            targeters[j].updateTarget(targets[i], il.getEnd());
3939:            //                        }
3940:            //                    }
3941:            //                }
3942:            //
3943:            //                MethodGen newCons = new MethodGen(  Constants.ACC_PROTECTED,
3944:            //                        Type.VOID,
3945:            //                        new Type[]{},
3946:            //                        null,
3947:            //                        "<init>",
3948:            //                        classInfo.getClassName(),
3949:            //                        il,
3950:            //                        constantPoolGen);
3951:            //                newCons.getMaxLocals();
3952:            //                newCons.getMaxStack();
3953:            //                classGen.addMethod(newCons.getMethod());
3954:            //                wasGen = true;
3955:            //                break;
3956:            //            }
3957:            //        }
3958:            //        if (!wasGen){
3959:            //            classGen.addEmptyConstructor(Constants.ACC_PROTECTED);
3960:            //        }
3961:            //    }
3962:
3963:            /**
3964:             * All class variables i.e. String.class has a static variable called
3965:             * class$java$lang$String of type java.lang.Class, this method creates it if
3966:             * it does not exist.
3967:             *
3968:             * @param type
3969:             * @return String fieldName i.e. class$java$lang$String
3970:             */
3971:            private InstructionList pushDotClass(Type type) {
3972:                InstructionList il = new InstructionList();
3973:                String signature = type.getSignature();
3974:                String fieldName = null;
3975:                String tempFieldName = null;
3976:                String loadName = null;
3977:
3978:                if (signature.startsWith("[")) {
3979:                    tempFieldName = ("array" + signature).replace('/', '$');
3980:                    tempFieldName = tempFieldName.replace('[', '$');
3981:                    fieldName = (tempFieldName.replace(';', ' ')).trim();
3982:                    loadName = signature.replace('/', '.');
3983:                } else {
3984:                    tempFieldName = ("class/" + signature).replace('/', '$');
3985:                    fieldName = (tempFieldName.replace(';', ' ')).trim();
3986:                    loadName = type.toString();
3987:                }
3988:
3989:                il.append(instructionFactory.createGetStatic(classGen
3990:                        .getClassName(), fieldName, new ObjectType(
3991:                        "java.lang.Class")));
3992:                IFNONNULL ifnonnull = new IFNONNULL(null);
3993:                il.append(ifnonnull);
3994:                il.append(new PUSH(constantPoolGen, loadName));
3995:                il.append(instructionFactory.createInvoke(classGen
3996:                        .getClassName(), "class$", new ObjectType(
3997:                        "java.lang.Class"), new Type[] { Type.STRING },
3998:                        Constants.INVOKESTATIC));
3999:                il.append(new DUP());
4000:                il.append(instructionFactory.createPutStatic(classGen
4001:                        .getClassName(), fieldName, new ObjectType(
4002:                        "java.lang.Class")));
4003:                GOTO aGoto = new GOTO(null);
4004:                il.append(aGoto);
4005:                InstructionHandle getStaticHandle = il
4006:                        .append(instructionFactory.createGetStatic(classGen
4007:                                .getClassName(), fieldName, new ObjectType(
4008:                                "java.lang.Class")));
4009:                ifnonnull.setTarget(getStaticHandle);
4010:                InstructionHandle lastHandle = il.append(new NOP());
4011:                aGoto.setTarget(lastHandle);
4012:
4013:                setClass$();
4014:                Field[] fields = classGen.getFields();
4015:                for (int i = 0; i < fields.length; i++) {
4016:                    Field f = fields[i];
4017:                    if (f.getName().equals(fieldName)) {
4018:                        return il;
4019:                    }
4020:                }
4021:                FieldGen fieldGen = new FieldGen(Constants.ACC_STATIC
4022:                        | Constants.ACC_PRIVATE, new ObjectType(
4023:                        "java.lang.Class"), fieldName, constantPoolGen);
4024:                classGen.addField(fieldGen.getField());
4025:                return il;
4026:
4027:            }
4028:
4029:            /**
4030:             * Compute the JVM signature for the class.
4031:             */
4032:            static String getSignature(Class clazz) {
4033:                String type = null;
4034:                if (clazz.isArray()) {
4035:                    Class cl = clazz;
4036:                    int dimensions = 0;
4037:                    while (cl.isArray()) {
4038:                        dimensions++;
4039:                        cl = cl.getComponentType();
4040:                    }
4041:                    StringBuffer sb = new StringBuffer();
4042:                    for (int i = 0; i < dimensions; i++) {
4043:                        sb.append("[");
4044:                    }
4045:                    sb.append(getSignature(cl));
4046:                    type = sb.toString();
4047:                } else if (clazz.isPrimitive()) {
4048:                    if (clazz == Integer.TYPE) {
4049:                        type = "I";
4050:                    } else if (clazz == Byte.TYPE) {
4051:                        type = "B";
4052:                    } else if (clazz == Long.TYPE) {
4053:                        type = "J";
4054:                    } else if (clazz == Float.TYPE) {
4055:                        type = "F";
4056:                    } else if (clazz == Double.TYPE) {
4057:                        type = "D";
4058:                    } else if (clazz == Short.TYPE) {
4059:                        type = "S";
4060:                    } else if (clazz == Character.TYPE) {
4061:                        type = "C";
4062:                    } else if (clazz == Boolean.TYPE) {
4063:                        type = "Z";
4064:                    } else if (clazz == Void.TYPE) {
4065:                        type = "V";
4066:                    }
4067:                } else {
4068:                    type = "L" + clazz.getName().replace('.', '/') + ";";
4069:                }
4070:                return type;
4071:            }
4072:
4073:            // all the detach suff goes here
4074:
4075:            private void addIsDirtyInt(String methodName) {
4076:
4077:                InstructionList il = new InstructionList();
4078:                MethodGen methodGen = new MethodGen(
4079:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4080:                        Type.BOOLEAN, new Type[] { Type.INT },
4081:                        new String[] { "fieldNo" }, methodName, classGen
4082:                                .getClassName(), il, constantPoolGen);
4083:
4084:                int num = getNumOfControlFields();
4085:                if (num == 1) {
4086:                    il.append(new ALOAD(0));
4087:                    il.append(instructionFactory.createGetField(classGen
4088:                            .getClassName(), getDirtyFieldName(0), Type.INT));
4089:                    il.append(new ICONST(1));
4090:                    il.append(new ILOAD(1));
4091:                    il.append(new ISHL());
4092:                    il.append(new IAND());
4093:                    IFNE ifne = new IFNE(null);
4094:                    il.append(ifne);
4095:                    il.append(new ICONST(0));
4096:                    il.append(new IRETURN());
4097:                    InstructionHandle handle = il.append(new ICONST(1));
4098:                    ifne.setTarget(handle);
4099:                    il.append(new IRETURN());
4100:
4101:                } else {
4102:                    il.append(new ILOAD(1));
4103:                    for (int i = 0; i < num; i++) {
4104:                        il.append(new PUSH(constantPoolGen, ((32 * i) + 32)));
4105:                        IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
4106:                        il.append(if_icmpge);
4107:                        il.append(new ALOAD(0));
4108:                        il.append(instructionFactory
4109:                                .createGetField(classGen.getClassName(),
4110:                                        getDirtyFieldName(i), Type.INT));
4111:                        il.append(new ICONST(1));
4112:                        il.append(new ILOAD(1));
4113:                        il.append(new ISHL());
4114:                        il.append(new IAND());
4115:                        IFEQ ifeq = new IFEQ(null);
4116:                        il.append(ifeq);
4117:                        il.append(new ICONST(1));
4118:                        GOTO aGoto = new GOTO(null);
4119:                        il.append(aGoto);
4120:                        InstructionHandle iconst0Handle = il.append(new ICONST(
4121:                                0));
4122:                        ifeq.setTarget(iconst0Handle);
4123:                        InstructionHandle gotoHandle = il.append(new IRETURN());
4124:                        aGoto.setTarget(gotoHandle);
4125:                        InstructionHandle iload1Handle = il
4126:                                .append(new ILOAD(1));
4127:                        if_icmpge.setTarget(iload1Handle);
4128:                    }
4129:                    // take last one and replace with ICONST_0
4130:                    InstructionHandle lastHandle = il.getEnd();
4131:                    InstructionHandle replaceHandle = il.append(new ICONST(0));
4132:                    try {
4133:                        il.delete(lastHandle);
4134:                    } catch (TargetLostException e) {
4135:                        InstructionHandle[] targets = e.getTargets();
4136:                        for (int i = 0; i < targets.length; i++) {
4137:                            InstructionTargeter[] targeters = targets[i]
4138:                                    .getTargeters();
4139:                            for (int j = 0; j < targeters.length; j++) {
4140:                                targeters[j].updateTarget(targets[i],
4141:                                        replaceHandle);
4142:                            }
4143:                        }
4144:                    }
4145:                    il.append(new IRETURN());
4146:                }
4147:
4148:                methodGen.setMaxLocals();
4149:                methodGen.setMaxStack();
4150:                classGen.addMethod(methodGen.getMethod());
4151:                il.dispose();
4152:            }
4153:
4154:            private void addMakeDirtyInt(String methodName) {
4155:
4156:                InstructionList il = new InstructionList();
4157:                MethodGen methodGen = new MethodGen(
4158:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4159:                        Type.VOID, new Type[] { Type.INT },
4160:                        new String[] { "fieldNo" }, methodName, classGen
4161:                                .getClassName(), il, constantPoolGen);
4162:
4163:                int num = getNumOfControlFields();
4164:                if (num == 1) {
4165:                    il.append(new ALOAD(0));
4166:                    il.append(new DUP());
4167:                    il.append(instructionFactory.createGetField(classGen
4168:                            .getClassName(), getDirtyFieldName(0), Type.INT));
4169:
4170:                    il.append(new ICONST(1));
4171:                    il.append(new ILOAD(1));
4172:                    il.append(new ISHL());
4173:                    il.append(new IOR());
4174:                    il.append(instructionFactory.createPutField(classGen
4175:                            .getClassName(), getDirtyFieldName(0), Type.INT));
4176:                    il.append(new RETURN());
4177:                } else {
4178:                    il.append(new ILOAD(1));
4179:                    for (int i = 0; i < num; i++) {
4180:                        il.append(new PUSH(constantPoolGen, ((32 * i) + 32)));
4181:                        IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
4182:                        il.append(if_icmpge);
4183:
4184:                        il.append(new ALOAD(0));
4185:                        il.append(new DUP());
4186:                        il.append(instructionFactory
4187:                                .createGetField(classGen.getClassName(),
4188:                                        getDirtyFieldName(i), Type.INT));
4189:                        il.append(new ICONST(1));
4190:                        il.append(new ILOAD(1));
4191:                        il.append(new ISHL());
4192:                        il.append(new IOR());
4193:                        il.append(instructionFactory
4194:                                .createPutField(classGen.getClassName(),
4195:                                        getDirtyFieldName(i), Type.INT));
4196:                        if (i != (num - 1)) {
4197:                            il.append(new RETURN());
4198:                            InstructionHandle iloadHandle = il
4199:                                    .append(new ILOAD(1));
4200:                            if_icmpge.setTarget(iloadHandle);
4201:                        } else {
4202:                            InstructionHandle returnHandle = il
4203:                                    .append(new RETURN()); // last return
4204:                            if_icmpge.setTarget(returnHandle);
4205:                        }
4206:                    }
4207:
4208:                }
4209:                methodGen.setMaxLocals();
4210:                methodGen.setMaxStack();
4211:                classGen.addMethod(methodGen.getMethod());
4212:                il.dispose();
4213:            }
4214:
4215:            private void addMakeDirtyString(String methodName) {
4216:
4217:                InstructionList il = new InstructionList();
4218:                MethodGen methodGen = new MethodGen(Constants.ACC_PUBLIC,
4219:                        Type.VOID, new Type[] { Type.STRING },
4220:                        new String[] { "fieldName" }, methodName, classGen
4221:                                .getClassName(), il, constantPoolGen);
4222:
4223:                ArrayList list = new ArrayList(fieldSet);
4224:                Collections.sort(list);
4225:                Iterator iter = list.iterator();
4226:                ArrayList gotos = new ArrayList();
4227:
4228:                while (iter.hasNext()) {
4229:                    FieldInfo info = (FieldInfo) iter.next();
4230:                    String fieldname = info.getFieldName();
4231:                    int fieldNo = info.getFieldNo();
4232:
4233:                    il.append(new PUSH(constantPoolGen, fieldname));
4234:                    il.append(new ALOAD(1));
4235:                    il.append(instructionFactory
4236:                            .createInvoke("java.lang.String", "equals",
4237:                                    Type.BOOLEAN, new Type[] { Type.OBJECT },
4238:                                    Constants.INVOKEVIRTUAL));
4239:                    IFEQ ifeq = new IFEQ(null); //17
4240:                    il.append(ifeq);
4241:                    il.append(new ALOAD(0));
4242:                    il.append(new PUSH(constantPoolGen, fieldNo));
4243:                    il.append(instructionFactory.createInvoke(classGen
4244:                            .getClassName(), "versantMakeDirty", Type.VOID,
4245:                            new Type[] { Type.INT }, Constants.INVOKEVIRTUAL));
4246:                    GOTO aGoto = new GOTO(null);
4247:                    gotos.add(aGoto);
4248:                    il.append(aGoto);
4249:                    InstructionHandle nopHandle = il.append(new NOP());
4250:                    ifeq.setTarget(nopHandle);
4251:                }
4252:                // now we do the else part
4253:                if (classInfo.getPersistenceCapableSuperclass() != null) {
4254:                    il.append(new ALOAD(0));
4255:                    il.append(new ALOAD(1));
4256:                    il.append(instructionFactory
4257:                            .createInvoke(classInfo
4258:                                    .getPersistenceCapableSuperclass(),
4259:                                    "versantMakeDirty", Type.VOID,
4260:                                    new Type[] { Type.STRING },
4261:                                    Constants.INVOKESPECIAL));
4262:                } else {
4263:                    // todo throw exception or something
4264:                }
4265:
4266:                InstructionHandle lastHandle = il.append(new RETURN());
4267:                for (Iterator iterator = gotos.iterator(); iterator.hasNext();) {
4268:                    GOTO aGoto = (GOTO) iterator.next();
4269:                    aGoto.setTarget(lastHandle);
4270:                }
4271:                methodGen.removeNOPs();
4272:                methodGen.setMaxLocals();
4273:                methodGen.setMaxStack();
4274:                classGen.addMethod(methodGen.getMethod());
4275:                il.dispose();
4276:            }
4277:
4278:            private void addIsDirty(String methodName) {
4279:
4280:                InstructionList il = new InstructionList();
4281:                MethodGen methodGen = new MethodGen(
4282:                        Constants.ACC_PUBLIC, //| NEW Constants.ACC_FINAL,
4283:                        Type.BOOLEAN, new Type[] {}, new String[] {},
4284:                        methodName, classGen.getClassName(), il,
4285:                        constantPoolGen);
4286:
4287:                ArrayList list = new ArrayList();
4288:                int num = getNumOfControlFields();
4289:                for (int i = 0; i < num; i++) {
4290:                    il.append(new ALOAD(0));
4291:                    il.append(instructionFactory.createGetField(classGen
4292:                            .getClassName(), getDirtyFieldName(i), Type.INT));
4293:                    IFNE ifne = new IFNE(null);
4294:                    list.add(ifne);
4295:                    il.append(ifne);
4296:                }
4297:                il.append(new ICONST(0));
4298:                il.append(new IRETURN());
4299:                InstructionHandle ifne_handle = il.append(new ICONST(1));
4300:                for (Iterator iter = list.iterator(); iter.hasNext();) {
4301:                    IFNE ifne = (IFNE) iter.next();
4302:                    ifne.setTarget(ifne_handle);
4303:                }
4304:                il.append(new IRETURN());
4305:
4306:                methodGen.setMaxLocals();
4307:                methodGen.setMaxStack();
4308:                classGen.addMethod(methodGen.getMethod());
4309:                il.dispose();
4310:            }
4311:
4312:            private void addIsLoadedInt(String methodName) {
4313:
4314:                InstructionList il = new InstructionList();
4315:                MethodGen methodGen = new MethodGen(
4316:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4317:                        Type.BOOLEAN, new Type[] { Type.INT },
4318:                        new String[] { "fieldNo" }, methodName, classGen
4319:                                .getClassName(), il, constantPoolGen);
4320:
4321:                int num = getNumOfControlFields();
4322:                if (num == 1) {
4323:                    il.append(new ALOAD(0));
4324:                    il.append(instructionFactory.createGetField(classGen
4325:                            .getClassName(), getLoadedFieldName(0), Type.INT));
4326:                    il.append(new ICONST(1));
4327:                    il.append(new ILOAD(1));
4328:                    il.append(new ISHL());
4329:                    il.append(new IAND());
4330:                    IFNE ifne = new IFNE(null);
4331:                    il.append(ifne);
4332:                    il.append(new ICONST(0));
4333:                    il.append(new IRETURN());
4334:                    InstructionHandle handle = il.append(new ICONST(1));
4335:                    ifne.setTarget(handle);
4336:                    il.append(new IRETURN());
4337:
4338:                } else {
4339:                    il.append(new ILOAD(1));
4340:                    for (int i = 0; i < num; i++) {
4341:                        il.append(new PUSH(constantPoolGen, ((32 * i) + 32)));
4342:                        IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
4343:                        il.append(if_icmpge);
4344:                        il.append(new ALOAD(0));
4345:                        il.append(instructionFactory.createGetField(classGen
4346:                                .getClassName(), getLoadedFieldName(i),
4347:                                Type.INT));
4348:                        il.append(new ICONST(1));
4349:                        il.append(new ILOAD(1));
4350:                        il.append(new ISHL());
4351:                        il.append(new IAND());
4352:                        IFEQ ifeq = new IFEQ(null);
4353:                        il.append(ifeq);
4354:                        il.append(new ICONST(1));
4355:                        GOTO aGoto = new GOTO(null);
4356:                        il.append(aGoto);
4357:                        InstructionHandle iconst0Handle = il.append(new ICONST(
4358:                                0));
4359:                        ifeq.setTarget(iconst0Handle);
4360:                        InstructionHandle gotoHandle = il.append(new IRETURN());
4361:                        aGoto.setTarget(gotoHandle);
4362:                        InstructionHandle iload1Handle = il
4363:                                .append(new ILOAD(1));
4364:                        if_icmpge.setTarget(iload1Handle);
4365:                    }
4366:                    // take last one and replace with ICONST_0
4367:                    InstructionHandle lastHandle = il.getEnd();
4368:                    InstructionHandle replaceHandle = il.append(new ICONST(0));
4369:                    try {
4370:                        il.delete(lastHandle);
4371:                    } catch (TargetLostException e) {
4372:                        InstructionHandle[] targets = e.getTargets();
4373:                        for (int i = 0; i < targets.length; i++) {
4374:                            InstructionTargeter[] targeters = targets[i]
4375:                                    .getTargeters();
4376:                            for (int j = 0; j < targeters.length; j++) {
4377:                                targeters[j].updateTarget(targets[i],
4378:                                        replaceHandle);
4379:                            }
4380:                        }
4381:                    }
4382:                    il.append(new IRETURN());
4383:                }
4384:
4385:                methodGen.setMaxLocals();
4386:                methodGen.setMaxStack();
4387:                classGen.addMethod(methodGen.getMethod());
4388:                il.dispose();
4389:            }
4390:
4391:            private void addSetLoadedInt(String methodName) {
4392:
4393:                InstructionList il = new InstructionList();
4394:                MethodGen methodGen = new MethodGen(
4395:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4396:                        Type.VOID, new Type[] { Type.INT },
4397:                        new String[] { "fieldNo" }, methodName, classGen
4398:                                .getClassName(), il, constantPoolGen);
4399:
4400:                int num = getNumOfControlFields();
4401:                if (num == 1) {
4402:                    il.append(new ALOAD(0));
4403:                    il.append(new DUP());
4404:                    il.append(instructionFactory.createGetField(classGen
4405:                            .getClassName(), getLoadedFieldName(0), Type.INT));
4406:
4407:                    il.append(new ICONST(1));
4408:                    il.append(new ILOAD(1));
4409:                    il.append(new ISHL());
4410:                    il.append(new IOR());
4411:                    il.append(instructionFactory.createPutField(classGen
4412:                            .getClassName(), getLoadedFieldName(0), Type.INT));
4413:                    il.append(new RETURN());
4414:                } else {
4415:                    il.append(new ILOAD(1));
4416:                    for (int i = 0; i < num; i++) {
4417:                        il.append(new PUSH(constantPoolGen, ((32 * i) + 32)));
4418:                        IF_ICMPGE if_icmpge = new IF_ICMPGE(null);
4419:                        il.append(if_icmpge);
4420:
4421:                        il.append(new ALOAD(0));
4422:                        il.append(new DUP());
4423:                        il.append(instructionFactory.createGetField(classGen
4424:                                .getClassName(), getLoadedFieldName(i),
4425:                                Type.INT));
4426:                        il.append(new ICONST(1));
4427:                        il.append(new ILOAD(1));
4428:                        il.append(new ISHL());
4429:                        il.append(new IOR());
4430:                        il.append(instructionFactory.createPutField(classGen
4431:                                .getClassName(), getLoadedFieldName(i),
4432:                                Type.INT));
4433:                        if (i != (num - 1)) {
4434:                            il.append(new RETURN());
4435:                            InstructionHandle iloadHandle = il
4436:                                    .append(new ILOAD(1));
4437:                            if_icmpge.setTarget(iloadHandle);
4438:                        } else {
4439:                            InstructionHandle returnHandle = il
4440:                                    .append(new RETURN()); // last return
4441:                            if_icmpge.setTarget(returnHandle);
4442:                        }
4443:                    }
4444:
4445:                }
4446:                methodGen.setMaxLocals();
4447:                methodGen.setMaxStack();
4448:                classGen.addMethod(methodGen.getMethod());
4449:                il.dispose();
4450:            }
4451:
4452:            private final int getNumOfControlFields() {
4453:                return (totlalManagedFields / 32) + 1;
4454:            }
4455:
4456:            private final String getDirtyFieldName(int index) {
4457:                return DIRTY_FIELD_NAME + index;
4458:            }
4459:
4460:            private final String getLoadedFieldName(int index) {
4461:                return LOADED_FIELD_NAME + index;
4462:            }
4463:
4464:            private void addFields() {
4465:                int num = getNumOfControlFields();
4466:                for (int i = 0; i < num; i++) {
4467:                    FieldGen fieldGenFilled = new FieldGen(// Added our int LOADED_FIELD_NAME , to see what has been loaded in
4468:                            Constants.ACC_PRIVATE, Type.INT, LOADED_FIELD_NAME
4469:                                    + i, constantPoolGen);
4470:                    makeSynthetic(fieldGenFilled);
4471:                    classGen.addField(fieldGenFilled.getField());
4472:
4473:                    FieldGen fieldGenDirtyFields = new FieldGen(// Added our int DIRTY_FIELD_NAME , to see what is dirty
4474:                            Constants.ACC_PRIVATE, Type.INT, DIRTY_FIELD_NAME
4475:                                    + i, constantPoolGen);
4476:                    makeSynthetic(fieldGenDirtyFields);
4477:                    classGen.addField(fieldGenDirtyFields.getField());
4478:
4479:                }
4480:
4481:                FieldGen fieldGenVersionField = new FieldGen(
4482:                        // Added our Version field
4483:                        Constants.ACC_PRIVATE, Type.OBJECT, VERSION_FIELD_NAME,
4484:                        constantPoolGen);
4485:                makeSynthetic(fieldGenVersionField);
4486:                classGen.addField(fieldGenVersionField.getField());
4487:
4488:                FieldGen fieldGenOIDField = new FieldGen(
4489:                        // Added our OID field
4490:                        Constants.ACC_PRIVATE, Type.OBJECT, OID_FIELD_NAME,
4491:                        constantPoolGen);
4492:                makeSynthetic(fieldGenOIDField);
4493:                classGen.addField(fieldGenOIDField.getField());
4494:            }
4495:
4496:            private void addGetOid(String methodName) {
4497:                InstructionList il = new InstructionList();
4498:                MethodGen methodGen = new MethodGen(
4499:                        Constants.ACC_PUBLIC,// | NEW Constants.ACC_FINAL,
4500:                        Type.OBJECT, new Type[] {}, new String[] {},
4501:                        methodName, classGen.getClassName(), il,
4502:                        constantPoolGen);
4503:
4504:                il.append(new ALOAD(0));
4505:                il.append(instructionFactory.createGetField(classGen
4506:                        .getClassName(), OID_FIELD_NAME, Type.OBJECT));
4507:                il.append(new ARETURN());
4508:
4509:                methodGen.setMaxLocals();
4510:                methodGen.setMaxStack();
4511:                classGen.addMethod(methodGen.getMethod());
4512:                il.dispose();
4513:
4514:            }
4515:
4516:            private void addSetOid(String methodName) {
4517:                InstructionList il = new InstructionList();
4518:                MethodGen methodGen = new MethodGen(
4519:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4520:                        Type.VOID, new Type[] { Type.OBJECT },
4521:                        new String[] { "oid" }, methodName, classGen
4522:                                .getClassName(), il, constantPoolGen);
4523:
4524:                il.append(new ALOAD(0));
4525:                il.append(new ALOAD(1));
4526:                il.append(instructionFactory.createPutField(classGen
4527:                        .getClassName(), OID_FIELD_NAME, Type.OBJECT));
4528:                il.append(new RETURN());
4529:
4530:                methodGen.setMaxLocals();
4531:                methodGen.setMaxStack();
4532:                classGen.addMethod(methodGen.getMethod());
4533:                il.dispose();
4534:            }
4535:
4536:            private void addGetVersion(String methodName) {
4537:                InstructionList il = new InstructionList();
4538:                MethodGen methodGen = new MethodGen(
4539:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4540:                        Type.OBJECT, new Type[] {}, new String[] {},
4541:                        methodName, classGen.getClassName(), il,
4542:                        constantPoolGen);
4543:
4544:                il.append(new ALOAD(0));
4545:                il.append(instructionFactory.createGetField(classGen
4546:                        .getClassName(), VERSION_FIELD_NAME, Type.OBJECT));
4547:                il.append(new ARETURN());
4548:
4549:                methodGen.setMaxLocals();
4550:                methodGen.setMaxStack();
4551:                classGen.addMethod(methodGen.getMethod());
4552:                il.dispose();
4553:
4554:            }
4555:
4556:            private void addGetStateManager(String methodName) {
4557:                InstructionList il = new InstructionList();
4558:                MethodGen methodGen = new MethodGen(
4559:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4560:                        new ObjectType(DETACHED_STATE_MANAGER), new Type[] {},
4561:                        new String[] {}, methodName, classGen.getClassName(),
4562:                        il, constantPoolGen);
4563:
4564:                il.append(new ALOAD(0));
4565:                il.append(instructionFactory.createGetField(classGen
4566:                        .getClassName(), "jdoStateManager", new ObjectType(
4567:                        STATE_MANAGER)));
4568:                il.append(new INSTANCEOF(constantPoolGen
4569:                        .addClass(DETACHED_STATE_MANAGER)));
4570:                IFEQ ifeq = new IFEQ(null);
4571:                il.append(ifeq);
4572:                il.append(new ALOAD(0));
4573:                il.append(instructionFactory.createGetField(classGen
4574:                        .getClassName(), "jdoStateManager", new ObjectType(
4575:                        STATE_MANAGER)));
4576:                il.append(instructionFactory.createCheckCast(new ObjectType(
4577:                        DETACHED_STATE_MANAGER)));
4578:                il.append(new ARETURN());
4579:                InstructionHandle nullHandle = il.append(new ACONST_NULL());
4580:                ifeq.setTarget(nullHandle);
4581:                il.append(new ARETURN());
4582:
4583:                methodGen.setMaxLocals();
4584:                methodGen.setMaxStack();
4585:                classGen.addMethod(methodGen.getMethod());
4586:                il.dispose();
4587:
4588:            }
4589:
4590:            private void addSetVersion(String methodName) {
4591:                InstructionList il = new InstructionList();
4592:                MethodGen methodGen = new MethodGen(
4593:                        Constants.ACC_PUBLIC,//| NEW Constants.ACC_FINAL,
4594:                        Type.VOID, new Type[] { Type.OBJECT },
4595:                        new String[] { "version" }, methodName, classGen
4596:                                .getClassName(), il, constantPoolGen);
4597:
4598:                il.append(new ALOAD(0));
4599:                il.append(new ALOAD(1));
4600:                il.append(instructionFactory.createPutField(classGen
4601:                        .getClassName(), VERSION_FIELD_NAME, Type.OBJECT));
4602:                il.append(new RETURN());
4603:
4604:                methodGen.setMaxLocals();
4605:                methodGen.setMaxStack();
4606:                classGen.addMethod(methodGen.getMethod());
4607:                il.dispose();
4608:            }
4609:
4610:            private void addDetachInterfase() {
4611:                classGen.addInterface(DETACHABLE_INTERFASE);
4612:            }
4613:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.