/*
 * 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.Iterator;
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.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.oxm.XPathEngine;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.AnyCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.ListContainerPolicy;
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.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.ContainerMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
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.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
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.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * <p>Any collection XML mappings map an attribute that contains a heterogenous collection of
 * objects to multiple XML elements.  Unlike composite collection XML mappings, the referenced
 * objects may be of different types (including String), and do not need to be related to each
 * other through inheritance or a common interface.  The corresponding object attribute should
 * be generic enough for all possible application values.  Note that each of the referenced objects
 * (except String) must specify a default root element on their descriptor.
 *
 * <p><b>Any collection mappings are useful with the following XML schema constructs</b>:<ul>
 * <li> any </li>
 * <li> choice </li>
 * <li> substitution groups </li>
 * </ul>
 *
 * <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 Collection Mappings the XPath
 * is optional.
 *
 * <p>The following XPath statements may be used to specify the location of XML data relating to an object's
 * name attribute:
 *
 * <table border="1">
 * <caption>XPath statements</caption>
 * <tr>
 * <th id="c1">XPath</th>
 * <th id="c2">Description</th>
 * </tr>
 * <tr>
 * <td headers="c1">contact-methods</td>
 * <td headers="c2">The name information is stored in the contact-methods element.</td>
 * </tr>
 * <tr>
 * <td headers="c1" style="nowrap">contact-methods/info</td>
 * <td headers="c2">The XPath statement may be used to specify any valid path.</td>
 * </tr>
 * <tr>
 * <td headers="c1">contact-methods[2]</td>
 * <td headers="c2">The XPath statement may contain positional information.  In this case the contact
 * information is stored in the second occurrence of the contact-methods element.</td>
 * </tr>
 * </table>
 *
 * <p><b>Mapping an element of type xs:anyType as an Any Collection Mapping</b>:
 *  <!--
 * <?xml version="1.0" encoding="UTF-8"?>
 * <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 *     <xsd:element name="customer" type="customer-type"/>
 *    <xsd:complexType name="customer-type">
 *         <xsd:sequence>
 *             <xsd:element name="contact-methods" type="xsd:anyType"/>
 *         </xsd:sequence>
 *     </xsd:complexType>
 *     <xsd:element name="address">
 *         <xsd:complexType>
 *             <xsd:sequence>
 *                 <xsd:element name="street" type="xsd:string"/>
 *                 <xsd:element name="city" type="xsd:string"/>
 *             </xsd:sequence>
 *         </xsd:complexType>
 *     </xsd:element>
 *     <xsd:element name="phone-number" type="xsd:string"/>
 * </xsd:schema>
 *  -->
 *
 * <p><em>XML Schema</em><br>
 * <code>
 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
 * &lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="customer" type="customer-type"/&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:complexType name="customer-type"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="contact-methods" type="xsd:anyType"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="address"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="street" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="city" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:element&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="phone-number" type="xsd:string"/&gt;<br>
 * &lt;/xsd:schema&gt;<br>
 * </code>
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLAnyCollectionMapping contactMethodsMapping = new XMLAnyCollectionMapping();<br>
 * contactMethodsMapping.setAttributeName("contactMethods");<br>
 * contactMethodsMapping.setXPath("contact-methods");<br>
 * </code>
 *
 * <p><b>More Information</b>: For more information about using the XML Any Collection Mapping, see the
 * "Understanding XML Mappings" chapter of the Oracle TopLink Developer's Guide.
 *
 * @since Oracle TopLink 10<i>g</i> Release 2 (10.1.3)
 */
public class XMLAnyCollectionMapping extends XMLAbstractAnyMapping implements AnyCollectionMapping<AbstractSession, AttributeAccessor, ContainerPolicy, XMLConverter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord>, XMLMapping, ContainerMapping {
    private XMLField field;
    private ContainerPolicy containerPolicy;
    private boolean defaultEmptyContainer = XMLContainerMapping.EMPTY_CONTAINER_DEFAULT;
    private boolean useXMLRoot;
    private boolean mixedContent = true;
    private boolean isWhitespacePreservedForMixedContent = false;
    private boolean areOtherMappingInThisContext = true;
    private XMLConverter valueConverter;
    private boolean reuseContainer;
    private AbstractNullPolicy wrapperNullPolicy;

