/*
 * 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 = (Namespace)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 = (Namespace)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);
        }

    }

}
