/*
 * 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.sdo.helper.delegates;

import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.XMLDocument;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.WeakHashMap;

import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.sdo.SDOXMLDocument;
import org.eclipse.persistence.sdo.helper.SDOUnmappedContentHandler;
import org.eclipse.persistence.sdo.helper.SDOClassLoader;
import org.eclipse.persistence.sdo.helper.SDOMarshalListener;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
import org.eclipse.persistence.sdo.helper.SDOUnmarshalListener;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.types.SDOPropertyType;
import org.eclipse.persistence.sdo.types.SDOTypeType;
import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentMarshaller;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentUnmarshaller;
import org.eclipse.persistence.oxm.record.ContentHandlerRecord;
import org.eclipse.persistence.oxm.record.FormattedWriterRecord;
import org.eclipse.persistence.oxm.record.NodeRecord;
import org.eclipse.persistence.oxm.record.WriterRecord;
import org.eclipse.persistence.sessions.Project;
import org.xml.sax.InputSource;

/**
 * <p><b>Purpose</b>: Helper to XML documents into DataObects and DataObjects into XML documents.
 * <p><b>Responsibilities</b>:<ul>
 * <li> Load methods create commonj.sdo.XMLDocument objects from XML (unmarshal)
 * <li> Save methods create XML from commonj.sdo.XMLDocument and commonj.sdo.DataObject objects (marshal)
 * </ul>
 */
public class SDOXMLHelperDelegate implements SDOXMLHelper {
    private SDOClassLoader loader;
    private XMLContext xmlContext;

    private Map<Thread, XMLMarshaller> xmlMarshallerMap;
    private Map<Thread, XMLUnmarshaller> xmlUnmarshallerMap;

    private Project topLinkProject;

    // hold the context containing all helpers so that we can preserve inter-helper relationships
    private HelperContext aHelperContext;

    public SDOXMLHelperDelegate(HelperContext aContext) {
        this(aContext, Thread.currentThread().getContextClassLoader());
    }

    public SDOXMLHelperDelegate(HelperContext aContext, ClassLoader aClassLoader) {
        aHelperContext = aContext;
        // This ClassLoader is internal to SDO so no inter servlet-ejb container context issues should arise
        loader = new SDOClassLoader(aClassLoader, aContext);
        // WeakHashMap needs to be synchronized to prevent endless loop under the heavy load
        xmlMarshallerMap = Collections.synchronizedMap(new WeakHashMap<Thread, XMLMarshaller>());
        xmlUnmarshallerMap = Collections.synchronizedMap(new WeakHashMap<Thread, XMLUnmarshaller>());
    }

    /**
     * The specified TimeZone will be used for all String to date object
     * conversions.  By default the TimeZone from the JVM is used.
     */
    @Override
    public void setTimeZone(TimeZone timeZone) {
        getXmlConversionManager().setTimeZone(timeZone);
    }

    /**
     * By setting this flag to true the marshalled date objects marshalled to
     * the XML schema types time and dateTime will be qualified by a time zone.
     * By default time information is not time zone qualified.
     */
    @Override
    public void setTimeZoneQualified(boolean timeZoneQualified) {
        getXmlConversionManager().setTimeZoneQualified(timeZoneQualified);
    }

    /**
     * Creates and returns an XMLDocument from the input String.
     * By default does not perform XSD validation.
     * Same as
     *   load(new StringReader(inputString), null, null);
     *
     * @param inputString specifies the String to read from
     * @return the new XMLDocument loaded
     * @throws RuntimeException for errors in XML parsing or
     *    implementation-specific validation.
     */
    @Override
    public XMLDocument load(String inputString) {
        StringReader reader = new StringReader(inputString);
        try {
            return load(reader, null, null);
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return null;
        }
    }

    /**
     * Creates and returns an XMLDocument from the inputStream.
     * The InputStream will be closed after reading.
     * By default does not perform XSD validation.
     * Same as
     *   load(inputStream, null, null);
     *
     * @param inputStream specifies the InputStream to read from
     * @return the new XMLDocument loaded
     * @throws IOException for stream exceptions.
     * @throws RuntimeException for errors in XML parsing or
     *    implementation-specific validation.
     */
    @Override
    public XMLDocument load(InputStream inputStream) throws IOException {
        return load(inputStream, null, null);
    }

