/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm;

import javax.xml.namespace.QName;

import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: Class to handle (un)marshal operations for
 * XMLObjectReferenceMappings.  An instance of this class is required for each
 * XMLField set on the mapping, that is, for each source field in the
 * source-target key field association list.</p>
 *
 * <p>When unmarshalling, an instance of org.eclipse.persistence.internal.oxm.Reference is
 * created on a per mapping basis (keyed on source object instance) and sotred
 * on the associated session's org.eclipse.persistence.internal.oxm.ReferenceResolver
 * instance.  Each target primary key value is stored in the Reference instance
 * for use during mapping resolution phase after unmarshalling completes.</p>
 *
 * <p>When marshalling, the target object's primary key value that is mapped to
 * this NodeValue's XMLField (in the XMLObjectReferenceMapping's source-target
 * key field association list) is retrieved and written out.</p>
 *
 * @see org.eclipse.persistence.internal.oxm.Reference
 * @see org.eclipse.persistence.internal.oxm.ReferenceResolver
 * @see org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping
 */

public class XMLObjectReferenceMappingNodeValue extends MappingNodeValue {
    private ObjectReferenceMapping xmlObjectReferenceMapping;
    private Field xmlField;

    /**
     * This constructor sets the XMLObjectReferenceMapping member to the provided
     * value.
     *
     * @param xmlObjectReferenceMapping
     */
    public XMLObjectReferenceMappingNodeValue(ObjectReferenceMapping xmlObjectReferenceMapping) {
        super();
        this.xmlObjectReferenceMapping = xmlObjectReferenceMapping;
    }

    /**
     * This constructor sets the XMLObjectReferenceMapping and XMLField members to
     * the provided values.
     *
     * @param xmlObjectReferenceMapping
     * @param xmlField
     */
    public XMLObjectReferenceMappingNodeValue(ObjectReferenceMapping xmlObjectReferenceMapping, Field xmlField) {
        super();
        this.xmlObjectReferenceMapping = xmlObjectReferenceMapping;
        this.xmlField = xmlField;
    }

    /**
     * Handle attribute operation.  Here we will create and populate an
     * org.eclipse.persistence.internal.oxm.Reference instance to be used during
     * the mapping resolution stage.  In particular, the primary key value
     * for this element will be added to the Reference object's list of
     * target primary key values.  Note that if a reference already exists
     * for the xmlObjectReferenceMapping's source object instance, we will
     * simply add to the target pk value list.  The Reference object will
     * is stored on the ReferenceResolver associated with the UnmarshalRecord's
     * session.
     */
    @Override
    public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
        if (value != null) {
            Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(),unmarshalRecord);

            // build a reference which will be resolved after unmarshalling is complete
            xmlObjectReferenceMapping.buildReference(unmarshalRecord, xmlField, realValue, unmarshalRecord.getSession());
        }
    }

    /**
     * Handle endElement operation.  Here we will create and populate an
     * org.eclipse.persistence.internal.oxm.Reference instance to be used during
     * the mapping resolution stage.  In particular, the primary key value
     * for this element will be added to the Reference object's list of
     * target primary key values.  Note that if a reference already exists
     * for the xmlObjectReferenceMapping's source object instance, we will
     * simply add to the target pk value list.  The Reference object will
     * is stored on the ReferenceResolver associated with the UnmarshalRecord's
     * session.
     */
    @Override
    public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
        if (!xmlField.getLastXPathFragment().nameIsText()) {
            return;
        }
        Object value = unmarshalRecord.getCharacters().toString().trim();
        unmarshalRecord.resetStringBuffer();
        ConversionManager conversionManager = unmarshalRecord.getConversionManager();
        if (unmarshalRecord.getTypeQName() != null) {
            Class typeClass = xmlField.getJavaClass(unmarshalRecord.getTypeQName(), conversionManager);
            value = conversionManager.convertObject(value, typeClass, unmarshalRecord.getTypeQName());
        } else {
            value = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, conversionManager, unmarshalRecord);
        }

        // build a reference which will be resolved after unmarshalling is complete
        xmlObjectReferenceMapping.buildReference(unmarshalRecord, xmlField, value, unmarshalRecord.getSession());
    }

    /**
     * Indicate if the XPathFragment is an attribute or text() node.
     */
    @Override
    public boolean isOwningNode(XPathFragment xPathFragment) {
        return xPathFragment.isAttribute() || xPathFragment.nameIsText();
    }

    /**
     * Handle the marshal operation for this NodeValue's XMLField.  The target
     * object's primary key value that is mapped to this NodeValue's XMLField
     * (in the XMLObjectReferenceMapping's source-target key field association list)
     * is retrieved and written out.
     */
    @Override
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
        return marshal(xPathFragment, marshalRecord, object, session, namespaceResolver, ObjectMarshalContext.getInstance());
    }

    /**
     * Handle the marshal operation for this NodeValue's XMLField.  The target
     * object's primary key value that is mapped to this NodeValue's XMLField
     * (in the XMLObjectReferenceMapping's source-target key field association list)
     * is retrieved and written out.
     */
    @Override
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        if (xmlObjectReferenceMapping.isReadOnly()) {
            return false;
        }
        Object targetObject = marshalContext.getAttributeValue(object, xmlObjectReferenceMapping);
        return this.marshalSingleValue(xPathFragment, marshalRecord, object, targetObject, session, namespaceResolver, marshalContext);
    }

    @Override
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object targetObject, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        Object fieldValue = xmlObjectReferenceMapping.buildFieldValue(targetObject, xmlField, session);
        if (fieldValue == null) {
            if(null != targetObject) {
                Field fkField = (Field) xmlObjectReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField);
                if(null == fkField) {
                    Descriptor targetDescriptor = (Descriptor) session.getDescriptor(targetObject);
                    fieldValue = marshalRecord.getMarshaller().getContext().getValueByXPath(targetObject, ((CoreField) targetDescriptor.getPrimaryKeyFields().get(0)).getName(), targetDescriptor.getNamespaceResolver(), Object.class);
                } else {
                    fieldValue = marshalRecord.getMarshaller().getContext().getValueByXPath(targetObject, fkField.getXPath(), fkField.getNamespaceResolver(), Object.class);
                }
            }
            if(null == fieldValue) {
                return false;
            }
        }

        QName schemaType = xmlField.getSchemaTypeForValue(fieldValue, session);
        XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);

        if (xPathFragment != null && xPathFragment.isAttribute()) {
            marshalRecord.attribute(xPathFragment, namespaceResolver, fieldValue, schemaType);
            marshalRecord.closeStartGroupingElements(groupingFragment);
        } else {
            marshalRecord.closeStartGroupingElements(groupingFragment);
            marshalRecord.characters(schemaType, fieldValue, null, false);
        }
        return true;
    }

    @Override
    public ObjectReferenceMapping getMapping() {
        return xmlObjectReferenceMapping;
    }

}
