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));
}