*/
public void addSetterMethodForFieldAccess(ClassDetails classDetails, AttributeDetails attributeDetails) {
String attribute = attributeDetails.getAttributeName();
// create _persistence_set_variableName
MethodVisitor cv_set = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_SET + attribute, "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", null, null);
// Get the opcode for the load instruction. This may be different
// depending on the type
int opcode = attributeDetails.getReferenceClassType().getOpcode(ILOAD);
if (classDetails.shouldWeaveFetchGroups()) {
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitLdcInsn(attribute);
// _persistence_checkFetchedForSet("variableName");
cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V");
}
if (classDetails.shouldWeaveChangeTracking()) {
if (attributeDetails.weaveValueHolders()) {
// _persistence_initialize_variableName_vh();
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V");
// _persistenc_variableName_vh.getValue();
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;");
// Add the cast:
// (<VariableClass>)_persistenc_variableName_vh.getValue()
cv_set.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
// add the assignment: this.variableName =
// (<VariableClass>)_persistenc_variableName_vh.getValue();
cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
}
// load the string attribute name as the first argument of the
// property change call
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitLdcInsn(attribute);
// if the attribute is a primitive, wrap it
// e.g. if it is an integer: new Integer(attribute)
// This is the first part of the wrapping
String wrapper = ClassWeaver.wrapperFor(attributeDetails.getReferenceClassType().getSort());
if (wrapper != null) {
cv_set.visitTypeInsn(NEW, wrapper);
cv_set.visitInsn(DUP);
}
// load the method argument
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
if (wrapper != null) {
// invoke the constructor for wrapping
// e.g. new Integer(variableName)
cv_set.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V");
// wrap the method argument
// e.g. new Integer(argument)
cv_set.visitTypeInsn(NEW, wrapper);
cv_set.visitInsn(DUP);
cv_set.visitVarInsn(opcode, 1);
cv_set.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V");
} else {
// if we are not wrapping the argument, just load it
cv_set.visitVarInsn(ALOAD, 1);
}
// _persistence_propertyChange("variableName", variableName,
// argument);
cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V");
} else {
if (attributeDetails.weaveValueHolders()) {
// _persistence_initialize_variableName_vh();
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V");
// _persistenc_variableName_vh.getValue();
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;");
// Add the cast:
// (<VariableClass>)_persistenc_variableName_vh.getValue()
cv_set.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
// add the assignment: this.variableName =
// (<VariableClass>)_persistenc_variableName_vh.getValue();
cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
}
}
// Must set variable after raising change event, so event has old and
// new value.
// variableName = argument
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitVarInsn(opcode, 1);
cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute, attributeDetails.getReferenceClassType().getDescriptor());
if (attributeDetails.weaveValueHolders()) {
// _persistence_variableName_vh.setValue(argument);
cv_set.visitVarInsn(ALOAD, 0);
cv_set.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
cv_set.visitVarInsn(ALOAD, 1);
cv_set.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "setValue", "(Ljava/lang/Object;)V");
}
cv_set.visitInsn(RETURN);
cv_set.visitMaxs(0, 0);
}