/*
 * 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:
//     rbarkhouse - 2009-04-14 - 2.0 - Initial implementation

package org.eclipse.persistence.oxm.mappings;

import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * <p><b>Purpose:</b> An abstract superclass for XMLAnyObjectMapping and XMLAnyCollectionMapping.
 * Maps an attribute of an object to an xs:any construct in the schema.
 *
 *  @see XMLAnyObjectMapping
 *  @see XMLAnyCollectionMapping
 *
 */
public abstract class XMLAbstractAnyMapping extends DatabaseMapping {

    private UnmarshalKeepAsElementPolicy keepAsElementPolicy;
    private boolean isWriteOnly;

    public UnmarshalKeepAsElementPolicy getKeepAsElementPolicy() {
        return keepAsElementPolicy;
    }

    public void setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy keepAsElementPolicy) {
        this.keepAsElementPolicy = keepAsElementPolicy;
    }

    protected XMLDescriptor getDescriptor(XMLRecord xmlRecord, AbstractSession session, QName rootQName) throws XMLMarshalException {
        if (rootQName == null) {
            rootQName = new QName(xmlRecord.getNamespaceURI(), xmlRecord.getLocalName());
        }
        XMLContext xmlContext = xmlRecord.getUnmarshaller().getXMLContext();
        XMLDescriptor xmlDescriptor = xmlContext.getDescriptor(rootQName);
        if (null == xmlDescriptor) {
            if (!(getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT || getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT)) {
                throw XMLMarshalException.noDescriptorWithMatchingRootElement(xmlRecord.getLocalName());
            }
        }
        return xmlDescriptor;
    }

    protected Object buildObjectForNonXMLRoot(ClassDescriptor referenceDescriptor, XMLConverter converter, ObjectBuildingQuery query, DOMRecord record, DOMRecord nestedRecord, JoinedAttributeManager joinManager, AbstractSession session, Node next, Object container, ContainerPolicy containerPolicy) {
        Object objectValue = null;

        if ((referenceDescriptor != null) && (getKeepAsElementPolicy() != UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT)) {
            ObjectBuilder builder = referenceDescriptor.getObjectBuilder();
            objectValue = builder.buildObject(query, nestedRecord, joinManager);
            if (converter != null) {
                objectValue = converter.convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
            }
            if (containerPolicy != null) {
                containerPolicy.addInto(objectValue, container, session);
            }
        } else {
            if ((getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) || (getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT)) {
                XMLPlatformFactory.getInstance().getXMLPlatform().namespaceQualifyFragment((Element) next);
                objectValue = next;
                if (converter != null) {
                    objectValue = converter.convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
                }
                if (containerPolicy != null) {
                    containerPolicy.addInto(objectValue, container, session);
                }
            }
        }

        return objectValue;
    }

    /**
     * Uses a given reference descriptor to build an object based on a given DOMRecord.
     * If a converter is provided it is applied to the newly built object.  The
     * reference descriptor will wrap the object in an XMLRoot if required, and the
     * object will be added to the given Container Policy if it is non-null.
     */
    protected Object buildObjectAndWrapInXMLRoot(ClassDescriptor referenceDescriptor, XMLConverter converter, ObjectBuildingQuery query, DOMRecord record, DOMRecord nestedRecord, JoinedAttributeManager joinManager, AbstractSession session, Node next, Object container, ContainerPolicy containerPolicy) {
        ObjectBuilder builder = referenceDescriptor.getObjectBuilder();
        Object objectValue = builder.buildObject(query, nestedRecord, joinManager);
        if (converter != null) {
            objectValue = converter.convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
        }
        Object updated = ((XMLDescriptor) referenceDescriptor).wrapObjectInXMLRoot(objectValue, next.getNamespaceURI(), next.getLocalName(), next.getPrefix(), false, record.isNamespaceAware(), record.getUnmarshaller());
        if (containerPolicy != null) {
            containerPolicy.addInto(updated, container, session);
        }
        return updated;
    }

    /**
     * Convenience method that takes a given Node and applies namespace
     * information, converts it if necessary, and adds the resulting
     * object to the given ContainerPolicy if non-null.
     */
    protected Object buildObjectNoReferenceDescriptor(DOMRecord record, XMLConverter converter, AbstractSession session, Node next, Object container, ContainerPolicy cp) {
        XMLPlatformFactory.getInstance().getXMLPlatform().namespaceQualifyFragment((Element) next);
        Object objectValue = next;
        if (converter != null) {
            objectValue = converter.convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
        }
        if (cp != null) {
            cp.addInto(objectValue, container, session);
        }
        return objectValue;
    }

    /**
     * Convenience method that takes a given node and checks the first child for
     * TEXT_NODE.  If the first child is a text node containing a non-empty
     * String, the String value will be processed and wrapped in an XMLRoot.
     * If schemaTypeQName represents a default XML type (boolean, dateTime, etc)
     * the String value will be converted to that type.  If a converter is
     * provided it will be applied before wrapping in an XMLRoot.
     */
    protected XMLRoot buildXMLRootForText(Node node, QName schemaTypeQName, XMLConverter converter, AbstractSession session, DOMRecord record) {
        XMLRoot rootValue = null;
        Node textchild = node.getFirstChild();
        if ((textchild != null) && (textchild.getNodeType() == Node.TEXT_NODE)) {
            String stringValue = textchild.getNodeValue();
            if ((stringValue != null) && stringValue.length() > 0) {
                Object convertedValue = stringValue;
                if (schemaTypeQName != null) {
                    ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
                    Class<Object> theClass = conversionManager.javaType(schemaTypeQName);
                    if (theClass != null) {
                        convertedValue = conversionManager.convertObject(convertedValue, theClass, schemaTypeQName);
                    }
                }
                if (converter != null) {
                    convertedValue = converter.convertDataValueToObjectValue(convertedValue, session, record.getUnmarshaller());
                }
                rootValue = new XMLRoot();
                rootValue.setLocalName(node.getLocalName());
                rootValue.setSchemaType(schemaTypeQName);
                rootValue.setNamespaceURI(node.getNamespaceURI());
                rootValue.setObject(convertedValue);
            }
        }
        return rootValue;
    }

    /**
     * Convenience method that builds an XMLRoot wrapping a given object.
     * The local name and uri are set using the given Node.
     */
    protected XMLRoot buildXMLRoot(Node node, Object object) {
        XMLRoot xmlRoot = new XMLRoot();
        xmlRoot.setLocalName(node.getLocalName());
        xmlRoot.setNamespaceURI(node.getNamespaceURI());
        xmlRoot.setObject(object);
        return xmlRoot;
    }

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

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

    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        if(isWriteOnly()) {
            return;
        }
        super.setAttributeValueInObject(object, value);
    }

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