/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 *     14/05/2012-2.4 Guy Pelletier   
 *       - 376603: Provide for table per tenant support for multitenant applications
 ******************************************************************************/
package org.eclipse.persistence.oxm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.TreeObjectBuilder;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathQName;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLMapping;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.DoesExistQuery;

/**
 * Use an XML project for nontransactional, nonpersistent (in-memory) conversions between Java objects and XML documents.
 *
 * An XMLDescriptor is a set of mappings that describe how an objects's data is to be represented in an
 * XML document. XML descriptors describe Java objects that you map to simple and complex types defined
 * by an XML schema document (XSD). Using XML descriptors in an EclipseLink XML project, you can configure XML mappings.
 *
 * @see org.eclipse.persistence.oxm.mappings
 */
public class XMLDescriptor extends ClassDescriptor implements Descriptor<AttributeAccessor, DatabaseMapping, DatabaseField, InheritancePolicy, InstantiationPolicy, NamespaceResolver, ObjectBuilder, UnmarshalRecord, XMLUnmarshaller>{

    private static final Vector EMPTY_VECTOR = NonSynchronizedVector.newInstance(1);

    private NamespaceResolver namespaceResolver;
    private XMLSchemaReference schemaReference;
    private boolean shouldPreserveDocument = false;
    private XMLField defaultRootElementField;
    private boolean sequencedObject = false;
    private boolean isWrapper = false;
    private boolean resultAlwaysXMLRoot = false;
    private boolean lazilyInitialized = false;
    private AttributeAccessor locationAccessor = null;
    private boolean hasReferenceMappings = false;
    

    /**
     * PUBLIC:
     * Return a new XMLDescriptor.
     */
    public XMLDescriptor() {
        this.tables = NonSynchronizedVector.newInstance(3);
        this.mappings = NonSynchronizedVector.newInstance();
        this.primaryKeyFields = null;
        this.fields = NonSynchronizedVector.newInstance();
        this.allFields = NonSynchronizedVector.newInstance();
        this.constraintDependencies = EMPTY_VECTOR;
        this.multipleTableForeignKeys = Collections.EMPTY_MAP;
        this.queryKeys = Collections.EMPTY_MAP;
        this.initializationStage = UNINITIALIZED;
        this.interfaceInitializationStage = UNINITIALIZED;
        this.descriptorType = NORMAL;
        this.shouldOrderMappings = true;
        this.shouldBeReadOnly = false;
        this.shouldAlwaysConformResultsInUnitOfWork = false;
        this.shouldAcquireCascadedLocks = false;
        this.hasSimplePrimaryKey = false;
        this.idValidation = null;
        this.derivesIdMappings = Collections.EMPTY_MAP;
        this.additionalWritableMapKeyFields = Collections.EMPTY_LIST;

        // Policies        
        this.objectBuilder = new TreeObjectBuilder(this);

        this.shouldOrderMappings = false;
        descriptorIsAggregate();
    }

    /**
     * PUBLIC:
     * Return the default root element name for the ClassDescriptor
     * This value is stored in place of a table name
     * This value is mandatory for all root objects
     * @return the default root element specified on this ClassDescriptor
     */
    public String getDefaultRootElement() {
        if (getTables().isEmpty()) {
            return null;
        }
        return getTables().firstElement().getName();
    }
    
    /**
     * PUBLIC:
     * Return if unmapped information from the XML document should be maintained for this
     * descriptor
     * By default unmapped data is not preserved.
     * @return if this descriptor should preserve unmapped data
     */
    public boolean shouldPreserveDocument() {
        return this.shouldPreserveDocument;
    }

    /**
     * PUBLIC:
     * Specifies that object built from this descriptor should retain any unmapped
     * information from their original XML Document when being written back out.
     * By default unmapped data is not preserved.
     * @return if this descriptor should preserve unmapped data
     */
    public void setShouldPreserveDocument(boolean shouldPreserveDocument) {
        this.shouldPreserveDocument = shouldPreserveDocument;
    }

    /**
    * PUBLIC:
    * Add a root element name for the Descriptor
    * This value is stored in place of a table name
    * @param rootElementName a root element to specify on this Descriptor
    */
    public void addRootElement(String rootElementName) {
        if (rootElementName != null) {
            if (!getTableNames().contains(rootElementName)) {
                addTableName(rootElementName);
            }
        }
    }

