/*
 * Copyright (c) 1998, 2021 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.oxm.mappings;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.AbstractUnmarshalRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.NullPolicy;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.sessions.Session;

/**
 * <p>XML Direct Mappings map a Java attribute directly to XML attribute or text node.
 *
 * <p><b>XML Direct Mappings can be used in the following scenarios</b>:<ul>
 * <li>Mapping to a Text Node</li>
 * <li>Mapping to an Attribute</li>
 * <li>Mapping to a Specified Schema Type</li>
 * <li>Mapping to a List Field</li>
 * <li>Mapping to a Union Field</li>
 * <li>Mapping to a Union of Lists</li>
 * <li>Mapping to a Union of Unions</li>
 * <li>Mapping with a Simple Type Translator</li>
 * </ul>
 *
 * <p><b>Setting the XPath</b>: TopLink XML mappings make use of XPath statements to find the relevant
 * data in an XML document.  The XPath statement is relative to the context node specified in the descriptor.
 * The XPath may contain node type, path, and positional information.  The XPath is specified on the
 * mapping using the <code>setXPath</code> method.
 *
 * <p>The following XPath statements may be used to specify the location of XML data relating to an object's
 * name attribute:
 *
 * <table border="1">
 * <caption>XPath statements</caption>
 * <tr>
 * <th id="c1">XPath</th>
 * <th id="c2">Description</th>
 * </tr>
 * <tr>
 * <td headers="c1">@name</td>
 * <td headers="c2">The "@" character indicates that the node is an attribute.</td>
 * </tr>
 * <tr>
 * <td headers="c1">text()</td>
 * <td headers="c2">"text()" indicates that the node is a text node.  In this case the name value in the
 * text node belongs to the context node.</td>
 * </tr>
 * <tr>
 * <td headers="c1">full-name/text()</td>
 * <td headers="c2">The name information is stored in the text node of the full-name element.</td>
 * </tr>
 * <tr>
 * <td headers="c1" style="nowrap">personal-info/name/text()</td>
 * <td headers="c2">The XPath statement may be used to specify any valid path.</td>
 * </tr>
 * <tr>
 * <td headers="c1">name[2]/text()</td>
 * <td headers="c2">The XPath statement may contain positional information.  In this case the name
 * information is stored in the text node of the second occurrence of the name element.</td>
 * </tr>
 * </table>
 *
 * <p><b>Mapping to a Specific Schema Type</b>: In most cases TopLink can determine the target format in the
 * XML document.  However, there are cases where you must specify which one of a number of possible targets
 * TopLink should use. For example, a java.util.Calendar could be marshalled to a schema date, time, or dateTime,
 * or a byte[] could be marshalled to a schema hexBinary or base64Binary node.
 *
 * <!--
 *    <?xml version="1.0" encoding="UTF-8"?>
 *    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 *        <xsd:element name="customer" type="customer-type"/>
 *        <xsd:complexType name="customer-type">
 *            <xsd:sequence>
 *                <xsd:element name="picture" type="xsd:hexBinary"/>
 *                <xsd:element name="resume" type="xsd:base64Binary"/>
 *            </xsd:sequence>
 *        </xsd:complexType>
 *    </xsd:schema>
 * -->
 *
 * <p><em>XML Schema</em><br>
 * <code>
 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
 * &lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="customer" type="customer-type"/&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:complexType name="customer-type"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="picture" type="xsd:hexBinary"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="resume" type="xsd:base64Binary"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &lt;/xsd:schema&gt;<br>
 * </code>
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLDirectMapping pictureMapping = new XMLDirectMapping();<br>
 * pictureMapping.setAttributeName("picture");<br>
 * pictureMapping.setXPath("picture/text()");<br>
 * XMLField pictureField = (XMLField) pictureMapping.getField();<br>
 * pictureField.setSchemaType(XMLConstants.HEX_BINARY_QNAME);<br>
 * </code>
 *
 * <p><b>Mapping to a Union Field</b>:
 *
 * <!--
 * <?xml version="1.0" encoding="UTF-8"?>
 * <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 *        <xsd:element name="customer" type="customer-type"/>
 *        <xsd:complexType name="customer-type">
 *            <xsd:sequence>
 *                <xsd:element name="shoe-size" type="size-type"/>
 *            </xsd:sequence>
 *        </xsd:complexType>
 *        <xsd:simpleType name="size-type">
 *            <xsd:union memberTypes="xsd:decimal xsd:string"/>
 *        </xsd:simpleType>
 * </xsd:schema>
 * -->
 *
 * <p><em>XML Schema</em><br>
 * <code>
 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
 * &lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="customer" type="customer-type"/&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:complexType name="customer-type"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="shoe-size" type="size-type"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:simpleType name="size-type"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:union memberTypes="xsd:decimal xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:simpleType&gt;<br>
 * &lt;/xsd:schema&gt;<br>
 * </code>
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLDirectMapping shoeSizeMapping = new XMLDirectMapping();<br>
 * shoeSizeMapping.setAttributeName("shoeSize");<br>
 * XMLUnionField shoeSizeField = new XMLUnionField();<br>
 * shoeSizeField.setXPath("shoe-size/text()");<br>
 * shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);<br>
 * shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);<br>
 * shoeSizeMapping.setField(shoeSizeField);<br>
 * </code>
 *
 * <p><b>Preserving the Node Type</b>: If the type of a node is not defined in your XML schema,
 * you can configure an XML Direct Mapping to use the xsi:type attribute to provide type information.
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLDirectMapping numberMapping = new XMLDirectMapping();<br>
 * numberMapping.setAttributeName("number");<br>
 * numberMapping.setXPath("number/text()");<br>
 * XMLField numberField = (XMLField) numberMapping.getField();<br>
 * numberField.setIsTypedTextField(true);<br>
 * </code>
 *
 * <p><b>More Information</b>: For more information about using the XML Direct Mapping, see the
 * "Understanding XML Mappings" chapter of the Oracle TopLink Developer's Guide.
 *
 * @since Oracle TopLink 10<i>g</i> Release 2 (10.1.3)
 */
