/*
 * 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.Collection;
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.AnyObjectMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.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.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 object XML mappings map an attribute that contains a single object to  an XML element.
 * The referenced object may be of any type (including String), and does not need not be related
 * to any other particular type through inheritance or a common interface.  The corresponding
 * object attribute value 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 object XML 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 Object 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-method</td>
 * <td headers="c2">The name information is stored in the contact-method element.</td>
 * </tr>
 * <tr>
 * <td headers="c1" style="nowrap">contact-method/info</td>
 * <td headers="c2">The XPath statement may be used to specify any valid path.</td>
 * </tr>
 * <tr>
 * <td headers="c1">contact-method[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-method element.</td>
 * </tr>
 * </table>
 *
 * <p><b>Mapping an element of type xs:anyType as an Any Object 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-method" 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-method" 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>
 * XMLAnyObjectMapping contactMethodMapping = new XMLAnyObjectMapping();<br>
 * contactMethodMapping.setAttributeName("contactMethod");<br>
 * contactMethodMapping.setXPath("contact-method");<br>
 * </code>
 *
 * <p><b>More Information</b>: For more information about using the XML Any Object 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 XMLAnyObjectMapping extends XMLAbstractAnyMapping implements XMLMapping, AnyObjectMapping<AbstractSession, AttributeAccessor, ContainerPolicy, XMLConverter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord> {
    private XMLField field;
    private boolean useXMLRoot;
    private boolean areOtherMappingInThisContext = true;
    private XMLConverter converter;
    private boolean isMixedContent = true;

    public XMLAnyObjectMapping() {
        useXMLRoot = false;
    }

    /**
    * 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 objectDescriptors, Map processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        throw DescriptorException.invalidMappingOperation(this, "fixObjectReferences");
    }

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

    /**
    * 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 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 Object 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 nodes = root.getChildNodes();
        Collection unmappedChildren = getUnmappedChildNodes(nodes);
        Iterator iter = unmappedChildren.iterator();
        int i = 0;
        int length = unmappedChildren.size();
        while (iter.hasNext()) {
            Object objectValue = null;
            org.w3c.dom.Node next = (Node) iter.next();
            if (next.getNodeType() == Node.TEXT_NODE) {
                if ((i == (length - 1)) || (next.getNodeValue().trim().length() > 0)) {
                    objectValue = next.getNodeValue();
                    objectValue = convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller());
                    return objectValue;
                }
            } else if (next.getNodeType() == Node.ELEMENT_NODE) {
                ClassDescriptor 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) {
                    return buildObjectForNonXMLRoot(getDescriptor(nestedRecord, session, null), getConverter(), query, record, nestedRecord, joinManager, session, next, null, null);
                }
                // need to wrap the object in an XMLRoot
                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 {
                        referenceDescriptor = getDescriptor(nestedRecord, session, new QName(nestedRecord.getNamespaceURI(), nestedRecord.getLocalName()));
                    } catch (XMLMarshalException e) {
                        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(nestedRecord, 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) {
                        return ((XMLDescriptor) referenceDescriptor).wrapObjectInXMLRoot(objVal, next.getNamespaceURI(), next.getLocalName(), next.getPrefix(), false, record.isNamespaceAware(),record.getUnmarshaller());
                    }
                    // no descriptor, so manually build the XMLRoot
                    return buildXMLRoot(next, objVal);
                }
                // if we have a descriptor use it to build the object and wrap it in an XMLRoot
                if (referenceDescriptor != null) {
                    return buildObjectAndWrapInXMLRoot(referenceDescriptor, getConverter(), query, record, nestedRecord, joinManager, session, next, null, null);
                }
                // no descriptor, but could be TEXT to wrap and return
                XMLRoot rootValue;
                if ((rootValue = buildXMLRootForText(next, schemaTypeQName, getConverter(), session, record)) != null) {
                    return rootValue;
                }
            }
            i++;
        }
        return null;
    }

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

    @Override
    public void writeSingleValue(Object value, Object parent, XMLRecord row, AbstractSession session) {
        DOMRecord record = (DOMRecord) row;
        Node root = record.getDOM();
        Object objectValue = value;
        objectValue = convertObjectValueToDataValue(objectValue, session, row.getMarshaller());
        if (field != null) {
            root = XPathEngine.getInstance().create((XMLField) getField(), root, session);
        }
        org.w3c.dom.Document doc = record.getDocument();

        XMLField xmlRootField = null;
        boolean wasXMLRoot = false;
        Object originalObject = objectValue;
        Node toReplace = getNodeToReplace(root);
        if (usesXMLRoot() && (objectValue instanceof XMLRoot)) {
            xmlRootField = new XMLField();
            wasXMLRoot = true;
            XPathFragment frag = new XPathFragment();
            if ((((XMLRoot) objectValue)).getNamespaceURI() != null) {
                frag.setNamespaceURI(((XMLRoot) objectValue).getNamespaceURI());
            }
            frag.setXPath(((XMLRoot) objectValue).getLocalName());

            xmlRootField.setXPathFragment(frag);
            xmlRootField.setNamespaceResolver(row.getNamespaceResolver());

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

            DOMRecord nestedRecord = (DOMRecord) buildCompositeRow(objectValue, session, referenceDescriptor, row, xmlRootField, originalObject, wasXMLRoot);

            if ((nestedRecord != null) && (toReplace != null)) {
                if (nestedRecord.getDOM() != toReplace) {
                    root.replaceChild(nestedRecord.getDOM(), toReplace);
                }
            } else if (nestedRecord != null) {
                root.appendChild(nestedRecord.getDOM());
            } else if (toReplace != null) {
                root.removeChild(toReplace);
            }
        }
    }

    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 void initialize(AbstractSession session) throws DescriptorException {
        if (getField() != null) {
            setField(getDescriptor().buildField(getField()));
        }
        if (null != converter) {
            converter.initialize(this, session);
        }
    }

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

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

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

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


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

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

    public Node getNodeToReplace(Node parent) {
        //find the first child node that this any applies to.
        Node next = parent.getFirstChild();
        while(next != null) {
            if ((next.getNodeType() == Node.ELEMENT_NODE) || (next.getNodeType() == Node.TEXT_NODE) || (next.getNodeType() == Node.CDATA_SECTION_NODE)) {
                if (isUnmappedContent(next)) {
                    return next;
                }
            }
            next = next.getNextSibling();
        }
        return null;
    }

    private void writeSimpleValue(XMLField xmlRootField, DOMRecord row, AbstractSession session, Object originalObject, Object value, Node root, Node toReplace, boolean wasXMLRoot) {
        org.w3c.dom.Document doc = row.getDocument();
        if (wasXMLRoot) {
            if (((XMLRoot) originalObject).getNamespaceURI() != null) {
                String prefix = row.getNamespaceResolver().resolveNamespaceURI(((XMLRoot) originalObject).getNamespaceURI());
                if ((prefix == null) || prefix.length() == 0) {
                    xmlRootField.getXPathFragment().setGeneratedPrefix(true);
                    prefix = row.getNamespaceResolver().generatePrefix();
                }
                xmlRootField.getXPathFragment().setXPath(prefix + XMLConstants.COLON + ((XMLRoot) originalObject).getLocalName());
            }
        }

        if (null == xmlRootField) {
            Text textNode = doc.createTextNode((String) value);
            if (toReplace != null) {
                root.replaceChild(textNode, toReplace);
            } else {
                root.appendChild(textNode);
            }
        } else {
            QName qname = ((XMLRoot) originalObject).getSchemaType();
            if(qname != null && !qname.equals(XMLConstants.STRING_QNAME)){
                xmlRootField.setSchemaType(qname);
                xmlRootField.setIsTypedTextField(true);
                xmlRootField.addJavaConversion(value.getClass(), qname);
            }
            Node newNode = XPathEngine.getInstance().create(xmlRootField, root, value, session);
        }
    }

    public XMLConverter getConverter() {
        return converter;
    }

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

    @Override
    public boolean isMixedContent() {
        return this.isMixedContent;
    }

    @Override
    public void setMixedContent(boolean mixed) {
        this.isMixedContent = mixed;
    }

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

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

}
