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

import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.Type;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.impl.HelperProvider;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.eclipse.persistence.sdo.helper.SDOClassLoader;
import org.eclipse.persistence.sdo.helper.SDOHelperContext;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.helper.SDOXSDHelper;
import org.eclipse.persistence.sdo.helper.extension.SDOUtil;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLAnyAttributeMapping;
import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;

public class SDOType implements Type, Serializable {
    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];

    private QName qName;
    private boolean open;// if this Type is open
    private boolean isAbstract;// if this is an abstract Type
    protected boolean isDataType;// if this is a dataType
    private List baseTypes;// a list of this Type's base Types (added for now waitting for final decision)
    private List declaredProperties;// a list of Properties defined by this Type.(Optional, leave it for now)
    private transient Map declaredPropertiesMap;
    private List aliasNames;
    private boolean xsd;
    private boolean xsdList;
    private String xsdLocalName;
    private QName xsdType;
    protected transient XMLDescriptor xmlDescriptor;
    private Map propertyValues;
    private SDOProperty changeSummaryProperty;
    private List allProperties;
    private SDOProperty[] allPropertiesArr;
    private List subTypes;
    private boolean finalized;
    private Class javaClass;
    private String javaClassName;
    private String javaImplClassName;
    protected Class javaImplClass;
    private List<SDOProperty> nonFinalizedReferencingProps;
    private List nonFinalizedMappingURIs;

    /** hold a wrapper object for primitive numeric defaults */
    private Object pseudoDefault;

    // hold the context containing all helpers so that we can preserve inter-helper relationships
    protected HelperContext aHelperContext;
    private List appInfoElements;
    private Map appInfoMap;

    /** Open Content setOpen constants */
    private static final String ANY_MAPPING_ATTRIBUTE_NAME = "openContentProperties";
    private static final String ANY_MAPPING_GET_METHOD_NAME = "_getOpenContentPropertiesWithXMLRoots";
    private static final String ANY_MAPPING_SET_METHOD_NAME = "_setOpenContentPropertiesWithXMLRoots";
    private static final String SDO_REF_MAPPING_ATTRIBUTE_NAME = "sdoRef";

    public SDOType(HelperContext helperContext) {
        this((SDOTypeHelper)helperContext.getTypeHelper());
    }

    public SDOType(SDOTypeHelper sdoTypeHelper) {
        this(sdoTypeHelper, new XMLDescriptor());
        xmlDescriptor.setLazilyInitialized(true);
    }

    protected SDOType(SDOTypeHelper sdoTypeHelper, XMLDescriptor xmlDescriptor) {
        this.xmlDescriptor = xmlDescriptor;
        if(null != sdoTypeHelper) {
            aHelperContext = sdoTypeHelper.getHelperContext();
            if(null != xmlDescriptor) {
                this.xmlDescriptor.setNamespaceResolver(sdoTypeHelper.getNamespaceResolver());
            }
        }
    }

    /**
     * INTERNAL:
     * Build up a Type with given name and uri and a default static HelperContext.
     * Use  {@link #SDOType(String, String, org.eclipse.persistence.sdo.helper.SDOTypeHelper)} instead
     * @param uri           the URI of this type
     * @param type_name     the unique of this Type
     */
    public SDOType(String uri, String type_name) {
        // JIRA129 - default to static global context - Do Not use this convenience constructor outside of JUnit testing
        this(uri, type_name, (SDOTypeHelper) HelperProvider.getDefaultContext().getTypeHelper());
    }

    /**
     * Build up a Type with given name and uri
     * @param uri           the URI of this type
     * @param name          the unique of this Type
     * @param sdoTypeHelper the current HelperContext
     */
    public SDOType(String uri, String name, SDOTypeHelper sdoTypeHelper) {
        this(sdoTypeHelper);
        if(null != uri) {
            uri = uri.intern();
        }
        if(null != name) {
            name = name.intern();
        }
        this.qName = new QName(uri, name);
    }

    protected SDOType(String uri, String name, SDOTypeHelper sdoTypeHelper, XMLDescriptor xmlDescriptor) {
        this(sdoTypeHelper, xmlDescriptor);
        if(null != uri) {
            uri = uri.intern();
        }
        if(null != name) {
            name = name.intern();
        }
        this.qName = new QName(uri, name);
    }

    public QName getQName() {
        return qName;
    }

    public void setQName(QName qName) {
        this.qName = qName;
    }

    @Override
    public String getName() {
        return qName.getLocalPart();
    }

    @Override
    public String getURI() {
        String uri = qName.getNamespaceURI();
        if("".equals(uri)) {
            return null;
        } else {
            return uri;
        }
    }

    @Override
    public Class getInstanceClass() {
        if ((javaClass == null) && (javaClassName != null)) {
            try {
                SDOClassLoader loader = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getLoader();
                Class<?> clazz = loader.getParent().loadClass(javaClassName);
                if(isValidInstanceClass(clazz)) {
                    javaClass = clazz;
                } else {
                    javaClass = getClass();
                }
            } catch (ClassNotFoundException e) {
                javaClass = getClass();
            } catch (SecurityException e) {
                throw SDOException.classNotFound(e, getURI(), getName());
            }
        }
        if(javaClass == getClass()) {
            return null;
        }
        return javaClass;
    }

    /**
     * Verify that the class is a valid instance class.
     */
    private boolean isValidInstanceClass(Class clazz) {
        if(isDataType) {
            return true;
        }
        if(!clazz.isInterface()) {
            return false;
        }
        return !isStrictTypeCheckingEnabled() || hasClassGetterForEachProperty(clazz);
    }
    
    /**
     * Checks that the given class has getter for each property of this type.
     * 
     * @param clazz class to be checked
     * @return {@code true} if given class has getter for each property
     */
    private boolean hasClassGetterForEachProperty(Class clazz) {
        for(Object object: this.getDeclaredProperties()) {
            SDOProperty sdoProperty = (SDOProperty) object;
            SDOType sdoPropertyType = sdoProperty.getType();
            if(!sdoPropertyType.isChangeSummaryType()) {
                String javaType = SDOUtil.getJavaTypeForProperty(sdoProperty);
                try {
                    // Verify get method
                    String getMethodName = SDOUtil.getMethodName(sdoProperty.getName(), javaType);
                    PrivilegedAccessHelper.getPublicMethod(clazz, getMethodName, EMPTY_CLASS_ARRAY, false);
                } catch(NoSuchMethodException e) {
                    //if the method isn't found and the type is boolean try looking for a "get" method instead of an "is" method
                    if(sdoPropertyType == SDOConstants.SDO_BOOLEAN || sdoPropertyType == SDOConstants.SDO_BOOLEANOBJECT ){
                        try{
                            String booleanGetterMethodName = SDOUtil.getBooleanGetMethodName(sdoProperty.getName(), javaType);
                            PrivilegedAccessHelper.getPublicMethod(clazz, booleanGetterMethodName, EMPTY_CLASS_ARRAY, false);
                        } catch(NoSuchMethodException e2) {
                            return false;
                        }
                    }else{
                        return false;
                    }
                }
            }
        } 
        return true;
    }
    
    /**
     * Indicates whether to check instance class strictly.
     * 
     * @return boolean
     */
    private boolean isStrictTypeCheckingEnabled() {
        final HelperContext helperContext = getHelperContext();
        if (helperContext instanceof SDOHelperContext) {
            return ((SDOHelperContext)helperContext).isStrictTypeCheckingEnabled();
        }
        return true;
    }

    @Override
    public boolean isInstance(Object object) {
        if ((!isDataType()) && (object instanceof DataObject)) {
            Type doType = ((DataObject)object).getType();
            if (doType != null) {
                return doType.equals(this);
            }
        }

        //this check is taken from page 77 of the spec
        Class instanceClass = getInstanceClass();
        if (instanceClass != null) {
            return instanceClass.isInstance(object);
        }

        return false;
    }

    @Override
    public List getProperties() {
        if (allProperties == null) {
            allProperties = new ArrayList();
        }
        return allProperties;
    }

    @Override
    public SDOProperty getProperty(String propertyName) {
        SDOProperty queriedProperty = (SDOProperty)getDeclaredPropertiesMap().get(propertyName);
        if (null == queriedProperty && isSubType()) {
            for (int i = 0; i < getBaseTypes().size(); i++) {
                queriedProperty = ((SDOType)getBaseTypes().get(i)).getProperty(propertyName);
                if (queriedProperty != null) {
                    break;
                }
            }
        }
        return queriedProperty;
    }

    @Override
    public boolean isDataType() {
        return isDataType;
    }

    @Override
    public boolean isOpen() {
        return open;
    }

    @Override
    public boolean isSequenced() {
        return xmlDescriptor.isSequencedObject();
    }

    @Override
    public boolean isAbstract() {
        return isAbstract;
    }

    @Override
    public List getBaseTypes() {
        if (baseTypes == null) {
            baseTypes = new ArrayList();
        }
        return baseTypes;
    }

    /**
     * INTERNAL:
     * Provide a means to determine if this type has base types without causing the base types property to be initialized.
     */
    public boolean isSubType() {
        return !(null == baseTypes || baseTypes.isEmpty());
    }

    @Override
    public List getDeclaredProperties() {
        if (declaredProperties == null) {
            declaredProperties = new ArrayList();
        }
        return declaredProperties;
    }

    @Override
    public List getAliasNames() {
        if (aliasNames == null) {
            aliasNames = new ArrayList();
        }
        return aliasNames;
    }

    /**
     * INTERNAL:
     * Assign a unique string to a type, which belongs to same uri, among types.
     * @param name  a unique string representing a type.
     */
    public void addAliasName(String name) {
        getAliasNames().add(name);
        QName qname = new QName(getURI(), name);
        ((SDOTypeHelper)aHelperContext.getTypeHelper()).getTypesHashMap().put(qname, this);
    }

    /**
     * INTERNAL:
     * Assign a list of alias names to a type, which are unique in URI.
     * @param names  a unique string representing a type.
     */
    public void setAliasNames(List names) {
        for (int i = 0; i < names.size(); i++) {
            addAliasName((String)names.get(i));
        }
    }

    /**
     * INTERNAL:
     * Make this Type an opened Type to allow open content by assigning true value
     * or a Type not to accept any additional properties by assigning false value,
     * {@link #isOpen()}.
     * @param bOpen  boolean value implying if this Type is open
     */
    public void setOpen(boolean bOpen) {
        if (isDataType() && bOpen) {
            throw SDOException.typeCannotBeOpenAndDataType(getURI(), getName());
        }
        if (open != bOpen) {
            open = bOpen;
            if (open) {
                if (isSubType()) {
                    Type baseType = (Type)getBaseTypes().get(0);
                    if (!baseType.isOpen()) {
                        addOpenMappings();
                    }
                } else {
                    addOpenMappings();
                }

                if(isBaseType()) {
                    for (int i = 0; i < getSubTypes().size(); i++) {
                        SDOType nextSubType = (SDOType)getSubTypes().get(i);
                        nextSubType.setOpen(bOpen);
                    }
                }
            }
        }
    }

    private void addOpenMappings() {
        XMLAnyCollectionMapping anyMapping = new XMLAnyCollectionMapping();
        anyMapping.setAttributeName(ANY_MAPPING_ATTRIBUTE_NAME);
        anyMapping.setGetMethodName(ANY_MAPPING_GET_METHOD_NAME);
        anyMapping.setSetMethodName(ANY_MAPPING_SET_METHOD_NAME);
        anyMapping.setUseXMLRoot(true);
        getXmlDescriptor().addMapping(anyMapping);

        XMLAnyAttributeMapping anyAttrMapping = new XMLAnyAttributeMapping();
        anyAttrMapping.setAttributeName("openContentPropertiesAttributes");
        anyAttrMapping.setGetMethodName("_getOpenContentPropertiesAttributesMap");
        anyAttrMapping.setSetMethodName("_setOpenContentPropertiesAttributesMap");
        getXmlDescriptor().addMapping(anyAttrMapping);
    }

    /**
     * INTERNAL:
     * Change this Type's abstract setting. If it is true, this Type can't be instantiated and typically serve as base Type.
     * @param makeAbstract    boolean value implying if this Type is abstract.
     */
    public void setAbstract(boolean makeAbstract) {
        isAbstract = makeAbstract;
    }

    /**
     * INTERNAL:
     * If set as true, this Type specifies Sequenced DataObjects.
     * @param sequenced     boolean value implying if this type is sequenced.
     */
    public void setSequenced(boolean sequenced) {
        xmlDescriptor.setSequencedObject(sequenced);
    }

    public void setMixed(boolean isMixed) {
        String textAttribute = "text";
        XMLDirectMapping textMapping = (XMLDirectMapping) xmlDescriptor.getMappingForAttributeName(textAttribute);
        if (isMixed) {
            if (null == textMapping) {
                textMapping = new XMLDirectMapping();
                textMapping.setAttributeName(textAttribute);
                textMapping.setXPath("text()");
                xmlDescriptor.addMapping(textMapping);
            }
        } else {
            xmlDescriptor.removeMappingForAttributeName(textAttribute);
        }
    }

    /**
     * INTERNAL:
     * Set this Type to a simple Type by passing in boolean value true. Otherwise,
     * If boolean value is passed in, instances of this type implement DataObject.
     * @param datatype      boolean value implying if it is a simple Type
     */
    public void setDataType(boolean datatype) {
        if (datatype && isOpen()) {
            throw SDOException.typeCannotBeOpenAndDataType(getURI(), getName());
        }
        isDataType = datatype;
        if (datatype) {
            setFinalized(true);
        }
    }

    /**
     * INTERNAL:
     * Set a list of Types as This Type's base Types.
     * @param bTypes    a list types to become this Type's base Type.
     */
    public void setBaseTypes(List bTypes) {
        if (bTypes != null) {
            for (int i = 0; i < bTypes.size(); i++) {
                addBaseType((SDOType)bTypes.get(i));
            }
        } else {
            baseTypes = null;
        }
    }

    /**
     * INTERNAL:
     * @param type    a  type to become this Type's base Type.
     */
    public void addBaseType(SDOType type) {
        if (!this.getBaseTypes().contains(type)) {
            getBaseTypes().add(type);

            updateSubtypes(type);

            if(!(type.isDataType() && (type.getQName().getNamespaceURI() == SDOConstants.SDO_URL || type.getQName().getNamespaceURI() == SDOConstants.SDOJAVA_URL))) {
                type.getSubTypes().add(this);
            }

            if (type.isOpen() && this.isOpen()) {
                //don't want any mappings on this descriptor
                DatabaseMapping anyCollectionMapping = getXmlDescriptor().getMappingForAttributeName(ANY_MAPPING_ATTRIBUTE_NAME);
                getXmlDescriptor().getMappings().remove(anyCollectionMapping);

                DatabaseMapping anyAttrMapping = getXmlDescriptor().getMappingForAttributeName("openContentPropertiesAttributes");
                getXmlDescriptor().getMappings().remove(anyAttrMapping);
            }

            //int increaseBy = type.getProperties().size();
            //increaseIndices(increaseBy);
        }
    }

    private void updateSubtypes(Type baseType) {
        getProperties().addAll(0, baseType.getProperties());
        if(isBaseType()) {
            for (int i = 0; i < getSubTypes().size(); i++) {
                SDOType nextSubType = (SDOType)getSubTypes().get(i);
                nextSubType.updateSubtypes(baseType);
            }
        }
    }

    /**
      * INTERNAL:
      * Sets the Java class that this type represents.
      * @param aClass the Java class that this type represents.
      */
    public void setInstanceClass(Class aClass) {
        javaClass = aClass;
        if (javaClass != null) {
            javaClassName = javaClass.getName();
        }
    }

    /**
      * INTERNAL:
      * Set if this property was declared in an XML schema.
      * @param bXsd a boolean representing if this property was declared in an XML schema
      */
    public void setXsd(boolean bXsd) {
        xsd = bXsd;
    }

    /**
      * INTERNAL:
      * Returns if this property was declared in an XML schema.  Defaults to false.
      * @return if this property was declared in an XML schema
      */
    public boolean isXsd() {
        return xsd;
    }

    /**
      * INTERNAL:
      * Set the local name of this property.
      * @param xsdLocalNameString a String representing the local name of this property if it was declared in an XML schema
      */
    public void setXsdLocalName(String xsdLocalNameString) {
        xsdLocalName = xsdLocalNameString;
    }

    /**
      * INTERNAL:
      * Returns the  local name of the Property.
      * @return the local name of the property.
      */
    public String getXsdLocalName() {
        return xsdLocalName;
    }

    /**
     * INTERNAL:
     * @param property
    */
    public void addDeclaredProperty(Property property) {
        addDeclaredProperty((SDOProperty)property);
    }

    /**
     * INTERNAL:
     * @param property
    */
    public void addDeclaredProperty(SDOProperty property) {
        int end = getDeclaredProperties().size();
        addDeclaredProperty(property, end);
    }

    /**
    * INTERNAL:
    * @param property
    */
    public void addDeclaredProperty(Property property, int index) {
        addDeclaredProperty((SDOProperty)property, index);
    }

    /**
    * INTERNAL:
    * @param property
    */
    public void addDeclaredProperty(SDOProperty property, int index) {
        if (!getDeclaredPropertiesMap().containsKey(property.getName())) {
            int currentSize = getDeclaredProperties().size();

            int allSize = getProperties().size();
            int insertPlace = allSize - currentSize + index;

            //updateSubTypesProps
            if(isBaseType()) {
                for (int i = 0; i < getSubTypes().size(); i++) {
                    SDOType nextSubType = (SDOType)getSubTypes().get(i);
                    nextSubType.updateIndices(insertPlace, property);
                }
            }

            getDeclaredProperties().add(index, property);
            getProperties().add(insertPlace, property);

            property.setContainingType(this);

            getDeclaredPropertiesMap().put(property.getName(), property);
            if (property.hasAliasNames()) {
                for (int j = 0; j < property.getAliasNames().size(); j++) {
                    getDeclaredPropertiesMap().put(property.getAliasNames().get(j), property);
                }
            }
            if ((property.getType() != null) && (property.getType().isChangeSummaryType())) {
                changeSummaryProperty = property;
            }
        }
    }

    /**
     * INTERNAL:
     */
    public void removeDeclaredProperties(Property p) {
        getDeclaredProperties().remove(p);
        getDeclaredPropertiesMap().remove(p.getName());
        getProperties().remove(p);
    }

    /**
     * INTERNAL:
     */
    public Map getDeclaredPropertiesMap() {
        if (null == declaredPropertiesMap) {
            declaredPropertiesMap = new HashMap();
        }
        return declaredPropertiesMap;
    }

    /**
      * INTERNAL:
      * Sets the name of the Java class that this type represents.
      * @param instanceClassName the Java class that this type represents.
      */
    public void setInstanceClassName(String instanceClassName) {
        javaClassName = instanceClassName;
        javaClass = null;
    }

    /**
      * INTERNAL:
      * Returns the Java class name that this type represents.
      * @return the Java class name.
      */
    public String getInstanceClassName() {
        if ((javaClassName == null) && (javaClass != null)) {
            javaClassName = javaClass.getName();
        }
        return javaClassName;
    }

    /**
      * INTERNAL:
      * Set if this type is an xsd:list in the schema
      * @param anXsdList a boolean representing if this type represents an xsd:list in the schema
      */
    public void setXsdList(boolean anXsdList) {
        xsdList = anXsdList;
    }

    /**
      * INTERNAL:
      * Indicates if this Type is an xsd:list in the schema
      * @return true if this Type represents an xsd:list in the schema
      */
    public boolean isXsdList() {
        return xsdList;
    }

    /**
      * INTERNAL:
      * Set the XMLDescriptor on this Type
      * @param anXMLDescriptor
      */
    public void setXmlDescriptor(XMLDescriptor anXMLDescriptor) {
        xmlDescriptor = anXMLDescriptor;
    }

    public XMLDescriptor getXmlDescriptor() {
        return xmlDescriptor;
    }

    /**
      * INTERNAL:
      * Get the XMLDescriptor associated with this Type or generate a new one.
      */
    public void initializeNamespaces(List namespaceResolvers) {
        if (!isDataType()) {
            NamespaceResolver nr = new NamespaceResolver();

            // copy namespaces between resolvers for well known and SDO namespaces
            if (namespaceResolvers != null) {
                for (int i = 0; i < namespaceResolvers.size(); i++) {
                    NamespaceResolver nextNR = (NamespaceResolver)namespaceResolvers.get(i);
                    if (nextNR != null) {
                        for (int j = 0, size = nextNR.getNamespaces().size(); j < size; j++) {
                            Namespace nextNamespace = nextNR.getNamespaces().get(j);
                            if ((!nextNamespace.getPrefix().equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) && (!nextNamespace.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) &&
                                (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) && (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDOXML_URL)) &&
                                (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDO_URL))) {
                                String newPrefix = ((SDOTypeHelper)aHelperContext.getTypeHelper()).addNamespace(nextNamespace.getPrefix(), nextNamespace.getNamespaceURI());
                                nr.put(newPrefix, nextNamespace.getNamespaceURI());
                            }
                        }
                    }
                }
            }
            xmlDescriptor.setNamespaceResolver(nr);
            if (getURI() != null) {
                String prefix = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getPrefix(getURI());
                xmlDescriptor.getNamespaceResolver().put(prefix, getURI());
            }
            xmlDescriptor.getNamespaceResolver().put(XMLConstants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
        }
    }

    /**
     * INTERNAL:
     * Convenience method that sets up class indicator and @sdoRef
     * attribute.
     *
     * @param xdesc
     * @param pCls
     */
    private void addClassIndicator(XMLDescriptor xdesc, Class pCls, boolean isInheritanceRoot) {
        XMLField field = (XMLField)getXmlDescriptor().buildField("@xsi:type");
        field.initialize();
        xdesc.getInheritancePolicy().setClassIndicatorField(field);

        String parentIndicator = getName();
        String parentPrefix = xdesc.getNamespaceResolver().resolveNamespaceURI(getURI());
        if (parentPrefix != null) {
            parentIndicator = parentPrefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + parentIndicator;
        }
        xdesc.getInheritancePolicy().addClassIndicator(pCls, parentIndicator);


        // only add the @sdoRef attribute if necessary
        if (xdesc.getMappingForAttributeName(SDO_REF_MAPPING_ATTRIBUTE_NAME) == null) {
            String sdoPrefix = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getPrefix(SDOConstants.SDO_URL);
            XMLDirectMapping sdoRefMapping = new XMLDirectMapping();
            sdoRefMapping.setAttributeName(SDO_REF_MAPPING_ATTRIBUTE_NAME);

            XMLField xmlField = new XMLField("@" + sdoPrefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + SDOConstants.CHANGESUMMARY_REF);
            xmlField.getXPathFragment().setNamespaceURI(SDOConstants.SDO_URL);
            xmlField.getLastXPathFragment().setNamespaceURI(SDOConstants.SDO_URL);

            sdoRefMapping.setField(xmlField);
            xdesc.addMapping(sdoRefMapping);
        }
    }

    public void setupInheritance(SDOType parentType) {
        if (parentType == null) {
            // root of inheritance
            addClassIndicator(getXmlDescriptor(), getImplClass(), true);
        } else {
            if ((parentType.getURI() != null) && (!parentType.getURI().equals(SDOConstants.SDO_URL))) {
                // set parent descriptor indicator if necessary
                if (!parentType.getXmlDescriptor().hasInheritance()) {
                    addClassIndicator(parentType.getXmlDescriptor(), parentType.getImplClass(), false);
                }

                XMLDescriptor parentDescriptor = (XMLDescriptor)parentType.getXmlDescriptor().getInheritancePolicy().getRootParentDescriptor();
                NamespaceResolver parentNR = parentDescriptor.getNonNullNamespaceResolver();
                if (parentNR != null) {
                    for (int i = 0; i < parentNR.getNamespaces().size(); i++) {
                        Namespace nextNamespace = parentNR.getNamespaces().get(i);
                        if ((!nextNamespace.getPrefix().equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) && (!nextNamespace.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) &&
                            (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) && (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDOXML_URL)) &&
                            (!nextNamespace.getNamespaceURI().equals(SDOConstants.SDO_URL))) {
                            getXmlDescriptor().getNonNullNamespaceResolver().put(nextNamespace.getPrefix(), nextNamespace.getNamespaceURI());
                        }
                    }
                }
                if (getInstanceClassName() != null) {
                    String indicator = getName();
                    String prefix = parentDescriptor.getNamespaceResolver().resolveNamespaceURI(getURI());
                    if (prefix == null) {
                        prefix = getXmlDescriptor().getNamespaceResolver().resolveNamespaceURI(getURI());
                        if (prefix != null) {
                            parentDescriptor.getNamespaceResolver().put(prefix, getURI());
                        }
                    }
                    if (prefix != null) {
                        indicator = prefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + indicator;
                    }
                    Class implClass = getImplClass();
                    parentDescriptor.getInheritancePolicy().addClassIndicator(implClass, indicator);
                    parentDescriptor.getInheritancePolicy().setShouldReadSubclasses(true);
                    Class parentClass = parentType.getImplClass();
                    getXmlDescriptor().getInheritancePolicy().setParentClass(parentClass);
                    getXmlDescriptor().getInheritancePolicy().setParentDescriptor(parentType.getXmlDescriptor());
                    parentType.getXmlDescriptor().getNamespaceResolver().put(XMLConstants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                    getXmlDescriptor().getNamespaceResolver().put(XMLConstants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                }
            }
        }
        // now setup inheritance for any subtypes
        if(isBaseType()) {
            for (int i = 0; i < subTypes.size(); i++) {
                SDOType nextSubType = (SDOType)subTypes.get(i);
                if (!nextSubType.isDataType() && nextSubType.isSubType()) {
                    nextSubType.setupInheritance(this);
                }
            }
        }
    }

    /**
     * INTERNAL:
     * For this Type generate classes
     * @param packageName
     * @param namespaceResolvers
     */
    public void preInitialize(String packageName, List namespaceResolvers) {
        String instanceClassName = getInstanceClassName();
        if (null == instanceClassName) {
            if (null == packageName) {
                String uri = getURI();
                if (null == uri) {
                    packageName = SDOUtil.getDefaultPackageName() + SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR;
                } else {
                    packageName = SDOUtil.getPackageNameFromURI(uri) + SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR;
                }
            }

            // Verify and fix any Class name that does not conform to conventions
            // run the class name through the JAXB mangler
            String mangledClassName = SDOUtil.className(getName(), false, true, true);

            // we will not fix any type collision at this time as a result of class renaming
            // write fully qualified java class name
            StringBuffer fullClassName = new StringBuffer(packageName);
            fullClassName.append(mangledClassName);
            setInstanceClassName(fullClassName.toString());
        }
        AbstractSessionLog.getLog().log(AbstractSessionLog.FINER,//
                                        "sdo_type_generation_processing_type", //
                                        new Object[] { Helper.getShortClassName(getClass()), getInstanceClassName() });

        initializeNamespaces(namespaceResolvers);
        getXmlDescriptor().setJavaClassName(getImplClassName());

        // See SDOResolvable enhancement
        String schemaContext = getName();
        if (getXmlDescriptor().getNamespaceResolver() != null) {
            String prefix = getXmlDescriptor().getNamespaceResolver().resolveNamespaceURI(getURI());
            if ((prefix != null) && !prefix.equals(SDOConstants.EMPTY_STRING)) {
                schemaContext = prefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + schemaContext;
            }
        }
        String schemaContextWithSlash = SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + schemaContext;

        XMLSchemaReference schemaRef = new XMLSchemaClassPathReference();
        schemaRef.setSchemaContext(schemaContextWithSlash);
        schemaRef.setType(XMLSchemaReference.COMPLEX_TYPE);
        getXmlDescriptor().setSchemaReference(schemaRef);

    }

    /**
      * INTERNAL:
      */
    public void postInitialize() {
        String idPropName = (String)get(SDOConstants.ID_PROPERTY);
        if (idPropName != null) {
            SDOProperty idProp = getProperty(idPropName);
            if (idProp != null) {
                String targetxpath = idProp.getQualifiedXPath(getURI(), true);
                getXmlDescriptor().addPrimaryKeyFieldName(targetxpath);
            }
        }
        setFinalized(true);
        if(null != nonFinalizedReferencingProps) {
            for (int i = 0; i < nonFinalizedReferencingProps.size(); i++) {
                SDOProperty nextProp = nonFinalizedReferencingProps.get(i);
                String nextURI = (String)getNonFinalizedMappingURIs().get(i);
                nextProp.buildMapping(nextURI, nextProp.getIndexInType());
            }
            nonFinalizedReferencingProps = null;
            nonFinalizedMappingURIs = null;
        }
        // set @sdoRef attribute mapping for complex types that are not involved in inheritance
        if (!isDataType() && !isSubType() && !isBaseType()) {
            String sdoPrefix = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getPrefix(SDOConstants.SDO_URL);
            XMLDirectMapping sdoRefMapping = new XMLDirectMapping();
            sdoRefMapping.setAttributeName(SDO_REF_MAPPING_ATTRIBUTE_NAME);

            XMLField xmlField = new XMLField("@" + sdoPrefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + SDOConstants.CHANGESUMMARY_REF);
            xmlField.getXPathFragment().setNamespaceURI(SDOConstants.SDO_URL);
            xmlField.getLastXPathFragment().setNamespaceURI(SDOConstants.SDO_URL);
            sdoRefMapping.setField(xmlField);
            xmlDescriptor.addMapping(sdoRefMapping);
        }
        if(!isDataType()) {
            getImplClass();
            if(!isAbstract() && !isWrapperType()) {
                TypeInstantiationPolicy tip = new TypeInstantiationPolicy(this);
                this.xmlDescriptor.setInstantiationPolicy(tip);
            }
        }
    }

    /**
      * INTERNAL:
      */
    public void setImplClassName(String implClassName) {
        javaImplClassName = implClassName;
        javaImplClass = null;
    }

    /**
      * INTERNAL:
      */
    public String getImplClassName() {
        if ((javaImplClassName == null) && (javaClassName != null)) {
            javaImplClassName = javaClassName + SDOConstants.SDO_IMPL_NAME;
        }
        return javaImplClassName;
    }

    /**
      * INTERNAL:
      */
    public Class getImplClass() {
        if ((javaImplClass == null) && (getImplClassName() != null)) {
            try {
                SDOClassLoader loader = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getLoader();
                javaImplClass = loader.loadClass(getImplClassName(), this);
                xmlDescriptor.setJavaClass(javaImplClass);
            } catch (ClassNotFoundException e) {
                throw SDOException.classNotFound(e, getURI(), getName());
            } catch (SecurityException e) {
                throw SDOException.classNotFound(e, getURI(), getName());
            }
        }
        return javaImplClass;
    }

    @Override
    public Object get(Property property) {
        if(null == propertyValues) {
            return null;
        }
        return propertyValues.get(property);
    }

    @Override
    public List getInstanceProperties() {
        if(null == propertyValues) {
            return Collections.EMPTY_LIST;
        }
        return new ArrayList(getPropertyValues().keySet());
    }

    /**
      * INTERNAL:
      */
    public void setPropertyValues(Map properties) {
        this.propertyValues = properties;
    }

    /**
      * INTERNAL:
      */
    public Map getPropertyValues() {
        if (propertyValues == null) {
            propertyValues = new HashMap();
        }
        return propertyValues;
    }

    /**
     * INTERNAL:
     *
     * @param property
     * @param value
     */
    public void setInstanceProperty(Property property, Object value) {
        if (property.equals(SDOConstants.JAVA_CLASS_PROPERTY) && value instanceof String) {
            setInstanceClassName((String)value);
        }
        getPropertyValues().put(property, value);
    }

    /**
      * INTERNAL:
      */
    public SDOProperty getChangeSummaryProperty() {
        return changeSummaryProperty;
    }

    /**
     * INTERNAL:
     */
    public SDOProperty[] getPropertiesArray() {
        if ((allPropertiesArr == null) || (allPropertiesArr.length != getProperties().size())) {
            List l = getProperties();
            int s = (l == null) ? 0 : l.size();
            if (s > 0) {
                allPropertiesArr = (SDOProperty[])l.toArray(new SDOProperty[s]);
            } else {
                // initialize an empty array
                allPropertiesArr = new SDOProperty[0];
            }
        }
        return allPropertiesArr;
    }

    /**
      * INTERNAL:
      */
    public void setSubTypes(List subTypesList) {
        subTypes = subTypesList;
    }

    /**
      * INTERNAL:
      */
    public List getSubTypes() {
        if (subTypes == null) {
            subTypes = new ArrayList();
        }
        return subTypes;
    }

    /**
     * INTERNAL:
     * Provide a means to determine if this type has sub types without causing the sub types property to be initialized.
     */
    public boolean isBaseType() {
        return !(null == subTypes || subTypes.isEmpty());
    }

    private void updateIndices(int insertPosition, Property property) {
        int declaredSize = getDeclaredProperties().size();
        SDOProperty nextProp = null;
        for (int i = 0; i < declaredSize; i++) {
            nextProp = (SDOProperty)getDeclaredProperties().get(i);
            nextProp.incrementIndexInType();
        }
        getProperties().add(insertPosition, property);
        if(isBaseType()) {
            int subTypesSize = getSubTypes().size();

            SDOType nextSubType = null;
            for (int i = 0; i < subTypesSize; i++) {
                nextSubType = (SDOType)getSubTypes().get(i);
                nextSubType.updateIndices(insertPosition, property);
            }
        }
    }

    /**
      * INTERNAL:
      */
    public void setXsdType(QName xsdTypeQName) {
        xsdType = xsdTypeQName;
    }

    /**
      * INTERNAL:
      */
    public QName getXsdType() {
        return xsdType;
    }

    /**
      * INTERNAL:
      */
    public void setFinalized(boolean bFinalized) {
        finalized = bFinalized;
    }

    /**
      * INTERNAL:
      */
    public boolean isFinalized() {
        return finalized;
    }

    /**
      * INTERNAL:
      */
    public void setNonFinalizedReferencingProps(List nonFinalizedReferencingProps) {
        this.nonFinalizedReferencingProps = nonFinalizedReferencingProps;
    }

    /**
      * INTERNAL:
      */
    public List getNonFinalizedReferencingProps() {
        if (nonFinalizedReferencingProps == null) {
            nonFinalizedReferencingProps = new ArrayList();
        }
        return nonFinalizedReferencingProps;
    }

    /**
      * INTERNAL:
      */
    public void setNonFinalizedMappingURIs(List nonFinalizedMappingURIsList) {
        nonFinalizedMappingURIs = nonFinalizedMappingURIsList;
    }

    /**
      * INTERNAL:
      */
    public List getNonFinalizedMappingURIs() {
        if (nonFinalizedMappingURIs == null) {
            nonFinalizedMappingURIs = new ArrayList();
        }
        return nonFinalizedMappingURIs;
    }

    /**
      * INTERNAL:
      */
    public void setAppInfoElements(List appInfoElementsList) {
        appInfoElements = appInfoElementsList;
    }

    /**
      * INTERNAL:
      */
    public List getAppInfoElements() {
        return appInfoElements;
    }

    /**
      * INTERNAL:
      */
    public Map getAppInfoMap() {
        if (appInfoMap == null) {
            appInfoMap = ((SDOXSDHelper)aHelperContext.getXSDHelper()).buildAppInfoMap(appInfoElements);
        }
        return appInfoMap;
    }

    /**
     * INTERNAL:
     * Return the wrapped initial value for the primitive numeric (when not defined)
     * See p.45 of Java Spec 4th edition.
     * See p.85 Sect 9.3 of the SDO Spec.
     * @return aDefault Object (primitive numerics) or null (DataObjects, String, Lists)
     */
    public Object getPseudoDefault() {
        return pseudoDefault;
    }

    /**
     * INTERNAL:
     * Set an Object wrapper around primitive numeric types
     * @param anObject
     */
    public void setPseudoDefault(Object anObject) {
        pseudoDefault = anObject;
    }

    /**
     * Return the HelperContext object associated with this type.
     * For example, the typeHelper associated with the returned HelperContext would contain this type
     */
    public HelperContext getHelperContext(){
      return aHelperContext;
    }

    public boolean isChangeSummaryType() {
        return false;
    }

    public boolean isDataObjectType() {
        return false;
    }

    public boolean isTypeType() {
        return false;
    }

    public boolean isOpenSequencedType() {
        return false;
    }

    public boolean isWrapperType() {
        return false;
    }

    public static class TypeInstantiationPolicy extends InstantiationPolicy {

        SDOType sdoType;

        public TypeInstantiationPolicy(SDOType type) {
            sdoType = type;
        }

        @Override
        public Object buildNewInstance() throws DescriptorException {
            return sdoType.getHelperContext().getDataFactory().create(sdoType);
        }

    }

}
