FileDocCategorySizeDatePackage
MethodBuilder.javaAPI DocGlassfish v2 API99760Fri May 04 22:34:38 BST 2007com.sun.jdo.api.persistence.enhancer.impl

MethodBuilder

public class MethodBuilder extends com.sun.jdo.api.persistence.enhancer.util.Support implements VMConstants
MethodBuilder is a collection of methods which create the persistence methods of a persistent class

Fields Summary
private static final boolean
addSyntheticAttr
private static final boolean
addLineNumberTableAttr
private final Environment
env
Constructors Summary
public MethodBuilder(Environment env)
Constructor.


          
    //@olsen: added constructor
    //@olsen: added parameter 'env' for association
       
        this.env = env;
    
Methods Summary
ClassMethodmakeJDOClearMethod(ClassAction ca, java.lang.String methodName)
Build the jdoClear method for the class. public void jdoClear() { ... }

        //@olsen: added variable
        final String methodSig = "()V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod jdoClearMethod
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        //@olsen: disabled code
        if (false) {
            // reset jdoFlags = LOAD_REQUIRED
            insn = insn.append(Insn.create(opc_aload_0));
            insn = insn.append(Insn.create(opc_iconst_1));
            insn = insn.append(
                Insn.create(opc_putfield,
                            pool.addFieldRef(theClass.asString(),
                                             JDOMetaData.JDOFlagsFieldName,
                                             JDOMetaData.JDOFlagsFieldSig)));
        }

        // iterate over all declared fields of the class
        for (Iterator e = ca.fieldActions(); e.hasNext();) {
            final FieldAction act = (FieldAction)e.next();
            //printFieldAction(act);
            //System.out.println();

            // ignore non-persistent fields
            if (!act.isPersistent())
                continue;

            // ignore primary key fields
            if (act.isPrimaryKey())
                continue;

            //@olsen: disconnect mutable SCOs before clear
            if (act.isMutableSCO()) {
                // fetch field
                insn = insn.append(Insn.create(opc_aload_0));
                insn = insn.append(
                    Insn.create(opc_getfield,
                                pool.addFieldRef(
                                    theClass.asString(),
                                    act.fieldName(),
                                    act.typeDescriptor())));

                // test whether instanceof SCO base type
                // skip disconnecting if == 0
                final ConstClass cc
                    = pool.addClass(JDOMetaData.JDOSecondClassObjectBasePath);
                InsnTarget disconnect = new InsnTarget();
                InsnTarget afterDisconnect = new InsnTarget();
                insn = insn.append(
                    Insn.create(opc_dup));
                insn = insn.append(
                    Insn.create(opc_instanceof,
                                cc));
                insn = insn.append(
                    Insn.create(opc_ifne,
                                disconnect));

                // pop field and skip disconnecting
                insn = insn.append(
                    Insn.create(opc_pop));
                insn = insn.append(
                    Insn.create(opc_goto, afterDisconnect));

                // disconnect SCO field's object
                insn = insn.append(disconnect);

                // cast to SCO base type
                insn = insn.append(
                    Insn.create(opc_checkcast,
                                cc));

                // call method: void unsetOwner();
                final int requiredStack = 1;
                insn = insn.append(
                    new InsnInterfaceInvoke(
                        pool.addInterfaceMethodRef(
                            JDOMetaData.JDOSecondClassObjectBasePath,
                            "unsetOwner",//NOI18N
                            "()V"),//NOI18N
                        requiredStack));

                insn = insn.append(afterDisconnect);
            }

            // get this
            insn = insn.append(Insn.create(opc_aload_0));

            // use the getMethodReturn type to decide how to clear field
            switch(act.getMethodReturn()) {
            case T_DOUBLE:
                insn = insn.append(Insn.create(opc_dconst_0));
                break;
            case T_LONG:
                insn = insn.append(Insn.create(opc_lconst_0));
                break;
            case T_FLOAT:
                insn = insn.append(Insn.create(opc_fconst_0));
                break;
            case T_BOOLEAN:
            case T_CHAR:
            case T_BYTE:
            case T_SHORT:
            case T_INT:
                insn = insn.append(Insn.create(opc_iconst_0));
                break;
            case TC_STRING:
            case TC_OBJECT:
            case TC_INTERFACE:
                insn = insn.append(Insn.create(opc_aconst_null));
                break;
            default:
                throw new InternalError("Unexpected return type");//NOI18N
            }

            // put default value to field
            insn = insn.append(
                Insn.create(opc_putfield,
                            pool.addFieldRef(theClass.asString(),
                                             act.fieldName(),
                                             act.typeDescriptor())));
        }

        // end of method body
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              3, // maxStack
                              1, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoClearMethod;
    