    public XMLAnyCollectionMapping() {
        this.containerPolicy = ContainerPolicy.buildDefaultPolicy();
        useXMLRoot = false;
        setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_NONE_AS_ELEMENT);
    }

    /**
    * 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 databaseRow, 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
        XMLAnyCollectionMapping mapping = null;
        mapping = (XMLAnyCollectionMapping) 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<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> 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()));
        }
        if(valueConverter != null) {
            valueConverter.initialize(this, session);
        }
    }

    /**
    * 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");
    }

    @Override
    public void setContainerPolicy(ContainerPolicy cp) {
        this.containerPolicy = 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, joinManager);
    }

    private Object buildObjectValuesFromDOMRecord(DOMRecord record, AbstractSession session, ObjectBuildingQuery query, JoinedAttributeManager joinManager) {
        //This DOMRecord represents the root node of the AnyType instance
        //Grab ALL children to populate the collection.
        Node root = record.getDOM();
        NodeList children = root.getChildNodes();

        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();
        }

        int length = children.getLength();
        Node next = null;
        if(length > 0) {
            next = record.getDOM().getFirstChild();
        }
        while(next != null) {
            Object objectValue = null;
            if (isUnmappedContent(next)) {
                if ((next.getNodeType() == Node.TEXT_NODE) && this.isMixedContent()) {
                    if (next.getNodeValue().trim().length() > 0) {
                        objectValue = next.getNodeValue();
                        objectValue = convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
                        cp.addInto(objectValue, container, session);
                    }
                } else if (next.getNodeType() == Node.ELEMENT_NODE) {
                    XMLDescriptor referenceDescriptor = null;

                    //In this case it must be an element so we need to dig up the descriptor
                    //make a nested record and build an object from it.
                    DOMRecord nestedRecord = (DOMRecord) record.buildNestedRow((Element) next);

                    if (!useXMLRoot) {
                        referenceDescriptor = getDescriptor(nestedRecord, session, null);
                        objectValue = buildObjectForNonXMLRoot(referenceDescriptor, getConverter(), query, record, nestedRecord, joinManager, session, next, container, cp);
                    } else {
                        String schemaType = ((Element) next).getAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);
                        QName schemaTypeQName = null;
                        XPathFragment frag = new XPathFragment();
                        if ((null != schemaType) && (schemaType.length() > 0)) {
                            frag.setXPath(schemaType);
                            if (frag.hasNamespace()) {
                                String prefix = frag.getPrefix();
                                XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
                                String url = xmlPlatform.resolveNamespacePrefix(next, prefix);
                                frag.setNamespaceURI(url);
                                schemaTypeQName = new QName(url, frag.getLocalName());
                            }
                            XMLContext xmlContext = nestedRecord.getUnmarshaller().getXMLContext();
                            referenceDescriptor = xmlContext.getDescriptorByGlobalType(frag);
                        }
                        if (referenceDescriptor == null) {
                            try {
                                QName qname = new QName(nestedRecord.getNamespaceURI(), nestedRecord.getLocalName());
                                referenceDescriptor = getDescriptor(nestedRecord, session, qname);
                            } catch (XMLMarshalException e) {
                                referenceDescriptor = null;
                            }
                            // Check if descriptor is for a wrapper, if it is null it out and let continue
                            XMLDescriptor xmlReferenceDescriptor = referenceDescriptor;
                            if (referenceDescriptor != null && xmlReferenceDescriptor.isWrapper()) {
                                referenceDescriptor = null;
                            }
                        }
                        // if KEEP_ALL_AS_ELEMENT is set, or we don't have a descriptor and KEEP_UNKNOWN_AS_ELEMENT
                        // is set, then we want to return either an Element or an XMLRoot wrapping an Element
                        if (getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT || (referenceDescriptor == null && getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT)) {
                            Object objVal = buildObjectNoReferenceDescriptor(record, getConverter(), session, next, null, null);
                            // wrap the object in an XMLRoot
                            // if we know the descriptor use it to wrap the Element in an XMLRoot (if necessary)
                            if (referenceDescriptor != null) {
                                objVal = referenceDescriptor.wrapObjectInXMLRoot(objVal, next.getNamespaceURI(), next.getLocalName(), next.getPrefix(), false, record.isNamespaceAware(), record.getUnmarshaller());
                                cp.addInto(objVal, container, session);
                            } else {
                                // no descriptor, so manually build the XMLRoot
                                cp.addInto(buildXMLRoot(next, objVal), container, session);
                            }
                        }
                        // if we have a descriptor use it to build the object and wrap it in an XMLRoot
                        else if (referenceDescriptor != null) {
                            buildObjectAndWrapInXMLRoot(referenceDescriptor, getConverter(), query, record, nestedRecord, joinManager, session, next, container, cp);
                        } else {
                            // no descriptor, but could be TEXT to wrap and return
                            XMLRoot rootValue;
                            if ((rootValue = buildXMLRootForText(next, schemaTypeQName, getConverter(), session, record)) != null) {
                                cp.addInto(rootValue, container, session);
                            }
                        }
                    }
                }
            }
            next = next.getNextSibling();
        }
        return container;
    }

    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) throws DescriptorException {
        if (this.isReadOnly()) {
            return;
        }
        DOMRecord record = (DOMRecord) row;
        Object attributeValue = this.getAttributeValueFromObject(object);
        Node root = record.getDOM();
        org.w3c.dom.Document doc = record.getDocument();
        XMLField xmlRootField = null;
        if (attributeValue == null) {
            return;
        }
        if (field != null) {
            root = XPathEngine.getInstance().create((XMLField) getField(), record.getDOM(), session);
            DOMRecord rootRecord = new DOMRecord(root);
            rootRecord.setSession(session);
            rootRecord.setDocPresPolicy(record.getDocPresPolicy());
            rootRecord.setNamespaceResolver(record.getNamespaceResolver());
            rootRecord.setMarshaller(record.getMarshaller());
            record = rootRecord;
        }

        ContainerPolicy cp = this.getContainerPolicy();
        ArrayList childNodes = getUnmappedChildNodes(record.getDOM().getChildNodes());
        Object iter = cp.iteratorFor(attributeValue);
        int childNodeCount = 0;
        boolean wasXMLRoot = false;
        if(null != iter) {
            while (cp.hasNext(iter) && (childNodeCount < childNodes.size())) {
                Object element = cp.next(iter, session);
                element = convertObjectValueToDataValue(element, session, record.getMarshaller());
                Object originalObject = element;
                Node nextChild = null;
                while (childNodeCount < childNodes.size()) {
                    Node nextPossible = (Node) childNodes.get(childNodeCount);
                    if ((nextPossible.getNodeType() == Node.ELEMENT_NODE) || (nextPossible.getNodeType() == Node.TEXT_NODE) || (nextPossible.getNodeType() == Node.CDATA_SECTION_NODE)) {
                        nextChild = nextPossible;
                        childNodeCount++;
                        break;
                    }
                    childNodeCount++;
                }
                if (nextChild == null) {
                    break;
                }
                if (usesXMLRoot() && (element instanceof XMLRoot)) {
                    xmlRootField = new XMLField();
                    wasXMLRoot = true;
                    XPathFragment frag = new XPathFragment();

                    if ((((XMLRoot) element)).getNamespaceURI() != null) {
                        frag.setNamespaceURI(((XMLRoot) element).getNamespaceURI());
                    }
                    frag.setXPath(((XMLRoot) element).getLocalName());
                    xmlRootField.setXPathFragment(frag);

                    xmlRootField.setNamespaceResolver(record.getNamespaceResolver());
                    element = ((XMLRoot) element).getObject();
                }
                if (element instanceof String) {
                    if (wasXMLRoot) {
                        if (((XMLRoot) originalObject).getNamespaceURI() != null) {
                            String prefix = record.getNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                            if ((prefix == null) || prefix.length() == 0) {
                                xmlRootField.getXPathFragment().setGeneratedPrefix(true);
                                prefix = record.getNamespaceResolver().generatePrefix();
                            }
                            xmlRootField.getXPathFragment().setXPath(prefix + XMLConstants.COLON + ((XMLRoot) originalObject).getLocalName());
                        }
                    }

                    if (xmlRootField != null) {
                        XPathEngine.getInstance().create(xmlRootField, root, element, session);
                    } else {
                        Text textNode = doc.createTextNode((String) element);
                        root.replaceChild(textNode, nextChild);
                    }
                } else if (element instanceof org.w3c.dom.Node) {
                    Node importedCopy = doc.importNode((Node) element, true);
                    root.replaceChild(importedCopy, nextChild);
                } else {
                    XMLDescriptor referenceDescriptor = (XMLDescriptor) session.getDescriptor(element.getClass());

                    if (wasXMLRoot) {
                        if (((XMLRoot) originalObject).getNamespaceURI() != null) {
                            String prefix = referenceDescriptor.getNonNullNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                            if ((prefix == null) || prefix.length() == 0) {
                                prefix = record.getNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                            }
                            if ((prefix == null) || prefix.length() == 0) {
                                xmlRootField.getXPathFragment().setGeneratedPrefix(true);
                                prefix = record.getNamespaceResolver().generatePrefix();
                            }
                            xmlRootField.getXPathFragment().setXPath(prefix + XMLConstants.COLON + ((XMLRoot) originalObject).getLocalName());
                        }
                    }

                    DOMRecord nestedRecord = (DOMRecord) buildCompositeRow(element, session, referenceDescriptor, row, xmlRootField, element, wasXMLRoot);
                    if (nestedRecord != null) {
                        if (nestedRecord.getDOM() != nextChild) {
                            root.replaceChild(nestedRecord.getDOM(), nextChild);
                        }
                    }
                }
            }
        }
        if (childNodeCount < childNodes.size()) {
            //Remove whatever's left
            for (int i = childNodeCount; i < childNodes.size(); i++) {
                Node child = (Node) childNodes.get(i);
                if ((child.getNodeType() == Node.ELEMENT_NODE) || (child.getNodeType() == Node.TEXT_NODE) || (child.getNodeType() == Node.CDATA_SECTION_NODE)) {
                    root.removeChild(child);
                }
            }
        }
        if (null != iter && cp.hasNext(iter)) {
            while (cp.hasNext(iter)) {
                //add in extras
                Object element = cp.next(iter, session);
                writeSingleValue(element, object, record, session);
            }
        }
    }

    @Override
    public void writeSingleValue(Object element, Object parent, XMLRecord row, AbstractSession session) {
        XMLField xmlRootField = null;
        Object originalObject = element;
        DOMRecord record = (DOMRecord) row;
        Node root = record.getDOM();
        org.w3c.dom.Document doc = row.getDocument();
        boolean wasXMLRoot = false;

        if (usesXMLRoot() && (element instanceof XMLRoot)) {
            wasXMLRoot = true;
            xmlRootField = new XMLField();
            XPathFragment frag = new XPathFragment();
            if ((((XMLRoot) element)).getNamespaceURI() != null) {
                frag.setNamespaceURI(((XMLRoot) element).getNamespaceURI());
            }
            frag.setLocalName(((XMLRoot) element).getLocalName());

            xmlRootField.setXPathFragment(frag);

            xmlRootField.setNamespaceResolver(row.getNamespaceResolver());
            element = ((XMLRoot) element).getObject();
        }
        if (element instanceof String) {
            writeSimpleValue(xmlRootField, element, originalObject, record, doc, root, wasXMLRoot, session);
        } else if (element instanceof org.w3c.dom.Node) {
            Node importedCopy = doc.importNode((Node) element, true);
            root.appendChild(importedCopy);
        } else {
            XMLDescriptor referenceDescriptor = (XMLDescriptor) session.getDescriptor(element.getClass());
            if (referenceDescriptor == null) {
                writeSimpleValue(xmlRootField, element, originalObject, record, doc, root, wasXMLRoot, session);
                return;
            }
            if (wasXMLRoot) {
                if (((XMLRoot) originalObject).getNamespaceURI() != null) {
                    String prefix = referenceDescriptor.getNonNullNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                    if ((prefix == null) || prefix.length() == 0) {
                        prefix = record.getNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                    }
                    if ((prefix == null) || prefix.length() == 0) {
                        xmlRootField.getXPathFragment().setGeneratedPrefix(true);
                        prefix = record.getNamespaceResolver().generatePrefix();
                    }
                    xmlRootField.getXPathFragment().setXPath(prefix + XMLConstants.COLON + ((XMLRoot) originalObject).getLocalName());
                }
            }

            DOMRecord nestedRecord = (DOMRecord) buildCompositeRow(element, session, referenceDescriptor, row, xmlRootField, originalObject, wasXMLRoot);
            if (nestedRecord != null) {
                root.appendChild(nestedRecord.getDOM());
            }
        }
    }

    private void writeSimpleValue(XMLField xmlRootField, Object element, Object originalObject, DOMRecord record, org.w3c.dom.Document doc, Node root, boolean wasXMLRoot, AbstractSession session) {
        if (wasXMLRoot) {
            if (((XMLRoot) originalObject).getNamespaceURI() != null) {
                String prefix = record.getNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                if ((prefix == null) || prefix.length() == 0) {
                    xmlRootField.getXPathFragment().setGeneratedPrefix(true);
                    prefix = record.getNamespaceResolver().generatePrefix();
                }
                xmlRootField.getXPathFragment().setXPath(prefix + XMLConstants.COLON + ((XMLRoot) originalObject).getLocalName());
            }
        }
        if (xmlRootField != null) {
            xmlRootField.setNamespaceResolver(record.getNamespaceResolver());
            QName qname = ((XMLRoot) originalObject).getSchemaType();
            if(qname != null){
                if(!qname.equals(XMLConstants.STRING_QNAME)){
                    xmlRootField.setSchemaType(qname);
                    xmlRootField.setIsTypedTextField(true);
                    xmlRootField.addJavaConversion(((XMLRoot) originalObject).getObject().getClass(), qname);
                }
            }
           Node newNode = XPathEngine.getInstance().create(xmlRootField, root, element, session);
        } else {
            Text textNode = doc.createTextNode((String) element);
            root.appendChild(textNode);
        }
    }

    protected AbstractRecord buildCompositeRow(Object attributeValue, AbstractSession session, XMLDescriptor referenceDescriptor, AbstractRecord parentRow, DatabaseField field, Object originalObject, boolean wasXMLRoot) {
        String defaultRootElementString = null;
        if(referenceDescriptor != null){
            defaultRootElementString = referenceDescriptor.getDefaultRootElement();
            if (!wasXMLRoot && defaultRootElementString == null) {
                throw XMLMarshalException.defaultRootElementNotSpecified((XMLDescriptor) descriptor);
            }
        }

        if ((field == null) && (referenceDescriptor != null) && (defaultRootElementString != null)) {
            field = referenceDescriptor.buildField(defaultRootElementString);
        }

        if ((field != null) && (referenceDescriptor != null)) {
            ((XMLRecord) parentRow).setLeafElementType(referenceDescriptor.getDefaultRootElementType());
            XMLObjectBuilder objectBuilder = (XMLObjectBuilder) referenceDescriptor.getObjectBuilder();

            XMLRecord child = (XMLRecord) objectBuilder.createRecordFor(attributeValue, (XMLField) field, (XMLRecord) parentRow, this);
            child.setNamespaceResolver(((XMLRecord) parentRow).getNamespaceResolver());
            objectBuilder.buildIntoNestedRow(child, originalObject, attributeValue, session, referenceDescriptor, (XMLField) field, wasXMLRoot);
            return child;
        }
        return null;
    }

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

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

    /**
     * PUBLIC:
     * Configure the mapping to use an instance of the specified container class
     * to hold the target objects.
     * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Collection interface.
     * <p>jdk1.1.x: The container class must be a subclass of Vector.
     */
    @Override
    public void useCollectionClass(Class<?> concreteContainerClass) {
        this.setContainerPolicy(ContainerPolicy.buildPolicyFor(concreteContainerClass));
    }

    @Override
    public void useMapClass(Class<?> concreteContainerClass, String methodName) {
        throw DescriptorException.invalidMappingOperation(this, "useMapClass");
    }

    @Override
    public void useMapClassName(String concreteContainerClass, String methodName) {
        throw DescriptorException.invalidMappingOperation(this, "useMapClass");
    }

    @Override
    public void useCollectionClassName(String concreteContainerClassName) {
        this.setContainerPolicy(new CollectionContainerPolicy(concreteContainerClassName));
    }

    @Override
    public void useListClassName(String concreteContainerClassName) {
        this.setContainerPolicy(new ListContainerPolicy(concreteContainerClassName));
    }

    @Override
    public void setUseXMLRoot(boolean useXMLRoot) {
        this.useXMLRoot = useXMLRoot;
    }

    @Override
    public boolean usesXMLRoot() {
        return useXMLRoot;
    }

    @Override
    public boolean isMixedContent() {
        return mixedContent;
    }

    @Override
    public void setMixedContent(boolean mixed) {
        mixedContent = mixed;
    }


    private boolean isUnmappedContent(Node node) {
        if (!areOtherMappingInThisContext) {
            return true;
        }
        XMLDescriptor parentDesc = (XMLDescriptor) this.getDescriptor();
        XMLField field = (XMLField) this.getField();
        Iterator<DatabaseMapping> mappings = parentDesc.getMappings().iterator();
        int mappingsInContext = 0;
        while (mappings.hasNext()) {
            DatabaseMapping next = mappings.next();
            if (!(next == this)) {
                XMLField nextField = (XMLField) next.getField();
                XPathFragment frag = getFragmentToCompare(nextField, field);
                if (frag != null) {
                    mappingsInContext++;
                    if (((node.getNodeType() == Node.TEXT_NODE) || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && frag.nameIsText()) {
                        return false;
                    }
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        String nodeNS = node.getNamespaceURI();
                        String fragNS = frag.getNamespaceURI();
                        String nodeLocalName = node.getLocalName();
                        String fragLocalName = frag.getLocalName();
                        if ((nodeNS == fragNS) || ((nodeNS != null) && (fragNS != null) && nodeNS.equals(fragNS))) {
                            if ((nodeLocalName == fragLocalName) || ((nodeLocalName != null) && (fragLocalName != null) && nodeLocalName.equals(fragLocalName))) {
                                return false;
                            }
                        }
                    }
                }
            }
            if (mappingsInContext == 0) {
                this.areOtherMappingInThisContext = false;
            }
        }
        return true;
    }

    private XPathFragment getFragmentToCompare(XMLField field, XMLField context) {
        if (field == null) {
            return null;
        }
        if (context == null) {
            return field.getXPathFragment();
        }
        XPathFragment fieldFrag = field.getXPathFragment();
        XPathFragment contextFrag = context.getXPathFragment();

        while ((fieldFrag != null) && (contextFrag != null)) {
            if (fieldFrag.equals(contextFrag)) {
                if (contextFrag.getNextFragment() == null) {
                    return fieldFrag.getNextFragment();
                } else {
                    contextFrag = contextFrag.getNextFragment();
                    fieldFrag = fieldFrag.getNextFragment();
                }
            } else {
                return null;
            }
        }
        return null;
    }

    private ArrayList getUnmappedChildNodes(NodeList nodes) {
        ArrayList unmappedNodes = new ArrayList();
        int length = nodes.getLength();
        for (int i = 0; i < length; i++) {
            Node next = nodes.item(i);
            if (isUnmappedContent(next)) {
                unmappedNodes.add(next);
            }
        }
        return unmappedNodes;
    }

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

    @Override
    public void setConverter(XMLConverter conv) {
        this.valueConverter = conv;
    }

    public XMLConverter getConverter() {
        return this.valueConverter;
    }

    /**
     * Setting this to true indicates that text nodes containing *only* whitespaces should still be
     * added to the collection as strings for mixed content.
     *
     * If mixedContent is false, this setting has no effect.
     */
    @Override
    public boolean isWhitespacePreservedForMixedContent() {
        return this.isWhitespacePreservedForMixedContent;
    }

    @Override
    public void setPreserveWhitespaceForMixedContent(boolean preserveWhitespace) {
        this.isWhitespacePreservedForMixedContent = preserveWhitespace;
    }

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

    /**
     * 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.defaultEmptyContainer = defaultEmptyContainer;
    }

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

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

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertObjectValueToDataValue(Object value, Session session, XMLMarshaller marshaller) {
        if (null != valueConverter) {
            return valueConverter.convertObjectValueToDataValue(value, session, marshaller);
        }
        return value;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertDataValueToObjectValue(Object fieldValue, Session session, XMLUnmarshaller unmarshaller) {
        if (null != valueConverter) {
            return valueConverter.convertDataValueToObjectValue(fieldValue, session, unmarshaller);
        }
        return fieldValue;
    }

}