public class XMLDirectMapping extends AbstractDirectMapping implements XMLMapping, DirectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLRecord>, XMLNillableMapping {

    AbstractNullPolicy nullPolicy;
    public boolean isCDATA;
    private boolean isWriteOnly;
    private boolean isCollapsingStringValues;
    private boolean isNormalizingStringValues;
    private boolean isNullValueMarshalled = false;

    public XMLDirectMapping() {
        super();
        // The default policy is NullPolicy
        nullPolicy = new NullPolicy();
        nullPolicy.setNullRepresentedByEmptyNode(true);
        isCDATA = false;
    }

    /**
     * Set the AbstractNullPolicy on the mapping<br>
     * The default policy is NullPolicy.<br>
     *
     */
    @Override
    public void setNullPolicy(AbstractNullPolicy aNullPolicy) {
        nullPolicy = aNullPolicy;
    }

    /**
     * INTERNAL:
     * Get the AbstractNullPolicy from the Mapping.<br>
     * The default policy is NullPolicy.<br>
     */
    @Override
    public AbstractNullPolicy getNullPolicy() {
        return nullPolicy;
    }


    /**
     * INTERNAL:
     */
    @Override
    public boolean isXMLMapping() {
        return true;
    }

    /**
     * Set the Mapping field name attribute to the given XPath String
     * @param xpathString String
     */
    @Override
    public void setXPath(String xpathString) {
        if ((xpathString.indexOf(XMLConstants.ATTRIBUTE) == -1) && (!xpathString.endsWith(XMLConstants.TEXT))) {
            xpathString += '/' + XMLConstants.TEXT;
        }
        setField(new XMLField(xpathString));
    }
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);
        ((XMLField)getField()).setIsCDATA(this.isCDATA());
        String xpathString = ((XMLField)getField()).getXPath();
        if (this.isAbstractDirectMapping() && (xpathString.indexOf(XMLConstants.ATTRIBUTE) == -1) && (!xpathString.endsWith(XMLConstants.TEXT))) {
            throw DescriptorException.invalidXpathForXMLDirectMapping(this);
        }
    }

    /**
     * INTERNAL:
     * Allows for subclasses to convert the attribute value.
     */
    @Override
    public Object getAttributeValue(Object fieldValue, AbstractSession session, AbstractUnmarshalRecord record) {
        // Unmarshal DOM
        // If attribute is empty string representing (null) then return the nullValue
        boolean isNullRepresentedByEmptyNode = nullPolicy.isNullRepresentedByEmptyNode();
        boolean isNullRepresentedByXsiNil = nullPolicy.isNullRepresentedByXsiNil();
        if (isNullRepresentedByEmptyNode && XMLConstants.EMPTY_STRING.equals(fieldValue)) {
           fieldValue = null;
        } else if (null == fieldValue && !isNullRepresentedByEmptyNode) {
            fieldValue = XMLConstants.EMPTY_STRING;
        }

        // PERF: Direct variable access.
        Object attributeValue = fieldValue;
        // If attribute is absent check the policy
        if(attributeValue == XMLRecord.noEntry) {
            if(!getNullPolicy().getIsSetPerformedForAbsentNode()) {
                return attributeValue;
            } else {
                fieldValue = null;
                attributeValue = null;
            }
        }

        if (attributeValue == XMLRecord.NIL && isNullRepresentedByXsiNil) {
            fieldValue = null;
            attributeValue = null;
        }

        // Allow for user defined conversion to the object value.
        if (converter != null) {
            attributeValue = convertDataValueToObjectValue(attributeValue, session, (XMLUnmarshaller) record.getUnmarshaller());
        } else {
            // PERF: Avoid conversion check when not required.
            if ((attributeValue == null) || (attributeValue.getClass() != this.attributeObjectClassification)) {
                try {
                    attributeValue = session.getDatasourcePlatform().convertObject(attributeValue, this.attributeClassification);
                } catch (ConversionException e) {
                    throw ConversionException.couldNotBeConverted(this, getDescriptor(), e);
                }
            }
        }
        if (attributeValue == null) {// Translate default null value, conversion may have produced null.
            attributeValue = this.nullValue;
        }

        return attributeValue;
    }

    /**
     * INTERNAL:
     * Convert the attribute value to a field value.
     * Process any converter if defined, and check for null values.
     */
    @Override
    public Object getFieldValue(Object attributeValue, CoreAbstractSession session, AbstractMarshalRecord record) {
        // Marshal
        // PERF: This method is a major performance code point,
        // so has been micro optimized and uses direct variable access.
        Object fieldValue = attributeValue;

        if ((this.nullValue != null) && (this.nullValue.equals(fieldValue)) && !this.isNullValueMarshalled && !((XMLField)field).isRequired()) {
            return null;
        }

        // Allow for user defined conversion to the object value.
        fieldValue = convertObjectValueToDataValue(fieldValue, (AbstractSession) session, (XMLMarshaller) record.getMarshaller());

        if (fieldValue != null) {
             Class fieldClassification = getFieldClassification(field);
             // PERF: Avoid conversion if not required.
             if(fieldClassification != fieldValue.getClass()){
                 try {
                     fieldValue = session.getPlatform(descriptor.getJavaClass()).convertObject(fieldValue, fieldClassification);
                 } catch (ConversionException exception) {
                     throw ConversionException.couldNotBeConverted(this, descriptor, exception);
                 }
             }
        }
        return fieldValue;
    }

    /**
     * Get the XPath String
     * @return String the XPath String associated with this Mapping
     */
    @Override
    public String getXPath() {
        return getFieldName();
    }

    /**
     * INTERNAL:
     * Return the mapping's attribute value from the row.
     * The execution session is passed for the case of building a UnitOfWork clone
     * directly from a row, the session set in the query will not know which platform to use
     * for converting the value.  Allows the correct session to be passed in.
     */
    @Override
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery query, CacheKey cacheKey, AbstractSession executionSession, boolean isTargetProtected, Boolean[] wasCacheUsed) {
        // PERF: Direct variable access.
        boolean shouldCheckForXsiNil = getNullPolicy().isNullRepresentedByXsiNil();
        return getAttributeValue(((DOMRecord)row).getIndicatingNoEntry(this.field, false, shouldCheckForXsiNil), executionSession, (XMLRecord)row);
    }

    /**
     * INTERNAL:
     * Get a value from the object and set that in the respective field of the row.
     */
    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) {
        if (isReadOnly()) {
            return;
        }
        writeSingleValue(getAttributeValueFromObject(object), object, (XMLRecord)row, session);
    }

    @Override
    protected void writeValueIntoRow(AbstractRecord row, DatabaseField aField, Object fieldValue) {
            row.put(getField(), fieldValue);
    }

    @Override
    public void writeSingleValue(Object value, Object parent, XMLRecord row, AbstractSession session) {
        Object fieldValue = getFieldValue(value, session, row);
        if(fieldValue == null && getNullPolicy() != null) {
            getNullPolicy().directMarshal((Field) this.getField(), row, parent);
        } else {
            writeValueIntoRow(row, getField(), fieldValue);
        }
    }

    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        // PERF: Direct variable access.
        if(isWriteOnly()) {
            return;
        }
        try {
            if(value == XMLRecord.noEntry) {
                return;
            }
            if (value != null && value instanceof String) {
                if(isCollapsingStringValues) {
                    value = XMLConversionManager.getDefaultXMLManager().collapseStringValue((String)value);
                } else if(isNormalizingStringValues) {
                    value = XMLConversionManager.getDefaultXMLManager().normalizeStringValue((String)value);
                }
            }
            this.attributeAccessor.setAttributeValueInObject(object, value);
        } catch (DescriptorException exception) {
            exception.setMapping(this);
            throw exception;
        }
    }

    @Override
    public void setIsCDATA(boolean CDATA) {
        isCDATA = CDATA;
    }

    @Override
    public boolean isCDATA() {
        return isCDATA;
    }

    @Override
    public boolean isWriteOnly() {
        return this.isWriteOnly;
    }

    @Override
    public void setIsWriteOnly(boolean b) {
        this.isWriteOnly = b;
    }

    @Override
    public boolean isCloningRequired() {
        return false;
    }

    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        getAttributeAccessor().setIsWriteOnly(this.isWriteOnly());
        getAttributeAccessor().setIsReadOnly(this.isReadOnly());
        super.preInitialize(session);
    }


    /**
     * PUBLIC:
     * Returns true if this mapping is normalizing string values on unmarshal before setting
     * them in the object. Normalize replaces any CR, LF or Tab characters with a
     * single space character.
     */
    public boolean isNormalizingStringValues() {
        return this.isNormalizingStringValues;
    }

    /**
     * PUBLIC:
     * Indicates that this mapping should normalize all string values before setting them
     * in the object on unmarshal. Normalize replaces any CR, LF or Tab characters with a
     * single space character.
     */
    @Override
    public void setNormalizingStringValues(boolean normalize) {
        this.isNormalizingStringValues = normalize;
    }


    /**
     * PUBLIC:
     * Indicates that this mapping should collapse all string values before setting them
     * in the object on unmarshal. Collapse removes leading and trailing whitespaces, and replaces
     * any sequence of whitepsace characters with a single space.
     */
    @Override
    public void setCollapsingStringValues(boolean collapse) {
        this.isCollapsingStringValues = collapse;
    }

    /**
     * PUBLIC:
     * Returns true if this mapping should collapse all string values before setting them
     * in the object on unmarshal. Collapse removes leading and trailing whitespaces, and replaces
     * any sequence of whitepsace characters with a single space.
     */
    public boolean isCollapsingStringValues() {
        return this.isCollapsingStringValues;
    }

    /**
     * PUBLIC:
     * Returns true if this mapping's value should be marshalled, in the case that
     * it is equal to the default null value.
     */
    public boolean isNullValueMarshalled() {
        return this.isNullValueMarshalled;
    }

    /**
     * PUBLIC:
     * Set whether this mapping's value should be marshalled, in the case that
     * it is equal to the default null value.
     */
    @Override
    public void setNullValueMarshalled(boolean value) {
        this.isNullValueMarshalled = value;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertObjectValueToDataValue(Object value, Session session, XMLMarshaller marshaller) {
        if (hasConverter()) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertObjectValueToDataValue(value, session, marshaller);
            } else {
                return converter.convertObjectValueToDataValue(value, session);
            }
        }
        return value;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertDataValueToObjectValue(Object fieldValue, Session session, XMLUnmarshaller unmarshaller) {
        if (hasConverter()) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertDataValueToObjectValue(fieldValue, session, unmarshaller);
            } else {
                return converter.convertDataValueToObjectValue(fieldValue, session);
            }
        }
        return fieldValue;
    }

}