    /**
    * PUBLIC:
    * Return the default root element name for the ClassDescriptor
    * This value is stored in place of a table name
    * This value is mandatory for all root objects
    * @param newDefaultRootElement the default root element to specify on this ClassDescriptor
    */
    public void setDefaultRootElement(String newDefaultRootElement) {
        if(setDefaultRootElementField(newDefaultRootElement)) {
            int index = getTableNames().indexOf(newDefaultRootElement);
            if (index == 0) {
                return;
            } 
            DatabaseTable databaseTable = new DatabaseTable();
            databaseTable.setUseDelimiters(false);
            databaseTable.setName(newDefaultRootElement);
            if (index >= 0) {
                getTables().remove(index);
                getTables().add(0, databaseTable);
            } else {
                getTables().add(0, databaseTable);
            }
        }
    }

    /**
    * PUBLIC:
    * Return the NamespaceResolver associated with this descriptor
    * @return the NamespaceResolver associated with this descriptor
    * @see org.eclipse.persistence.oxm.NamespaceResolver
    */
    public NamespaceResolver getNamespaceResolver() {
        return namespaceResolver;
    }

    public NamespaceResolver getNonNullNamespaceResolver() {
        if (namespaceResolver == null) {
            namespaceResolver = new NamespaceResolver();
        }
        return namespaceResolver;
    }

    /**
     * PUBLIC:
     * The inheritance policy is used to define how a descriptor takes part in inheritance.
     * All inheritance properties for both child and parent classes is configured in inheritance policy.
     * Caution must be used in using this method as it lazy initializes an inheritance policy.
     * Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.
     * @return the InheritancePolicy associated with this descriptor
     */
    public InheritancePolicy getInheritancePolicy() {
        if (inheritancePolicy == null) {
            // Lazy initialize to conserve space in non-inherited classes.
            setInheritancePolicy(new org.eclipse.persistence.internal.oxm.QNameInheritancePolicy(this));
        }
        return inheritancePolicy;
    }

    /**
    * PUBLIC:
    * Set the NamespaceResolver to associate with this descriptor
    * @param newNamespaceResolver the NamespaceResolver to associate with this descriptor
    * @see org.eclipse.persistence.oxm.NamespaceResolver
    */
    public void setNamespaceResolver(NamespaceResolver newNamespaceResolver) {
        namespaceResolver = newNamespaceResolver;
    }

    /**
    * PUBLIC:
    * Return the SchemaReference associated with this descriptor
    * @return the SchemaReference associated with this descriptor
    * @see org.eclipse.persistence.oxm.schema
    */
    public XMLSchemaReference getSchemaReference() {
        return schemaReference;
    }

    /**
     * PUBLIC:
     * Set the SchemaReference to associate with this descriptor
     * @param newSchemaReference the SchemaReference to associate with this descriptor
     * @see org.eclipse.persistence.oxm.schema
     */
    public void setSchemaReference(XMLSchemaReference newSchemaReference) {
        schemaReference = newSchemaReference;
    }

    /**
     * PUBLIC:
     * Return if the descriptor maps to XML.
     */
    @Override
    public boolean isXMLDescriptor() {
        return true;
    }
    
    /**
     * If true, the descriptor may be lazily initialized.  This is useful if the
     * descriptor may not get used.
     */
    public boolean isLazilyInitialized() {
        return lazilyInitialized;
    }

    /**
     * Specify in the descriptor may be lazily initialized.  The default is 
     * false.
     */
    public void setLazilyInitialized(boolean shouldLazyInitiailize) {
        this.lazilyInitialized = shouldLazyInitiailize;
    }

    @Override
    public Vector<String> getPrimaryKeyFieldNames() {
        if(null == primaryKeyFields) {
            return new Vector<String>(0);
        }
        return super.getPrimaryKeyFieldNames();
    }

    protected void validateMappingType(DatabaseMapping mapping) {
        if (!(mapping.isXMLMapping())) {
            throw DescriptorException.invalidMappingType(mapping);
        }
    }

    /**
     * INTERNAL:
     * Avoid SDK initialization.

    public void setQueryManager(DescriptorQueryManager queryManager) {
        this.queryManager = queryManager;
        if (queryManager != null) {
            queryManager.setDescriptor(this);
        }
    }*/
    /**
    * INTERNAL:
    * Build(if necessary) and return the nested XMLRecord from the specified field value.
    * The field value should be an XMLRecord or and XMLElement
    */
    public AbstractRecord buildNestedRowFromFieldValue(Object fieldValue) {
        if (fieldValue instanceof XMLRecord) {
            return (XMLRecord) fieldValue;
        }
        
        // BUG#2667762 - If the tag was empty this could be a string of whitespace.
        if (!(fieldValue instanceof Vector)) {
            return getObjectBuilder().createRecord(null);
        }

        Vector nestedRows = (Vector) fieldValue;
        if (nestedRows.isEmpty()) {
            return getObjectBuilder().createRecord(null);
        } else {
            // BUG#2667762 - If the tag was empty this could be a string of whitespace.
            if (!(nestedRows.firstElement() instanceof AbstractRecord)) {
                return getObjectBuilder().createRecord(null);
            }
            return (XMLRecord) nestedRows.firstElement();
        }
    }

