Search in sources :

Example 6 with Label

use of org.eclipse.persistence.internal.libraries.asm.Label in project eclipselink by eclipse-ee4j.

the class MethodWeaver method weaveBeginningOfMethodIfRequired.

/**
 * Makes modifications to the beginning of a method.
 *
 * 1. Modifies getter method for attributes using property access
 *
 * In a getter method for 'attributeName', the following lines are added at the beginning of the method
 *
 *  _persistence_checkFetched("attributeName");
 *  _persistence_initialize_attributeName_vh();
 *  if (!_persistence_attributeName_vh.isInstantiated()) {
 *      PropertyChangeListener temp_persistence_listener = _persistence_listener;
 *      _persistence_listener = null;
 *      setAttributeName((AttributeType)_persistence_attributeName_vh.getValue());
 *      _persistence_listener = temp_persistence_listener;
 *  }
 *
 *  2. Modifies setter methods to store old value of attribute
 *  If weaving for fetch groups:
 *
 *  // if weaving for change tracking:
 *  if(_persistence_listener != null)
 *      // for Objects
 *      AttributeType oldAttribute = getAttribute()
 *      // for primitives
 *      AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute());
 *          e.g. Double oldAttribute = Double.valueOf(getAttribute());
 *  else
 *      _persistence_checkFetchedForSet("attributeName");
 *  _persistence_propertyChange("attributeName", oldAttribute, argument);
 *
 *  otherwise (not weaving for fetch groups):
 *
 *      // for Objects
 *      AttributeType oldAttribute = getAttribute()
 *      // for primitives
 *      AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute());
 *          e.g. Double oldAttribute = Double.valueOf(getAttribute());
 *  _persistence_propertyChange("attributeName", oldAttribute, argument);
 *
 *  // if not weaving for change tracking, but for fetch groups only:
 *  _persistence_checkFetchedForSet("attributeName");
 *
 *  3. Modifies getter Method for attributes using virtual access
 *
 *  add: _persistence_checkFetched(name);
 *
 *  4. Modifies setter Method for attributes using virtual access
 *
 *  add code of the following form:
 *
 *   Object obj = null;
 *   if(_persistence_listener != null){
 *      obj = get(name);
 *   } else {
 *       _persistence_checkFetchedForSet(name);
 *   }
 *   _persistence_propertyChange(name, obj, value);
 *
 *   _persistence_checkFetchedForSet(name) call will be excluded if weaving of fetch groups is not enabled
 *
 *   _persistence_propertyChange(name, obj, value); will be excluded if weaving of change tracking is not enabled
 */
