/*
 * 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;

import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.oxm.documentpreservation.XMLBinderPolicy;
import org.eclipse.persistence.internal.oxm.record.DOMReader;
import org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;

/**
 * PUBLIC:
 * <p><b>Purpose:</b>Provide a runtime public interface for preserving unmapped content from an
 * XML Document.
 * <p><b>Responsibilities:</b><ul>
 * <li>Unmarshal XML into JavaObjects and maintain the associations between nodes and objects</li>
 * <li>Update the cached XML based on changes to the object</li>
 * <li>Update the cached objects based on changes to the XML Document</li>
 * <li>Provide API to access the cached Node for a given object</li>
 * <li>Provide API to access the cached Object for a given XML Node</li>
 * </ul>
 *
 * <p>The XML Binder is a runtime class that allows an association to be maintained between the
 * original XML Document and the Java Objects built from the Document. It allows unmapped content
 * (such as comments, processing instructions or other unmapped elements and attributes) to be
 * preserved. The XMLBinder is created through an XMLContext.
 *
 *  @see org.eclipse.persistence.oxm.XMLContext
 *  @author mmacivor
 */

public class XMLBinder {

    SAXUnmarshaller saxUnmarshaller;
    XMLContext context;
    XMLMarshaller marshaller;
    XMLUnmarshaller unmarshaller;
    DocumentPreservationPolicy documentPreservationPolicy;
    DOMReader reader;

    public XMLBinder(XMLContext context) {
        this.context = new XMLContext(context.getXMLContextState());
        marshaller = this.context.createMarshaller();
        unmarshaller = this.context.createUnmarshaller();
        initialize();
    }

    public XMLBinder(XMLContext context, XMLMarshaller marshaller, XMLUnmarshaller unmarshaller) {
        this.context = new XMLContext(context.getXMLContextState());
        this.marshaller = marshaller;
        this.unmarshaller = unmarshaller;
        initialize();
    }

    private void initialize() {
        saxUnmarshaller = new SAXUnmarshaller(unmarshaller, null);
        documentPreservationPolicy = new XMLBinderPolicy();
        reader = new DOMReader(unmarshaller);
    }

    /**
     * This method will unmarshal the provided node into mapped java objects. The original node
     * will be cached rather than thrown away.
     * @return The root object unmarshalled from the provided node.
     */
    public Object unmarshal(org.w3c.dom.Node node) {
        validateNode(node);

        reader.setDocPresPolicy(documentPreservationPolicy);
        Object toReturn = saxUnmarshaller.unmarshal(reader, node);
        return toReturn;
    }

    private void validateNode(org.w3c.dom.Node node) {
        if (getSchema() != null) {
            Validator validator = getSchema().newValidator();
            validator.setErrorHandler(getErrorHandler());
            try {
                validator.validate(new DOMSource(node));
            } catch (Exception e) {
                throw XMLMarshalException.validateException(e);
            }
        }
    }

    public XMLRoot unmarshal(org.w3c.dom.Node node, Class javaClass) {
        validateNode(node);
        reader.setDocPresPolicy(documentPreservationPolicy);
        return buildXMLRootFromObject(saxUnmarshaller.unmarshal(reader, node, javaClass));
    }

    /**
     * This method will update the cached XML node for the provided object. If no node exists for this
     * object, then no operation is performed.
     */
    public void updateXML(Object obj) {
        if(obj instanceof Root) {
            obj = ((Root)obj).getObject();
        }
        Node associatedNode = documentPreservationPolicy.getNodeForObject(obj);
        if(associatedNode == null) {
            return;
        }
        updateXML(obj, associatedNode);
    }

    public void marshal(Object obj, Node node) {
        XMLDescriptor desc = null;
        boolean isXMLRoot = obj instanceof Root;
        if (isXMLRoot) {
            Object o = ((Root) obj).getObject();
            desc = (XMLDescriptor) context.getSession(o).getDescriptor(o);
        } else {
            desc = (XMLDescriptor) context.getSession(obj).getDescriptor(obj);
        }

        DOMRecord domRecord = null;
        if (!isXMLRoot) {
            domRecord = new DOMRecord(desc.getDefaultRootElement(), desc.getNamespaceResolver());
            domRecord.setDocPresPolicy(getDocumentPreservationPolicy());
        }
        Node n = this.marshaller.objectToXML(obj, node, desc, domRecord, isXMLRoot, this.getDocumentPreservationPolicy());

        validateNode(n);

        DOMResult result = new DOMResult(node);
        XMLTransformer transformer = marshaller.getTransformer();
        if (isXMLRoot) {
            String oldEncoding = transformer.getEncoding();
            String oldVersion = transformer.getVersion();
            if (((Root) obj).getEncoding() != null) {
                transformer.setEncoding(((Root) obj).getEncoding());
            }
            if (((Root) obj).getXMLVersion() != null) {
                transformer.setVersion(((Root) obj).getXMLVersion());
            }
            transformer.transform(n, result);
            if(oldEncoding != null){
                transformer.setEncoding(oldEncoding);
            }
            if(oldVersion != null){
                transformer.setVersion(oldVersion);
            }
        } else {
            transformer.transform(n, result);

        }
    }

