/*
 * 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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.oxm.XPathEngine;
import org.eclipse.persistence.internal.oxm.mappings.AnyAttributeMapping;
import org.eclipse.persistence.internal.oxm.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * <p><b>Purpose</b>:The XMLAnyAttributeMapping is used to map to an attribute in an object to any xml attributes contained
 * on a specific element in the XML Document. The attribute in the object will contain a map of attribute values keyed
 * on QName. In the case that one or more of the attributes found on the specified element is already mapped to another
 * attribute in the object, that attribute will be ignored during the unmarshal operation.
 *
 * <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.  Note that for XML Any Attribute Mappings the XPath
 * is optional. Not setting the xpath, will cause the mapping to look for any attribute children directly owned by the
 * current Element.
 *
 */
public class XMLAnyAttributeMapping extends DatabaseMapping implements XMLMapping,AnyAttributeMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, XMLRecord> {
    private AbstractNullPolicy wrapperNullPolicy;
    private XMLField field;
    private MappedKeyMapContainerPolicy containerPolicy;
    private boolean isDefaultEmptyContainer = XMLContainerMapping.EMPTY_CONTAINER_DEFAULT;
    private boolean isNamespaceDeclarationIncluded;
    private boolean isSchemaInstanceIncluded;
    private boolean isWriteOnly;
    private boolean reuseContainer;

    public XMLAnyAttributeMapping() {
        this.containerPolicy = new MappedKeyMapContainerPolicy(HashMap.class);
        this.containerPolicy.setKeyMapping(new XMLDirectMapping());
        this.isNamespaceDeclarationIncluded = true;
        this.isSchemaInstanceIncluded = true;
    }

