/*
 * Copyright (c) 1998, 2019 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>
     *
     * @param aNullPolicy
     */
    @Override
    public void setNullPolicy(AbstractNullPolicy aNullPolicy) {
        nullPolicy = aNullPolicy;
    }

    /**
     * INTERNAL:
     * Get the AbstractNullPolicy from the Mapping.<br>
     * The default policy is NullPolicy.<br>
     * @return
     */
    @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.
     * @param normalize
     */
    @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.
     * @param collapse
     */
    @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;
    }

}