ClassMethodmakeJDOClone(ClassAction ca, java.lang.String methodName)
Build the clone method for the class.

        //@olsen: added variable
        final String methodSig = "()Ljava/lang/Object;";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ClassFile cFile = ca.classFile();
        final ConstantPool pool = cFile.pool();
        final ConstClass theClass = cFile.className();
        final ConstClass superClass = cFile.superName();

        final AttributeVector methodAttrs = new AttributeVector();
        //@olsen: fixed bug: changed ACCProtected to ACCPublic to allow for
        //        an inherited method clone() to be public!
        //@olsen: removed ACCSynchronized flag
        final ClassMethod cloneMethod
            = new ClassMethod(ACCPublic, //|ACCSynchronized,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

//@olsen: disabled feature
/*
        //   if (jdoFlags < 0)
        //     Implementation.fetch(this);

        InsnTarget cloneStart = new InsnTarget();

        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(opc_getfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOFlagsFieldName,
                                         JDOMetaData.JDOFlagsFieldSig)));
        insn = insn.append(Insn.create(opc_ifge, cloneStart));

        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(opc_invokestatic,
                        pool.addMethodRef("com/sun/forte4j/persistence/internal/Implementation", "fetch",
                                          "(" + JDOMetaData.JDOPersistenceCapableSig + ")V")));

        insn = insn.append(cloneStart);
*/

        // THISCLASS newObject = (THISCLASS) super.clone();
        {
            insn = insn.append(Insn.create(opc_aload_0));
            insn = insn.append(
                Insn.create(opc_invokespecial,
                            pool.addMethodRef(superClass.asString(),
//                            pool.addMethodRef("java/lang/Object",
                                              methodName,
                                              methodSig)));

            // add cast to the appropriate type
            insn = insn.append(Insn.create(opc_checkcast, theClass));
        }

//@olsen: disabled feature
/*
        if (ca.getNeedsJDOStateManagerMethods()) {
*/
        // newObject.jdoStateManager = null;
        if (false)
        {
            insn = insn.append(Insn.create(opc_dup));
            insn = insn.append(Insn.create(opc_aconst_null));
            insn = insn.append(
                Insn.create(
                    opc_putfield,
                    pool.addFieldRef(theClass.asString(),
                                     JDOMetaData.JDOStateManagerFieldName,
                                     JDOMetaData.JDOStateManagerFieldSig)));
        }

//@olsen: disabled feature
/*
        if (ca.getNeedsJDOFlagsMethods()) {
*/
        // newObject.jdoFlags = 0;
        if (false)
        {
            insn = insn.append(Insn.create(opc_dup));
            insn = insn.append(Insn.create(opc_iconst_0));
            insn = insn.append(
                Insn.create(opc_putfield,
                            pool.addFieldRef(theClass.asString(),
                                             JDOMetaData.JDOFlagsFieldName,
                                             JDOMetaData.JDOFlagsFieldSig)));
        }

        // return newObject;

        // end of method body
        insn = insn.append(Insn.create(opc_areturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              //@olsen: updated maxLocals
                              1, //3, //3, // maxStack
                              1, //2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        methodAttrs.addElement(
            new ExceptionsAttribute(
                pool.addUtf8(ExceptionsAttribute.expectedAttrName),
                pool.addClass("java/lang/CloneNotSupportedException")));//NOI18N

        return cloneMethod;
    
ClassMethodmakeJDOConstructor(ClassAction ca, java.lang.String methodName)
Build the jdoGetJDOConstructor method for the class. public (StateManager sm) { this.jdoFlags = 1; this.jdoStateManager = sm; }

        //@olsen: added variable
        final String methodSig = "(" + JDOMetaData.JDOStateManagerSig + ")V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod jdoGetJDOConstructor
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // call the super-class' constructor
        final ConstClass superClass = ca.classFile().superName();
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(opc_invokespecial,
                        pool.addMethodRef(superClass.asString(),
                                          "<init>",//NOI18N
                                          "()V")));//NOI18N

        // put argument value to jdoFlags field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(Insn.create(opc_iconst_1));
        insn = insn.append(
            Insn.create(opc_putfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOFlagsFieldName,
                                         JDOMetaData.JDOFlagsFieldSig)));

        // put argument value to jdoStateManager field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            Insn.create(
                opc_putfield,
                pool.addFieldRef(theClass.asString(),
                                 JDOMetaData.JDOStateManagerFieldName,
                                 JDOMetaData.JDOStateManagerFieldSig)));

        // end of method body
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              2, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetJDOConstructor;
    