    /**
     * Creates and returns an XMLDocument from the inputStream.
     * The InputStream will be closed after reading.
     * By default does not perform XSD validation.
     * @param inputStream specifies the InputStream to read from
     * @param locationURI specifies the URI of the document for relative schema locations
     * @param options implementation-specific options.
     * @return the new XMLDocument loaded
     * @throws IOException for stream exceptions.
     * @throws RuntimeException for errors in XML parsing or
     *    implementation-specific validation.
     */
    @Override
    public XMLDocument load(InputStream inputStream, String locationURI, Object options) throws IOException {
        InputSource inputSource = new InputSource(inputStream);
        return load(inputSource, locationURI, options);
    }

    /**
       * Creates and returns an XMLDocument from the inputSource.
       * The InputSource will be closed after reading.
       * By default does not perform XSD validation.
       * @param inputSource specifies the InputSource to read from
       * @param locationURI specifies the URI of the document for relative schema locations
       * @param options implementation-specific options.
       * @return the new XMLDocument loaded
       * @throws IOException for stream exceptions.
       * @throws RuntimeException for errors in XML parsing or
       *    implementation-specific validation.
       */
    @Override
    public XMLDocument load(InputSource inputSource, String locationURI, Object options) throws IOException {
        // get XMLUnmarshaller once - as we may create a new instance if this helper isDirty=true
        XMLUnmarshaller anXMLUnmarshaller = getXmlUnmarshaller(options);
        Object unmarshalledObject = null;
        if (options == null) {
            try {
               unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
            } catch(XMLMarshalException xmlException){
               handleXMLMarshalException(xmlException);
            }
        } else {
            try {
                DataObject optionsDataObject = (DataObject)options;
                try {
                    SDOType theType = (SDOType)optionsDataObject.get(SDOConstants.TYPE_LOAD_OPTION);
                    try{
                        if (theType != null) {
                            if(theType.isDataType()) {
                                theType = (SDOType)((SDOTypeHelper)this.aHelperContext.getTypeHelper()).getWrappersHashMap().get(theType.getQName());
                            }
                            if(theType != null) {
                                unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource, theType.getImplClass());
                            } else {
                                unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
                            }
                        }else{
                            unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
                        }
                    } catch(XMLMarshalException xmlException){
                        handleXMLMarshalException(xmlException);
                    }
                } catch (ClassCastException ccException) {
                  throw SDOException.typePropertyMustBeAType(ccException);
                }
            } catch (ClassCastException ccException) {
               throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
            }
        }

        if (unmarshalledObject instanceof XMLRoot) {
            XMLRoot xmlRoot = (XMLRoot)unmarshalledObject;
            XMLDocument xmlDocument = createDocument((DataObject)((XMLRoot)unmarshalledObject).getObject(), ((XMLRoot)unmarshalledObject).getNamespaceURI(), ((XMLRoot)unmarshalledObject).getLocalName());
            if(xmlRoot.getEncoding() != null) {
                xmlDocument.setEncoding(xmlRoot.getEncoding());
            }
            if(xmlRoot.getXMLVersion() != null) {
                xmlDocument.setXMLVersion(xmlRoot.getXMLVersion());
            }
            xmlDocument.setSchemaLocation(xmlRoot.getSchemaLocation());
            xmlDocument.setNoNamespaceSchemaLocation(xmlRoot.getNoNamespaceSchemaLocation());
            return xmlDocument;
        } else if (unmarshalledObject instanceof DataObject) {
            String localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXmlDescriptor().getDefaultRootElement();
            if (localName == null) {
                localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXsdLocalName();
            }
            return createDocument((DataObject)unmarshalledObject, ((DataObject)unmarshalledObject).getType().getURI(), localName);
        } else if (unmarshalledObject instanceof XMLDocument) {
            return (XMLDocument)unmarshalledObject;
        }

