/*
 * 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.lang.reflect.Modifier;
import java.util.Enumeration;
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.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.ConversionManager;
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.XPathQName;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.MapContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.foundation.AbstractCompositeCollectionMapping;
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.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.NullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.sessions.Session;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * <p>Composite collection XML mappings map an attribute that contains a homogeneous collection of objects
 * to multiple XML elements.  Use composite collection XML mappings to represent one-to-many relationships.
 * Composite collection XML mappings can reference any class that has a TopLink descriptor. The attribute in
 * the object mapped must implement either the Java Collection interface (for example, Vector or HashSet)
 * or Map interface (for example, Hashtable or TreeMap). The CompositeCollectionMapping class
 * allows a reference to the mapped class and the indexing type for that class.  This mapping is, by
 * definition, privately owned.
 *
 * <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 path and positional information;  the last node in the XPath forms the local
 * root node for the composite object.  The XPath is specified on the mapping using the <code>setXPath</code>
 * method.
 *
 * <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">phone-number</td>
 * <td headers="c2">The phone number information is stored in the phone-number element.</td>
 * </tr>
 * <tr>
 * <td headers="c1" style="nowrap">contact-info/phone-number</td>
 * <td headers="c2">The XPath statement may be used to specify any valid path.</td>
 * </tr>
 * <tr>
 * <td headers="c1">phone-number[2]</td>
 * <td headers="c2">The XPath statement may contain positional information.  In this case the phone
 * number information is stored in the second occurrence of the phone-number element.</td>
 * </tr>
 * </table>
 *
 * <p><b>Mapping a Composite Collection</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="first-name" type="xsd:string"/>
 *             <xsd:element name="last-name" type="xsd:string"/>
 *             <xsd:element name="phone-number">
 *                 <xsd:complexType>
 *                     <xsd:sequence>
 *                         <xsd:element name="number" type="xsd:string"/>
 *                     </xsd:sequence>
 *                     <xsd:attribute name="type" type="xsd:string"/>
 *                 </xsd:complexType>
 *             </xsd:element>
 *         </xsd:sequence>
 *     </xsd:complexType>
 * </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="first-name" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="last-name" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="phone-number"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="number" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:attribute name="type" type="xsd:string"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &lt;/xsd:schema&gt;<br>
 * </code>
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLCompositeCollectionMapping phoneNumbersMapping = new XMLCompositeCollectionMapping();<br>
 * phoneNumbersMapping.setAttributeName("phoneNumbers");<br>
 * phoneNumbersMapping.setXPath("phone-number");<br>
 * phoneNumbersMapping.setReferenceClass(PhoneNumber.class);<br>
 * </code>
 *
 * <p><b>More Information</b>: For more information about using the XML Composite 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 XMLCompositeCollectionMapping extends AbstractCompositeCollectionMapping implements CompositeCollectionMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, UnmarshalKeepAsElementPolicy, XMLUnmarshaller, XMLRecord>, XMLMapping, XMLNillableMapping {
    AbstractNullPolicy nullPolicy;
    private AbstractNullPolicy wrapperNullPolicy;
    private UnmarshalKeepAsElementPolicy keepAsElementPolicy;
    private XMLInverseReferenceMapping inverseReferenceMapping;

    private boolean defaultEmptyContainer = XMLContainerMapping.EMPTY_CONTAINER_DEFAULT;
    private boolean isWriteOnly;
    private boolean reuseContainer = false;

    public XMLCompositeCollectionMapping() {
        super();
        // The default policy is NullPolicy
        nullPolicy = new NullPolicy();
    }

    /**
     * Gets the AttributeAccessor that is used to get and set the value of the
     * container on the target object.
     * @deprecated Replaced by getInverseReferenceMapping().getAttributeAccessor()
     */
    @Deprecated
    public AttributeAccessor getContainerAccessor() {
        if (this.inverseReferenceMapping == null) {
            return null;
        }
        return this.inverseReferenceMapping.getAttributeAccessor();
    }

    /**
     * Sets the AttributeAccessor that is used to get and set the value of the
     * container on the target object.
     *
     * @param anAttributeAccessor - the accessor to be used.
     * @deprecated Replaced by getInverseReferenceMapping().setAttributeAccessor()
     */
    @Deprecated
    public void setContainerAccessor(AttributeAccessor anAttributeAccessor) {
        if (this.inverseReferenceMapping == null) {
            return;
        }
        this.inverseReferenceMapping.setAttributeAccessor(anAttributeAccessor);
    }

    /**
     * Sets the name of the backpointer attribute on the target object. Used to
     * populate the backpointer. If the specified attribute doesn't exist on the
     * reference class of this mapping, a DescriptorException will be thrown
     * during initialize.
     *
     * @param attributeName - the name of the backpointer attribute to be populated
     * @deprecated Replaced by getInverseReferenceMapping().setAttributeName()
     */
    @Deprecated
    public void setContainerAttributeName(String attributeName) {
        if (this.inverseReferenceMapping == null) {
            return;
        }
        this.inverseReferenceMapping.setAttributeName(attributeName);
    }

    /**
     * Gets the name of the backpointer attribute on the target object.
     * @deprecated Replaced by getInverseReferenceMapping().getAttributeName()
     */
    @Deprecated
    public String getContainerAttributeName() {
        if (this.inverseReferenceMapping == null) {
            return null;
        }
        return this.inverseReferenceMapping.getAttributeName();
    }

    /**
     * Sets the method name to be used when accessing the value of the back pointer
     * on the target object of this mapping. If the specified method isn't declared
     * on the reference class of this mapping, a DescriptorException will be thrown
     * during initialize.
     *
     * @param methodName - the name of the getter method to be used.
     * @deprecated Replaced by getInverseReferenceMapping().setGetMethodName()
     */
    @Deprecated
    public void setContainerGetMethodName(String methodName) {
        if (this.inverseReferenceMapping == null) {
            return;
        }
        this.inverseReferenceMapping.setGetMethodName(methodName);
    }

    /**
     * Gets the name of the method to be used when accessing the value of the
     * back pointer on the target object of this mapping.
     * @deprecated Replaced by getInverseReferenceMapping().getGetMethodName()
     */
    @Deprecated
    public String getContainerGetMethodName() {
        if (this.inverseReferenceMapping == null) {
            return null;
        }
        return this.inverseReferenceMapping.getGetMethodName();
    }

    /**
     * Gets the name of the method to be used when setting the value of the
     * back pointer on the target object of this mapping.
     * @deprecated Replaced by getInverseReferenceMapping().getSetMethodName()
     */
    @Deprecated
    public String getContainerSetMethodName() {
        if (this.inverseReferenceMapping == null) {
            return null;
        }
        return this.inverseReferenceMapping.getSetMethodName();
    }

    /**
     * Sets the name of the method to be used when setting the value of the back pointer
     * on the target object of this mapping. If the specified method isn't declared on
     * the reference class of this mapping, a DescriptorException will be
     * raised during initialize.
     *
     * @param methodName - the name of the setter method to be used.
     * @deprecated Replaced by getInverseReferenceMapping().setSetMethodName()
     */
    @Deprecated
    public void setContainerSetMethodName(String methodName) {
        if (this.inverseReferenceMapping == null) {
            return;
        }
        this.inverseReferenceMapping.setSetMethodName(methodName);
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isXMLMapping() {
        return true;
    }


    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        if(XMLConstants.UNKNOWN_OR_TRANSIENT_CLASS.equals(referenceClassName)){
            return;
        }
        super.convertClassNamesToClasses(classLoader);
    }
    /**
     * INTERNAL:
     * The mapping is initialized with the given session. This mapping is fully initialized
     * after this.
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        //modified so that reference class on composite mappings is no longer mandatory
        String referenceClassName = getReferenceClassName();
        if (this.referenceClass == null && referenceClassName != null) {
            if (!referenceClassName.equals(XMLConstants.UNKNOWN_OR_TRANSIENT_CLASS)) {
                setReferenceClass(session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(referenceClassName));
            }
        }
        initializeReferenceDescriptorAndField(session);
        ContainerPolicy cp = getContainerPolicy();
        if (cp != null) {
            if (cp.getContainerClass() == null) {
                Class cls = session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(cp.getContainerClassName());
                cp.setContainerClass(cls);
            }
            if (cp instanceof MapContainerPolicy) {
                initializeMapContainerPolicy(session, (MapContainerPolicy)cp);

            }
        }



        if(null != getContainerAccessor()) {
            getContainerAccessor().initializeAttributes(this.referenceClass);
        }

    }

    protected void initializeMapContainerPolicy(AbstractSession session, MapContainerPolicy cp){
         cp.setElementClass(this.referenceClass);
    }

    protected void initializeReferenceDescriptorAndField(AbstractSession session){
         if (this.referenceClass != null) {
             super.initialize(session);
         } else {
              //below should be the same as AbstractCompositeCollectionMapping.initialize
             if (this.field == null) {
                 throw DescriptorException.fieldNameNotSetInMapping(this);
             }
             setField(getDescriptor().buildField(this.field));
             setFields(collectFields());
             if (hasConverter()) {
                 getConverter().initialize(this, session);
             }
         }
    }

    /**
     * Get the XPath String
     * @return String the XPath String associated with this Mapping     *
     */
    public String getXPath() {
        return getField().getName();
    }

    /**
     * Set the Mapping field name attribute to the given XPath String
     *
     * @param xpathString String
     *
     */
    @Override
    public void setXPath(String xpathString) {
        this.setField(new XMLField(xpathString));
    }

    @Override
    protected Object buildCompositeObject(ClassDescriptor descriptor, AbstractRecord nestedRow, ObjectBuildingQuery query, CacheKey parentCacheKey, JoinedAttributeManager joinManger, AbstractSession targetSession) {
        return descriptor.getObjectBuilder().buildObject(query, nestedRow, joinManger);
    }

    @Override
    protected AbstractRecord buildCompositeRow(Object attributeValue, AbstractSession session, AbstractRecord parentRow, WriteType writeType) {
        ClassDescriptor classDesc = null;
        try{
            classDesc = getReferenceDescriptor(attributeValue, session);
        }catch(Exception e){
            //do nothing
        }
        XMLField xmlFld = (XMLField) getField();
        if (xmlFld.hasLastXPathFragment() && xmlFld.getLastXPathFragment().hasLeafElementType()) {
            XMLRecord xmlRec = (XMLRecord) parentRow;
            xmlRec.setLeafElementType(xmlFld.getLastXPathFragment().getLeafElementType());
        }
        XMLRecord parent = (XMLRecord) parentRow;

        if (classDesc != null) {
            return buildCompositeRowForDescriptor(classDesc, attributeValue, session, parent, writeType);
        } else {
            if (attributeValue instanceof Element && getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) {
                return new DOMRecord((Element) attributeValue);
            }else{
                Node newNode = XPathEngine.getInstance().create((XMLField)getField(), parent.getDOM(), attributeValue, session);
                DOMRecord newRow = new DOMRecord(newNode);
                return newRow;
            }
        }
    }


       protected AbstractRecord buildCompositeRowForDescriptor(ClassDescriptor classDesc, Object attributeValue, AbstractSession session, XMLRecord parentRow, WriteType writeType) {
        XMLObjectBuilder objectBuilder = (XMLObjectBuilder) classDesc.getObjectBuilder();


        XMLRecord child = (XMLRecord) objectBuilder.createRecordFor(attributeValue, (XMLField) getField(), parentRow, this);
        child.setNamespaceResolver(parentRow.getNamespaceResolver());
        child.setSession(session);
        objectBuilder.buildIntoNestedRow(child, attributeValue, session, (XMLDescriptor)getReferenceDescriptor(), (XMLField) getField());
        return child;
    }

    /**
     * INTERNAL:
     */
    @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) {
            row.put(this.getField(), null);
            return;
        }

        ContainerPolicy cp = this.getContainerPolicy();

        Vector nestedRows = new Vector(cp.sizeFor(attributeValue));
        Object iter = cp.iteratorFor(attributeValue);
        if(null != iter) {
            while(cp.hasNext(iter)) {
                Object element = cp.next(iter, session);
                // convert the value - if necessary
                element = convertObjectValueToDataValue(element, session, ((XMLRecord) row).getMarshaller());
                if(element == null) {
                    XMLNullRepresentationType nullRepresentation = getNullPolicy().getMarshalNullRepresentation();
                    if(nullRepresentation == XMLNullRepresentationType.XSI_NIL) {
                        nestedRows.add(XMLRecord.NIL);
                    } else if(nullRepresentation == XMLNullRepresentationType.EMPTY_NODE) {
                        Node emptyNode = XPathEngine.getInstance().createUnownedElement(((XMLRecord)row).getDOM(), (XMLField)field);
                        DOMRecord nestedRow = new DOMRecord(emptyNode);
                        nestedRows.add(nestedRow);
                    }
                } else {
                    nestedRows.addElement(buildCompositeRow(element, session, row, writeType));
                }
            }
        }

        Object fieldValue = null;
        if (!nestedRows.isEmpty()) {
            fieldValue = this.getDescriptor().buildFieldValueFromNestedRows(nestedRows, getStructureName(), session);
        }
        row.put(this.getField(), fieldValue);
    }

    @Override
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey cacheKey, AbstractSession executionSession, boolean isTargetProtected, Boolean[] wasCacheUsed) throws DatabaseException {
        ContainerPolicy cp = this.getContainerPolicy();

        Object fieldValue = row.getValues(this.getField());

        // BUG#2667762 there could be whitespace in the row instead of null
        if ((fieldValue == null) || (fieldValue instanceof String)) {
            if (reuseContainer) {
                Object currentObject = ((XMLRecord) row).getCurrentObject();
                Object container = getAttributeAccessor().getAttributeValueFromObject(currentObject);
                return container != null ? container : cp.containerInstance();
            } else {
                return cp.containerInstance();
            }
        }

        Vector nestedRows = this.getDescriptor().buildNestedRowsFromFieldValue(fieldValue, executionSession);
        if (nestedRows == null) {
            if (reuseContainer) {
                Object currentObject = ((XMLRecord) row).getCurrentObject();
                Object container = getAttributeAccessor().getAttributeValueFromObject(currentObject);
                return container != null ? container : cp.containerInstance();
            } else {
                return cp.containerInstance();
            }
        }

        Object result = null;
        if (reuseContainer) {
            Object currentObject = ((XMLRecord) row).getCurrentObject();
            Object container = getAttributeAccessor().getAttributeValueFromObject(currentObject);
            result = container != null ? container : cp.containerInstance();
        } else {
            result = cp.containerInstance(nestedRows.size());
        }

        for (Enumeration stream = nestedRows.elements(); stream.hasMoreElements();) {
            XMLRecord nestedRow = (XMLRecord) stream.nextElement();
            Object objectToAdd;
            if (getNullPolicy().valueIsNull((Element) nestedRow.getDOM())) {
                objectToAdd = null;
            } else {
                objectToAdd = buildObjectFromNestedRow(nestedRow, joinManager, sourceQuery, executionSession, isTargetProtected);
            }
            cp.addInto(objectToAdd, result, sourceQuery.getSession());
            if(null != getContainerAccessor()) {
                Object currentObject = ((XMLRecord)row).getCurrentObject();
                if(this.inverseReferenceMapping.getContainerPolicy() == null) {
                    getContainerAccessor().setAttributeValueInObject(objectToAdd, currentObject);
                } else {
                    Object backpointerContainer = getContainerAccessor().getAttributeValueFromObject(objectToAdd);
                    if(backpointerContainer == null) {
                        backpointerContainer = this.inverseReferenceMapping.getContainerPolicy().containerInstance();
                        getContainerAccessor().setAttributeValueInObject(objectToAdd, backpointerContainer);
                    }
                    this.inverseReferenceMapping.getContainerPolicy().addInto(currentObject, backpointerContainer, executionSession);
                }
            }
        }
        return result;
    }

    public Object buildObjectFromNestedRow(AbstractRecord nestedRow, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, AbstractSession executionSession, boolean isTargetProtected) {
        Object objectToAdd = null;
        ClassDescriptor aDescriptor = getReferenceDescriptor((DOMRecord) nestedRow);

        if(aDescriptor == null){
            if ((getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) || (getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT)) {
                XMLPlatformFactory.getInstance().getXMLPlatform().namespaceQualifyFragment((Element) ((DOMRecord)nestedRow).getDOM());
                objectToAdd = ((DOMRecord)nestedRow).getDOM();
                convertDataValueToObjectValue(objectToAdd, executionSession, ((XMLRecord) nestedRow).getUnmarshaller());
                //simple case
                objectToAdd = convertToSimpleTypeIfPresent(objectToAdd, nestedRow,executionSession);
            } else {
                NodeList children = ((DOMRecord)nestedRow).getDOM().getChildNodes();
                for(int i=0; i< children.getLength(); i++){
                    Node nextNode = children.item(i);
                    if(nextNode.getNodeType() == Node.ELEMENT_NODE){
                        //complex child
                        String type = ((Element) ((DOMRecord)nestedRow).getDOM()).getAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);
                        if(type != null && type.length() > 0) {
                            throw XMLMarshalException.unknownXsiTypeValue(type, (Mapping) this);
                        } else {
                            throw XMLMarshalException.noDescriptorFound((Mapping) this);
                        }
                    }
                }
                 //simple case
                 objectToAdd = convertToSimpleTypeIfPresent(objectToAdd, nestedRow,executionSession);
            }
        }
        else{
            if (aDescriptor.hasInheritance()) {
                Class newElementClass = aDescriptor.getInheritancePolicy().classFromRow(nestedRow, executionSession);
                if (newElementClass == null) {
                    // no xsi:type attribute - look for type indicator on the field
                    QName leafElementType = ((XMLField) getField()).getLeafElementType();
                    if (leafElementType != null) {
                        XPathQName leafElementXPathQName = new XPathQName(leafElementType, ((XMLRecord) nestedRow).isNamespaceAware());
                        Object indicator = aDescriptor.getInheritancePolicy().getClassIndicatorMapping().get(leafElementXPathQName);
                        if(indicator != null) {
                            newElementClass = (Class) indicator;
                        }
                    }
                }
                if (newElementClass != null) {
                    aDescriptor = this.getReferenceDescriptor(newElementClass, executionSession);
                } else {
                    // since there is no xsi:type attribute or leaf element type set,
                    // use the reference descriptor -  make sure it is non-abstract
                    if (Modifier.isAbstract(aDescriptor.getJavaClass().getModifiers())) {
                        // throw an exception
                        throw DescriptorException.missingClassIndicatorField(nestedRow, aDescriptor.getInheritancePolicy().getDescriptor());
                    }
                }
            }

            //Object element
            objectToAdd = buildCompositeObject(aDescriptor, nestedRow, sourceQuery, null, joinManager, executionSession);
            objectToAdd = convertDataValueToObjectValue(objectToAdd, executionSession, ((XMLRecord) nestedRow).getUnmarshaller());
        }
        return objectToAdd;
    }
    private Object convertToSimpleTypeIfPresent(Object objectToAdd, AbstractRecord nestedRow, AbstractSession executionSession){
        String stringValue = null;

        Element theElement = ((Element) ((DOMRecord)nestedRow).getDOM());
        Node textchild = theElement.getFirstChild();

        if ((textchild != null) && (textchild.getNodeType() == Node.TEXT_NODE)) {
            stringValue = textchild.getNodeValue();
            if(stringValue != null && getKeepAsElementPolicy() != UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT && getKeepAsElementPolicy()!=UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT){
                objectToAdd = stringValue;
            }
        }
        if ((stringValue == null) || stringValue.length() == 0 ) {
            return objectToAdd;
        }

        String type = theElement.getAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);
        if ((null != type) && type.length() > 0) {
            XPathFragment typeFragment = new XPathFragment(type);
            String namespaceURI = ((DOMRecord)nestedRow).resolveNamespacePrefix(typeFragment.getPrefix());
            typeFragment.setNamespaceURI(namespaceURI);
            QName schemaTypeQName = new QName(namespaceURI, typeFragment.getLocalName());
            ConversionManager conversionManager = (ConversionManager) executionSession.getDatasourcePlatform().getConversionManager();
            Class theClass = conversionManager.javaType(schemaTypeQName);
            if (theClass != null) {
                objectToAdd = conversionManager.convertObject(stringValue, theClass, schemaTypeQName);
            }
        }
        return objectToAdd;
    }

    public ClassDescriptor getReferenceDescriptor(DOMRecord xmlRecord) {
        ClassDescriptor returnDescriptor = referenceDescriptor;

        if (returnDescriptor == null) {
            // Try to find a descriptor based on the schema type
            String type = ((Element) xmlRecord.getDOM()).getAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);

            if ((null != type) && type.length() >0 ) {
                XPathFragment typeFragment = new XPathFragment(type);
                String namespaceURI = xmlRecord.resolveNamespacePrefix(typeFragment.getPrefix());
                typeFragment.setNamespaceURI(namespaceURI);

                returnDescriptor = xmlRecord.getUnmarshaller().getXMLContext().getDescriptorByGlobalType(typeFragment);

            } else {
                //try leaf element type
                QName leafType = ((XMLField) getField()).getLastXPathFragment().getLeafElementType();
                if (leafType != null) {
                    XPathFragment frag = new XPathFragment();
                    String xpath = leafType.getLocalPart();
                    String uri = leafType.getNamespaceURI();
                    if ((uri != null) && uri.length() > 0) {
                        frag.setNamespaceURI(uri);
                        String prefix = ((XMLDescriptor) getDescriptor()).getNonNullNamespaceResolver().resolveNamespaceURI(uri);
                        if ((prefix != null) && prefix.length() > 0) {
                            xpath = prefix + XMLConstants.COLON + xpath;
                        }
                    }
                    frag.setXPath(xpath);

                    returnDescriptor = xmlRecord.getUnmarshaller().getXMLContext().getDescriptorByGlobalType(frag);
                }
            }
        }

        return returnDescriptor;

    }

    @Override
    protected ClassDescriptor getReferenceDescriptor(Class theClass, AbstractSession session) {
        if ((getReferenceDescriptor() != null) && getReferenceDescriptor().getJavaClass().equals(theClass)) {
            return getReferenceDescriptor();
        }

        ClassDescriptor subDescriptor = session.getDescriptor(theClass);
        if (subDescriptor == null && getKeepAsElementPolicy() != UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) {
            throw DescriptorException.noSubClassMatch(theClass, this);
        } else {
            return subDescriptor;
        }
    }

    @Override
    public void writeSingleValue(Object value, Object parent, XMLRecord record, AbstractSession session) {
        Object element = convertObjectValueToDataValue(value, session, record.getMarshaller());
        XMLRecord nestedRow = (XMLRecord) buildCompositeRow(element, session, record, WriteType.UNDEFINED);
        record.add(getField(), nestedRow);
    }

    /**
     * Set the AbstractNullPolicy on the mapping<br>
     * The default policy is NullPolicy.<br>
     *
     */
    @Override
    public void setNullPolicy(AbstractNullPolicy aNullPolicy) {
        nullPolicy = aNullPolicy;
    }

    /**
     * INTERNAL:
     * Get the AbstractNullPolicy from the Mapping.<br>
     * The default policy is NullPolicy.<br>
     */
    @Override
    public AbstractNullPolicy getNullPolicy() {
        return nullPolicy;
    }

    @Override
    public UnmarshalKeepAsElementPolicy getKeepAsElementPolicy() {
        return keepAsElementPolicy;
    }

    @Override
    public void setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy keepAsElementPolicy) {
        this.keepAsElementPolicy = keepAsElementPolicy;
    }

    protected XMLDescriptor getDescriptor(XMLRecord xmlRecord, AbstractSession session, QName rootQName) throws XMLMarshalException {
        if (rootQName == null) {
            rootQName = new QName(xmlRecord.getNamespaceURI(), xmlRecord.getLocalName());
        }
        XMLContext xmlContext = xmlRecord.getUnmarshaller().getXMLContext();
        XMLDescriptor xmlDescriptor = xmlContext.getDescriptor(rootQName);
        if (null == xmlDescriptor) {
            if (!((getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) || (getKeepAsElementPolicy() == UnmarshalKeepAsElementPolicy.KEEP_ALL_AS_ELEMENT))) {
                throw XMLMarshalException.noDescriptorWithMatchingRootElement(xmlRecord.getLocalName());
            }
        }
        return xmlDescriptor;
    }

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

    @Override
    public void setIsWriteOnly(boolean b) {
        this.isWriteOnly = b;
    }

    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        getAttributeAccessor().setIsWriteOnly(this.isWriteOnly());
        getAttributeAccessor().setIsReadOnly(this.isReadOnly());
        super.preInitialize(session);
    }

    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        if(isWriteOnly()) {
            return;
        }
        super.setAttributeValueInObject(object, value);
    }

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

    @Override
    public XMLInverseReferenceMapping getInverseReferenceMapping() {
        return inverseReferenceMapping;
    }

    void setInverseReferenceMapping(XMLInverseReferenceMapping inverseReferenceMapping) {
        this.inverseReferenceMapping = inverseReferenceMapping;
    }

    /**
     * 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 (hasConverter()) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertObjectValueToDataValue(value, session, marshaller);
            } else {
                return converter.convertObjectValueToDataValue(value, session);
            }
        }
        return value;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertDataValueToObjectValue(Object value, Session session, XMLUnmarshaller unmarshaller) {
        if (hasConverter()) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertDataValueToObjectValue(value, session, unmarshaller);
            } else {
                return converter.convertDataValueToObjectValue(value, session);
            }
        }
        return value;
    }

}