ClassMethodmakeJDOGetFieldMethod(ClassAction ca, java.lang.String methodName)
Build the jdoGetField method for the class. public Object jdoGetField(int fieldNumber) { return ... }

        //@olsen: added variable
        final String methodSig = "(I)Ljava/lang/Object;";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod jdoGetFieldMethod
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // get the declared, persistent fields from the JDOMetaData
        final String className = ca.className();
        //@lars: changed getPersistentFields() into getManagedFields()
        final String[] fieldNames
            = env.getJDOMetaData().getManagedFields(className);
        final int nofFields = fieldNames.length;
        //@olsen: added println() for debugging
        if (false) {
            System.out.print("MethodBuilder.makeJDOGetFieldMethod(): "//NOI18N
                             + " declared, persistent fields of class '"//NOI18N
                             + className + "' = {");//NOI18N
            for (int i = 0; i < nofFields; i++)
                System.out.print(" " + fieldNames[i]);//NOI18N
            System.out.println(" }");//NOI18N
        }

        // generate the switch-statement only if more than zero fields
        final InsnTarget defaultOp = new InsnTarget();
        if (nofFields > 0) {
            // get the declared, persistent fields from the class
            final HashMap fieldsByName = new HashMap();
            for (Iterator e = ca.fieldActions(); e.hasNext();) {
                final FieldAction act = (FieldAction)e.next();
                fieldsByName.put(act.fieldName(), act);
            }

            // do the tableswitch on argument
            insn = insn.append(Insn.create(opc_iload_1));
            final int lowOp = 0;
            final InsnTarget[] targetsOp = new InsnTarget[nofFields];
            for (int i = 0; i < nofFields; i++)
                targetsOp[i] = new InsnTarget();
            insn = insn.append(
                new InsnTableSwitch(lowOp, defaultOp, targetsOp));

            // do the case-targets for field accesses
            for (int i = 0; i < nofFields; i++) {
                // target for accessing field [i]
                insn = insn.append(targetsOp[i]);

                final FieldAction act
                    = (FieldAction)fieldsByName.get(fieldNames[i]);
                affirm(act,
                       ("Field '" + fieldNames[i]//NOI18N
                        + "' returned by JDOMetaData is not known by class '"//NOI18N
                        + className + "'."));//NOI18N

                // use the getMethodReturn type to create the wrapper object
                final String wrapperClassName;
                final String wrapperSignature;
                switch(act.getMethodReturn()) {
                case T_DOUBLE:
                    wrapperClassName = "java/lang/Double";//NOI18N
                    wrapperSignature = "(D)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_LONG:
                    wrapperClassName = "java/lang/Long";//NOI18N
                    wrapperSignature = "(J)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_FLOAT:
                    wrapperClassName = "java/lang/Float";//NOI18N
                    wrapperSignature = "(F)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_BOOLEAN:
                    wrapperClassName = "java/lang/Boolean";//NOI18N
                    wrapperSignature = "(Z)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_CHAR:
                    wrapperClassName = "java/lang/Character";//NOI18N
                    wrapperSignature = "(C)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_BYTE:
                    wrapperClassName = "java/lang/Byte";//NOI18N
                    wrapperSignature = "(B)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_SHORT:
                    wrapperClassName = "java/lang/Short";//NOI18N
                    wrapperSignature = "(S)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case T_INT:
                    wrapperClassName = "java/lang/Integer";//NOI18N
                    wrapperSignature = "(I)V";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_new, pool.addClass(wrapperClassName)));
                    insn = insn.append(Insn.create(opc_dup));
                    break;
                case TC_STRING:
                case TC_OBJECT:
                case TC_INTERFACE:
                    wrapperClassName = null;
                    wrapperSignature = null;
                    break;
                default:
                    throw new InternalError("Unexpected return type");//NOI18N
                }

                // fetch this object's field
                insn = insn.append(Insn.create(opc_aload_0));
                insn = insn.append(
                    Insn.create(
                        opc_getfield,
                        pool.addFieldRef(
                            theClass.asString(),
                            act.fieldName(),
                            act.typeDescriptor())));

                // wrap the field value if primitive
                switch(act.getMethodReturn()) {
                case T_DOUBLE:
                case T_LONG:
                case T_FLOAT:
                case T_BOOLEAN:
                case T_CHAR:
                case T_BYTE:
                case T_SHORT:
                case T_INT:
                    insn = insn.append(
                        Insn.create(
                            opc_invokespecial,
                            pool.addMethodRef(
                                wrapperClassName,
                                "<init>",//NOI18N
                                wrapperSignature)));
                    break;
                case TC_STRING:
                case TC_OBJECT:
                case TC_INTERFACE:
                    break;
                default:
                    throw new InternalError("Unexpected return type");//NOI18N
                }

                // return the object (break)
                insn = insn.append(Insn.create(opc_areturn));
            }
        }

        // do the default branch target creating a fatal exception
        insn = insn.append(defaultOp);
        final String exceptionClassName
            = "com/sun/jdo/api/persistence/support/JDOFatalException";//NOI18N
        insn = insn.append(
            Insn.create(
                opc_new,
                pool.addClass(exceptionClassName)));
        insn = insn.append(Insn.create(opc_dup));
        insn = insn.append(
            Insn.create(
                opc_invokespecial,
                pool.addMethodRef(
                    exceptionClassName,
                    "<init>",//NOI18N
                    "()V")));//NOI18N

        // end of method body
        insn = insn.append(Insn.create(opc_athrow));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              4, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetFieldMethod;
    
