/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper;

import commonj.sdo.ChangeSummary;
import commonj.sdo.DataObject;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.eclipse.persistence.sdo.SDOChangeSummary;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOSetting;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshalListener;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * <p><b>Purpose</b>: Implementation of XMLMarshalListener used when marshalling DataObjects to XML
 * <p><b>Responsibilities</b>:<ul>
 * <li> Need to do extra work to marshal org.eclipse.persistence.sdo.SDOChangeSummary objects
 * </ul>
 */
public class SDOMarshalListener implements XMLMarshalListener {
    // marshalledObject may or may not be the root object
    private Object marshalledObject;
    private QName marshalledObjectRootQName;
    private MarshalRecord rootMarshalRecord;
    private SDOTypeHelper typeHelper;

    /** maintain narrowed context from the larger HelperContext (inside the xmlMarshaller)<br>
     * Visibility reduced from [public] in 2.1.0. May 15 2007 */
    private XMLMarshaller xmlMarshaller;

    public SDOMarshalListener(XMLMarshaller aMarshaller, SDOTypeHelper aTypeHelper) {
        xmlMarshaller = aMarshaller;
        typeHelper = aTypeHelper;
    }

    @Override
    public void afterMarshal(Object obj) {
    }

    @Override
    public void beforeMarshal(Object obj) {
        if (obj instanceof SDOChangeSummary) {
            SDOChangeSummary changeSummary = ((SDOChangeSummary)obj);

            //CREATED - build a list of xpaths to write to the created attribute
            //this must be done dynamically because the xpath is relative to the marshalledObject
            //so it can't be calculated until we know what object is being marshalled
            List createdSet = changeSummary.getCreated();
            List xpaths = new ArrayList(createdSet.size());

            String rootElementName = this.marshalledObjectRootQName.getLocalPart();
            String rootNamespaceUri = this.marshalledObjectRootQName.getNamespaceURI();
            if(rootNamespaceUri != null && !rootNamespaceUri.equals(XMLConstants.EMPTY_STRING)) {
                org.eclipse.persistence.internal.oxm.NamespaceResolver resolver = getRootMarshalRecord().getNamespaceResolver();
                if(resolver != null) {
                    String prefix = resolver.resolveNamespaceURI(this.marshalledObjectRootQName.getNamespaceURI());
                    if(prefix != null) {
                        rootElementName = prefix + XMLConstants.COLON + rootElementName;
                    }
                }
            }
            if ((createdSet != null) && (createdSet.size() > 0)) {
                Iterator anIterator = createdSet.iterator();
                SDODataObject nextCreatedDO = null;
                while (anIterator.hasNext()) {
                    // get path to the changeSummaryRoot (may not be the root marshalled object - may be internal)
                    nextCreatedDO = ((SDODataObject)anIterator.next());
                    String nextPath = getPathFromAncestor(nextCreatedDO, (SDODataObject)marshalledObject, changeSummary);
                    //Add sdoRef attribute...all modified objects written should have this
                    if(nextPath == SDOConstants.EMPTY_STRING) {
                        //if this is the root, just put the root element
                        xpaths.add(SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX +
                                SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT +//
                                rootElementName);

                    } else {
                        xpaths.add(SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX +
                                SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT +//
                                rootElementName + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + nextPath);
                    }
                }
            }
            changeSummary.setCreatedXPaths(xpaths);

            //Build xpathToCS
            String xpathMarshalledObjToCS = getPathFromAncestor(changeSummary.getRootObject(), (SDODataObject)marshalledObject, changeSummary);
            String xpathChangeSumProp = getXPathForProperty(changeSummary.getRootObject().getType().getChangeSummaryProperty());

            String xpathToCS = SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + rootElementName;

            // check if the CS is at the local-cs-root or is in a child property
            if ((xpathMarshalledObjToCS != null) && !xpathMarshalledObjToCS.equals(SDOConstants.EMPTY_STRING)) {//SDO_XPATH_TO_ROOT)) {
                // CS is not on the root
                xpathToCS = xpathToCS + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + xpathMarshalledObjToCS;
            }
            xpathToCS = xpathToCS + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT//
                         +xpathChangeSumProp + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT;

            //MODIFIED && DELETED
            List deletedXPaths = new ArrayList();
            Document document = XMLPlatformFactory.getInstance().getXMLPlatform().createDocument();
            Element csNode = null;
            List modifiedItems = changeSummary.getModified();
            int modifiedSize = modifiedItems.size();
            List newNodes = new ArrayList(modifiedSize);
            SDODataObject nextModifiedDO = null;

            //Iterate through CS modified items
            for (int i = 0; i < modifiedSize; i++) {
                nextModifiedDO = (SDODataObject)modifiedItems.get(i);
                String sdoPrefix = typeHelper.getPrefix(SDOConstants.SDO_URL);

                //List unsetPropNames = new ArrayList();
                String uri = getURI(nextModifiedDO);
                String qualifiedName = getQualifiedName(nextModifiedDO);
                String sdoRefPrefix = SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT;

                if (uri == null) {
                    csNode = document.createElement(qualifiedName);
                } else {
                    csNode = document.createElementNS(uri, qualifiedName);
                }

                String nextPath = getPathFromAncestor(nextModifiedDO, (SDODataObject)marshalledObject, changeSummary);
                //Add sdoRef attribute...all modified objects written should have this
                if(nextPath == SDOConstants.EMPTY_STRING) {
                    //if this is the root, just put the root element
                    csNode.setAttributeNS(SDOConstants.SDO_URL, sdoPrefix +//
                            SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT +//
                            SDOConstants.CHANGESUMMARY_REF,//
                            sdoRefPrefix + rootElementName);

                } else {
                    csNode.setAttributeNS(SDOConstants.SDO_URL, sdoPrefix +//
                                      SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT +//
                                      SDOConstants.CHANGESUMMARY_REF,//
                                      sdoRefPrefix + rootElementName + "/" + nextPath);
                }

                //Bug6346754 Add all namespaces if they are not yet declared above.
                Vector namespaces = nextModifiedDO.getType().getXmlDescriptor().getNonNullNamespaceResolver().getNamespaces();
                for (int j = 0; j < namespaces.size(); j++) {
                    Namespace next = (Namespace)namespaces.get(j);
                    if (declareNamespace(next.getNamespaceURI(), next.getPrefix(), changeSummary.getRootObject())) {
                        csNode.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + XMLConstants.COLON + next.getPrefix(), next.getNamespaceURI());
                    }
                }

                List nextDOSettings = changeSummary.getOldValues(nextModifiedDO);
                DOMRecord row = new DOMRecord(csNode);

                Session session = ((SDOXMLHelper)typeHelper.getHelperContext().getXMLHelper()).getXmlContext().getSession();
                row.setSession((AbstractSession) session);

                //Iterate through SDOSettings for the current modified Object
                SDOSetting nextSetting = null;
                for (int j = 0; j < nextDOSettings.size(); j++) {
                    nextSetting = (SDOSetting)nextDOSettings.get(j);
                    if (nextSetting.isSet()) {
                        if (!nextSetting.getProperty().getType().isDataType()) {
                            if (nextSetting.getProperty().isMany()) {
                                List values = (List)nextSetting.getValue();
                                for (int k = 0; k < values.size(); k++) {
                                    doMarshal(nextSetting.getProperty(), (DataObject)values.get(k),//
                                              changeSummary, csNode, nextModifiedDO, deletedXPaths, xpathToCS, sdoPrefix, rootElementName);
                                }
                            } else {
                                doMarshal(nextSetting.getProperty(), (DataObject)nextSetting.getValue(),//
                                          changeSummary, csNode, nextModifiedDO, deletedXPaths, xpathToCS, sdoPrefix, rootElementName);
                            }
                        } else {
                            //This writes out simple values
                            Object value = nextSetting.getValue();

                            if (value == null) {
                                //Marshal out xsi:nil=true
                                marshalNilAttribute(nextSetting.getProperty(), row);
                            } else {
                                String xPath = getXPathForProperty(nextSetting.getProperty());
                                XMLField field = new XMLField(xPath);
                                field.setNamespaceResolver(typeHelper.getNamespaceResolver());
                                row.put(field, value);
                            }
                        }
                    }
                }

                List unsetPropNames = changeSummary.getUnsetProps(nextModifiedDO);
                if (!unsetPropNames.isEmpty()) {
                    XMLConversionManager xmlConversionManager = ((SDOXMLHelper)typeHelper.getHelperContext().getXMLHelper()).getXmlConversionManager();
                    String unsetPropsString = xmlConversionManager.convertObject(unsetPropNames, String.class);
                    csNode.setAttributeNS(SDOConstants.SDO_URL, sdoPrefix +//
                                          SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT +//
                                          SDOConstants.CHANGESUMMARY_UNSET, unsetPropsString);
                }
                newNodes.add(csNode);
            }

            changeSummary.setDeletedXPaths(deletedXPaths);
            changeSummary.setModifiedDoms(newNodes);
        }
    }

    private void doMarshal(SDOProperty prop, DataObject value, SDOChangeSummary cs,//
                           Element csNode, SDODataObject modifiedObject, List deletedXPaths, String xpathToCS, String sdoPrefix, String rootElementName) {
        if (value == null) {
            //Marshal out xsi:nil=true
            DOMRecord row = new DOMRecord(csNode);
            Session session = ((SDOXMLHelper)typeHelper.getHelperContext().getXMLHelper()).getXmlContext().getSession();
            row.setSession((AbstractSession) session);
            marshalNilAttribute(prop, row);
            return;
        }

        boolean isDeleted = false;

        //Do we need a second map or can we just check the values of the deleted map
        Object original = cs.getReverseDeletedMap().get(value);

        if ((original != null) && cs.isDeleted((DataObject)original)) {
            isDeleted = true;
        }

        String qualifiedName = getXPathForProperty(prop);
        String uri = null;
        if (prop.isOpenContent()) {
            uri = prop.getUri();
        } else {
            uri = ((XMLField)prop.getXmlMapping().getField()).getXPathFragment().getNamespaceURI();
        }

        if (isDeleted) {
            String pathToNode = getPathFromAncestor(((SDODataObject)original), modifiedObject, cs);
            String containerPath = null;
            containerPath = getQualifiedName(modifiedObject);
            deletedXPaths.add(xpathToCS + containerPath + SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + pathToNode);

            XMLRoot xmlroot = new XMLRoot();
            xmlroot.setObject(value);//set the object to the deep copy
            xmlroot.setNamespaceURI(uri);
            xmlroot.setLocalName(qualifiedName);
            xmlMarshaller.marshal(xmlroot, csNode);
        } else {
            //need sdoref
            Element modifiedElement = null;
            if (uri == null) {
                modifiedElement = csNode.getOwnerDocument().createElement(qualifiedName);
            } else {
                modifiedElement = csNode.getOwnerDocument().createElementNS(uri, qualifiedName);
            }
            csNode.appendChild(modifiedElement);
            String nextPath = getPathFromAncestor((SDODataObject)original, (SDODataObject)marshalledObject, cs);
            //Add sdoRef attribute...all modified objects written should have this
            if(nextPath == SDOConstants.EMPTY_STRING) {
                //if this is the root, just put the root element
                modifiedElement.setAttributeNS(SDOConstants.SDO_URL, sdoPrefix +//
                        SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT +//
                        SDOConstants.CHANGESUMMARY_REF,//
                        SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX +
                        SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT +//
                        rootElementName);

            } else {
                modifiedElement.setAttributeNS(SDOConstants.SDO_URL, sdoPrefix +//
                                  SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT +//
                                  SDOConstants.CHANGESUMMARY_REF,//
                                  SDOConstants.SDO_CHANGESUMMARY_REF_PATH_PREFIX +
                                  SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT +//
                                  rootElementName + "/" + nextPath);
            }

            //Added for bug 6346754
            if ((((SDODataObject)original).getContainmentProperty() != null) && ((SDODataObject)original).getContainmentProperty().getType().isDataObjectType()) {
                //may also need xsi:type
                String schemaContext = ((SDOType)value.getType()).getXmlDescriptor().getSchemaReference().getSchemaContext();
                QName schemaContextQName = ((SDOType)value.getType()).getXmlDescriptor().getSchemaReference().getSchemaContextAsQName(((SDOType)value.getType()).getXmlDescriptor().getNonNullNamespaceResolver());

                if (schemaContext != null) {
                    String typeValue = schemaContext.substring(1, schemaContext.length());
                    String schemaInstancePrefix = ((SDOType)value.getType()).getXmlDescriptor().getNonNullNamespaceResolver().resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);

                    //may or may not need the xmlns declaration added.
                    String schemaContextUri = schemaContextQName.getNamespaceURI();
                    String schemaContextPrefix = ((SDOType)value.getType()).getXmlDescriptor().getNonNullNamespaceResolver().resolveNamespaceURI(schemaContextUri);
                    if (schemaContextPrefix != null) {
                        modifiedElement.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + XMLConstants.COLON + schemaContextPrefix, schemaContextQName.getNamespaceURI());
                    }
                    modifiedElement.setAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, schemaInstancePrefix + XMLConstants.COLON + XMLConstants.SCHEMA_TYPE_ATTRIBUTE, typeValue);
                }
            }
        }
    }
    private String getURI(SDODataObject currentObject) {
        String uri = null;

        // check if we are at the root - no containmentProperty
        if (currentObject.getContainmentProperty() == null) {
            // get ns from type/schemaReference/schemaContext = "/ns0:PurchaseOrderType"
            // get ns:name from the ns=nsr(value==uri) name=, or 2nd entry in xmlDescriptor->table[]
            //containerPath = ((SDOType)modifiedObject.getType()).getXmlDescriptor().getNamespaceResolver().resolveNamespaceURI(uri);
            // get uri from the type of the root object
            uri = currentObject.getType().getURI();
        } else {
            uri = getUriForProperty(currentObject);
        }
        return uri;
    }

    private String getQualifiedName(SDODataObject currentObject) {
        String qualifiedName = null;

        // check if we are at the root - no containmentProperty
        if (currentObject.getContainmentProperty() == null) {
            // get ns (without name) from type/schemaReference/schemaContext = "/ns0:PurchaseOrderType"
            //qualifiedName = ((SDOType)currentObject.getType()).getXmlDescriptor().getNamespaceResolver().resolveNamespaceURI(uri);
            // property id's do not match - don't use
            //qualifiedName += ((SDOXSDHelper)currentObject.getHelperContext().getXSDHelper()).getGlobalProperty(uri, currentObject.getType().getName() , true);
            // hack: get 2nd table name
            // get ns:name from the ns=nsr(value==uri) name=, or 2nd entry in xmlDescriptor->table[]
            qualifiedName = currentObject.getType().getXmlDescriptor().getDefaultRootElement();
        } else {
            qualifiedName = getXPathForProperty(currentObject.getContainmentProperty());
        }
        return qualifiedName;
    }

    public void setMarshalledObject(Object marshalledObject) {
        this.marshalledObject = marshalledObject;
    }

    public Object getMarshalledObject() {
        return marshalledObject;
    }

    public void setMarshalledObjectRootQName(QName rootQName) {
        this.marshalledObjectRootQName = rootQName;
    }

    public QName getMarshalledObjectRootQName() {
        return this.marshalledObjectRootQName;
    }

    public void setRootMarshalRecord(MarshalRecord rootRecord) {
        this.rootMarshalRecord = rootRecord;
    }

    public MarshalRecord getRootMarshalRecord() {
        return this.rootMarshalRecord;
    }

    private boolean declareNamespace(String uri, String prefix, DataObject theDataObject) {
        while (theDataObject != null) {
            NamespaceResolver nr = ((SDOType)theDataObject.getType()).getXmlDescriptor().getNonNullNamespaceResolver();
            String resolvedPrefix = nr.resolveNamespaceURI(uri);
            if ((resolvedPrefix != null) && !resolvedPrefix.equals("") && resolvedPrefix.equals(prefix)) {
                return false;
            }
            theDataObject = theDataObject.getContainer();
        }
        return true;
    }

    private String getUriForProperty(SDODataObject currentObject) {
        SDOProperty prop = currentObject.getContainmentProperty();
        if (prop.getXmlMapping() != null) {
            return ((XMLField)prop.getXmlMapping().getField()).getXPathFragment().getNamespaceURI();
        } else {
            return prop.getUri();
        }
    }

    private String getXPathForProperty(SDOProperty prop) {
        return getXPathForProperty(prop, false, typeHelper.getNamespaceResolver());
    }

    private String getXPathForProperty(SDOProperty prop, boolean removeText, NamespaceResolver namespaceResolver) {
        if ((prop).getXmlMapping() != null) {
            String xpath = prop.getXmlMapping().getField().getName();
            if (removeText && xpath.endsWith("/text()")) {
                xpath = xpath.substring(0, xpath.length() - 7);
            }
            return xpath;
        } else {
            String name = prop.getName();
            if (prop.isOpenContent()) {
                String uri = prop.getUri();
                if (uri != null) {
                    String prefix = namespaceResolver.resolveNamespaceURI(uri);

                    if ((prefix != null) && !prefix.equals(SDOConstants.EMPTY_STRING)) {
                        return prefix + XMLConstants.COLON + name;
                    }
                }
            }
            return name;
        }
    }

    /**
    * INTERNAL:
    * Return the XPath or SDO path from the anObject to the current internal node
    *
    * Prereq: We know that the targetObject will always have a parent as called
    * from getPath()
    *   We require a ChangeSummary object for when there are deleted
    *   objects in the path
    *
    * Matching conditions:
    *   Iterate up the tree
    *   return a non-null string for the XPath when we reach the target node
    *
    * Function is partially based on SDOCopyHelper.copy(DataObject dataObject)
    * Performance: This function is O(log n) where n=# of children in the tree
    *
    * @param currentPath
    * @param targetDO
    * @param currentObject
    * @param aSeparator (XPath separator is written only between elements - not for the first call)
    * @return String (representing the XPath)
    */
    private String getPathFromAncestorPrivate(SDOChangeSummary aChangeSummary,//
                                              String currentPath,//
                                              SDODataObject targetDO,//
                                              SDODataObject currentObject,//
                                              String aSeparator) {
        if ((currentObject == null) || (targetDO == null) || (aChangeSummary == null)) {
            return currentPath;
        }

        // Base Case: check we are at the target object first
        if (currentObject == targetDO) {
            // check for indexed property if root is a ListWrapper
            return currentPath;
        }

        // Recursive Case: O(log(n)) recursive calls, 1 for each tree level
        // get parent property based on parent property name in target, property will always be set
        // check containment for cases where we are searching for a sibling
        SDOProperty parentContainmentProperty;
        Object parent = null;

        // for already deleted dataobjects  - isDeleted=false, changeSummary= null - use oldContainer
        if (null == currentObject.getContainer()) {
            parent = aChangeSummary.getOldContainer(currentObject);
            parentContainmentProperty = aChangeSummary.getOldContainmentProperty(currentObject);
            // handle (at root) case for non-deleted objects for the cases
            // case: ancestor not found
            // case: ancestor is actually sibling
            if ((null == parent) || (null == parentContainmentProperty)) {
                return SDOConstants.SDO_XPATH_INVALID_PATH;
            }
        } else {
            // normal non-deleted non-changeSummary case
            parent = currentObject.getContainer();
            parentContainmentProperty = currentObject.getContainmentProperty();
        }

        // get XPath using SDO path - block
        String parentContainmentPropertyXPath = getXPathForProperty(parentContainmentProperty);

        // Handle ListWrapper contained DataObjects
        if (parentContainmentProperty.isMany()) {
            int index = (((SDODataObject)parent).getList(parentContainmentProperty)).indexOf(currentObject);

            if (index < 0) {

                /*
                * The current object has been deleted and was part of a ListWrapper (isMany=true)
                * Get the parent of this indexed list item and check the oldSetting (List) for the
                * original position of the indexed (Deleted) object
                */

                // get the list containing the old value of the item
                ChangeSummary.Setting anOldSetting = aChangeSummary.getOldValue((DataObject)parent, parentContainmentProperty);
                if (anOldSetting != null) {
                    // get index directly from oldSettings based on current object - where parent was not deleted
                    List aDeletedParent = (List)anOldSetting.getValue();

                    // bug# 5587042: we will assume that index is never < 0 and remove handling code for this case where we lookup anOldSetting directly instead of via the deepCopies map
                    index = aDeletedParent.indexOf(aChangeSummary.getDeepCopies().get(currentObject));
                } else {
                    // bug# 5587042: we will assume that oldSetting is never null and remove handling code for this case where we would hardcode to list.size()
                }

                // see: testGetXPathFromAncestorDeletedFromChildToAncestorInsideListWrapperLoggingOn
            }
            currentPath = parentContainmentPropertyXPath +//
                          SDOConstants.SDO_XPATH_LIST_INDEX_OPEN_BRACKET +//
                          (1 + index) +// [indexes] start at 1
                          SDOConstants.SDO_XPATH_LIST_INDEX_CLOSE_BRACKET +//
                          aSeparator +//
                          currentPath;
        } else {
            currentPath = parentContainmentPropertyXPath +//
                          aSeparator +//
                          currentPath;
        }

        // recursive call
        return getPathFromAncestorPrivate(aChangeSummary,//
                                          currentPath,//
                                          targetDO,//
                                          (SDODataObject)parent,//
                                          SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT);// we pass an empty separator so we have \a\b and not a\b\
    }

    /**
     * INTERNAL:
     * Get path for non-deleted DataObjects<br>
     * ChangeSummary is not required and is set to null.<br>
     * Assumptions:<br>
     *     target node is an ancestor of the source (this)
     * @param sourceDO
     * @param targetDO
     * @return String xpath
     */
    public String getPathFromAncestor(SDODataObject sourceDO, SDODataObject targetDO, SDOChangeSummary cs) {
        // Implementors: SDOMarshalListener
        // default to no changeSummary and xpath format

        /*
        * Algorithm:
        *   (1) Intact (non-deleted) objects:
        *     - recursively iterate up the container of each DataObject, recording property names as we go
        *   (2) Deleted objects:
        *     - use the changeSummary to get the deleted object with oldContainer state
        *     - recursively iterate up the oldContainer as in (1)
        *    Issues:
        *     - a deleted indexed object inside a ListWrapper will not retain its original index
        */

        // Base Case: The internal node is actually the root
        // Base Case: The source and target objects are equal
        // checking if this and target are equal will handle both cases above
        if (sourceDO == targetDO) {
            // return "" empty string and handle at implementor
            return SDOConstants.EMPTY_STRING;
        } else {
            // Recursive Case: call private recursive reverse O(logn) traversal
            // function on current object
            return getPathFromAncestorPrivate(cs,//
                                              SDOConstants.EMPTY_STRING,//
                                              targetDO,//
                                              sourceDO,//
                                              SDOConstants.EMPTY_STRING// we pass an empty separator so we have \a\b and not a\b\
            );
        }
    }

    private void marshalNilAttribute(SDOProperty property, DOMRecord row) {
        //Marshal out xsi:nil=true
        NamespaceResolver resolver = null;
        if(property.getContainingType() != null) {
            resolver = property.getContainingType().getXmlDescriptor().getNamespaceResolver();
        }
        if(null == resolver) {
            resolver = typeHelper.getNamespaceResolver();
        }
        String xsiPrefix = resolver.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        if ((xsiPrefix == null) || xsiPrefix.equals(SDOConstants.EMPTY_STRING)) {
            NamespaceResolver nsResolverWithXsi = new NamespaceResolver();
            copyNamespaces(resolver, nsResolverWithXsi);
            resolver = nsResolverWithXsi;
            xsiPrefix = resolver.generatePrefix(XMLConstants.SCHEMA_INSTANCE_PREFIX);
            resolver.put(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        }
        String xPath = getXPathForProperty(property, true, resolver);
        xPath = xPath + "/@" + xsiPrefix + XMLConstants.COLON + XMLConstants.SCHEMA_NIL_ATTRIBUTE;

        XMLField field = new XMLField(xPath);
        field.setNamespaceResolver(resolver);
        row.put(field, XMLConstants.BOOLEAN_STRING_TRUE);
    }

    private void copyNamespaces(NamespaceResolver source, NamespaceResolver target) {
        if (null != source && null != target) {
            if(source.hasPrefixesToNamespaces()) {
                target.getPrefixesToNamespaces().putAll(source.getPrefixesToNamespaces());
            }
            target.setDefaultNamespaceURI(source.getDefaultNamespaceURI());
        }
    }
}