public void weaveBeginningOfMethodIfRequired() {
    if (this.methodStarted) {
        return;
    }
    // Must set immediately, as weaving can trigger this method.
    this.methodStarted = true;
    boolean isVirtual = false;
    AttributeDetails attributeDetails = tcw.classDetails.getGetterMethodToAttributeDetails().get(methodName);
    boolean isGetMethod = (attributeDetails != null) && (this.methodDescriptor.startsWith("()") || (attributeDetails.isVirtualProperty() && this.methodDescriptor.startsWith("(" + ClassWeaver.STRING_SIGNATURE + ")")));
    String attributeName = null;
    String referenceClassName = null;
    String setterMethodName = null;
    Type referenceClassType = null;
    String getterMethodName = null;
    int valueHoldingLocation = 1;
    int valueStorageLocation = 2;
    if (attributeDetails == null) {
        VirtualAttributeMethodInfo info = tcw.classDetails.getInfoForVirtualGetMethod(methodName);
        if ((info != null) && this.methodDescriptor.equals(ClassWeaver.VIRTUAL_GETTER_SIGNATURE)) {
            isGetMethod = true;
            isVirtual = true;
            referenceClassName = "java.lang.Object";
            setterMethodName = info.getSetMethodName();
            referenceClassType = Type.getType(ClassWeaver.OBJECT_SIGNATURE);
            getterMethodName = methodName;
        }
    } else {
        attributeName = attributeDetails.getAttributeName();
        referenceClassName = attributeDetails.getReferenceClassName();
        setterMethodName = attributeDetails.getSetterMethodName();
        referenceClassType = attributeDetails.getReferenceClassType();
        getterMethodName = attributeDetails.getGetterMethodName();
        isVirtual = attributeDetails.isVirtualProperty();
    }
    if (isVirtual) {
        valueHoldingLocation = 2;
        valueStorageLocation = 3;
    }
    if (isVirtual || (isGetMethod && !attributeDetails.hasField())) {
        if (tcw.classDetails.shouldWeaveFetchGroups()) {
            mv.visitVarInsn(ALOAD, 0);
            if (isVirtual) {
                mv.visitVarInsn(ALOAD, 1);
            } else {
                mv.visitLdcInsn(attributeName);
            }
            // _persistence_checkFetched("attributeName");
            mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetched", "(Ljava/lang/String;)V", false);
        }
        if (!isVirtual && attributeDetails.weaveValueHolders()) {
            // _persistence_initialize_attributeName_vh();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_initialize_" + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);
            // if (!_persistence_attributeName_vh.isInstantiated()) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), ClassWeaver.PERSISTENCE_FIELDNAME_PREFIX + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
            mv.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "isInstantiated", "()Z", true);
            Label l0 = new Label();
            mv.visitJumpInsn(IFNE, l0);
            // Need to disable change tracking when the set method is called to avoid thinking the attribute changed.
            if (tcw.classDetails.shouldWeaveChangeTracking()) {
                // PropertyChangeListener temp_persistence_listener = _persistence_listener;
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
                mv.visitVarInsn(ASTORE, 4);
                // _persistence_listener = null;
                mv.visitVarInsn(ALOAD, 0);
                mv.visitInsn(ACONST_NULL);
                mv.visitFieldInsn(PUTFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
            }
            // setAttributeName((AttributeType)_persistence_attributeName_vh.getValue());
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), ClassWeaver.PERSISTENCE_FIELDNAME_PREFIX + attributeName + ClassWeaver.PERSISTENCE_FIELDNAME_POSTFIX, ClassWeaver.VHI_SIGNATURE);
            mv.visitMethodInsn(INVOKEINTERFACE, ClassWeaver.VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
            mv.visitTypeInsn(CHECKCAST, referenceClassName.replace('.', '/'));
            mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), setterMethodName, "(" + referenceClassType.getDescriptor() + ")V", false);
            if (tcw.classDetails.shouldWeaveChangeTracking()) {
                // _persistence_listener = temp_persistence_listener;
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(ALOAD, 4);
                mv.visitFieldInsn(PUTFIELD, tcw.classDetails.getClassName(), "_persistence_listener", ClassWeaver.PCL_SIGNATURE);
            }
            // }
            mv.visitLabel(l0);
        }
    } else {
        attributeDetails = tcw.classDetails.getSetterMethodToAttributeDetails().get(methodName);
        boolean isSetMethod = (attributeDetails != null) && this.methodDescriptor.equals(attributeDetails.getSetterMethodSignature());
        if (attributeDetails == null) {
            VirtualAttributeMethodInfo info = tcw.classDetails.getInfoForVirtualSetMethod(methodName);
            if (info != null && this.methodDescriptor.equals(ClassWeaver.VIRTUAL_GETTER_SIGNATURE)) {
                isGetMethod = true;
                isVirtual = true;
                referenceClassName = "java.lang.Object";
                setterMethodName = methodName;
                referenceClassType = Type.getType(ClassWeaver.OBJECT_SIGNATURE);
                getterMethodName = info.getGetMethodName();
            }
        } else {
            attributeName = attributeDetails.getAttributeName();
            referenceClassName = attributeDetails.getReferenceClassName();
            setterMethodName = attributeDetails.getSetterMethodName();
            referenceClassType = attributeDetails.getReferenceClassType();
            getterMethodName = attributeDetails.getGetterMethodName();
            isVirtual = attributeDetails.isVirtualProperty();
        }
        if (isVirtual) {
            valueHoldingLocation = 2;
            valueStorageLocation = 3;
        }
        if (isVirtual || (isSetMethod && !attributeDetails.hasField())) {
            if (tcw.classDetails.shouldWeaveChangeTracking()) {
                if (tcw.classDetails.shouldWeaveFetchGroups()) {
                    // if this is a primitive, get the wrapper class
                    String wrapper = ClassWeaver.wrapperFor(referenceClassType.getSort());
                    mv.visitInsn(ACONST_NULL);
                    if (wrapper != null) {
                        mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
                    } else {
                        mv.visitVarInsn(ASTORE, valueStorageLocation);
                    }
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitFieldInsn(GETFIELD, tcw.classDetails.getClassName(), "_persistence_listener", "Ljava/beans/PropertyChangeListener;");
                    Label l0 = new Label();
                    mv.visitJumpInsn(IFNULL, l0);
                    // 1st part of invoking constructor for primitives to wrap them
                    if (wrapper != null) {
                        mv.visitTypeInsn(NEW, wrapper);
                        mv.visitInsn(DUP);
                    }
                    // Call the getter
                    // getAttribute()
                    mv.visitVarInsn(ALOAD, 0);
                    String getterArgument = "";
                    String getterReturn = referenceClassType.getDescriptor();
                    if (isVirtual) {
                        getterArgument = ClassWeaver.STRING_SIGNATURE;
                        getterReturn = ClassWeaver.OBJECT_SIGNATURE;
                        mv.visitVarInsn(ALOAD, 1);
                    }
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), getterMethodName, "(" + getterArgument + ")" + getterReturn, false);
                    if (wrapper != null) {
                        // 2nd part of using constructor.
                        mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
                        mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
                    } else {
                        // store the result
                        mv.visitVarInsn(ASTORE, valueStorageLocation);
                    }
                    Label l1 = new Label();
                    mv.visitJumpInsn(GOTO, l1);
                    mv.visitLabel(l0);
                    mv.visitVarInsn(ALOAD, 0);
                    if (isVirtual) {
                        mv.visitVarInsn(ALOAD, 1);
                    } else {
                        mv.visitLdcInsn(attributeName);
                    }
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", false);
                    mv.visitLabel(l1);
                    mv.visitVarInsn(ALOAD, 0);
                    if (isVirtual) {
                        mv.visitVarInsn(ALOAD, 1);
                    } else {
                        mv.visitLdcInsn(attributeName);
                    }
                    if (wrapper != null) {
                        mv.visitVarInsn(ALOAD, valueStorageLocation + 1);
                        mv.visitTypeInsn(NEW, wrapper);
                        mv.visitInsn(DUP);
                    } else {
                        mv.visitVarInsn(ALOAD, valueStorageLocation);
                    }
                    // get an appropriate load opcode for the type
                    int opcode = referenceClassType.getOpcode(ILOAD);
                    mv.visitVarInsn(opcode, valueHoldingLocation);
                    if (wrapper != null) {
                        mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
                    }
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
                } else {
                    // tcw.classDetails.shouldWeaveFetchGroups()
                    /**
                     * The code below constructs the following code
                     *
                     * AttributeType oldAttribute = getAttribute() // for Objects
                     *
                     * AttributeWrapperType oldAttribute = new AttributeWrapperType(getAttribute()); // for primitives
                     */
                    // if this is a primitive, get the wrapper class
                    String wrapper = ClassWeaver.wrapperFor(referenceClassType.getSort());
                    // 1st part of invoking constructor for primitives to wrap them
                    if (wrapper != null) {
                        mv.visitTypeInsn(NEW, wrapper);
                        mv.visitInsn(DUP);
                    }
                    // Call the getter
                    // getAttribute()
                    mv.visitVarInsn(ALOAD, 0);
                    String getterArgument = "";
                    String getterReturn = referenceClassType.getDescriptor();
                    if (isVirtual) {
                        getterArgument = ClassWeaver.STRING_SIGNATURE;
                        getterReturn = ClassWeaver.OBJECT_SIGNATURE;
                        mv.visitVarInsn(ALOAD, 1);
                    }
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), getterMethodName, "(" + getterArgument + ")" + getterReturn, false);
                    if (wrapper != null) {
                        // 2nd part of using constructor.
                        mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")V", false);
                        mv.visitVarInsn(ASTORE, valueStorageLocation + 1);
                    } else {
                        // store the result
                        mv.visitVarInsn(ASTORE, valueStorageLocation);
                    }
                    // makes use of the value stored in weaveBeginningOfMethodIfRequired to call property change method
                    // _persistence_propertyChange("attributeName", oldAttribute, argument);
                    mv.visitVarInsn(ALOAD, 0);
                    if (isVirtual) {
                        mv.visitVarInsn(ALOAD, 1);
                    } else {
                        mv.visitLdcInsn(attributeName);
                    }
                    if (wrapper != null) {
                        mv.visitVarInsn(ALOAD, valueStorageLocation + 1);
                        mv.visitTypeInsn(NEW, wrapper);
                        mv.visitInsn(DUP);
                    } else {
                        mv.visitVarInsn(ALOAD, valueStorageLocation);
                    }
                    int opcode = referenceClassType.getOpcode(ILOAD);
                    mv.visitVarInsn(opcode, valueHoldingLocation);
                    if (wrapper != null) {
                        mv.visitMethodInsn(INVOKESPECIAL, wrapper, "<init>", "(" + referenceClassType.getDescriptor() + ")V", false);
                    }
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_propertyChange", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", false);
                }
            } else {
                // !tcw.classDetails.shouldWeaveChangeTracking()
                if (tcw.classDetails.shouldWeaveFetchGroups()) {
                    mv.visitVarInsn(ALOAD, 0);
                    if (isVirtual) {
                        mv.visitVarInsn(ALOAD, 1);
                    } else {
                        mv.visitLdcInsn(attributeName);
                    }
                    // _persistence_checkFetchedForSet("variableName");
                    mv.visitMethodInsn(INVOKEVIRTUAL, tcw.classDetails.getClassName(), "_persistence_checkFetchedForSet", "(Ljava/lang/String;)V", false);
                }
            }
        }
    }
}
Also used : Type(org.eclipse.persistence.internal.libraries.asm.Type) VirtualAttributeMethodInfo(org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo) Label(org.eclipse.persistence.internal.libraries.asm.Label)