    /**
    * INTERNAL:
    * Build(if necessary) and return a Vector of the nested XMLRecords from the specified field value.
    * The field value should be a Vector, an XMLRecord, or an XMLElement
    */
    public Vector buildNestedRowsFromFieldValue(Object fieldValue, AbstractSession session) {
        // BUG#2667762 - If the tag was empty this could be a string of whitespace.
        if (!(fieldValue instanceof Vector)) {
            return new Vector(0);
        }
        return (Vector) fieldValue;
    }
    
    /**
     * Return a new direct/basic mapping for this type of descriptor.
     */
    @Override
    public AbstractDirectMapping newDirectMapping() {
        return new XMLDirectMapping();
    }
    
    /**
     * Return a new aggregate/embedded mapping for this type of descriptor.
     */
    @Override
    public AggregateMapping newAggregateMapping() {
        return new XMLCompositeObjectMapping();
    }
    
    /**
     * Return a new aggregate collection/element collection mapping for this type of descriptor.
     */
    @Override
    public DatabaseMapping newAggregateCollectionMapping() {
        return new XMLCompositeCollectionMapping();
    }
    
    /**
     * Return a new direct collection/element collection mapping for this type of descriptor.
     */
    @Override
    public DatabaseMapping newDirectCollectionMapping() {
        return new XMLCompositeDirectCollectionMapping();
    }

    /**
    * PUBLIC:
    * Add a direct mapping to the receiver. The new mapping specifies that
    * an instance variable of the class of objects which the receiver describes maps in
    * the default manner for its type to the indicated database field.
    *
    * @param attributeName  the name of an instance variable of the
    * class which the receiver describes.
    * @param xpathString the xpath of the xml element or attribute which corresponds
    * with the designated instance variable.
    * @return The newly created DatabaseMapping is returned.
    */
    public DatabaseMapping addDirectMapping(String attributeName, String xpathString) {
        XMLDirectMapping mapping = new XMLDirectMapping();

        mapping.setAttributeName(attributeName);
        mapping.setXPath(xpathString);

        return addMapping(mapping);
    }

    /**
    * PUBLIC:
    * Add a direct to node mapping to the receiver. The new mapping specifies that
    * a variable accessed by the get and set methods of the class of objects which
    * the receiver describes maps in  the default manner for its type to the indicated
    * database field.
    */
    public DatabaseMapping addDirectMapping(String attributeName, String getMethodName, String setMethodName, String xpathString) {
        XMLDirectMapping mapping = new XMLDirectMapping();

        mapping.setAttributeName(attributeName);
        mapping.setSetMethodName(setMethodName);
        mapping.setGetMethodName(getMethodName);
        mapping.setXPath(xpathString);

        return addMapping(mapping);
    }

    @Override
    public void addPrimaryKeyFieldName(String fieldName) {
        addPrimaryKeyField(new XMLField(fieldName));
    }

    @Override
    public void addPrimaryKeyField(DatabaseField field) {
        if (!(field instanceof XMLField)) {
            String fieldName = field.getName();
            field = new XMLField(fieldName);
        }
        if(null == primaryKeyFields) {
            primaryKeyFields = new ArrayList<DatabaseField>(1);
        }
        super.addPrimaryKeyField(field);
    }

    @Override
    public void setPrimaryKeyFields(List<DatabaseField> thePrimaryKeyFields) {
        if(null == thePrimaryKeyFields) {
            return;
        }
        List<DatabaseField> xmlFields = new ArrayList(thePrimaryKeyFields.size());
        Iterator<DatabaseField> it = thePrimaryKeyFields.iterator();

        while (it.hasNext()) {
            DatabaseField field = it.next();
            if (!(field instanceof XMLField)) {
                String fieldName = field.getName();
                field = new XMLField(fieldName);
            }
            xmlFields.add(field);
        }

        super.setPrimaryKeyFields(xmlFields);
    }

    /**
     * INTERNAL:
     * Extract the direct values from the specified field value.
     * Return them in a vector.
     * The field value could be a vector or could be a text value if only a single value.
     */
    public Vector buildDirectValuesFromFieldValue(Object fieldValue) throws DatabaseException {
        if (!(fieldValue instanceof Vector)) {
            Vector fieldValues = new Vector(1);
            fieldValues.add(fieldValue);
            return fieldValues;
        }
        return (Vector) fieldValue;
    }

    /**
     * INTERNAL:
     * Build the appropriate field value for the specified
     * set of direct values.
     * The database better be expecting a Vector.
     */
    public Object buildFieldValueFromDirectValues(Vector directValues, String elementDataTypeName, AbstractSession session) throws DatabaseException {
        return directValues;
    }