ClassMethodmakeJDOGetFlags(ClassAction ca, java.lang.String methodName)
Build the jdoGetFlags method for the class. public byte jdoGetFlags() { return this.jdoFlags; }

        //@olsen: added variable
        final String methodSig = "()B";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoGetFlagsMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // get jdoFlags field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(opc_getfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOFlagsFieldName,
                                         JDOMetaData.JDOFlagsFieldSig)));

        // end of method body
        insn = insn.append(Insn.create(opc_ireturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              1, // maxStack
                              1, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetFlagsMethod;
    
ClassMethodmakeJDOGetObjectIdMethod(ClassAction ca, java.lang.String methodName)
Build the jdoGetObjectId method for the class. public Object jdoGetObjectId() { final StateManager sm = this.jdoStateManager; if (sm == null) return null; return sm.getObjectId(); }

        //@olsen: added variable
        final String methodSig = "()Ljava/lang/Object;";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoGetObjectIdMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // fetch the jdoStateManager field into local var
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(
                opc_getfield,
                pool.addFieldRef(theClass.asString(),
                                 JDOMetaData.JDOStateManagerFieldName,
                                 JDOMetaData.JDOStateManagerFieldSig)));
        insn = insn.append(Insn.create(opc_astore_1));

        // test the jdoStateManager field and return null if null
        InsnTarget call = new InsnTarget();
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(Insn.create(opc_ifnonnull, call));
        insn = insn.append(Insn.create(opc_aconst_null));
        insn = insn.append(Insn.create(opc_areturn));

        // call the jdoStateManager's getObjectId method
        insn = insn.append(call);
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            new InsnInterfaceInvoke(
                pool.addInterfaceMethodRef(
                    JDOMetaData.JDOStateManagerPath,
                    "getObjectId",//NOI18N
                    "()Ljava/lang/Object;"),//NOI18N
                1));

        // end of method body
        insn = insn.append(Insn.create(opc_areturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              1, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetObjectIdMethod;
    
ClassMethodmakeJDOGetPersistenceManagerMethod(ClassAction ca, java.lang.String methodName)
Build the jdoGetPersistenceManager method for the class. public PersistenceManager jdoGetPersistenceManager() { final StateManager sm = this.jdoStateManager; if (sm == null) return null; return sm.getPersistenceManager(); }

        //@olsen: added variable
        final String methodSig = "()" + JDOMetaData.JDOPersistenceManagerSig;//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoGetPersistenceManagerMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // fetch the jdoStateManager field into local var
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(
                opc_getfield,
                pool.addFieldRef(theClass.asString(),
                                 JDOMetaData.JDOStateManagerFieldName,
                                 JDOMetaData.JDOStateManagerFieldSig)));
        insn = insn.append(Insn.create(opc_astore_1));

        // test the jdoStateManager field and return null if null
        InsnTarget call = new InsnTarget();
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(Insn.create(opc_ifnonnull, call));
        insn = insn.append(Insn.create(opc_aconst_null));
        insn = insn.append(Insn.create(opc_areturn));

        // call the jdoStateManager's getPersistenceManager method
        insn = insn.append(call);
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            new InsnInterfaceInvoke(
                pool.addInterfaceMethodRef(
                    JDOMetaData.JDOStateManagerPath,
                    "getPersistenceManager",//NOI18N
                    "()" + JDOMetaData.JDOPersistenceManagerSig),//NOI18N
                1));

        // end of method body
        insn = insn.append(Insn.create(opc_areturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              1, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetPersistenceManagerMethod;
    
ClassMethodmakeJDOGetStateManager(ClassAction ca, java.lang.String methodName)
Build the jdoGetStateManager method for the class. public StateManager jdoGetStateManager() { return this.jdoStateManager; }

        //@olsen: added variable
        final String methodSig = "()" + JDOMetaData.JDOStateManagerSig;//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoGetStateManagerMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // get jdoStateManager field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(opc_getfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOStateManagerFieldName,
                                         JDOMetaData.JDOStateManagerFieldSig)));

        // end of method body
        insn = insn.append(Insn.create(opc_areturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              1, // maxStack
                              1, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoGetStateManagerMethod;
    
ClassMethodmakeJDOInterrogativeMethod(ClassAction ca, java.lang.String methodName)
Build an interrogative method named methodName for the class. public boolean isXXX() { final StateManager sm = this.jdoStateManager; if (sm == null) return false; return sm.isXXXX(); }

        //@olsen: added variable
        final String methodSig = "()Z";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod interrogativeMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // fetch the jdoStateManager field into local var
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(
                opc_getfield,
                pool.addFieldRef(theClass.asString(),
                                 JDOMetaData.JDOStateManagerFieldName,
                                 JDOMetaData.JDOStateManagerFieldSig)));
        insn = insn.append(Insn.create(opc_astore_1));

        // test the jdoStateManager field and return false if null
        InsnTarget call = new InsnTarget();
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(Insn.create(opc_ifnonnull, call));
        insn = insn.append(Insn.create(opc_iconst_0));
        insn = insn.append(Insn.create(opc_ireturn));

        // call the jdoStateManager's interrogative method (jdoIs... -> is...)
        final String callName = "i" + methodName.substring(4);//NOI18N
        insn = insn.append(call);
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            new InsnInterfaceInvoke(
                pool.addInterfaceMethodRef(
                    JDOMetaData.JDOStateManagerPath,
                    callName,
                    "()Z"),//NOI18N
                1));

        // end of method body
        insn = insn.append(Insn.create(opc_ireturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              1, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return interrogativeMethod;
    
ClassMethodmakeJDOMakeDirtyMethod(ClassAction ca, java.lang.String methodName)
Build the jdoMakeDirty method for the class. public void makeDirty() { final StateManager sm = this.jdoStateManager; if (sm != null) sm.makeDirty(fieldName); }

        //@olsen: added variable
        final String methodSig = "(Ljava/lang/String;)V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoMakeDirtyMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // fetch the jdoStateManager field into local var
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(
            Insn.create(
                opc_getfield,
                pool.addFieldRef(theClass.asString(),
                                 JDOMetaData.JDOStateManagerFieldName,
                                 JDOMetaData.JDOStateManagerFieldSig)));
        insn = insn.append(Insn.create(opc_astore_2));

        // test the jdoStateManager field and goto end if null
        InsnTarget end = new InsnTarget();
        insn = insn.append(Insn.create(opc_aload_2));
        insn = insn.append(Insn.create(opc_ifnull, end));

        // call the jdoStateManager's makeDirty method with argument
        insn = insn.append(Insn.create(opc_aload_2));
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            new InsnInterfaceInvoke(
                pool.addInterfaceMethodRef(
                    JDOMetaData.JDOStateManagerPath,
                    "makeDirty",//NOI18N
                    "(Ljava/lang/String;)V"),//NOI18N
                2));

        // end of method body
        insn = insn.append(end);
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              2, // maxStack
                              3, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoMakeDirtyMethod;
    
ClassMethodmakeJDONewInstanceMethod(ClassAction ca, java.lang.String methodName)
Build the jdoNewInstance method for the class. public Object jdoNewInstance(StateManager sm) { return new (sm); }

        //@olsen: added variable
        final String methodSig
            = "(" + JDOMetaData.JDOStateManagerSig + ")Ljava/lang/Object;";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod jdoNewInstanceMethod
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // create an instance of the class by JDO constructor
        insn = insn.append(Insn.create(opc_new, theClass));
        insn = insn.append(Insn.create(opc_dup));
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            Insn.create(
                opc_invokespecial,
                pool.addMethodRef(
                    theClass.asString(),
                    "<init>",//NOI18N
                    "(" + JDOMetaData.JDOStateManagerSig + ")V")));//NOI18N

        // end of method body
        insn = insn.append(Insn.create(opc_areturn));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              3, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoNewInstanceMethod;
    
