/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.persistence.oxm;

import java.util.Properties;

import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXResult;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.FragmentContentHandler;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.TreeObjectBuilder;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.oxm.XPathEngine;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.oxm.record.NodeRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.platform.xml.XMLPlatformException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * <p>Class used to marshal object to XML.
 *
 * <p>Create an XMLMarshaller from an XMLContext.<br>
 *  <em>Code Sample</em><br>
 *  <code>
 *  XMLContext context = new XMLContext("mySessionName");<br>
 *  XMLMarshaller marshaller = context.createMarshaller();<br>
 *  <code>
 *
 * <p>Objects can be marshalled to the following outputs:<ul>
 * <li>java.io.OutputStream</li>
 * <li>java.io.Writer</li>
 * <li>javax.xml.transform.Result</li>
 * <li>org.w3c.dom.Node</li>
 * <li>org.xml.sax.ContentHandler</li>
 * </ul>
 *
 * <p>Objects that can be marshalled are those which are mapped in the
 * TopLink project associated with the XMLContext, and which are mapped
 * to an XMLDescriptor that has a default root element specified.
 *
 * @see org.eclipse.persistence.oxm.XMLContext
 */
public class XMLMarshaller extends org.eclipse.persistence.internal.oxm.XMLMarshaller<AbstractSession, XMLContext, XMLDescriptor, MediaType, NamespacePrefixMapper, TreeObjectBuilder> implements Cloneable {

    private Object marshalAttributeGroup;

    /**
     * Create a new XMLMarshaller based on the specified session
     * @param session A single session
     */
    public XMLMarshaller(XMLContext xmlContext) {
        super(xmlContext);
        setMediaType(MediaType.APPLICATION_XML);
    }

    /**
     * Copy constructor
     */
    protected XMLMarshaller(XMLMarshaller xmlMarshaller) {
        super(xmlMarshaller);
    }

    /**
     * Return the instance of XMLContext that was used to create this instance
     * of XMLMarshaller.
     */
    public XMLContext getXMLContext() {
        return getContext();
    }

    /**
     * Set the XMLContext used by this instance of XMLMarshaller.
     */
    public void setXMLContext(XMLContext value) {
        context = value;
    }

    /**
     * Return a properties object for a given instance of the
     * XMLMarshaller.
     *
     * @return
     */
    public Properties getProperties() {
        if(null == marshalProperties) {
            marshalProperties = new Properties();
        }
        return marshalProperties;
    }

    public void setXMLMarshalHandler(XMLMarshalListener marshalListener) {
        setMarshalListener(marshalListener);
    }