Example 7 with Label

use of org.eclipse.persistence.internal.libraries.asm.Label in project eclipselink by eclipse-ee4j.

the class ClassWeaver method addGetterMethodForValueHolder.

/**
 * Add a get method for the newly added valueholder. Adds a method of the
 * following form:
 *
 * public WeavedAttributeValueHolderInterface _persistence_getfoo_vh(){
 * _persistence_initialize_attributeName_vh(); if
 * (_persistence_vh.isCoordinatedWithProperty() ||
 * _persistence_foo_vh.isNewlyWeavedValueHolder()){ EntityC object =
 * (EntityC)getFoo(); if (object != _persistence_foo_vh.getValue()){
 * setFoo(object); } } return _persistence_foo_vh; }
 */
public void addGetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
    String attribute = attributeDetails.getAttributeName();
    String className = classDetails.getClassName();
    // Create a getter method for the new valueholder
    MethodVisitor cv_get_VH = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_GET + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "()" + VHI_SIGNATURE, null, null);
    // _persistence_initialize_attributeName_vh();
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), "_persistence_initialize_" + attributeDetails.getAttributeName() + PERSISTENCE_FIELDNAME_POSTFIX, "()V", false);
    // if (_toplink_foo_vh.isCoordinatedWithProperty() ||
    // _toplink_foo_vh.isNewlyWeavedValueHolder()){
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isCoordinatedWithProperty", "()Z", true);
    Label l0 = new Label();
    cv_get_VH.visitJumpInsn(IFNE, l0);
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isNewlyWeavedValueHolder", "()Z", true);
    Label l1 = new Label();
    cv_get_VH.visitJumpInsn(IFEQ, l1);
    cv_get_VH.visitLabel(l0);
    cv_get_VH.visitVarInsn(ALOAD, 0);
    // EntityC object = (EntityC)getFoo();
    if (attributeDetails.getGetterMethodName() != null) {
        cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), attributeDetails.getGetterMethodName(), "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
        cv_get_VH.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
    } else {
        cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), PERSISTENCE_GET + attributeDetails.attributeName, "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
    }
    cv_get_VH.visitVarInsn(ASTORE, 1);
    // if (object != _toplink_foo_vh.getValue()){
    cv_get_VH.visitVarInsn(ALOAD, 1);
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitFieldInsn(GETFIELD, classDetails.getClassName(), PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    cv_get_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
    cv_get_VH.visitJumpInsn(IF_ACMPEQ, l1);
    // setFoo(object);
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitVarInsn(ALOAD, 1);
    if (attributeDetails.getSetterMethodName() != null) {
        cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
    } else {
        cv_get_VH.visitMethodInsn(INVOKEVIRTUAL, classDetails.getClassName(), PERSISTENCE_SET + attributeDetails.getAttributeName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
    }
    // }
    cv_get_VH.visitLabel(l1);
    // return _toplink_foo_vh;
    cv_get_VH.visitVarInsn(ALOAD, 0);
    cv_get_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    cv_get_VH.visitInsn(ARETURN);
    cv_get_VH.visitMaxs(0, 0);
}
Also used : Label(org.eclipse.persistence.internal.libraries.asm.Label) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor)

