/*
 * 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
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
package org.eclipse.persistence.mappings.xdb;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.platform.database.XMLTypePlaceholder;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.platform.xml.XMLComparer;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.eclipse.persistence.sessions.Session;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * <b>Purpose</b>: Mapping used to map from a DOM (org.w3c.Document) or XML String into
 * an Oracle XMLType field, in Oracle 9i XDB.
 *
 * @since Toplink 10.1.3
 */
public class DirectToXMLTypeMapping extends DirectToFieldMapping {
    /**
     * Indicates if we should initialize the whole DOM on a read.
     * This is only used if the user is mapping from an Oracle Document implementation.
     */
    protected boolean shouldReadWholeDocument = false;

    /**
     * Used to convert the DOM to a String.
     */
    private XMLTransformer xmlTransformer;

    /**
     * Used to determine if the XML document has been modified.
     */
    private XMLComparer xmlComparer;

    /**
     * Used to convert the String to a DOM
     */
    private  XMLParser xmlParser;

    /**
     * INTERNAL:
     * Default to mutable if mapped as a DOM.
     */
    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        if (this.attributeClassification == null) {
            this.attributeClassification = getAttributeAccessor().getAttributeClass();
        }
        if ((this.isMutable == null) && (this.attributeClassification != ClassConstants.STRING)) {
            setIsMutable(true);
        }
        super.preInitialize(session);
    }

    /**
     * INTERNAL:
     * The mapping is initialized with the given session. This mapping is fully initialized
     * after this.
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);
        setFieldClassification(XMLTypePlaceholder.class);
    }

    public DirectToXMLTypeMapping() {
        super();
        this.xmlTransformer = XMLPlatformFactory.getInstance().getXMLPlatform().newXMLTransformer();
        this.xmlTransformer.setFormattedOutput(false);
        this.xmlParser = XMLPlatformFactory.getInstance().getXMLPlatform().newXMLParser();
        this.xmlComparer = new XMLComparer();
    }

    /**
     * PUBLIC:
     * @param readWholeDocument - determines if the Oracle XDB DOM should be fully initialized
     * on a read.
     */
    public void setShouldReadWholeDocument(boolean readWholeDocument) {
        this.shouldReadWholeDocument = readWholeDocument;
    }

    /**
     * PUBLIC:
     * @return boolean - returns true if currently initializing DOMs on reads.
     */
    public boolean shouldReadWholeDocument() {
        return shouldReadWholeDocument;
    }

    /**
     * INTERNAL:
     * Get the attribute value for the given field value. If we're mapping to a
     * Document, we need to check if we should return the Oracle DOM or build a
     * new one.
     */
    @Override
    public Object getObjectValue(Object fieldValue, Session session) throws ConversionException {
        Object attributeValue = fieldValue;
        try {
            if (attributeValue != null) {
                if (this.attributeClassification != ClassConstants.STRING) {
                    String xml = (String)attributeValue;
                    java.io.StringReader reader = new java.io.StringReader(xml);
                    return this.xmlParser.parse(reader);
                }
            }
        } catch (Exception ex) {
            throw ConversionException.couldNotBeConverted(fieldValue, this.attributeClassification, ex);
        }

        if ((attributeValue == null) && (this.nullValue != null)) {// Translate default null value
            return this.nullValue;
        }

        // Allow for user defined conversion to the object value.
        if (this.converter != null) {
            attributeValue = this.converter.convertDataValueToObjectValue(attributeValue, session);
        }
        return attributeValue;
    }

    @Override
    public boolean isDirectToXMLTypeMapping() {
        return true;
    }

    /**
     * INTERNAL:
     * Clone the DOM Document if required.
     */
    @Override
    protected Object buildCloneValue(Object attributeValue, AbstractSession session) {
        Object newAttributeValue = attributeValue;
        if (isMutable() && attributeValue != null) {
            if ((getAttributeClassification() == ClassConstants.DOCUMENT) || (getAttributeClassification() == ClassConstants.NODE)) {
                Document doc = (Document)attributeValue;
                newAttributeValue = doc.cloneNode(true);
            }
        }
        return newAttributeValue;
    }

    /**
     * INTERNAL:
     * Compare the attribute values.
     * Compare Nodes if mapped as a DOM.
     */
    @Override
    protected boolean compareObjectValues(Object firstValue, Object secondValue, AbstractSession session) {
        // PERF: Check identity before conversion.
        if (firstValue == secondValue) {
            return true;
        }
        if ((firstValue == null) || (secondValue == null)) {
            return false;
        }
        if (getAttributeClassification() == ClassConstants.STRING) {
            return firstValue.equals(secondValue);
        } else {
            Object one = getFieldValue(firstValue, session);
            Object two = getFieldValue(secondValue, session);
            if (one instanceof Node && two instanceof Node) {
                return this.xmlComparer.isNodeEqual((Node)one, (Node)two);
            }
            return one.equals(two);
        }
    }
}