        return null;
    }

    /**
     * Creates and returns an XMLDocument from the inputReader.
     * The InputStream will be closed after reading.
     * By default does not perform XSD validation.
     * @param inputReader specifies the Reader to read from
     * @param locationURI specifies the URI of the document for relative schema locations
     * @param options implementation-specific options.
     * @return the new XMLDocument loaded
     * @throws IOException for stream exceptions.
     * @throws RuntimeException for errors in XML parsing or
     *    implementation-specific validation.
     */
    @Override
    public XMLDocument load(Reader inputReader, String locationURI, Object options) throws IOException {
        InputSource inputSource = new InputSource(inputReader);
        return load(inputSource, locationURI, options);
    }

    @Override
    public XMLDocument load(Source source, String locationURI, Object options) throws IOException {
        // get XMLUnmarshaller once - as we may create a new instance if this helper isDirty=true
        XMLUnmarshaller anXMLUnmarshaller = getXmlUnmarshaller(options);
        Object unmarshalledObject = null;
        if (options == null) {
            try {
                unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
            } catch(XMLMarshalException xmlException){
                handleXMLMarshalException(xmlException);
            }
        } else {
            try {
                DataObject optionsDataObject = (DataObject)options;
                try {
                    SDOType theType = (SDOType)optionsDataObject.get(SDOConstants.TYPE_LOAD_OPTION);
                    try{
                        if (theType != null) {
                            if(theType.isDataType()) {
                                theType = (SDOType)((SDOTypeHelper)this.aHelperContext.getTypeHelper()).getWrappersHashMap().get(theType.getQName());
                            }
                            if(theType != null) {
                                unmarshalledObject = anXMLUnmarshaller.unmarshal(source, theType.getImplClass());
                            } else {
                                unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
                            }
                        }else{
                            unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
                        }
                    } catch(XMLMarshalException xmlException){
                        handleXMLMarshalException(xmlException);
                    }
                } catch (ClassCastException ccException) {
                  throw SDOException.typePropertyMustBeAType(ccException);
                }
            } catch (ClassCastException ccException) {
               throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
            }

        }

        if (unmarshalledObject instanceof XMLRoot) {
            XMLRoot xmlRoot = (XMLRoot)unmarshalledObject;
            XMLDocument xmlDocument = createDocument((DataObject)((XMLRoot)unmarshalledObject).getObject(), ((XMLRoot)unmarshalledObject).getNamespaceURI(), ((XMLRoot)unmarshalledObject).getLocalName());
            if(xmlRoot.getEncoding() != null) {
                xmlDocument.setEncoding(xmlRoot.getEncoding());
            }
            if(xmlRoot.getXMLVersion() != null) {
                xmlDocument.setXMLVersion(xmlRoot.getXMLVersion());
            }
            xmlDocument.setSchemaLocation(xmlRoot.getSchemaLocation());
            xmlDocument.setNoNamespaceSchemaLocation(xmlRoot.getNoNamespaceSchemaLocation());
            return xmlDocument;
        } else if (unmarshalledObject instanceof DataObject) {
            DataObject unmarshalledDataObject = (DataObject)unmarshalledObject;
            String localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXmlDescriptor().getDefaultRootElement();
            if (localName == null) {
                localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXsdLocalName();
            }
            return createDocument(unmarshalledDataObject, unmarshalledDataObject.getType().getURI(), localName);
        } else if (unmarshalledObject instanceof XMLDocument) {
            return (XMLDocument)unmarshalledObject;
        }
        return null;
    }

    /**
     * Returns the DataObject saved as an XML document with the specified root element.
     * Same as
     *   StringWriter stringWriter = new StringWriter();
     *   save(createDocument(dataObject, rootElementURI, rootElementName),
     *     stringWriter, null);
     *   stringWriter.toString();
     *
     * @param dataObject specifies DataObject to be saved
     * @param rootElementURI the Target Namespace URI of the root XML element
     * @param rootElementName the Name of the root XML element
     * @return the saved XML document as a string
     * @throws IllegalArgumentException if the dataObject tree
     *    is not closed or has no container.
     */
    @Override
    public String save(DataObject dataObject, String rootElementURI, String rootElementName) {
        try {
            StringWriter writer = new StringWriter();
            save(dataObject, rootElementURI, rootElementName, writer, getXmlMarshaller(null));
            return writer.toString();
        } catch (XMLMarshalException e) {
            throw SDOException.xmlMarshalExceptionOccurred(e, rootElementURI, rootElementName);
        }
    }

    /**
     * Saves the DataObject as an XML document with the specified root element.
     * Same as
     *   save(createDocument(dataObject, rootElementURI, rootElementName),
     *     outputStream, null);
     *
     * @param dataObject specifies DataObject to be saved
     * @param rootElementURI the Target Namespace URI of the root XML element
     * @param rootElementName the Name of the root XML element
     * @param outputStream specifies the OutputStream to write to.
     * @throws IOException for stream exceptions.
     * @throws IllegalArgumentException if the dataObject tree
     *    is not closed or has no container.
     */
    @Override
    public void save(DataObject dataObject, String rootElementURI, String rootElementName, OutputStream outputStream) throws XMLMarshalException, IOException {
        XMLMarshaller xmlMarshaller = getXmlMarshaller(null);
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, xmlMarshaller.getEncoding());
        save(dataObject, rootElementURI, rootElementName, writer, xmlMarshaller);
    }

    @Override
    public void serialize(XMLDocument xmlDocument, OutputStream outputStream, Object options) throws IOException {
        XMLMarshaller xmlMarshaller = getXmlMarshaller();
        XMLAttachmentMarshaller attachmentMarshaller = xmlMarshaller.getAttachmentMarshaller();
        //temporarily null out the attachment marshaller as it should not be used during serialization
        xmlMarshaller.setAttachmentMarshaller(null);
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, xmlMarshaller.getEncoding());
        save(xmlDocument, writer, xmlMarshaller);
        xmlMarshaller.setAttachmentMarshaller(attachmentMarshaller);
    }

    /**
     * Serializes an XMLDocument as an XML document into the outputStream.
     * If the DataObject's Type was defined by an XSD, the serialization
     *   will follow the XSD.
     * Otherwise the serialization will follow the format as if an XSD
     *   were generated as defined by the SDO specification.
     * The OutputStream will be flushed after writing.
     * Does not perform validation to ensure compliance with an XSD.
     * @param xmlDocument specifies XMLDocument to be saved
     * @param outputStream specifies the OutputStream to write to.
     * @param options implementation-specific options.
     * @throws IOException for stream exceptions.
     * @throws IllegalArgumentException if the dataObject tree
     *    is not closed or has no container.
     */
    @Override
    public void save(XMLDocument xmlDocument, OutputStream outputStream, Object options) throws IOException {
        if (xmlDocument == null) {
            throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
        }
        XMLMarshaller xmlMarshaller = getXmlMarshaller(options);
        String encoding = xmlMarshaller.getEncoding();
        if(xmlDocument.getEncoding() != null) {
            encoding = xmlDocument.getEncoding();
        }
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding);
        save(xmlDocument, writer, xmlMarshaller);
    }

    /**
     * Serializes an XMLDocument as an XML document into the outputWriter.
     * If the DataObject's Type was defined by an XSD, the serialization
     *   will follow the XSD.
     * Otherwise the serialization will follow the format as if an XSD
     *   were generated as defined by the SDO specification.
     * The OutputStream will be flushed after writing.
     * Does not perform validation to ensure compliance with an XSD.
     * @param xmlDocument specifies XMLDocument to be saved
     * @param outputWriter specifies the Writer to write to.
     * @param options implementation-specific options.
     * @throws IOException for stream exceptions.
     * @throws IllegalArgumentException if the dataObject tree
     *    is not closed or has no container.
     */
    @Override
    public void save(XMLDocument xmlDocument, Writer outputWriter, Object options) throws IOException {
        save(xmlDocument, outputWriter, getXmlMarshaller(options));
    }

    private void save(XMLDocument xmlDocument, Writer outputWriter, XMLMarshaller anXMLMarshaller) throws IOException {
        if (xmlDocument == null) {
            throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
        }

        // Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
        anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());

        anXMLMarshaller.setEncoding(xmlDocument.getEncoding());
        anXMLMarshaller.setSchemaLocation(xmlDocument.getSchemaLocation());
        anXMLMarshaller.setNoNamespaceSchemaLocation(xmlDocument.getNoNamespaceSchemaLocation());

        WriterRecord writerRecord;
        if(anXMLMarshaller.isFormattedOutput()) {
            writerRecord = new FormattedWriterRecord();
        } else {
            writerRecord = new WriterRecord();
        }
        writerRecord.setWriter(outputWriter);
        writerRecord.setMarshaller(anXMLMarshaller);

        SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());

        listener.setMarshalledObject(xmlDocument.getRootObject());
        listener.setMarshalledObjectRootQName(new QName(xmlDocument.getRootElementURI(), xmlDocument.getRootElementName()));
        listener.setRootMarshalRecord(writerRecord);

        try{
            anXMLMarshaller.marshal(xmlDocument, writerRecord);
            writerRecord.flush();
        }catch(XMLMarshalException xme){
            if(xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
            if(aHelperContext != ((SDOType)xmlDocument.getRootObject().getType()).getHelperContext()){
                 throw SDOException.dataObjectNotFromHelperContext();
           }
            }
        } finally{
            listener.setMarshalledObject(null);
            listener.setMarshalledObjectRootQName(null);
            listener.setRootMarshalRecord(null);
        }
        outputWriter.flush();
    }

    @Override
    public void save(XMLDocument xmlDocument, Result result, Object options) throws IOException {
        if (xmlDocument == null) {
            throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
        }

        if (result instanceof StreamResult) {
            StreamResult streamResult = (StreamResult)result;
            Writer writer = streamResult.getWriter();
            if (null == writer) {
                save(xmlDocument, streamResult.getOutputStream(), options);
            } else {
                save(xmlDocument, writer, options);
            }

        } else {
            // get XMLMarshaller once - as we may create a new instance if this helper isDirty=true
            XMLMarshaller anXMLMarshaller = getXmlMarshaller(options);

            // Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
            anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());

            anXMLMarshaller.setEncoding(xmlDocument.getEncoding());
            anXMLMarshaller.setSchemaLocation(xmlDocument.getSchemaLocation());
            anXMLMarshaller.setNoNamespaceSchemaLocation(xmlDocument.getNoNamespaceSchemaLocation());

            SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());

            listener.setMarshalledObject(xmlDocument.getRootObject());
            listener.setMarshalledObjectRootQName(new QName(xmlDocument.getRootElementURI(), xmlDocument.getRootElementName()));

            if(result instanceof SAXResult) {
                ContentHandlerRecord marshalRecord = new ContentHandlerRecord();
                marshalRecord.setContentHandler(((SAXResult)result).getHandler());
                marshalRecord.setMarshaller(anXMLMarshaller);
                listener.setRootMarshalRecord(marshalRecord);
                anXMLMarshaller.marshal(xmlDocument, marshalRecord);
                marshalRecord.flush();
            } else if(result instanceof DOMResult) {
                NodeRecord marshalRecord = new NodeRecord();
                marshalRecord.setDOM(((DOMResult)result).getNode());
                marshalRecord.setMarshaller(anXMLMarshaller);
                listener.setRootMarshalRecord(marshalRecord);
                anXMLMarshaller.marshal(xmlDocument, marshalRecord);
                marshalRecord.flush();
            } else {
                StringWriter writer = new StringWriter();
                this.save(xmlDocument, writer, options);
                String xml = writer.toString();
                StreamSource source = new StreamSource(new java.io.StringReader(xml));
                anXMLMarshaller.getTransformer().transform(source, result);
            }
            listener.setMarshalledObject(null);
            listener.setMarshalledObjectRootQName(null);
            listener.setRootMarshalRecord(null);
        }

    }

    /**
     * Creates an XMLDocument with the specified XML rootElement for the DataObject.
     * @param dataObject specifies DataObject to be saved
     * @param rootElementURI the Target Namespace URI of the root XML element
     * @param rootElementName the Name of the root XML element
     * @return XMLDocument a new XMLDocument set with the specified parameters.
     */
    @Override
    public XMLDocument createDocument(DataObject dataObject, String rootElementURI, String rootElementName) {
        SDOXMLDocument document = new SDOXMLDocument();
        document.setRootObject(dataObject);
        document.setRootElementURI(rootElementURI);
        if (rootElementName != null) {
            document.setRootElementName(rootElementName);
        }

        Property globalProp = getHelperContext().getXSDHelper().getGlobalProperty(rootElementURI, rootElementName, true);
        if (null != globalProp) {
            document.setSchemaType(((SDOType) globalProp.getType()).getXsdType());
        }

        document.setEncoding(SDOXMLDocument.DEFAULT_XML_ENCODING);
        document.setXMLVersion(SDOXMLDocument.DEFAULT_XML_VERSION);

        return document;
    }

    /**
         * INTERNAL:
         * Saves the DataObject as an XML document with the specified root element.
         * Same as
         *   save(createDocument(dataObject, rootElementURI, rootElementName),
         *     writer, null);
         *
         * @param rootObject specifies DataObject to be saved
         * @param rootElementURI the Target Namespace URI of the root XML element
         * @param rootElementName the Name of the root XML element
         * @param writer specifies the Writer to write to.
         * @throws IllegalArgumentException if the dataObject tree
         *    is not closed or has no container.
         */
    private void save(DataObject rootObject, String rootElementURI, String rootElementName, Writer writer, XMLMarshaller anXMLMarshaller) throws XMLMarshalException {
        SDOXMLDocument xmlDocument = (SDOXMLDocument)createDocument(rootObject, rootElementURI, rootElementName);

        // Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
        anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());
        WriterRecord writerRecord;
        if(anXMLMarshaller.isFormattedOutput()) {
            writerRecord = new FormattedWriterRecord();
        } else {
            writerRecord = new WriterRecord();
        }
        writerRecord.setWriter(writer);
        writerRecord.setMarshaller(anXMLMarshaller);

        SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());

        listener.setMarshalledObject(rootObject);
        listener.setMarshalledObjectRootQName(new QName(rootElementURI, rootElementName));
        listener.setRootMarshalRecord(writerRecord);

        try{
            anXMLMarshaller.marshal(xmlDocument, writerRecord);
            writerRecord.flush();
        }catch(XMLMarshalException xme){
            if(xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
            if(aHelperContext != ((SDOType)rootObject.getType()).getHelperContext()){
                 throw SDOException.dataObjectNotFromHelperContext();
           }
            }
        }finally{
            listener.setMarshalledObject(null);
            listener.setMarshalledObjectRootQName(null);
            listener.setRootMarshalRecord(null);
        }


        try {
            writer.flush();
        } catch(IOException ex) {
            throw XMLMarshalException.marshalException(ex);
        }
    }

    @Override
    public void setLoader(SDOClassLoader loader) {
        this.loader = loader;
        getXmlConversionManager().setLoader(this.loader);
    }

    @Override
    public SDOClassLoader getLoader() {
        return loader;
    }

    @Override
    public void setXmlContext(XMLContext xmlContext) {
        this.xmlContext = xmlContext;
    }

    @Override
    public synchronized XMLContext getXmlContext() {
        if (xmlContext == null) {
            xmlContext = new XMLContext(getTopLinkProject());
            XMLConversionManager xmlConversionManager = getXmlConversionManager();
            xmlConversionManager.setLoader(this.loader);
            xmlConversionManager.setTimeZone(TimeZone.getTimeZone("GMT"));
            xmlConversionManager.setTimeZoneQualified(true);
        }
        return xmlContext;
    }

    @Override
    public void initializeDescriptor(XMLDescriptor descriptor){
        AbstractSession theSession = (AbstractSession)getXmlContext().getSession();

        //do initialization for new descriptor;
        descriptor.preInitialize(theSession);
        descriptor.initialize(theSession);
        descriptor.postInitialize(theSession);

        descriptor.getObjectBuilder().initializePrimaryKey(theSession);
        getXmlContext().storeXMLDescriptorByQName(descriptor);
    }

    @Override
    public void addDescriptors(List types) {
        for (int i = 0; i < types.size(); i++) {
            SDOType nextType = (SDOType)types.get(i);

            if (!nextType.isDataType() && nextType.isFinalized()){
              XMLDescriptor nextDescriptor = nextType.getXmlDescriptor();
              getTopLinkProject().addDescriptor(nextDescriptor);
            }
        }
        for (int i = 0; i < types.size(); i++) {
          SDOType nextType = (SDOType)types.get(i);
          if (!nextType.isDataType() && nextType.isFinalized()){
             XMLDescriptor nextDescriptor = nextType.getXmlDescriptor();
             initializeDescriptor(nextDescriptor);
          }
        }
    }

    @Override
    public void setTopLinkProject(Project toplinkProject) {
        this.topLinkProject = toplinkProject;
        this.xmlContext = null;
        this.xmlMarshallerMap.clear();
        this.xmlUnmarshallerMap.clear();
    }

    @Override
    public Project getTopLinkProject() {
        if (topLinkProject == null) {
            topLinkProject = new Project();
            XMLLogin xmlLogin = new XMLLogin();
            xmlLogin.setEqualNamespaceResolvers(false);
            topLinkProject.setDatasourceLogin(xmlLogin);
            // 200606_changeSummary
            NamespaceResolver nr = new NamespaceResolver();
            SDOTypeHelper sdoTypeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();
            String sdoPrefix = sdoTypeHelper.getPrefix(SDOConstants.SDO_URL);
            nr.put(sdoPrefix, SDOConstants.SDO_URL);
            SDOType changeSummaryType = (SDOType) sdoTypeHelper.getType(SDOConstants.SDO_URL, SDOConstants.CHANGESUMMARY);
            changeSummaryType.getXmlDescriptor().setNamespaceResolver(nr);
            topLinkProject.addDescriptor(changeSummaryType.getXmlDescriptor());
            SDOType openSequencedType = (SDOType) aHelperContext.getTypeHelper().getType(SDOConstants.ORACLE_SDO_URL, "OpenSequencedType");
            topLinkProject.addDescriptor(openSequencedType.getXmlDescriptor());
            SDOTypeType typeType = (SDOTypeType)aHelperContext.getTypeHelper().getType(SDOConstants.SDO_URL, SDOConstants.TYPE);
            typeType.getXmlDescriptor().setNamespaceResolver(nr);
            if(!typeType.isInitialized()) {
                typeType.initializeMappings();
            }
            topLinkProject.addDescriptor(typeType.getXmlDescriptor());
            SDOPropertyType propertyType = (SDOPropertyType)aHelperContext.getTypeHelper().getType(SDOConstants.SDO_URL, SDOConstants.PROPERTY);
            if(!propertyType.isInitialized()) {
                propertyType.initializeMappings();
            }
            topLinkProject.addDescriptor(propertyType.getXmlDescriptor());

            ((SDOTypeHelper)aHelperContext.getTypeHelper()).addWrappersToProject(topLinkProject);
        }
        return topLinkProject;
    }

    @Override
    public void setXmlMarshaller(XMLMarshaller xmlMarshaller) {
        this.xmlMarshallerMap.put(Thread.currentThread(), xmlMarshaller);
    }

    @Override
    public XMLMarshaller getXmlMarshaller() {
        XMLMarshaller marshaller = xmlMarshallerMap.get(Thread.currentThread());

        if (marshaller == null) {
            marshaller = getXmlContext().createMarshaller();
            marshaller.setMarshalListener(new SDOMarshalListener(marshaller, (SDOTypeHelper) aHelperContext.getTypeHelper()));
            xmlMarshallerMap.put(Thread.currentThread(), marshaller);
        }

        XMLContext context = getXmlContext();
        if (marshaller.getXMLContext() != context) {
            marshaller.setXMLContext(context);
        }
        return marshaller;
    }

    private XMLMarshaller getXmlMarshaller(Object options) {
        XMLMarshaller xmlMarshaller = getXmlMarshaller().clone();
        if(null == options) {
            return xmlMarshaller;
        }
        try {
            DataObject optionsDO = (DataObject) options;
            if(optionsDO.isSet(SDOConstants.ATTACHMENT_MARSHALLER_OPTION)) {
                xmlMarshaller.setAttachmentMarshaller((XMLAttachmentMarshaller)optionsDO.get(SDOConstants.ATTACHMENT_MARSHALLER_OPTION));
            }
            xmlMarshaller.setMarshalListener(new SDOMarshalListener(xmlMarshaller, (SDOTypeHelper) aHelperContext.getTypeHelper()));
            return xmlMarshaller;
        } catch(ClassCastException ccException) {
            throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
        }
    }

    @Override
    public void setXmlUnmarshaller(XMLUnmarshaller xmlUnmarshaller) {
        this.xmlUnmarshallerMap.put(Thread.currentThread(), xmlUnmarshaller);
    }

    @Override
    public XMLUnmarshaller getXmlUnmarshaller() {
        XMLUnmarshaller unmarshaller = xmlUnmarshallerMap.get(Thread.currentThread());

        if (null == unmarshaller) {
            unmarshaller = getXmlContext().createUnmarshaller();
            unmarshaller.getProperties().put(SDOConstants.SDO_HELPER_CONTEXT, aHelperContext);
            unmarshaller.setUnmappedContentHandlerClass(SDOUnmappedContentHandler.class);
            unmarshaller.setUnmarshalListener(new SDOUnmarshalListener(aHelperContext));
            unmarshaller.setResultAlwaysXMLRoot(true);
            xmlUnmarshallerMap.put(Thread.currentThread(), unmarshaller);
        }

        XMLContext context = getXmlContext();
        if (unmarshaller.getXMLContext() != context) {
            unmarshaller.setXMLContext(context);
        }
        return unmarshaller;
    }

    private XMLUnmarshaller getXmlUnmarshaller(Object options) {
        XMLUnmarshaller xmlUnmarshaller = getXmlUnmarshaller().clone();
        if(null == options) {
            return xmlUnmarshaller;
        }
        try {
            DataObject optionsDO = (DataObject) options;
            if(optionsDO.isSet(SDOConstants.ATTACHMENT_UNMARSHALLER_OPTION)) {
                xmlUnmarshaller.setAttachmentUnmarshaller((XMLAttachmentUnmarshaller)optionsDO.get(SDOConstants.ATTACHMENT_UNMARSHALLER_OPTION));
            }
            return xmlUnmarshaller;
        } catch(ClassCastException ccException) {
            throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
        }
    }

    @Override
    public void reset() {
        setTopLinkProject(null);
        setXmlContext(null);
        this.xmlMarshallerMap.clear();
        this.xmlUnmarshallerMap.clear();
        setLoader(new SDOClassLoader(getClass().getClassLoader(), aHelperContext));
    }

    @Override
    public HelperContext getHelperContext() {
        return aHelperContext;
    }

    @Override
    public void setHelperContext(HelperContext helperContext) {
        aHelperContext = helperContext;
    }

    private void handleXMLMarshalException(XMLMarshalException xmlException) throws IOException {
        if(xmlException.getErrorCode() == XMLMarshalException.NO_DESCRIPTOR_WITH_MATCHING_ROOT_ELEMENT || xmlException.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
            throw SDOException.globalPropertyNotFound();
        } else if (xmlException.getCause() instanceof IOException) {
            throw (IOException) xmlException.getCause();
        } else{
            throw xmlException;
        }
    }

    @Override
    public XMLConversionManager getXmlConversionManager() {
        return (XMLConversionManager) getXmlContext().getSession().getDatasourceLogin().getDatasourcePlatform().getConversionManager();
    }

}