Example 8 with Label

use of org.eclipse.persistence.internal.libraries.asm.Label in project eclipselink by eclipse-ee4j.

the class ClassWeaver method addSetterMethodForValueHolder.

/**
 * Add a set method for the newly added ValueHolder. Adds a method of this
 * form:
 *
 * public void _persistence_setfoo_vh(WeavedAttributeValueHolderInterface
 * valueholderinterface){ _persistence_foo_vh = valueholderinterface; if
 * (valueholderinterface.isInstantiated()){ Object object = getFoo(); Object
 * value = valueholderinterface.getValue(); if (object != value){
 * setFoo((EntityC)value); } } else { foo = null; } }
 */
public void addSetterMethodForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
    String attribute = attributeDetails.getAttributeName();
    String className = classDetails.getClassName();
    // create a setter method for the new valueholder
    MethodVisitor cv_set_value = cv.visitMethod(ACC_PUBLIC, PERSISTENCE_SET + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "(" + VHI_SIGNATURE + ")V", null, null);
    // _toplink_foo_vh = valueholderinterface;
    cv_set_value.visitVarInsn(ALOAD, 0);
    cv_set_value.visitVarInsn(ALOAD, 1);
    cv_set_value.visitFieldInsn(PUTFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    // if (valueholderinterface.isInstantiated()){
    cv_set_value.visitVarInsn(ALOAD, 1);
    cv_set_value.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "isInstantiated", "()Z", true);
    Label l0 = new Label();
    cv_set_value.visitJumpInsn(IFEQ, l0);
    // Object object = getFoo();
    cv_set_value.visitVarInsn(ALOAD, 0);
    if (attributeDetails.getGetterMethodName() != null) {
        cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, attributeDetails.getGetterMethodName(), "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
    } else {
        cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, PERSISTENCE_GET + attributeDetails.attributeName, "()L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";", false);
    }
    cv_set_value.visitVarInsn(ASTORE, 2);
    // Object value = valueholderinterface.getValue();
    cv_set_value.visitVarInsn(ALOAD, 1);
    cv_set_value.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "getValue", "()Ljava/lang/Object;", true);
    cv_set_value.visitVarInsn(ASTORE, 3);
    // if (object != value){
    cv_set_value.visitVarInsn(ALOAD, 2);
    cv_set_value.visitVarInsn(ALOAD, 3);
    if (attributeDetails.getSetterMethodName() != null) {
        cv_set_value.visitJumpInsn(IF_ACMPEQ, l0);
        // setFoo((EntityC)value);
        cv_set_value.visitVarInsn(ALOAD, 0);
        cv_set_value.visitVarInsn(ALOAD, 3);
        cv_set_value.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
        cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, attributeDetails.getSetterMethodName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
        // }
        cv_set_value.visitLabel(l0);
    } else {
        Label l1 = new Label();
        cv_set_value.visitJumpInsn(IF_ACMPEQ, l1);
        // _persistence_setFoo((EntityC)value);
        cv_set_value.visitVarInsn(ALOAD, 0);
        cv_set_value.visitVarInsn(ALOAD, 3);
        cv_set_value.visitTypeInsn(CHECKCAST, attributeDetails.getReferenceClassName().replace('.', '/'));
        cv_set_value.visitMethodInsn(INVOKEVIRTUAL, className, PERSISTENCE_SET + attributeDetails.getAttributeName(), "(L" + attributeDetails.getReferenceClassName().replace('.', '/') + ";)V", false);
        // }
        cv_set_value.visitLabel(l1);
        cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
        Label l2 = new Label();
        cv_set_value.visitJumpInsn(GOTO, l2);
        // }
        cv_set_value.visitLabel(l0);
        // else {
        cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
        // foo = null;
        cv_set_value.visitVarInsn(ALOAD, 0);
        cv_set_value.visitInsn(ACONST_NULL);
        cv_set_value.visitFieldInsn(PUTFIELD, className, attributeDetails.attributeName, attributeDetails.getReferenceClassType().getDescriptor());
        // }
        cv_set_value.visitLabel(l2);
        cv_set_value.visitFrame(F_SAME, 0, null, 0, null);
    }
    cv_set_value.visitInsn(RETURN);
    cv_set_value.visitMaxs(0, 0);
}
Also used : Label(org.eclipse.persistence.internal.libraries.asm.Label) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor)