    /**
     * INTERNAL:
     * Build and return the appropriate field value for the specified
     * set of nested rows.
     */
    public Object buildFieldValueFromNestedRows(Vector nestedRows, String structureName, AbstractSession session) throws DatabaseException {
        return nestedRows;
    }

    /**
     * INTERNAL:
     * A DatabaseField is built from the given field name.
     */
    public DatabaseField buildField(String fieldName) {
        XMLField xmlField = new XMLField(fieldName);
        xmlField.setNamespaceResolver(this.getNamespaceResolver());
        //xmlField.initialize();
        return xmlField;
    }

    /**
     * INTERNAL:
     * This is used only in initialization.
     */
    public DatabaseField buildField(DatabaseField field) {
        try {
            XMLField xmlField = (XMLField) field;
            xmlField.setNamespaceResolver(this.getNamespaceResolver());
            xmlField.initialize();
        } catch (ClassCastException e) {
            // Assumes field is always an XMLField
        }
        return super.buildField(field);
    }

    /**
     * INTERNAL:
     * This is needed by regular aggregate descriptors (because they require review);
     * but not by XML aggregate descriptors.
     */
    public void initializeAggregateInheritancePolicy(AbstractSession session) {
        // do nothing, since the parent descriptor was already modified during pre-initialize
    }

    @Override
    public void setTableNames(Vector tableNames) {
        if (null != tableNames && tableNames.size() > 0) {
            setDefaultRootElementField((String) tableNames.get(0));
        }
        super.setTableNames(tableNames);
    }

    /**
     * INTERNAL:
     * Sets the tables
     */
    public void setTables(Vector<DatabaseTable> theTables) {
         super.setTables(theTables);
    }

    /**
     * INTERNAL:
     * Allow the descriptor to initialize any dependencies on this session.
     */
    public void preInitialize(AbstractSession session) throws DescriptorException {
        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(PREINITIALIZED)) {
            return;
        }
        setInitializationStage(PREINITIALIZED);