    public void updateXML(Object obj, Node associatedNode) {
        if (obj instanceof Root) {
            obj = ((Root)obj).getObject();
        }

        Node objNode = this.getXMLNode(obj);

        AbstractSession session = context.getSession(obj);
        if (objNode == associatedNode) {
            DOMRecord root = new DOMRecord((Element)associatedNode);
            root.setMarshaller(marshaller);
            root.setDocPresPolicy(this.documentPreservationPolicy);
            XMLDescriptor rootDescriptor = (XMLDescriptor) session.getDescriptor(obj);
            ((XMLObjectBuilder)rootDescriptor.getObjectBuilder()).buildIntoNestedRow(root, obj, session);
        }
    }

    /**
     * Gets the XML Node associated with the provided object.
     * @return an XML Node used to construct the given object. Null if no node exists for this object.
     */
    public Node getXMLNode(Object object) {
        return documentPreservationPolicy.getNodeForObject(object);
    }

    /**
     * Gets the Java Object associated with the provided XML Node.
     * @return the Java Object associated with this node. If no object is associated then returns null
     */
    public Object getObject(Node node) {
        return documentPreservationPolicy.getObjectForNode(node);
    }

    /**
     * Updates the object associated with the provided node to reflect any changed made to that node.
     * If this Binder has no object associated with the given node, then no operation is performed.
     */
    public void updateObject(org.w3c.dom.Node node) {
        if (node.getNodeType() == Node.DOCUMENT_NODE) {
            node = ((Document) node).getDocumentElement();
        }

        Object cachedObject = documentPreservationPolicy.getObjectForNode(node);
        if (cachedObject != null) {
            unmarshal(node);
        } else {
            throw XMLMarshalException.objectNotFoundInCache(node.getNodeName());
        }
    }

    /**
     * Gets this XMLBinder's document preservation policy.
     * @return an instance of DocumentPreservationPolicy
     * @see org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy
     */
    public DocumentPreservationPolicy getDocumentPreservationPolicy() {
        return documentPreservationPolicy;
    }

    public XMLMarshaller getMarshaller() {
        return marshaller;
    }

    public void setMarshaller(XMLMarshaller marshaller) {
        this.marshaller = marshaller;
    }

    public void setSchema(Schema aSchema) {
        this.unmarshaller.setSchema(aSchema);
        this.saxUnmarshaller.setSchema(aSchema);
    }

    public Schema getSchema() {
        return this.unmarshaller.getSchema();
    }

    public void setErrorHandler(ErrorHandler errorHandler) {
        this.unmarshaller.setErrorHandler(errorHandler);
        this.saxUnmarshaller.setErrorHandler(errorHandler);
    }

    public ErrorHandler getErrorHandler() {
        return this.unmarshaller.getErrorHandler();
    }

    /**
     * Create an XMLRoot instance.  If the object is an instance of XMLRoot
     * it will simply be returned.  Otherwise, we will create a new XMLRoot
     * using the object's descriptor default root element - any prefixes
     * will be resolved - and the given object
     *
     * @return an XMLRoot instance encapsulating the given object
     */
    private XMLRoot buildXMLRootFromObject(Object obj) {
        if (obj instanceof XMLRoot) {
            return (XMLRoot) obj;
        }
        XMLRoot xmlRoot = new XMLRoot();
        xmlRoot.setObject(obj);

        // at this point, the default root element of the object being
        // marshalled to == the root element  - here we need to create
        // an XMLRoot instance using information from the returned
        // object
        org.eclipse.persistence.sessions.Session sess = this.unmarshaller.getXMLContext().getSession(obj);
        XMLDescriptor desc = (XMLDescriptor) sess.getClassDescriptor(obj);

        // here we are assuming that if we've gotten this far, there
        // must be a default root element set on the descriptor.  if
        // this is incorrect, we need to check for null and throw an
        // exception
        String rootName = desc.getDefaultRootElement();
        if (rootName == null) {
            return xmlRoot;
        }
        String rootNamespaceUri = null;
        int idx = rootName.indexOf(':');
        if (idx != -1) {
            rootNamespaceUri = desc.getNamespaceResolver().resolveNamespacePrefix(rootName.substring(0, idx));
            rootName = rootName.substring(idx + 1);
        }
        xmlRoot.setLocalName(rootName);
        xmlRoot.setNamespaceURI(rootNamespaceUri);
        return xmlRoot;
    }
}