Example 9 with Label

use of org.eclipse.persistence.internal.libraries.asm.Label in project eclipselink by eclipse-ee4j.

the class ClassWeaver method addPersistenceGetSet.

/**
 * Add an internal generic get and set method. This is used to avoid
 * reflection.
 *
 * public Object _persistence_get(String attribute) { if (attribute ==
 * "address") { return this.address; } if (attribute == "city") { return
 * this.city; } return null; }
 *
 * public void _persistence_set(int index, Object value) { if (attribute ==
 * "address") { this.address = (String)value; } else if (attribute ==
 * "city") { this.city = (String)city; } }
 */
public void addPersistenceGetSet(ClassDetails classDetails) {
    // create the _persistence_get() method
    MethodVisitor cv_get = cv.visitMethod(ACC_PUBLIC, "_persistence_get", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
    Label label = null;
    for (AttributeDetails attributeDetails : classDetails.getAttributesMap().values()) {
        if (!attributeDetails.isAttributeOnSuperClass() && !attributeDetails.isVirtualProperty()) {
            if (label != null) {
                cv_get.visitLabel(label);
            }
            // else if (attribute == "address")
            cv_get.visitVarInsn(ALOAD, 1);
            cv_get.visitLdcInsn(attributeDetails.getAttributeName().intern());
            label = new Label();
            cv_get.visitJumpInsn(IF_ACMPNE, label);
            // return this.address
            cv_get.visitVarInsn(ALOAD, 0);
            cv_get.visitFieldInsn(GETFIELD, classDetails.getClassName(), attributeDetails.getAttributeName(), attributeDetails.getReferenceClassType().getDescriptor());
            // if this is a primitive, get the wrapper class
            String wrapper = ClassWeaver.wrapperFor(attributeDetails.getReferenceClassType().getSort());
            if (wrapper != null) {
                // Call valueOf on the wrapper (more optimal than
                // constructor).
                cv_get.visitMethodInsn(INVOKESTATIC, wrapper, "valueOf", "(" + attributeDetails.getReferenceClassType().getDescriptor() + ")L" + wrapper + ";", false);
            }
            cv_get.visitInsn(ARETURN);
        }
    }
    if (label != null) {
        cv_get.visitLabel(label);
    }
    // call super, or return null
    if (classDetails.getSuperClassDetails() == null) {
        // return null;
        cv_get.visitInsn(ACONST_NULL);
    } else {
        cv_get.visitVarInsn(ALOAD, 0);
        cv_get.visitVarInsn(ALOAD, 1);
        cv_get.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "_persistence_get", "(Ljava/lang/String;)Ljava/lang/Object;", false);
    }
    cv_get.visitInsn(ARETURN);
    cv_get.visitMaxs(0, 0);
    // create the _persistence_set() method
    MethodVisitor cv_set = cv.visitMethod(ACC_PUBLIC, "_persistence_set", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
    label = null;
    for (AttributeDetails attribute : classDetails.getAttributesMap().values()) {
        if (!attribute.isAttributeOnSuperClass() && !attribute.isVirtualProperty()) {
            if (label != null) {
                cv_set.visitLabel(label);
            }
            // else if (attribute == "address")
            cv_set.visitVarInsn(ALOAD, 1);
            cv_set.visitLdcInsn(attribute.getAttributeName().intern());
            label = new Label();
            cv_set.visitJumpInsn(IF_ACMPNE, label);
            // this.address = (String)value;
            cv_set.visitVarInsn(ALOAD, 0);
            cv_set.visitVarInsn(ALOAD, 2);
            String wrapper = wrapperFor(attribute.getReferenceClassType().getSort());
            if (wrapper == null) {
                wrapper = attribute.getReferenceClassName().replace('.', '/');
            }
            cv_set.visitTypeInsn(CHECKCAST, wrapper);
            // Unwrap any primitive wrapper to its value.
            unwrapPrimitive(attribute, cv_set);
            cv_set.visitFieldInsn(PUTFIELD, classDetails.getClassName(), attribute.getAttributeName(), attribute.getReferenceClassType().getDescriptor());
            // return;
            cv_set.visitInsn(RETURN);
        }
    }
    if (label != null) {
        cv_set.visitLabel(label);
    }
    // call super, or return null
    if (classDetails.getSuperClassDetails() != null) {
        cv_set.visitVarInsn(ALOAD, 0);
        cv_set.visitVarInsn(ALOAD, 1);
        cv_set.visitVarInsn(ALOAD, 2);
        cv_set.visitMethodInsn(INVOKESPECIAL, classDetails.getSuperClassName(), "_persistence_set", "(Ljava/lang/String;Ljava/lang/Object;)V", false);
    }
    cv_set.visitInsn(RETURN);
    cv_set.visitMaxs(0, 0);
}
Also used : Label(org.eclipse.persistence.internal.libraries.asm.Label) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor)