    /**
    * PUBLIC:
    * Convert the given object to XML and update the given result with that XML Document
    * @param object the object to marshal
    * @param result the result to marshal the object to
    * @throws XMLMarshalException if an error occurred during marshalling
    */
    public void marshal(Object object, Result result) throws XMLMarshalException {
        if ((object == null) || (result == null)) {
            throw XMLMarshalException.nullArgumentException();
        }
        XMLDescriptor xmlDescriptor = null;
        AbstractSession session = null;
        
        boolean isXMLRoot = (object instanceof Root);
        
        if(isXMLRoot){
            try{
    	        session = context.getSession(((Root)object).getObject());
    	        if(session != null){
    	            xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
        	    }
           }catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                	throw marshalException;    
                }                
            }
        }else{
            Class objectClass = object.getClass();
            session = context.getSession(objectClass);
            xmlDescriptor = getDescriptor(objectClass, session);
        }

        //if this is a simple xml root, the session and descriptor will be null
        if (session == null ||  !context.getDocumentPreservationPolicy(session).shouldPreserveDocument()) {
            super.marshal(object, result);
            return;
        }
        try {
            Document document = objectToXML(object, xmlDescriptor, isXMLRoot);
            
            if ((result instanceof SAXResult) && (isFragment())) {
                FragmentContentHandler fragmentHandler = new FragmentContentHandler(((SAXResult) result).getHandler());
                getTransformer(); // Ensure transformer is initialized
                if (isXMLRoot) {
                    String oldEncoding = transformer.getEncoding();
                    String oldVersion = transformer.getVersion();
                    if (((Root) object).getEncoding() != null) {
                        transformer.setEncoding(((Root) object).getEncoding());
                    }
                    if (((Root) object).getXMLVersion() != null) {
                        transformer.setVersion(((Root) object).getXMLVersion());
                    }
                    transformer.transform(document, fragmentHandler);
                    transformer.setEncoding(oldEncoding);
                    transformer.setVersion(oldVersion);
                } else {
                    transformer.transform(document, fragmentHandler);
                }
            } else {
                if (result.getClass().equals(staxResultClass)) {
                    try {
                        String namespace = null;
                        String localName = null;
                        if(isXMLRoot){
                        	Root xmlRootObject = (Root)object;
                            if(xmlRootObject.getObject() != null && xmlRootObject.getObject() instanceof Node){
                                namespace = ((Root)object).getNamespaceURI();
                                localName = ((Root)object).getLocalName();
                            }
                        }
                        
                        Object xmlStreamWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetStreamWriterMethod, result);
                        if (xmlStreamWriter != null) {
                            Object domtostax = PrivilegedAccessHelper.newInstanceFromClass(domToStreamWriterClass);
                            PrivilegedAccessHelper.invokeMethod(writeToStreamMethod, domtostax, new Object[]{document,namespace, localName,xmlStreamWriter});
                            return;
                        } else {
                            Object xmlEventWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetEventWriterMethod, result);
                            if(xmlEventWriter != null) {
                                Object domToEventWriter = PrivilegedAccessHelper.newInstanceFromClass(domToEventWriterClass);
                                PrivilegedAccessHelper.invokeMethod(writeToEventWriterMethod, domToEventWriter, new Object[]{document, namespace, localName, xmlEventWriter});
                                return;
                            }
                        }
                    } catch(Exception e) {
                        throw XMLMarshalException.marshalException(e);
                    }
                }
                getTransformer(); // Ensure transformer is initialized 
                if (isXMLRoot) {
                    String oldEncoding = transformer.getEncoding();
                    String oldVersion = transformer.getVersion();
                    if (((Root) object).getEncoding() != null) {
                        transformer.setEncoding(((Root) object).getEncoding());
                    }
                    if (((Root) object).getXMLVersion() != null) {
                        transformer.setVersion(((Root) object).getXMLVersion());
                    }
                    transformer.transform(document, result);
                    transformer.setEncoding(oldEncoding);
                    transformer.setVersion(oldVersion);
                } else {
                    transformer.transform(document, result);
                }
            }
        } catch (XMLPlatformException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    @Override
    protected Node getNode(Object object, Node parentNode, AbstractSession session, XMLDescriptor xmlDescriptor, boolean isXMLRoot) {
        Node node = super.getNode(object, parentNode, session, xmlDescriptor, isXMLRoot);
        if(null != node) {
            return node;
        }
        if(null != session && context.getDocumentPreservationPolicy(session).shouldPreserveDocument()) {
            return objectToXMLNode(object, parentNode, session, xmlDescriptor, isXMLRoot);
        }
        return null;
    }

    
    /**
     * Convert the given object to XML and update the given marshal record with
     * that XML Document.
     * @param object the object to marshal
     * @param marshalRecord the marshalRecord to marshal the object to
     */
    protected void marshal(Object object, AbstractSession session, MarshalRecord marshalRecord) {
        boolean isXMLRoot = (object instanceof Root);
        marshal(object, marshalRecord, session, getDescriptor(object, isXMLRoot), isXMLRoot);
    }

    /**
    * INTERNAL:
    * Convert the given object to an XML Document
    * @param object the object to marshal
    * @return the document which the specified object has been marshalled to
    * @param descriptor the XMLDescriptor for the object being marshalled
    * @throws XMLMarshalException if an error occurred during marshalling
    */
    protected Document objectToXML(Object object, XMLDescriptor descriptor, boolean isXMLRoot) throws XMLMarshalException {
        AbstractSession session = context.getSession(descriptor);
        DocumentPreservationPolicy docPresPolicy = context.getDocumentPreservationPolicy(session);
        if (docPresPolicy != null && docPresPolicy.shouldPreserveDocument()) {
            XMLRecord xmlRow = null;
            if (!isXMLRoot) {
                xmlRow = (XMLRecord) ((XMLObjectBuilder) descriptor.getObjectBuilder()).createRecordFor(object, context.getDocumentPreservationPolicy(session));
                xmlRow.setMarshaller(this);
                if (this.attachmentMarshaller != null) {
                    xmlRow.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
                }
                addDescriptorNamespacesToXMLRecord(descriptor, xmlRow);
            }
            return objectToXML(object, descriptor, xmlRow, isXMLRoot, docPresPolicy);
        }
        return super.objectToXML(object, descriptor, isXMLRoot);
    }

    protected Node objectToXMLNode(Object object, Node rootNode, AbstractSession session,XMLDescriptor descriptor, boolean isXMLRoot) throws XMLMarshalException {
        DocumentPreservationPolicy docPresPolicy = context.getDocumentPreservationPolicy(session);
        if (docPresPolicy != null && docPresPolicy.shouldPreserveDocument()) {
            XMLRecord xmlRow = null;
            if (!isXMLRoot) {
                xmlRow = (XMLRecord) ((XMLObjectBuilder) descriptor.getObjectBuilder()).createRecordFor(object, context.getDocumentPreservationPolicy(session));
                xmlRow.setMarshaller(this);
                if (this.attachmentMarshaller != null) {
                    xmlRow.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
                }
                if (xmlRow.getDOM().getNodeType() == Node.ELEMENT_NODE) {
                    addDescriptorNamespacesToXMLRecord(descriptor, xmlRow);
                }
            }
            Document doc = objectToXML(object, rootNode, descriptor, xmlRow, isXMLRoot, docPresPolicy);
            if ((xmlRow != null) && (xmlRow.getDOM().getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)) {
                return xmlRow.getDOM();
            } else {
                return doc;
            }
        }
        return super.objectToXMLNode(object, rootNode, session, descriptor, isXMLRoot);
    }

    /**
    * PUBLIC:
    * Convert the given object to descendants of the parent element
    * @param object the object to marshal
    * @param parent the node to marshal the object to
    * @return the document which the specified object has been marshalled to
    * @throws XMLMarshalException if an error occurred during marshalling
    * @deprecated
    */
    public Document objectToXML(Object object, Node parent) throws XMLMarshalException {
        return objectToXML(object, parent, null);
    }

    public Document objectToXML(Object object, Node parent, DocumentPreservationPolicy docPresPolicy) {
        boolean isXMLRoot = (object instanceof Root);
        
        AbstractSession session = null;
        XMLDescriptor descriptor = null;
        if(isXMLRoot){
        	try{
        	    session = context.getSession(((Root)object).getObject());
        	    if(session != null){
        	        descriptor = getDescriptor(((Root)object).getObject(), session);
        	    }
        	}catch (XMLMarshalException marshalException) {
                if (!isSimpleXMLRoot((Root) object)) {
                	throw marshalException;    
                }                
            }
        }else{
            Class objectClass = object.getClass();
        	session = context.getSession(objectClass);
        	descriptor = getDescriptor(objectClass, session);
        }

        String localRootName = descriptor.getDefaultRootElement();
        if (null == localRootName) {
            throw XMLMarshalException.defaultRootElementNotSpecified(descriptor);
        }

        if(docPresPolicy == null) {
            docPresPolicy = context.getDocumentPreservationPolicy(session);
        }
        if (docPresPolicy != null && docPresPolicy.shouldPreserveDocument()) {
            XMLRecord xmlRow = (XMLRecord) ((XMLObjectBuilder) descriptor.getObjectBuilder()).createRecord(localRootName, parent, session);
            xmlRow.setMarshaller(this);
            if (this.attachmentMarshaller != null) {
                xmlRow.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
            }
            return objectToXML(object, descriptor, xmlRow, isXMLRoot, docPresPolicy);
        }
        MarshalRecord marshalRecord = new NodeRecord(localRootName, parent);
        marshalRecord.setMarshaller(this);
        marshal(object, marshalRecord, session, descriptor, isXMLRoot);
        return marshalRecord.getDocument();
    }

    /**
     * INTERNAL:
     * Convert the given object to an XML Document
     */
    public Document objectToXML(Object object, XMLDescriptor descriptor, XMLRecord xmlRow, boolean isXMLRoot, DocumentPreservationPolicy docPresPolicy) {
        return objectToXML(object, null, descriptor, xmlRow, isXMLRoot, docPresPolicy);
    }

    public Document objectToXML(Object object, Node rootNode, XMLDescriptor descriptor, XMLRecord xmlRow, boolean isXMLRoot, DocumentPreservationPolicy docPresPolicy) {
        if(null != rootNode) {
            int rootNodeType = rootNode.getNodeType();
            if(rootNodeType != Node.DOCUMENT_NODE && rootNodeType != Node.ELEMENT_NODE && rootNodeType != Node.DOCUMENT_FRAGMENT_NODE ) {
                throw XMLMarshalException.marshalException(null);
            }
        }
        Document document = null;
        NamespaceResolver resolver = new NamespaceResolver();
        resolver.setDOM(rootNode);
        this.copyNamespaces(descriptor.getNamespaceResolver(), resolver);
        boolean shouldCallSetAttributeNS = false;
        boolean isRootDocumentFragment = false;
        AbstractSession session = context.getSession(descriptor);
        if (xmlRow != null) {
            isRootDocumentFragment = (xmlRow.getDOM().getNodeType() == Node.DOCUMENT_FRAGMENT_NODE);
        }
        Object originalObject = object;
        if (isXMLRoot) {
            String xmlRootUri = ((Root) object).getNamespaceURI();
            String xmlRootPrefix = null;
            if (xmlRow == null) {
                String recordName = ((Root) object).getLocalName();
                if (xmlRootUri != null) {
                    xmlRootPrefix = resolver.resolveNamespaceURI(xmlRootUri);
                    if (xmlRootPrefix == null && !(xmlRootUri.equals(resolver.getDefaultNamespaceURI()))) {
                        xmlRootPrefix = resolver.generatePrefix();
                        resolver.put(xmlRootPrefix, xmlRootUri);
                        shouldCallSetAttributeNS = true;
                    }
                    if(xmlRootPrefix != null) {
                        recordName = xmlRootPrefix + XMLConstants.COLON + recordName;
                    }
                }
                xmlRow = (XMLRecord) ((XMLObjectBuilder) descriptor.getObjectBuilder()).createRecordFor(((Root) object).getObject(), docPresPolicy, recordName, xmlRootUri);
                xmlRow.setMarshaller(this);
                if (this.attachmentMarshaller != null) {
                    xmlRow.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
                }
                if (!isRootDocumentFragment) {
                    if (shouldCallSetAttributeNS) {
                        if (xmlRootPrefix != null) {
                            ((Element) xmlRow.getDOM()).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + XMLConstants.COLON + xmlRootPrefix, xmlRootUri);
                        }
                        shouldCallSetAttributeNS = false;
                    }
                }
            }

            copyNamespaces(resolver, xmlRow.getNamespaceResolver());
            document = xmlRow.getDocument();
            Element docElement = document.getDocumentElement();
            object = ((Root) object).getObject();
        }

        XMLObjectBuilder bldr = (XMLObjectBuilder) descriptor.getObjectBuilder();

        AbstractSession objectSession = context.getSession(object);
        xmlRow.setSession(objectSession);
        xmlRow.addXsiTypeAndClassIndicatorIfRequired(descriptor, null, null, originalObject, object, isXMLRoot, true);
        xmlRow.setMarshaller(this);
        if (shouldCallSetAttributeNS && !isRootDocumentFragment) {
            ((Element) xmlRow.getDOM()).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + XMLConstants.COLON + XMLConstants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        }
        xmlRow = (XMLRecord) bldr.buildRow(xmlRow, object,  objectSession, isXMLRoot);
      
        document = xmlRow.getDocument();

        addSchemaLocations(document, session);
        return document;
    }

    private void addSchemaLocations(Document document, AbstractSession session) {
        Element docElement = document.getDocumentElement();

        NamespaceResolver resolver = new NamespaceResolver();
        resolver.put(javax.xml.XMLConstants.XMLNS_ATTRIBUTE, javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
        resolver.put(XMLConstants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);

        if ((getSchemaLocation() != null) || (getNoNamespaceSchemaLocation() != null)) {
            XMLField field = new XMLField("@xmlns:xsi");
            field.setNamespaceResolver(resolver);
            XPathEngine.getInstance().create(field, docElement, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, session);
        }
        if (getSchemaLocation() != null) {
            XMLField field = new XMLField("@xsi:" + XMLConstants.SCHEMA_LOCATION);
            field.setNamespaceResolver(resolver);
            XPathEngine.getInstance().create(field, docElement, getSchemaLocation(), session);
        }
        if (getNoNamespaceSchemaLocation() != null) {
            XMLField field = new XMLField("@xsi:" + XMLConstants.NO_NS_SCHEMA_LOCATION);
            field.setNamespaceResolver(resolver);
            XPathEngine.getInstance().create(field, docElement, getNoNamespaceSchemaLocation(), session);
        }
    }

    protected XMLDescriptor getDescriptor(Object object, AbstractSession session, boolean isXMLRoot) {
        if (isXMLRoot) {
            return getDescriptor((Root) object, session);
        } else {
            return getDescriptor(object, session);
        }
    }

    @Override
    public XMLMarshaller clone() {
        return new XMLMarshaller(this);
    }

	/**
     * NamespacePrefixMapper that can be used during marshal (instead of those set in the project meta data)
     * @since 2.3.3
     * @return
     */
    public void setNamespacePrefixMapper(NamespacePrefixMapper mapper) {
        super.setNamespacePrefixMapper(mapper);
    }

    /**
     * NamespacePrefixMapper that can be used during marshal (instead of those set in the project meta data)
     * @since 2.3.3
     * @return
     */
    public NamespacePrefixMapper getNamespacePrefixMapper() {
        return super.getNamespacePrefixMapper();
    }

    /**
     * Set the MediaType for this xmlMarshaller.
     * See org.eclipse.persistence.oxm.MediaType for the media types supported by EclipseLink MOXy
     * @param mediaType
     * @since EclipseLink 2.4.0
     */
    @Override
    public void setMediaType(MediaType mediaType) {
        super.setMediaType(mediaType);
    }
    
    /**
     * Get the MediaType for this xmlMarshaller.
     * See org.eclipse.persistence.oxm.MediaType for the media types supported by EclipseLink MOXy
     * If not set the default is MediaType.APPLICATION_XML
     * @return MediaType
     * @since EclipseLink 2.4.0
     */
    @Override
    public MediaType getMediaType(){
        return mediaType;
    }

}