    /**
    * INTERNAL:
    * Clone the attribute from the clone and assign it to the backup.
    */
    @Override
    public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        throw DescriptorException.invalidMappingOperation(this, "buildBackupClone");
    }

    /**
    * INTERNAL:
    * Clone the attribute from the original and assign it to the clone.
    */
    @Override
    public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
        throw DescriptorException.invalidMappingOperation(this, "buildClone");
    }

    @Override
    public void buildCloneFromRow(AbstractRecord Record, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession) {
        throw DescriptorException.invalidMappingOperation(this, "buildCloneFromRow");
    }

    /**
     * INTERNAL:
     * Cascade perform delete through mappings that require the cascade
     */
    @Override
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        //objects referenced by this mapping are not registered as they have
        // no identity, this is a no-op.
    }

    /**
      * INTERNAL:
      * Cascade registerNew for Create through mappings that require the cascade
      */
    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        //Our current XML support does not make use of the UNitOfWork.
    }

    @Override
    public Object clone() {
        // Bug 3037701 - clone the AttributeAccessor
        XMLAnyAttributeMapping mapping = null;
        mapping = (XMLAnyAttributeMapping) super.clone();
        mapping.setContainerPolicy(this.getContainerPolicy());
        mapping.setField(this.getField());
        return mapping;
    }

    /**
    * INTERNAL:
    * This method was created in VisualAge.
    * @return prototype.changeset.ChangeRecord
    */
    @Override
    public ChangeRecord compareForChange(Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) {
        throw DescriptorException.invalidMappingOperation(this, "compareForChange");
    }

    /**
    * INTERNAL:
    * Compare the attributes belonging to this mapping for the objects.
    */
    @Override
    public boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session) {
        throw DescriptorException.invalidMappingOperation(this, "compareObjects");
    }

    /**
    * INTERNAL:
    * An object has been serialized from the server to the client.
    * Replace the transient attributes of the remote value holders
    * with client-side objects.
    */
    @Override
    public void fixObjectReferences(Object object, Map objectDescriptors, Map processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        throw DescriptorException.invalidMappingOperation(this, "fixObjectReferences");
    }

    /**
    * INTERNAL:
    * Return the mapping's containerPolicy.
    */
    @Override
    public ContainerPolicy getContainerPolicy() {
        return containerPolicy;
    }

    @Override
    public DatabaseField getField() {
        return field;
    }

    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        if (getField() != null) {
            setField(getDescriptor().buildField(getField()));
        }
        ContainerPolicy cp = getContainerPolicy();
        if (cp != null && cp.getContainerClass() == null) {
            Class cls = session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(cp.getContainerClassName());
            cp.setContainerClass(cls);
        }
    }

    /**
    * INTERNAL:
    * Iterate on the appropriate attribute value.
    */
    @Override
    public void iterate(DescriptorIterator iterator) {
        throw DescriptorException.invalidMappingOperation(this, "iterate");
    }

    public void setXPath(String xpath) {
        this.field = new XMLField(xpath);
    }

    /**
    * INTERNAL:
    * Merge changes from the source to the target object.
    */
    @Override
    public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
        throw DescriptorException.invalidMappingOperation(this, "mergeChangesIntoObject");
    }

    /**
    * INTERNAL:
    * Merge changes from the source to the target object.
    */
    @Override
    public void mergeIntoObject(Object target, boolean isTargetUninitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
        throw DescriptorException.invalidMappingOperation(this, "mergeIntoObject");
    }

    public void setContainerPolicy(ContainerPolicy cp) {
        if (!cp.isMappedKeyMapPolicy()) {
            throw DescriptorException.invalidContainerPolicy(cp, this.getClass());
        }
        if (((MappedKeyMapContainerPolicy)cp).getKeyMapping() == null) {
            ((MappedKeyMapContainerPolicy)cp).setKeyMapping(new XMLDirectMapping());
        }
        this.containerPolicy = (MappedKeyMapContainerPolicy) cp;
    }

    @Override
    public void setField(DatabaseField field) {
        this.field = (XMLField) field;
    }

    @Override
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey cacheKey, AbstractSession executionSession, boolean isTargetProtected, Boolean[] wasCacheUsed) throws DatabaseException {
        XMLRecord record = (XMLRecord) row;

        if (getField() != null) {
            //Get the nested row represented by this field to build the collection from
            Object nested = record.get(getField());
            if (nested instanceof Vector) {
                nested = ((Vector) nested).firstElement();
            }
            if (!(nested instanceof XMLRecord)) {
                return null;
            }
            record = (XMLRecord) nested;
        }
        return buildObjectValuesFromDOMRecord((DOMRecord) record, executionSession, sourceQuery);
    }

    private Object buildObjectValuesFromDOMRecord(DOMRecord record, AbstractSession session, ObjectBuildingQuery query) {
        //This DOMRecord represents the root node of the AnyType instance
        //Grab ALL children to populate the collection.
        ContainerPolicy cp = getContainerPolicy();

        Object container = null;
        if (reuseContainer) {
            Object currentObject = record.getCurrentObject();
            Object value = getAttributeAccessor().getAttributeValueFromObject(currentObject);
            container = value != null ? value : cp.containerInstance();
        } else {
            container = cp.containerInstance();
        }

        org.w3c.dom.Element root = (Element) record.getDOM();
        NamedNodeMap attributes = root.getAttributes();
        Attr next;
        String localName;
        int numberOfAtts = attributes.getLength();
        for (int i = 0; i < numberOfAtts; i++) {
            next = (Attr) attributes.item(i);
            localName = next.getLocalName();
            if (null == localName) {
                localName = next.getName();
            }
            String namespaceURI = next.getNamespaceURI();
            boolean includeAttribute = true;
            if (!isNamespaceDeclarationIncluded && javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)){
                includeAttribute = false;
            } else if (!isSchemaInstanceIncluded && javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(namespaceURI)){
                includeAttribute = false;
            }

            if (includeAttribute){
                String value = next.getValue();
                QName key = new QName(namespaceURI, localName);
                cp.addInto(key, value, container, session);
            }
        }
        return container;
    }

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

    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) throws DescriptorException {
        if (this.isReadOnly()) {
            return;
        }
        Object attributeValue = this.getAttributeValueFromObject(object);
        writeSingleValue(attributeValue, object, (XMLRecord) row, session);
    }

    protected AbstractRecord buildCompositeRow(Object attributeValue, AbstractSession session, AbstractRecord parentRow) {
        XMLDescriptor referenceDescriptor = (XMLDescriptor) session.getDescriptor(attributeValue.getClass());
        if ((referenceDescriptor != null) && (referenceDescriptor.getDefaultRootElement() != null)) {
            XMLObjectBuilder objectBuilder = (XMLObjectBuilder) referenceDescriptor.getObjectBuilder();
            return objectBuilder.buildRow(attributeValue, session, referenceDescriptor.buildField(referenceDescriptor.getDefaultRootElement()), (XMLRecord) parentRow);
        }
        return null;
    }

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

    @Override
    public Vector getFields() {
        return this.collectFields();
    }

    public void useMapClass(Class concreteMapClass) {
        if (!Helper.classImplementsInterface(concreteMapClass, Map.class)) {
            throw DescriptorException.illegalContainerClass(concreteMapClass);
        }
        this.containerPolicy.setContainerClass(concreteMapClass);
    }

    @Override
    public void writeSingleValue(Object attributeValue, Object parent, XMLRecord row, AbstractSession session) {
        ContainerPolicy cp = this.getContainerPolicy();
        if ((attributeValue == null) || (cp.sizeFor(attributeValue) == 0)) {
            return;
        }
        DOMRecord record = (DOMRecord) row;
        if (record.getDOM().getNodeType() != Node.ELEMENT_NODE) {
            return;
        }
        DOMRecord recordToModify = record;
        Element root = (Element) record.getDOM();
        if (field != null) {
            root = (Element) XPathEngine.getInstance().create((XMLField) getField(), root, session);
            recordToModify = new DOMRecord(root);
        }

        List extraNamespaces = new ArrayList();
        NamespaceResolver nr = recordToModify.getNamespaceResolver();
        for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter);) {
            Map.Entry entry = (Map.Entry)cp.nextEntry(iter, session);
            Object key = entry.getKey();
            if ((key != null) && key instanceof QName) {
                Object value = entry.getValue();
                QName attributeName = (QName) key;
                String namespaceURI = attributeName.getNamespaceURI();
                String qualifiedName = attributeName.getLocalPart();

                if (nr != null) {
                    String prefix = nr.resolveNamespaceURI(attributeName.getNamespaceURI());
                    if ((prefix != null) && prefix.length() > 0) {
                        qualifiedName = prefix + XMLConstants.COLON + qualifiedName;
                    } else if (attributeName.getNamespaceURI() != null && attributeName.getNamespaceURI().length() > 0) {
                        String generatedPrefix = nr.generatePrefix();
                        qualifiedName = generatedPrefix + XMLConstants.COLON + qualifiedName;
                        nr.put(generatedPrefix, attributeName.getNamespaceURI());
                        extraNamespaces.add(new Namespace(generatedPrefix, attributeName.getNamespaceURI()));
                        recordToModify.getNamespaceResolver().put(generatedPrefix, attributeName.getNamespaceURI());
                    }
                }
                if (namespaceURI != null) {
                    root.setAttributeNS(namespaceURI, qualifiedName, value.toString());
                } else {
                    root.setAttribute(attributeName.getLocalPart(), value.toString());
                }
            }
        }

        ((XMLObjectBuilder) descriptor.getObjectBuilder()).writeExtraNamespaces(extraNamespaces, recordToModify);
        recordToModify.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session);
    }

    /**
     * INTERNAL:
     * Indicates the Map class to be used.
     *
     * @param concreteMapClass
     */

    /**
     * INTERNAL:
     * Indicates the name of the Map class to be used.
     *
     */
    @Override
    public void useMapClassName(String concreteMapClassName) {
        MappedKeyMapContainerPolicy policy = new MappedKeyMapContainerPolicy(concreteMapClassName);
        policy.setKeyMapping(new XMLDirectMapping());
        this.setContainerPolicy(policy);
    }

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

    @Override
    public void setNamespaceDeclarationIncluded(boolean isNamespaceDeclarationIncluded) {
        this.isNamespaceDeclarationIncluded = isNamespaceDeclarationIncluded;
    }

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

    @Override
    public void setSchemaInstanceIncluded(boolean isSchemaInstanceIncluded) {
        this.isSchemaInstanceIncluded = isSchemaInstanceIncluded;
    }

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

    @Override
    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);
    }

    /**
     * Return true if the original container on the object should be used if
     * present.  If it is not present then the container policy will be used to
     * create the container.
     */
    @Override
    public boolean getReuseContainer() {
        return reuseContainer;
    }

    /**
     * Specify whether the original container on the object should be used if
     * present.  If it is not present then the container policy will be used to
     * create the container.
     */
    @Override
    public void setReuseContainer(boolean reuseContainer) {
        this.reuseContainer = reuseContainer;
    }

    /**
     * INTERNAL
     * Return true if an empty container should be set on the object if there
     * is no presence of the collection in the XML document.
     * @since EclipseLink 2.3.3
     */
    @Override
    public boolean isDefaultEmptyContainer() {
        return isDefaultEmptyContainer;
    }

    /**
     * INTERNAL
     * Indicate whether by default an empty container should be set on the
     * field/property if the collection is not present in the XML document.
     * @since EclipseLink 2.3.3
     */
    @Override
    public void setDefaultEmptyContainer(boolean defaultEmptyContainer) {
        this.isDefaultEmptyContainer = defaultEmptyContainer;
    }

    @Override
    public AbstractNullPolicy getWrapperNullPolicy() {
        return this.wrapperNullPolicy;
    }

    @Override
    public void setWrapperNullPolicy(AbstractNullPolicy policy) {
        this.wrapperNullPolicy = policy;
    }

}