Example 10 with Label

use of org.eclipse.persistence.internal.libraries.asm.Label in project eclipselink by eclipse-ee4j.

the class ClassWeaver method addInitializerForValueHolder.

/**
 * Add a method that allows us to lazily initialize a valueholder we have
 * woven in This allows us to avoid initializing valueholders in the
 * constructor.
 *
 * protected void _persistence_initialize_attribute_vh(){
 * if(_persistence_attribute_vh == null){ _persistence_attribute_vh = new
 * ValueHolder(this.attribute); // or new ValueHolder() if property access.
 * _persistence_attribute_vh.setIsNewlyWeavedValueHolder(true); } }
 */
public void addInitializerForValueHolder(ClassDetails classDetails, AttributeDetails attributeDetails) {
    String attribute = attributeDetails.getAttributeName();
    String className = classDetails.getClassName();
    // Create a getter method for the new valueholder
    // protected void _persistence_initialize_attribute_vh(){
    MethodVisitor cv_init_VH = cv.visitMethod(ACC_PROTECTED, "_persistence_initialize_" + attribute + PERSISTENCE_FIELDNAME_POSTFIX, "()V", null, null);
    // if(_persistence_attribute_vh == null){
    cv_init_VH.visitVarInsn(ALOAD, 0);
    cv_init_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    Label l0 = new Label();
    cv_init_VH.visitJumpInsn(IFNONNULL, l0);
    // _persistence_attribute_vh = new ValueHolder(this.attribute);
    cv_init_VH.visitVarInsn(ALOAD, 0);
    cv_init_VH.visitTypeInsn(NEW, VH_SHORT_SIGNATURE);
    cv_init_VH.visitInsn(DUP);
    if (attributeDetails.hasField()) {
        cv_init_VH.visitVarInsn(ALOAD, 0);
        cv_init_VH.visitFieldInsn(GETFIELD, className, attribute, attributeDetails.getReferenceClassType().getDescriptor());
        cv_init_VH.visitMethodInsn(INVOKESPECIAL, VH_SHORT_SIGNATURE, "<init>", "(Ljava/lang/Object;)V", false);
    } else {
        cv_init_VH.visitMethodInsn(INVOKESPECIAL, VH_SHORT_SIGNATURE, "<init>", "()V", false);
    }
    cv_init_VH.visitFieldInsn(PUTFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    // _persistence_attribute_vh.setIsNewlyWeavedValueHolder(true);
    cv_init_VH.visitVarInsn(ALOAD, 0);
    cv_init_VH.visitFieldInsn(GETFIELD, className, PERSISTENCE_FIELDNAME_PREFIX + attribute + PERSISTENCE_FIELDNAME_POSTFIX, VHI_SIGNATURE);
    cv_init_VH.visitInsn(ICONST_1);
    cv_init_VH.visitMethodInsn(INVOKEINTERFACE, VHI_SHORT_SIGNATURE, "setIsNewlyWeavedValueHolder", "(Z)V", true);
    // }
    cv_init_VH.visitLabel(l0);
    cv_init_VH.visitInsn(RETURN);
    cv_init_VH.visitMaxs(0, 0);
}
Also used : Label(org.eclipse.persistence.internal.libraries.asm.Label) MethodVisitor(org.eclipse.persistence.internal.libraries.asm.MethodVisitor)

Aggregations

Label (org.eclipse.persistence.internal.libraries.asm.Label)11 MethodVisitor (org.eclipse.persistence.internal.libraries.asm.MethodVisitor)10 XmlElement (jakarta.xml.bind.annotation.XmlElement)2 XmlJavaTypeAdapter (jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter)2 Annotation (java.lang.annotation.Annotation)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Method (java.lang.reflect.Method)2 AnnotationVisitor (org.eclipse.persistence.internal.libraries.asm.AnnotationVisitor)2 EclipseLinkASMClassWriter (org.eclipse.persistence.internal.libraries.asm.EclipseLinkASMClassWriter)2 FieldVisitor (org.eclipse.persistence.internal.libraries.asm.FieldVisitor)2 Type (org.eclipse.persistence.internal.libraries.asm.Type)2 JavaAnnotation (org.eclipse.persistence.jaxb.javamodel.JavaAnnotation)2 JavaClass (org.eclipse.persistence.jaxb.javamodel.JavaClass)2 JavaMethod (org.eclipse.persistence.jaxb.javamodel.JavaMethod)2 XmlAccessorType (jakarta.xml.bind.annotation.XmlAccessorType)1 XmlList (jakarta.xml.bind.annotation.XmlList)1 XmlMimeType (jakarta.xml.bind.annotation.XmlMimeType)1 XmlSchemaType (jakarta.xml.bind.annotation.XmlSchemaType)1 XmlType (jakarta.xml.bind.annotation.XmlType)1 ParameterizedType (java.lang.reflect.ParameterizedType)1