ClassMethodmakeJDOSetFieldMethod(ClassAction ca, java.lang.String methodName)
Build the jdoSetField method for the class. public jdoSetField(int fieldNumber, Object value) { ... }

        //@olsen: added variable
        final String methodSig = "(ILjava/lang/Object;)V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod jdoSetFieldMethod
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // get the declared, persistent fields from the JDOMetaData
        final String className = ca.className();
        //@lars: changed getPersistentFields() into getManagedFields()
        final String[] fieldNames
            = env.getJDOMetaData().getManagedFields(className);
        final int nofFields = fieldNames.length;
        //@olsen: added println() for debugging
        if (false) {
            System.out.print("MethodBuilder.makeJDOSetFieldMethod(): "//NOI18N
                             + " declared, persistent fields of class '"//NOI18N
                             + className + "' = {");//NOI18N
            for (int i = 0; i < nofFields; i++)
                System.out.print(" " + fieldNames[i]);//NOI18N
            System.out.println(" }");//NOI18N
        }

        // generate the switch-statement only if more than zero fields
        final InsnTarget defaultOp = new InsnTarget();
        if (nofFields > 0) {
            // get the declared, persistent fields from the class
            final HashMap fieldsByName = new HashMap();
            for (Iterator e = ca.fieldActions(); e.hasNext();) {
                final FieldAction act = (FieldAction)e.next();
                fieldsByName.put(act.fieldName(), act);
            }

            // do the tableswitch on argument
            insn = insn.append(Insn.create(opc_iload_1));
            final int lowOp = 0;
            final InsnTarget[] targetsOp = new InsnTarget[nofFields];
            for (int i = 0; i < nofFields; i++)
                targetsOp[i] = new InsnTarget();
            insn = insn.append(
                new InsnTableSwitch(lowOp, defaultOp, targetsOp));

            // do the case-targets for field accesses
            for (int i = 0; i < nofFields; i++) {
                // target for accessing field [i]
                insn = insn.append(targetsOp[i]);

                final FieldAction act
                    = (FieldAction)fieldsByName.get(fieldNames[i]);
                affirm(act,
                       ("Field '"//NOI18N
                        + fieldNames[i]
                        + "' returned by JDOMetaData is not known by class '"//NOI18N
                        + className + "'."));//NOI18N

                // get object and value argument
                insn = insn.append(Insn.create(opc_aload_0));
                insn = insn.append(Insn.create(opc_aload_2));

                // use the getMethodReturn type to downcast the Object argument
                final String wrapperClassName;
                final String unwrapperSignature;
                final String unwrapperName;
                switch(act.getMethodReturn()) {
                case T_DOUBLE:
                    wrapperClassName = "java/lang/Double";//NOI18N
                    unwrapperSignature = "()D";//NOI18N
                    unwrapperName = "doubleValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_LONG:
                    wrapperClassName = "java/lang/Long";//NOI18N
                    unwrapperSignature = "()J";//NOI18N
                    unwrapperName = "longValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_FLOAT:
                    wrapperClassName = "java/lang/Float";//NOI18N
                    unwrapperSignature = "()F";//NOI18N
                    unwrapperName = "floatValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_BOOLEAN:
                    wrapperClassName = "java/lang/Boolean";//NOI18N
                    unwrapperSignature = "()Z";//NOI18N
                    unwrapperName = "booleanValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_CHAR:
                    wrapperClassName = "java/lang/Character";//NOI18N
                    unwrapperSignature = "()C";//NOI18N
                    unwrapperName = "charValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_BYTE:
                    wrapperClassName = "java/lang/Byte";//NOI18N
                    unwrapperSignature = "()B";//NOI18N
                    unwrapperName = "byteValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_SHORT:
                    wrapperClassName = "java/lang/Short";//NOI18N
                    unwrapperSignature = "()S";//NOI18N
                    unwrapperName = "shortValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case T_INT:
                    wrapperClassName = "java/lang/Integer";//NOI18N
                    unwrapperSignature = "()I";//NOI18N
                    unwrapperName = "intValue";//NOI18N
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(wrapperClassName)));
                    break;
                case TC_STRING:
                case TC_OBJECT:
                case TC_INTERFACE:
                    wrapperClassName = null;
                    unwrapperSignature = null;
                    unwrapperName = null;
                    insn = insn.append(
                        Insn.create(opc_checkcast,
                                    pool.addClass(act.typeName())));
                    break;
                default:
                    throw new InternalError("Unexpected return type");//NOI18N
                }

                // unwrap the object if primitive wrapper
                switch(act.getMethodReturn()) {
                case T_DOUBLE:
                case T_LONG:
                case T_FLOAT:
                case T_BOOLEAN:
                case T_CHAR:
                case T_BYTE:
                case T_SHORT:
                case T_INT:
                    insn = insn.append(
                        Insn.create(
                            opc_invokevirtual,
                            pool.addMethodRef(
                                wrapperClassName,
                                unwrapperName,
                                unwrapperSignature)));
                    break;
                case TC_STRING:
                case TC_OBJECT:
                case TC_INTERFACE:
                    break;
                default:
                    throw new InternalError("Unexpected return type");//NOI18N
                }

                // store argument value in field
                insn = insn.append(
                    Insn.create(
                        opc_putfield,
                        pool.addFieldRef(
                            theClass.asString(),
                            act.fieldName(),
                            act.typeDescriptor())));

                // return (break)
                insn = insn.append(Insn.create(opc_return));
            }
        }

        // do the default branch target creating a fatal exception
        insn = insn.append(defaultOp);
        final String exceptionClassName
            = "com/sun/jdo/api/persistence/support/JDOFatalException";//NOI18N
        insn = insn.append(
            Insn.create(
                opc_new,
                pool.addClass(exceptionClassName)));
        insn = insn.append(Insn.create(opc_dup));
        insn = insn.append(
            Insn.create(
                opc_invokespecial,
                pool.addMethodRef(
                    exceptionClassName,
                    "<init>",//NOI18N
                    "()V")));//NOI18N

        // end of method body
        insn = insn.append(Insn.create(opc_athrow));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              3, // maxStack
                              3, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoSetFieldMethod;
    