        // Allow mapping pre init, must be done before validate.
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            try {
                DatabaseMapping mapping = (DatabaseMapping) mappingsEnum.nextElement();
                mapping.preInitialize(session);
            } catch (DescriptorException exception) {
                session.getIntegrityChecker().handleError(exception);
            }
        }

        getCachePolicy().useNoIdentityMap();
        getQueryManager().getDoesExistQuery().setExistencePolicy(DoesExistQuery.CheckDatabase);
 
        validateBeforeInitialization(session);

        preInitializeInheritancePolicy(session);

        verifyTableQualifiers(session.getDatasourcePlatform());
        initializeProperties(session);

        if (hasInterfacePolicy()) {
            preInterfaceInitialization(session);
        }
        getCachePolicy().assignDefaultValues(session);
    }

    
    @Override
    protected void preInitializeInheritancePolicy(AbstractSession session) throws DescriptorException {
        super.preInitializeInheritancePolicy(session);
        // Make sure that parent is already preinitialized
        if (hasInheritance()) {
            if(isChildDescriptor()) {
                XMLDescriptor parentDescriptor = (XMLDescriptor) getInheritancePolicy().getParentDescriptor();
                NamespaceResolver parentNamespaceResolver = parentDescriptor.getNamespaceResolver();
                if(null != parentNamespaceResolver && parentNamespaceResolver != namespaceResolver) {
                    if(null == namespaceResolver) {
                        namespaceResolver = getNonNullNamespaceResolver();
                    }
                    if(parentNamespaceResolver.hasPrefixesToNamespaces()) {
                        for(Entry<String, String> entry : parentNamespaceResolver.getPrefixesToNamespaces().entrySet()) {
                            String namespaceURI = namespaceResolver.resolveNamespacePrefix(entry.getKey());
                            if(null == namespaceURI) {
                                namespaceResolver.put(entry.getKey(), entry.getValue());
                            } else if(!namespaceURI.equals(entry.getValue())) {
                                throw XMLMarshalException.subclassAttemptedToOverrideNamespaceDeclaration(entry.getKey(), getJavaClassName(), namespaceURI, parentDescriptor.getJavaClassName(), entry.getValue());
                            }
                        }
                    }
                }
            }
            // The default table will be set in this call once the duplicate
            // tables have been removed.
            getInheritancePolicy().preInitialize(session);
        } else {
            // This must be done now, after validate, before init anything else.
            setInternalDefaultTable();
        }
    }

    /**
     * INTERNAL:
     * Post initializations after mappings are initialized.
     */
    public void postInitialize(AbstractSession session) throws DescriptorException {
        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(POST_INITIALIZED) || isInvalid()) {
            return;
        }

        setInitializationStage(POST_INITIALIZED);

        // Make sure that child is post initialized,
        // this initialize bottom up, unlike the two other phases that to top down.
        if (hasInheritance()) {
            for (ClassDescriptor child : getInheritancePolicy().getChildDescriptors()) {
                child.postInitialize(session);
            }
        }

        // Allow mapping to perform post initialization.
        for (DatabaseMapping mapping : getMappings()) {
            // This causes post init to be called multiple times in inheritance.
            mapping.postInitialize(session);
        }

        if (hasInheritance()) {
            getInheritancePolicy().postInitialize(session);
        }

        //PERF: Ensure that the identical primary key fields are used to avoid equals.
        if(null != primaryKeyFields) {
            for (int index = (primaryKeyFields.size() - 1); index >= 0; index--) {
                DatabaseField primaryKeyField = getPrimaryKeyFields().get(index);
                int fieldIndex = getFields().indexOf(primaryKeyField);

                // Aggregate/agg-collections may not have a mapping for pk field.
                if (fieldIndex != -1) {
                    primaryKeyField = getFields().get(fieldIndex);
                    getPrimaryKeyFields().set(index, primaryKeyField);
                }
            }
        }

        // Index and classify fields and primary key.
        // This is in post because it needs field classification defined in initializeMapping
        // this can come through a 1:1 so requires all descriptors to be initialized (mappings).
        // May 02, 2000 - Jon D.
        for (int index = 0; index < getFields().size(); index++) {
            DatabaseField field = getFields().elementAt(index);
            if (field.getType() == null) {
                DatabaseMapping mapping = getObjectBuilder().getMappingForField(field);
                if (mapping != null) {
                    field.setType(mapping.getFieldClassification(field));
                }
            }
            field.setIndex(index);
        }

        validateAfterInitialization(session);
    }

    /**
     * INTERNAL:
     * Initialize the mappings as a separate step.
     * This is done as a separate step to ensure that inheritance has been first resolved.
     */
    public void initialize(AbstractSession session) throws DescriptorException {
        if (this.hasInheritance()) {
            ((org.eclipse.persistence.internal.oxm.QNameInheritancePolicy) this.getInheritancePolicy()).setNamespaceResolver(this.getNamespaceResolver());
        }

        if(null != this.defaultRootElementField) {
            defaultRootElementField.setNamespaceResolver(this.namespaceResolver);
            defaultRootElementField.initialize();
        }
        if(schemaReference != null && schemaReference.getSchemaContext() != null && (schemaReference.getType() == XMLSchemaReference.COMPLEX_TYPE || schemaReference.getType() == XMLSchemaReference.SIMPLE_TYPE) && getDefaultRootElementType() == null){
        	
        	if(hasInheritance() && isChildDescriptor()){
        		XMLField parentField = ((XMLDescriptor)getInheritancePolicy().getParentDescriptor()).getDefaultRootElementField();
        		//if this descriptor has a root element field different than it's parent set the leaf element type of the default root field
        		if(parentField == null || (parentField !=null && defaultRootElementField !=null && !defaultRootElementField.getXPathFragment().equals(parentField.getXPathFragment()))){
        			setDefaultRootElementType(schemaReference.getSchemaContextAsQName(getNamespaceResolver()));
        		}
        	}else{
        		setDefaultRootElementType(schemaReference.getSchemaContextAsQName(getNamespaceResolver()));
        	}
       
        }

        if(null != primaryKeyFields) {
            for(int x = 0, primaryKeyFieldsSize = this.primaryKeyFields.size(); x<primaryKeyFieldsSize; x++) {
                XMLField pkField = (XMLField) this.primaryKeyFields.get(x);
                pkField.setNamespaceResolver(this.namespaceResolver);
                pkField.initialize();
            }
        }

        // These cached settings on the project must be set even if descriptor is initialized.
        // If defined as read-only, add to it's project's default read-only classes collection.
        if (shouldBeReadOnly() && (!session.getDefaultReadOnlyClasses().contains(getJavaClass()))) {
            session.getDefaultReadOnlyClasses().add(getJavaClass());
        }

        // Avoid repetitive initialization (this does not solve loops)
        if (isInitialized(INITIALIZED) || isInvalid()) {
            return;
        }

        setInitializationStage(INITIALIZED);

        // make sure that parent mappings are initialized?
        if (isChildDescriptor()) {
            ClassDescriptor parentDescriptor = getInheritancePolicy().getParentDescriptor();
            parentDescriptor.initialize(session);
            if(parentDescriptor.hasEventManager()) {
                getEventManager();
            }
        }

        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping) mappingsEnum.nextElement();
            validateMappingType(mapping);
            mapping.initialize(session);
            if(mapping.isObjectReferenceMapping()) {
                this.hasReferenceMappings = true;
            }
            if(mapping instanceof XMLChoiceObjectMapping) {
                XMLChoiceObjectMapping choiceMapping = ((XMLChoiceObjectMapping)mapping);
                for(XMLMapping next : choiceMapping.getChoiceElementMappings().values()) {
                    if(((DatabaseMapping)next).isObjectReferenceMapping()) {
                        this.hasReferenceMappings = true;
                    }
                }
            }
            if(mapping instanceof XMLChoiceCollectionMapping) {
                XMLChoiceCollectionMapping choiceMapping = ((XMLChoiceCollectionMapping)mapping);
                for(XMLMapping next : choiceMapping.getChoiceElementMappings().values()) {
                    if(((DatabaseMapping)next).isObjectReferenceMapping()) {
                        this.hasReferenceMappings = true;
                    }
                }
            }
            // Add all the fields in the mapping to myself.
            Helper.addAllUniqueToVector(getFields(), mapping.getFields());
        }

        // If this has inheritance then it needs to be initialized before all fields is set.
        if (hasInheritance()) {
            getInheritancePolicy().initialize(session);
        }

        // Initialize the allFields to its fields, this can be done now because the fields have been computed.
        setAllFields((Vector) getFields().clone());

        getObjectBuilder().initialize(session);
        if (hasInterfacePolicy()) {
            interfaceInitialization(session);
        }
        if (hasReturningPolicy()) {
            getReturningPolicy().initialize(session);
        }
        if (eventManager != null) {
            eventManager.initialize(session);
        }
        if (copyPolicy != null) {
            copyPolicy.initialize(session);
        }
        getInstantiationPolicy().initialize(session);
        if (getSchemaReference() != null) {
            getSchemaReference().initialize(session);
        }
        // If a Location Accessor is set on a superclass, inherit it
        if (getInheritancePolicyOrNull() != null && getInheritancePolicy().getParentDescriptor() != null) {
            XMLDescriptor d = (XMLDescriptor) getInheritancePolicy().getParentDescriptor();
            locationAccessor = d.getLocationAccessor();
        }
        if (locationAccessor != null) {
            locationAccessor.initializeAttributes(getJavaClass());
        }
    }

    /**
     * INTERNAL:
     * XML descriptors are initialized normally, since they do
     * not need to be cloned by XML aggregate mappings.
     */
    @Override
    public boolean requiresInitialization(AbstractSession session) {
        return (!isDescriptorForInterface());
    }

    /**
     * Aggregates use a dummy table as default.
     */
    protected DatabaseTable extractDefaultTable() {
        return new DatabaseTable();
    }

    /**
     * INTERNAL:
     * Determines the appropriate object to return from the unmarshal
     * call.  The method will either return the object created in the
     * xmlReader.parse() call or an instance of Root.  An Root
     * instance will be returned if the DOMRecord element being
     * unmarshalled does not equal the descriptor's default root
     * element.
     *
     * @param unmarshalRecord
     * @return object
     */
    public Object wrapObjectInXMLRoot(UnmarshalRecord unmarshalRecord, boolean forceWrap) {
        String elementLocalName = unmarshalRecord.getLocalName();
        String elementNamespaceUri = unmarshalRecord.getRootElementNamespaceUri();
        if (forceWrap || shouldWrapObject(unmarshalRecord.getCurrentObject(), elementNamespaceUri, elementLocalName, null, unmarshalRecord.isNamespaceAware())) {
            Root xmlRoot = new XMLRoot();
            xmlRoot.setLocalName(elementLocalName);
            xmlRoot.setNamespaceURI(elementNamespaceUri);
            xmlRoot.setObject(unmarshalRecord.getCurrentObject());
            xmlRoot.setEncoding(unmarshalRecord.getEncoding());
            xmlRoot.setVersion(unmarshalRecord.getVersion());
            xmlRoot.setSchemaLocation(unmarshalRecord.getSchemaLocation());
            xmlRoot.setNoNamespaceSchemaLocation(unmarshalRecord.getNoNamespaceSchemaLocation());
            xmlRoot.setNil(unmarshalRecord.isNil());
            setDeclaredTypeOnXMLRoot(xmlRoot, elementNamespaceUri, elementLocalName, unmarshalRecord.isNamespaceAware(), unmarshalRecord.getUnmarshaller());
            
            return xmlRoot;
        }
        return unmarshalRecord.getCurrentObject();
    }

    /**
      * INTERNAL:
      * Determines the appropriate object to return from the unmarshal
      * call.  The method will either return the object created in the
      * xmlReader.parse() call or an instance of Root.  An Root
      * instance will be returned if the DOMRecord element being
      * unmarshalled does not equal the descriptor's default root
      * element.
      *
      * @param object
      * @param elementNamespaceUri
      * @param elementLocalName
      * @param elementPrefix
      * @return object
      */
    public Object wrapObjectInXMLRoot(Object object, String elementNamespaceUri, String elementLocalName, String elementPrefix, boolean forceWrap, boolean isNamespaceAware, XMLUnmarshaller xmlUnmarshaller) {

        if (forceWrap || shouldWrapObject(object, elementNamespaceUri, elementLocalName, elementPrefix, isNamespaceAware)) {
            // if the DOMRecord element != descriptor's default 
            // root element, create an Root, populate and return it
            Root xmlRoot = new XMLRoot();
            xmlRoot.setLocalName(elementLocalName);
            xmlRoot.setNamespaceURI(elementNamespaceUri);
            xmlRoot.setObject(object);
            
            setDeclaredTypeOnXMLRoot(xmlRoot, elementNamespaceUri, elementLocalName, isNamespaceAware, xmlUnmarshaller);
            
            return xmlRoot;
        }
        return object;
    }

    /**
     * INTERNAL:
     * @return
     */
    public Object wrapObjectInXMLRoot(Object object, String elementNamespaceUri, String elementLocalName, String elementPrefix, String encoding, String version, boolean forceWrap, boolean isNamespaceAware, XMLUnmarshaller unmarshaller) {
        if (forceWrap || shouldWrapObject(object, elementNamespaceUri, elementLocalName, elementPrefix, isNamespaceAware)) {
            // if the DOMRecord element != descriptor's default 
            // root element, create an XMLRoot, populate and return it
            Root xmlRoot = new XMLRoot();
            xmlRoot.setLocalName(elementLocalName);
            xmlRoot.setNamespaceURI(elementNamespaceUri);
            xmlRoot.setObject(object);
            xmlRoot.setEncoding(encoding);
            xmlRoot.setVersion(version);  
            setDeclaredTypeOnXMLRoot(xmlRoot, elementNamespaceUri, elementLocalName, isNamespaceAware, unmarshaller);

            return xmlRoot;
        }
        return object;

    }
    
    private void setDeclaredTypeOnXMLRoot(Root xmlRoot, String elementNamespaceUri, String elementLocalName, boolean isNamespaceAware, Unmarshaller unmarshaller){
    	XPathQName xpathQName = new XPathQName(elementNamespaceUri, elementLocalName, isNamespaceAware);
    	Descriptor desc = unmarshaller.getContext().getDescriptor(xpathQName);
    	if(desc != null){
    		xmlRoot.setDeclaredType(desc.getJavaClass());
    	}
    }
    
    /**
     * INTERNAL:
     * @return
     */
    public boolean shouldWrapObject(Object object, String elementNamespaceUri, String elementLocalName, String elementPrefix, boolean isNamespaceAware) {
        if(resultAlwaysXMLRoot){
            return true;
        }
        XMLField defaultRootField = getDefaultRootElementField();

        // if the descriptor's default root element is null, we want to 
        // create/return an XMLRoot - otherwise, we need to compare the 
        // default root element vs. the root element in the instance doc.
        if (defaultRootField != null) {
            // resolve namespace prefix if one exists
            String defaultRootName = defaultRootField.getXPathFragment().getLocalName();
            String defaultRootNamespaceUri = defaultRootField.getXPathFragment().getNamespaceURI();
            // if the DOMRecord element == descriptor's default 
            // root element, return the object as per usual

            if(isNamespaceAware){
            	if ((((defaultRootNamespaceUri == null) && (elementNamespaceUri == null)) || ((defaultRootNamespaceUri == null) && (elementNamespaceUri.length() == 0)) || ((elementNamespaceUri == null) && (defaultRootNamespaceUri.length() == 0)) || (((defaultRootNamespaceUri != null) && (elementNamespaceUri != null)) && (defaultRootNamespaceUri
                        .equals(elementNamespaceUri))))
                        && (defaultRootName.equals(elementLocalName))) {
                    return false;
                }
            }else{
                if (defaultRootName.equals(elementLocalName)) {
                    return false;
                }
            }
        }
        return true;
    }

    public XMLField getDefaultRootElementField() {
        return defaultRootElementField;
    }

    /**
     * @return true if a new default root element field was created, else false.
     */
    private boolean setDefaultRootElementField(String newDefaultRootElement) {
        if (null == newDefaultRootElement || 0 == newDefaultRootElement.length()) {
            setDefaultRootElementField((XMLField) null);
            return false;
        }
        if(getDefaultRootElementField() != null && newDefaultRootElement.equals(getDefaultRootElementField().getName())){
        	return false;
        }
        // create the root element xml field based on default root element name
        setDefaultRootElementField(new XMLField(newDefaultRootElement));
        return true;
    }

    public void setDefaultRootElementField(XMLField xmlField) {
        defaultRootElementField = xmlField;
    }

    public QName getDefaultRootElementType() {
        if (defaultRootElementField != null) {
            return defaultRootElementField.getLeafElementType();
        }
        return null;
    }

    /**
     * The default root element type string will be stored until
     * initialization - a QName will be created and stored on the
     * default root element field during initialize.
     *
     * @param type
     */
    public void setDefaultRootElementType(QName type) {
        if (defaultRootElementField != null) {
            defaultRootElementField.setLeafElementType(type);
        }
    }

    /**
     * INTERNAL:
     * <p>Indicates if the Object mapped by this descriptor is a sequenced data object
     * and should be marshalled accordingly.
     */
    public boolean isSequencedObject() {
        return sequencedObject;
    }

    public void setSequencedObject(boolean isSequenced) {
        this.sequencedObject = isSequenced;
    }

	public boolean isWrapper() {
		return isWrapper;
	}

	public void setIsWrapper(boolean value) {
		this.isWrapper = value;
	}

    public boolean isResultAlwaysXMLRoot() {
        return resultAlwaysXMLRoot;
    }

    public void setResultAlwaysXMLRoot(boolean resultAlwaysXMLRoot) {
        this.resultAlwaysXMLRoot = resultAlwaysXMLRoot;
    }
    
    /**
     * INTERNAL:
     * Returns true if any of the mappings on this descriptor are key-based reference
     * mappings.
     */
    public boolean hasReferenceMappings() {
        return this.hasReferenceMappings;
    }

    @Override
    public DatabaseField getTypedField(DatabaseField field) {
        XMLField foundField = (XMLField) super.getTypedField(field);
        if(null != foundField) {
            return foundField;
        }
        StringTokenizer stringTokenizer = new StringTokenizer(field.getName(), "/");
        DatabaseField typedField = getTypedField(stringTokenizer);
        if(null == typedField) {
            DatabaseMapping selfMapping = objectBuilder.getMappingForField(new XMLField("."));
            if(null != selfMapping) {
                return selfMapping.getReferenceDescriptor().getTypedField(field); 
            }
        }
        return typedField;
    }

    protected DatabaseField getTypedField(StringTokenizer stringTokenizer) {
        String xPath = ""; 
        XMLField xmlField = new XMLField(); 
        xmlField.setNamespaceResolver(namespaceResolver); 
        while(stringTokenizer.hasMoreElements()) {
            String nextToken = stringTokenizer.nextToken();
            xmlField.setXPath(xPath + nextToken);
            xmlField.initialize();
            DatabaseMapping mapping = objectBuilder.getMappingForField(xmlField); 
            if(null == mapping) {
                XPathFragment xPathFragment = new XPathFragment(nextToken);
                if(xPathFragment.getIndexValue() > 0) {
                    xmlField.setXPath(xPath + nextToken.substring(0, nextToken.indexOf('[')));
                    xmlField.initialize();
                    mapping = objectBuilder.getMappingForField(xmlField);
                    if(null != mapping) {
                        if(mapping.isCollectionMapping()) {
                            if(mapping.getContainerPolicy().isListPolicy()) {
                                if(stringTokenizer.hasMoreElements()) {
                                    return ((XMLDescriptor) mapping.getReferenceDescriptor()).getTypedField(stringTokenizer); 
                                } else {
                                    return mapping.getField();
                                }
                            }
                        }
                    }
                }
            } else {
                if(stringTokenizer.hasMoreElements()) {
                    return ((XMLDescriptor) mapping.getReferenceDescriptor()).getTypedField(stringTokenizer);
                } else {
                    return mapping.getField();
                } 
            } 
            xPath = xPath + nextToken + "/"; 
        }
        return null; 
    }

    /**
     * INTERNAL:
     * Returns this Descriptor's location accessor, if one is defined.
     */
    public AttributeAccessor getLocationAccessor() {
        return locationAccessor;
    }

    /**
     * INTERNAL:
     * Set this Descriptor's location accessor.
     */
    public void setLocationAccessor(AttributeAccessor value) {
        this.locationAccessor = value;
    }
    
    
    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this Descriptor to actual class-based
     * settings. This method is used when converting a project that has been built
     * with class names to a project with classes.
     * @param classLoader 
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        super.convertClassNamesToClasses(classLoader);
        if(this.attributeGroups != null) {
            for(AttributeGroup next:attributeGroups.values()) {
                next.convertClassNamesToClasses(classLoader);
            }
        }
    }
}