private void addStoreMethod()

in openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java [955:1078]


    private void addStoreMethod(ClassNodeTracker cnt, ClassMetaData meta, boolean fields) {

        MethodNode store;
        if (fields) {
            store = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNCHRONIZED,
                                   "store",
                                   Type.getMethodDescriptor(Type.VOID_TYPE,
                                                            Type.getType(OpenJPAStateManager.class), Type.getType(BitSet.class)),
                                   null, null);
        }
        else {
            store = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNCHRONIZED,
                                   "store",
                                   Type.getMethodDescriptor(Type.VOID_TYPE,
                                                            Type.getType(OpenJPAStateManager.class)),
                                   null, null);
        }
        ClassNode classNode = cnt.getClassNode();
        classNode.methods.add(store);
        InsnList instructions = store.instructions;

        // initialize();
        instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
        instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                            classNode.name,
                                            "initialize",
                                            Type.getMethodDescriptor(Type.VOID_TYPE)));

        // storeVersion(sm);
        instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
        instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st parameter
        instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                            classNode.name,
                                            "storeVersion",
                                            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(OpenJPAStateManager.class))));

        // storeImplData(sm);
        instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
        instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st parameter
        instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                            classNode.name,
                                            "storeImplData",
                                            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(OpenJPAStateManager.class))));

        FieldMetaData[] fmds = meta.getFields();
        int objectCount = 0;
        for (int i = 0; i < fmds.length; i++) {
            LabelNode lblEndIf = new LabelNode();

            if (fields) {
                //  if (fields != null && fields.get(index))
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); // 2nd parameter, BitSet
                instructions.add(new JumpInsnNode(Opcodes.IFNULL, lblEndIf));
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); // 2nd parameter, BitSet
                instructions.add(AsmHelper.getLoadConstantInsn(i));
                instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                                    Type.getInternalName(BitSet.class),
                                                    "get",
                                                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
                instructions.add(new JumpInsnNode(Opcodes.IFEQ, lblEndIf));
            } else {
                // if (sm.getLoaded().get(index)))
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st parameter, OpenJPAStateManager
                instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
                                                    Type.getInternalName(OpenJPAStateManager.class),
                                                    "getLoaded",
                                                    Type.getMethodDescriptor(Type.getType(BitSet.class))));
                instructions.add(AsmHelper.getLoadConstantInsn(i));
                instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                                    Type.getInternalName(BitSet.class),
                                                    "get",
                                                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
                instructions.add(new JumpInsnNode(Opcodes.IFEQ, lblEndIf));
            }
            addStore(classNode, store, instructions, fmds[i], objectCount);

            if (usesIntermediate(fmds[i])) {
                // } else { ..
                LabelNode lblEndElse = new LabelNode(); // new jump target for end else
                instructions.add(new JumpInsnNode(Opcodes.GOTO, lblEndElse));
                instructions.add(lblEndIf); // actually this is now the begin of the else part
                lblEndIf = new LabelNode(); //X TODO not sure!

                // if (!loaded.get(index))
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
                instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
                instructions.add(AsmHelper.getLoadConstantInsn(i));
                instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                                                    Type.getInternalName(BitSet.class),
                                                    "get",
                                                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
                instructions.add(new JumpInsnNode(Opcodes.IFNE, lblEndElse));
                // Object val = sm.getIntermediate(index);
                // if (val != null)
                //         objects[objectCount] = val;
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st parameter
                instructions.add(AsmHelper.getLoadConstantInsn(i));
                instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
                                                    Type.getInternalName(OpenJPAStateManager.class),
                                                    "getIntermediate",
                                                    Type.getMethodDescriptor(AsmHelper.TYPE_OBJECT, Type.INT_TYPE)));
                int localVarPos = AsmHelper.getLocalVarPos(store);
                instructions.add(new VarInsnNode(Opcodes.ASTORE, localVarPos));
                instructions.add(new VarInsnNode(Opcodes.ALOAD, localVarPos));
                instructions.add(new JumpInsnNode(Opcodes.IFNULL, lblEndElse));
                instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
                instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "objects", Type.getDescriptor(Object[].class)));
                instructions.add(AsmHelper.getLoadConstantInsn(objectCount));
                instructions.add(new VarInsnNode(Opcodes.ALOAD, localVarPos));
                instructions.add(new InsnNode(Opcodes.AASTORE));

                instructions.add(lblEndElse);
            }

            if (lblEndIf != null) {
                instructions.add(lblEndIf);
            }

            if (replaceType(fmds[i]) >= JavaTypes.OBJECT)
                objectCount++;
        }

        instructions.add(new InsnNode(Opcodes.RETURN));
    }