ClassMethodmakeJDOSetFlags(ClassAction ca, java.lang.String methodName)
Build the jdoSetFlags method for the class. public void jdoSetFlags(byte flags) { this.jdoFlags = flags; }

        //@olsen: added variable
        final String methodSig = "(B)V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoSetFlagsMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // put argument value to jdoFlags field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(Insn.create(opc_iload_1));
        insn = insn.append(
            Insn.create(opc_putfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOFlagsFieldName,
                                         JDOMetaData.JDOFlagsFieldSig)));

        // end of method body
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              2, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoSetFlagsMethod;
    
ClassMethodmakeJDOSetStateManager(ClassAction ca, java.lang.String methodName)
Build the jdoSetStateManager method for the class. public void jdoSetStateManager(StateManager sm) { this.jdoStateManager = sm; }

        //@olsen: added variable
        final String methodSig = "(" + JDOMetaData.JDOStateManagerSig + ")V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass theClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();

        //@olsen: made method final
        final ClassMethod jdoSetStateManagerMethod
            = new ClassMethod(ACCPublic | ACCFinal,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // put argument value to jdoStateManager field
        insn = insn.append(Insn.create(opc_aload_0));
        insn = insn.append(Insn.create(opc_aload_1));
        insn = insn.append(
            Insn.create(opc_putfield,
                        pool.addFieldRef(theClass.asString(),
                                         JDOMetaData.JDOStateManagerFieldName,
                                         JDOMetaData.JDOStateManagerFieldSig)));

        // end of method body
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              2, // maxStack
                              2, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return jdoSetStateManagerMethod;
    
ClassMethodmakeNullMethod(ClassAction ca, java.lang.String methodName)
Build a null method named methodName for the class. public void methodName() { }

        //@olsen: added variable
        final String methodSig = "()V";//NOI18N
        env.message("adding "//NOI18N
                    + ca.classControl().userClassName() +
                    "." + methodName//NOI18N
                    + Descriptor.userMethodArgs(methodSig));

        final ConstantPool pool = ca.classFile().pool();
        final ConstClass thisClass = ca.classFile().className();

        final AttributeVector methodAttrs = new AttributeVector();
        final ClassMethod nullMethod
            = new ClassMethod(ACCPublic,
                              pool.addUtf8(methodName),
                              pool.addUtf8(methodSig),
                              methodAttrs);

        // begin of method body
        //@olsen: fix 4467428, made 'begin' final InsnTarget
        final InsnTarget begin = new InsnTarget();
        Insn insn = begin;

        // end of method body
        insn = insn.append(Insn.create(opc_return));

        final AttributeVector codeSpecificAttrs = new AttributeVector();

        //@olsen: fix 4467428, added dummy, non-empty line number table
        if (addLineNumberTableAttr) {
            codeSpecificAttrs.addElement(
                new LineNumberTableAttribute(
                    pool.addUtf8(LineNumberTableAttribute.expectedAttrName),
                    new short[]{ 0 }, new InsnTarget[]{ begin }));
        }

        methodAttrs.addElement(
            new CodeAttribute(pool.addUtf8(CodeAttribute.expectedAttrName),
                              0, // maxStack
                              1, // maxLocals
                              begin,
                              new ExceptionTable(),
                              codeSpecificAttrs));

        //@olsen: fix 4467428, added synthetic attribute for generated method
        if (addSyntheticAttr) {
            methodAttrs.addElement(
                new SyntheticAttribute(
                    pool.addUtf8(SyntheticAttribute.expectedAttrName)));
        }

        return nullMethod;
    
private static voidprintFieldAction(FieldAction act)

        System.out.println("fieldName() = " + act.fieldName());//NOI18N
        System.out.println("userFieldName() = " + act.userFieldName());//NOI18N
        System.out.println("typeDescriptor() = " + act.typeDescriptor());//NOI18N
        System.out.println("typeName() = " + act.typeName());//NOI18N
        System.out.println("fieldClassName() = " + act.fieldClassName());//NOI18N
        System.out.println("isPersistent() = " + act.isPersistent());//NOI18N
        System.out.println("isPrimaryKey() = " + act.isPrimaryKey());//NOI18N
        System.out.println("isMutableSCO() = " + act.isMutableSCO());//NOI18N
        System.out.println("isSynthetic() = " + act.isSynthetic());//NOI18N
        //System.out.println("index() = " + act.index());
        System.out.println("nDims() = " + act.nDims());//NOI18N
        System.out.println("createMethod() = " + act.createMethod());//NOI18N
        System.out.println("createMethodSig() = " + act.createMethodSig());//NOI18N
        System.out.println("setMethod() = " + act.setMethod());//NOI18N
        System.out.println("setMethodSig() = " + act.setMethodSig());//NOI18N
        System.out.println("setMethodArg() = "//NOI18N
                           + typeToString(act.setMethodArg()));
        System.out.println("getMethod() = " + act.getMethod());//NOI18N
        System.out.println("getMethodSig() = " + act.getMethodSig());//NOI18N
        System.out.println("getMethodReturn() = "//NOI18N
                           + typeToString(act.getMethodReturn()));
    
private static java.lang.StringtypeToString(int val)

        switch(val) {
        case T_DOUBLE:
            return "T_DOUBLE";//NOI18N
        case T_LONG:
            return "T_LONG";//NOI18N
        case T_BOOLEAN:
            return "T_BOOLEAN";//NOI18N
        case T_CHAR:
            return "T_CHAR";//NOI18N
        case T_FLOAT:
            return "T_FLOAT";//NOI18N
        case T_BYTE:
            return "T_BYTE";//NOI18N
        case T_SHORT:
            return "T_SHORT";//NOI18N
        case T_INT:
            return "T_INT";//NOI18N
        case TC_STRING:
            return "TC_STRING";//NOI18N
        case TC_OBJECT:
            return "TC_OBJECT";//NOI18N
        case TC_INTERFACE:
            return "TC_INTERFACE";//NOI18N
        default:
            throw new InternalError("Unexpected return type");//NOI18N
        }