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

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

import commonj.sdo.Property;
import commonj.sdo.Type;
import commonj.sdo.helper.HelperContext;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject;
import org.eclipse.persistence.internal.oxm.schema.model.*;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.platform.DOMPlatform;
import org.eclipse.persistence.sessions.Project;

/**
 * <p><b>Purpose</b> SDOSchemaGenerator generates an XSD (returned as a String)
 * from a list of SDO Type objects. Populates an org.eclipse.persistence.internal.oxm.schema.model.Schema
 * object and makes use of org.eclipse.persistence.internal.oxm.schema.SchemaModelProject to marshal
 * the Schema Object to XML.
 * @see commonj.sdo.helper.XSDHelper
 */
public class SDOSchemaGenerator {
    private Map namespaceToSchemaLocation;
    private SchemaLocationResolver schemaLocationResolver;
    private List allTypes;
    private Schema generatedSchema;

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

    public SDOSchemaGenerator(HelperContext aContext) {
        aHelperContext = aContext;
    }

    /**
     * <p>Method to generate an XSD. Note the following:<ul>
     * <li> All types must have same URI
     * <li> Referenced types in same URI will also be generated in schema
     * <li> Includes will never be generated
     * <li> Imports will be generated for referenced types in other URIs
     * </ul>
     * @param types The list of commonj.sdo.Type objects to generate the XSD from
     * @param aSchemaLocationResolver implementation of the org.eclipse.persistence.sdo.helper.SchemaLocationResolver interface
     * used for getting the value of the schemaLocation attribute of generated imports and includes
     * @return String The generated XSD.
     */
    public String generate(List types, SchemaLocationResolver aSchemaLocationResolver) {
        schemaLocationResolver = aSchemaLocationResolver;
        if ((types == null) || (types.size() == 0)) {
            throw new IllegalArgumentException("No Schema was generated from null or empty list of types.");
        }

        String uri = null;
        Type firstType = (Type)types.get(0);
        uri = firstType.getURI();

        allTypes = types;
        generateSchema(uri, types);

        //Now we have a built schema model
        Project p = new SchemaModelProject();
        Vector generatedNamespaces = generatedSchema.getNamespaceResolver().getNamespaces();
        XMLDescriptor desc = ((XMLDescriptor)p.getDescriptor(Schema.class));
        for (int i = 0; i < generatedNamespaces.size(); i++) {
            Namespace next = (Namespace)generatedNamespaces.get(i);
            desc.getNamespaceResolver().put(next.getPrefix(), next.getNamespaceURI());

            if (next.getNamespaceURI().equals(SDOConstants.SDO_URL) || next.getNamespaceURI().equals(SDOConstants.SDOXML_URL) || next.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) {
                if (!importExists(generatedSchema.getImports(), next.getNamespaceURI())) {
                    Import theImport = new Import();
                    theImport.setNamespace(next.getNamespaceURI());
                    String schemaLocation = "classpath:/xml/";
                    String customLocation = null;
                    if (next.getNamespaceURI().equals(SDOConstants.SDO_URL)) {
                        if(schemaLocationResolver != null) {
                            customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, SDOConstants.SDO_BOOLEAN);
                        }
                        if(customLocation != null) {
                            schemaLocation = customLocation;
                        } else {
                            schemaLocation += "sdoModel.xsd";
                        }
                    } else if (next.getNamespaceURI().equals(SDOConstants.SDOXML_URL)) {
                        if(schemaLocationResolver != null) {
                            customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, new SDOType(SDOConstants.SDOXML_URL, "XMLInfo"));
                        }
                        if(customLocation != null) {
                            schemaLocation = customLocation;
                        } else {
                            schemaLocation += "sdoXML.xsd";
                        }
                    } else if (next.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) {
                        if(schemaLocationResolver != null) {
                            customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, SDOConstants.SDO_BOOLEANOBJECT);
                        }
                        if(customLocation != null) {
                            schemaLocation = customLocation;
                        } else {
                            schemaLocation += "sdoJava.xsd";
                        }
                    }
                    theImport.setSchemaLocation(schemaLocation);
                    generatedSchema.getImports().add(theImport);
                }
            }
        }

        XMLLogin login = new XMLLogin();
        login.setDatasourcePlatform(new DOMPlatform());
        p.setDatasourceLogin(login);

        XMLContext context = new XMLContext(p);

        XMLMarshaller marshaller = context.createMarshaller();

        StringWriter generatedSchemaWriter = new StringWriter();
        marshaller.marshal(generatedSchema, generatedSchemaWriter);
        return generatedSchemaWriter.toString();
    }

    /**
     * <p>Method to generate an XSD. Note the following:<ul>
     * <li> All types must have same URI
     * <li> Referenced types in same URI will also be generated in schema
     * <li> Includes will never be generated
     * <li> Imports will be generated for referenced types in other URIs
     * </ul>
     * @param types The list of commonj.sdo.Type objects to generate the XSD from
     * @param aNamespaceToSchemaLocation map of namespaces to schemaLocations
     * used for getting the value of the schemaLocation attribute of generated imports and includes
     * @return String The generated XSD.
    */
    public String generate(List types, Map aNamespaceToSchemaLocation) {
        if ((types == null) || (types.size() == 0)) {
            throw new IllegalArgumentException("No Schema was generated from null or empty list of types.");
        }

        String uri = null;
        namespaceToSchemaLocation = aNamespaceToSchemaLocation;

        Type firstType = (Type)types.get(0);
        if (firstType == null) {
            throw new IllegalArgumentException("No Schema was generated from a list of types containing null elements");
        } else {
            uri = firstType.getURI();
        }
        allTypes = types;
        generateSchema(uri, types);

        //Now we have a built schema model
        Project p = new SchemaModelProject();
        Vector namespaces = generatedSchema.getNamespaceResolver().getNamespaces();
        for (int i = 0; i < namespaces.size(); i++) {
            Namespace next = (Namespace)namespaces.get(i);
            ((XMLDescriptor)p.getDescriptor(Schema.class)).getNamespaceResolver().put(next.getPrefix(), next.getNamespaceURI());
        }

        XMLLogin login = new XMLLogin();
        login.setDatasourcePlatform(new DOMPlatform());
        p.setDatasourceLogin(login);
        XMLContext context = new XMLContext(p);
        XMLMarshaller marshaller = context.createMarshaller();

        StringWriter generatedSchemaWriter = new StringWriter();
        marshaller.marshal(generatedSchema, generatedSchemaWriter);
        return generatedSchemaWriter.toString();
    }

    private void generateSchema(String uri, List typesWithSameUri) {
        generatedSchema = new Schema();
        generatedSchema.setTargetNamespace(uri);
        generatedSchema.setDefaultNamespace(uri);

        generatedSchema.setAttributeFormDefault(false);
        generatedSchema.setElementFormDefault(true);
        String javaPackage = null;

        for (int i = 0; i < typesWithSameUri.size(); i++) {
            SDOType nextType = (SDOType)typesWithSameUri.get(i);
            if (nextType.isSubType()) {
                //A schema can not be generated because the following type has more than 1 base type + type
            }

            if (!nextType.isDataType()) {
                String fullName = nextType.getInstanceClassName();
                if (fullName != null) {
                    String nextPackage = null;

                    int lastDot = fullName.lastIndexOf('.');
                    if (lastDot != -1) {
                        nextPackage = fullName.substring(0, lastDot);
                    }

                    if (nextPackage != null) {
                        javaPackage = nextPackage;
                    }
                }
            }

            if (nextType.isDataType()) {
                //generate simple type
                SimpleType generatedType = generateSimpleType(nextType);
                generatedSchema.addTopLevelSimpleTypes(generatedType);
            } else {
                //generate complex type
                ComplexType generatedType = generateComplexType(nextType);
                generatedSchema.addTopLevelComplexTypes(generatedType);

                //generate global element for the complex type generated above
                Element element = buildElementForComplexType(generatedSchema, generatedType);
                if (element != null) {
                    generatedSchema.addTopLevelElement(element);
                }
            }
        }
        if (javaPackage != null) {
            getPrefixForURI(SDOConstants.SDOJAVA_URL);
            generatedSchema.getAttributesMap().put(SDOConstants.SDOJAVA_PACKAGE_QNAME, javaPackage);
        }
    }

    private SimpleType generateSimpleType(Type type) {
        SDOType sdoType = (SDOType) type;
        SimpleType simpleType = new SimpleType();

        String xsdLocalName = sdoType.getXsdLocalName();
        if (xsdLocalName != null) {
            simpleType.setName(xsdLocalName);
        } else {
            simpleType.setName(sdoType.getName());
        }

        if ((sdoType.getAppInfoElements() != null) && (sdoType.getAppInfoElements().size() > 0)) {
            Annotation annotation = new Annotation();

            annotation.setAppInfo(sdoType.getAppInfoElements());
            simpleType.setAnnotation(annotation);
        }

        if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoType.getName()))) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix);
            simpleType.getAttributesMap().put(qname, sdoType.getName());
        }

        if ((sdoType.getAliasNames() != null) && (sdoType.getAliasNames().size() > 0)) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            String aliasNamesString = buildAliasNameString(sdoType.getAliasNames());
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix);
            simpleType.getAttributesMap().put(qname, aliasNamesString);
        }

        Object value = sdoType.get(SDOConstants.JAVA_CLASS_PROPERTY);
        if ((value != null) && value instanceof String) {
            String sdoJavaPrefix = getPrefixForURI(SDOConstants.SDOJAVA_URL);
            QName qname = new QName(SDOConstants.SDOJAVA_URL, SDOConstants.SDOJAVA_INSTANCECLASS, sdoJavaPrefix);
            simpleType.getAttributesMap().put(qname, value);
        }

        SDOType baseType = null;
        if (sdoType.isSubType()) {
            baseType = (SDOType) sdoType.getBaseTypes().get(0);
        }

        if (baseType != null) {
            Restriction restriction = new Restriction();
            addTypeToListIfNeeded(sdoType, baseType);
            QName schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(baseType);

            if (schemaType != null) {
                String prefix = getPrefixStringForURI(schemaType.getNamespaceURI());
                restriction.setBaseType(prefix + schemaType.getLocalPart());
            } else {
                String prefix = getPrefixStringForURI(baseType.getURI());
                restriction.setBaseType(prefix + baseType.getName());
            }
            simpleType.setRestriction(restriction);
        }

        return simpleType;
    }

    private ComplexType generateComplexType(Type type) {
        SDOType sdoType = (SDOType) type;
        ComplexType complexType = new ComplexType();
        String xsdLocalName = sdoType.getXsdLocalName();
        if (xsdLocalName != null) {
            complexType.setName(xsdLocalName);
        } else {
            complexType.setName(sdoType.getName());
        }

        if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoType.getName()))) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix);
            complexType.getAttributesMap().put(qname, sdoType.getName());
        }

        complexType.setAbstractValue(sdoType.isAbstract());
        if ((sdoType.getAppInfoElements() != null) && (sdoType.getAppInfoElements().size() > 0)) {
            Annotation annotation = new Annotation();
            annotation.setAppInfo(sdoType.getAppInfoElements());
            complexType.setAnnotation(annotation);
        }

        if ((sdoType.getAliasNames() != null) && (sdoType.getAliasNames().size() > 0)) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            String aliasNamesString = buildAliasNameString(sdoType.getAliasNames());

            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix);
            complexType.getAttributesMap().put(qname, aliasNamesString);
        }

        complexType.setMixed(sdoType.isSequenced());
        Type baseType = null;
        if (sdoType.isSubType()) {
            baseType = (Type)sdoType.getBaseTypes().get(0);

            //baseName = base.getName();
            //String baseURI = ((Type)type.getBaseTypes().get(0)).getURI();
            //if (baseURI != type.getURI()) {
            //need to add something  to track referenced uris for includes/imports
            //}
        }

        if (baseType != null) {
            addTypeToListIfNeeded(sdoType, baseType);
            Extension extension = new Extension();
            QName schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(baseType);

            //fixed below for bug5893546
            if (schemaType != null) {
                extension.setBaseType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart());
            } else if ((baseType.getURI() == null) || (baseType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) {
                extension.setBaseType(baseType.getName());
            } else {
                extension.setBaseType(getPrefixStringForURI(baseType.getURI()) + baseType.getName());
            }

            buildElementsAndAttributes(extension, sdoType);
            ComplexContent complexContent = new ComplexContent();
            complexContent.setExtension(extension);
            complexType.setComplexContent(complexContent);
            return complexType;
        }

        buildElementsAndAttributes(complexType, sdoType);

        return complexType;
    }

    private void buildElementsAndAttributes(Object owner, Type type) {
        List properties = type.getDeclaredProperties();
        NestedParticle nestedParticle = null;

        if ((properties == null) || (properties.size() == 0)) {
            if (type.isOpen()) {
                nestedParticle = new Sequence();
            } else {
                return;
            }
        } else {
            if (type.isSequenced()) {
                nestedParticle = new Choice();
                nestedParticle.setMaxOccurs(Occurs.UNBOUNDED);
            } else {
                nestedParticle = new Sequence();
            }
        }
        for (int i = 0; i < properties.size(); i++) {
            Property nextProperty = (Property)properties.get(i);

            if (aHelperContext.getXSDHelper().isElement(nextProperty)) {
                Element elem = buildElement(nextProperty, nestedParticle);
                nestedParticle.addElement(elem);
            } else if (aHelperContext.getXSDHelper().isAttribute(nextProperty)) {
                Attribute attr = buildAttribute(nextProperty);
                if (owner instanceof ComplexType) {
                    ((ComplexType)owner).getOrderedAttributes().add(attr);
                } else if (owner instanceof Extension) {
                    ((Extension)owner).getOrderedAttributes().add(attr);
                }
            }
        }
        if (type.isOpen()) {
            Any any = new Any();
            any.setProcessContents(AnyAttribute.LAX);
            any.setMaxOccurs(Occurs.UNBOUNDED);
            nestedParticle.addAny(any);

            AnyAttribute anyAttribute = new AnyAttribute();
            anyAttribute.setProcessContents(AnyAttribute.LAX);
            if (owner instanceof ComplexType) {
                ((ComplexType)owner).setAnyAttribute(anyAttribute);
            }
        }

        if (!nestedParticle.isEmpty()) {
            if (owner instanceof ComplexType) {
                ((ComplexType)owner).setTypeDefParticle((TypeDefParticle)nestedParticle);
                //baseType.getAttributes().add(attr);
            } else if (owner instanceof Extension) {
                ((Extension)owner).setTypeDefParticle((TypeDefParticle)nestedParticle);
            }
        }
    }

    private void addSimpleComponentAnnotations(SimpleComponent sc, Property property, boolean element) {
        SDOProperty sdoProperty = (SDOProperty) property;
        if (sdoProperty.isReadOnly()) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_READONLY, sdoXmlPrefix);
            sc.getAttributesMap().put(qname, "true");
        }
        if (sdoProperty.hasAliasNames()) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            String aliasNamesString = buildAliasNameString(sdoProperty.getAliasNames());
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix);
            sc.getAttributesMap().put(qname, aliasNamesString);
        }

        String xsdLocalName = sdoProperty.getXsdLocalName();

        if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoProperty.getName()))) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix);
            sc.getAttributesMap().put(qname, sdoProperty.getName());
        }

        if ((element && !sdoProperty.isContainment() && !sdoProperty.getType().isDataType()) || (!element && !sdoProperty.getType().isDataType())) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            String uri = sdoProperty.getType().getURI();
            String value = sdoProperty.getType().getName();
            if (uri != null) {
                String typePrefix = getPrefixForURI(uri);
                if (typePrefix != null) {
                    value = typePrefix + ":" + value;
                }
            }
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_PROPERTYTYPE, sdoXmlPrefix);
            sc.getAttributesMap().put(qname, value);
        }

        if (sdoProperty.getOpposite() != null) {
            String value = sdoProperty.getOpposite().getName();
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_OPPOSITEPROPERTY, sdoXmlPrefix);
            sc.getAttributesMap().put(qname, value);
        }

        Property xmlDataTypeProperty = aHelperContext.getTypeHelper().getOpenContentProperty(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_DATATYPE);
        Type dataType = (Type) sdoProperty.get(xmlDataTypeProperty);
        if (dataType == null) {
            dataType = getAutomaticDataTypeForType(sdoProperty.getType());
        }
        if (dataType != null && !shouldSuppressDataType(sdoProperty, dataType)) {
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_DATATYPE, sdoXmlPrefix);
            String dataTypeString = dataType.getName();
            if (dataType.getURI() != null) {
                String dataTypePrefix = getPrefixForURI(dataType.getURI());
                if (dataTypePrefix != null) {
                    dataTypeString = dataTypePrefix + ":" + dataTypeString;
                }
            }
            sc.getAttributesMap().put(qname, dataTypeString);
        }

        if (element) {
            String mimeType = (String) sdoProperty.get(SDOConstants.MIME_TYPE_PROPERTY);
            if (mimeType != null) {
                String prefix = getPrefixForURI(SDOConstants.MIMETYPE_URL);
                QName qname = new QName(SDOConstants.XML_MIME_TYPE_QNAME.getNamespaceURI(), SDOConstants.XML_MIME_TYPE_QNAME.getLocalPart(), prefix);
                sc.getAttributesMap().put(qname, mimeType);
            } else {
                mimeType = (String) sdoProperty.get(SDOConstants.MIME_TYPE_PROPERTY_PROPERTY);
                if (mimeType != null) {
                    String prefix = getPrefixForURI(SDOConstants.ORACLE_SDO_URL);
                    QName qname = new QName(SDOConstants.XML_MIME_TYPE_PROPERTY_QNAME.getNamespaceURI(), SDOConstants.XML_MIME_TYPE_PROPERTY_QNAME.getLocalPart(), prefix);
                    sc.getAttributesMap().put(qname, mimeType);
                }
            }
        }
    }

    private boolean shouldSuppressDataType(SDOProperty prop, Type dataType){
        if(prop.isNullable()){
            SDOType type = prop.getType();
            if(dataType == SDOConstants.SDO_BOOLEANOBJECT && (type == SDOConstants.SDO_BOOLEAN || type == SDOConstants.SDO_BOOLEANOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_BYTEOBJECT && (type == SDOConstants.SDO_BYTE || type == SDOConstants.SDO_BYTEOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_CHARACTEROBJECT && (type == SDOConstants.SDO_CHARACTER || type == SDOConstants.SDO_CHARACTEROBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_DOUBLEOBJECT && (type == SDOConstants.SDO_DOUBLE || type == SDOConstants.SDO_DOUBLEOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_FLOATOBJECT && (type == SDOConstants.SDO_FLOAT || type == SDOConstants.SDO_FLOATOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_INTOBJECT && (type == SDOConstants.SDO_INT || type == SDOConstants.SDO_INTOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_LONGOBJECT && (type == SDOConstants.SDO_LONG || type == SDOConstants.SDO_LONGOBJECT )){
                return true;
            }
            if(dataType == SDOConstants.SDO_SHORTOBJECT && (type == SDOConstants.SDO_SHORT || type == SDOConstants.SDO_SHORTOBJECT )){
                return true;
            }
        }
        return false;
    }

    private String buildAliasNameString(List<String> aliasNames) {
        StringBuilder aliasNamesStringBuilder = new StringBuilder();
        for (int i = 0, size = aliasNames.size(); i < size; i++) {
            aliasNamesStringBuilder.append(aliasNames.get(i));
            if (i < (size - 1)) {
                aliasNamesStringBuilder.append(' ');
            }
        }
        return aliasNamesStringBuilder.toString();
    }

    private Element buildElement(Property property, NestedParticle nestedParticle) {
        SDOProperty sdoProperty = (SDOProperty) property;
        Element elem = new Element();
        String xsdLocalName = sdoProperty.getXsdLocalName();
        if (xsdLocalName != null) {
            elem.setName(xsdLocalName);
        } else {
            elem.setName(sdoProperty.getName());
        }
        elem.setMinOccurs(Occurs.ZERO);
        elem.setNillable(sdoProperty.isNullable());
        if ((sdoProperty.getAppInfoElements() != null) && (sdoProperty.getAppInfoElements().size() > 0)) {
            Annotation annotation = new Annotation();
            annotation.setAppInfo(sdoProperty.getAppInfoElements());
            elem.setAnnotation(annotation);
        }

        // process default values that are defined in the schema (not via primitive numeric Object wrapped pseudo defaults)
        if (sdoProperty.isDefaultSet()) {
            if (!sdoProperty.isMany() && sdoProperty.getType().isDataType()) {
                XMLConversionManager xmlConversionManager = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getXmlConversionManager();
                elem.setDefaultValue(xmlConversionManager.convertObject(sdoProperty.getDefault(), ClassConstants.STRING, sdoProperty.getXsdType()));
            }

        }

        addSimpleComponentAnnotations(elem, sdoProperty, true);

        /*
         When containment is true, then DataObjects of that Type will appear as nested elements in an XML document.
        When containment is false and the property's type is a DataObject, a URI reference
        to the element containing the DataObject is used and an sdo:propertyType
        declaration records the target type. Values in XML documents will be of the form
        "#xpath" where the xpath is an SDO DataObject XPath subset. It is typical to
        customize the declaration to IDREF if the target element has an attribute with type
        customized to ID.

        [TYPE.NAME] is the type of the element. If property.type.dataType is true,
        [TYPE.NAME] is the name of the XSD built in SimpleType corresponding to
        property.type, where the prefix is for the xsd namespace. Otherwise,
        [TYPE.NAME] is property.type.name where the tns: prefix is determined by the
        namespace declaration for the Type's URI.
         */
        Type schemaSDOType = null;
        QName schemaType = sdoProperty.getXsdType();
        if (schemaType != null) {
            schemaSDOType = aHelperContext.getTypeHelper().getType(schemaType.getNamespaceURI(), schemaType.getLocalPart());

            if ((sdoProperty.getType() == SDOConstants.SDO_STRING) && (schemaSDOType != SDOConstants.SDO_STRING)) {
                String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
                QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_STRING_NAME, sdoXmlPrefix);
                elem.getAttributesMap().put(qname, "true");
            }
        }
        if (!sdoProperty.isContainment() && !sdoProperty.getType().isDataType()) {
            schemaType = SDOConstants.ANY_URI_QNAME;
        }

        Type propertyType = sdoProperty.getType();

        if (propertyType != null) {
            if (sdoProperty.getContainingType() != null) {
                addTypeToListIfNeeded(sdoProperty.getContainingType(), propertyType);
            }

            if (schemaType == null) {
                schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(propertyType);
            }

            //get url for prefix in namespace resolver and map sure it is added to the schema if necessary
            if (schemaType != null) {
                elem.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart());
                if (schemaSDOType != null) {
                    addTypeToListIfNeeded(sdoProperty.getContainingType(), schemaSDOType);
                }
            } else if ((propertyType.getURI() == null) || (propertyType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) {
                String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName();
                if (xsdTypeLocalName != null) {
                    elem.setType(xsdTypeLocalName);
                } else {
                    elem.setType(propertyType.getName());
                }
            } else {
                String nameString = null;
                String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName();
                if (xsdTypeLocalName != null) {
                    nameString = xsdTypeLocalName;
                } else {
                    nameString = propertyType.getName();
                }

                elem.setType(getPrefixStringForURI(propertyType.getURI()) + nameString);
            }
        } else {
            elem.setType("anyURI");
        }
        if (sdoProperty.isMany()) {
            elem.setMaxOccurs(Occurs.UNBOUNDED);
        } else if (nestedParticle.getMaxOccurs() == Occurs.UNBOUNDED) {
            //this means property.isMany==false and the owning sequence of choice is unbounded Jira SDO-3
            String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
            QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_MANY, sdoXmlPrefix);
            elem.getAttributesMap().put(qname, "false");
        }

        return elem;
    }

    private Attribute buildAttribute(Property property) {
        Attribute attr = new Attribute();
        String xsdLocalName = ((SDOProperty)property).getXsdLocalName();
        if (xsdLocalName != null) {
            attr.setName(xsdLocalName);
        } else {
            attr.setName(property.getName());
        }

        if ((((SDOProperty)property).getAppInfoElements() != null) && (((SDOProperty)property).getAppInfoElements().size() > 0)) {
            Annotation annotation = new Annotation();
            annotation.setAppInfo(((SDOProperty)property).getAppInfoElements());
            attr.setAnnotation(annotation);
        }

        // process default values that are defined in the schema (not via primitive numeric Object wrapped pseudo defaults)
        if (((SDOProperty)property).isDefaultSet()) {
            if (!property.isMany() && property.getType().isDataType()) {
                XMLConversionManager xmlConversionManager = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getXmlConversionManager();
                attr.setDefaultValue(xmlConversionManager.convertObject(property.getDefault(), ClassConstants.STRING, ((SDOProperty)property).getXsdType()));
            }
        }
        addSimpleComponentAnnotations(attr, property, false);

        Type propertyType = property.getType();
        QName schemaType = ((SDOProperty)property).getXsdType();

        if (schemaType != null) {
            Type schemaSDOType = aHelperContext.getTypeHelper().getType(schemaType.getNamespaceURI(), schemaType.getLocalPart());

            if ((property.getType() == SDOConstants.SDO_STRING) && (schemaSDOType != SDOConstants.SDO_STRING)) {
                String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL);
                QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_STRING_NAME, sdoXmlPrefix);
                attr.getAttributesMap().put(qname, "true");
            }
        }

        if (!property.getType().isDataType()) {
            schemaType = SDOConstants.ANY_URI_QNAME;
        }

        if (propertyType != null) {
            if (property.getContainingType() != null) {
                addTypeToListIfNeeded(property.getContainingType(), propertyType);
            }
            if (schemaType == null) {
                schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(propertyType);
            }
            if (schemaType != null) {
                attr.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart());
            } else if ((propertyType.getURI() == null) || (propertyType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) {
                String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName();
                if (xsdTypeLocalName != null) {
                    attr.setType(xsdTypeLocalName);
                } else {
                    attr.setType(propertyType.getName());
                }
            } else {
                String nameString = null;
                String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName();

                if (xsdTypeLocalName != null) {
                    nameString = xsdTypeLocalName;
                } else {
                    nameString = propertyType.getName();
                }

                attr.setType(getPrefixStringForURI(propertyType.getURI()) + nameString);
            }

            //get url for prefix in namespace resolver and map sure it is added to the schema if necessary

            /*
            if (schemaType != null) {
            attr.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart());
            } else {
            attr.setType(propertyType.getName());
            }*/
        }

        return attr;
    }

    private void addTypeToListIfNeeded(Type sourceType, Type targetType) {
        if ((targetType.getURI() != null) && !targetType.getURI().equals(SDOConstants.SDO_URL) && !targetType.getURI().equals(SDOConstants.SDOJAVA_URL) && !targetType.getURI().equals(SDOConstants.SDOXML_URL)) {
            boolean alreadyGenerated = allTypes.contains(targetType);
            String schemaLocation = null;
            if (namespaceToSchemaLocation != null) {
                schemaLocation = (String)namespaceToSchemaLocation.get(targetType.getURI());

                if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) {
                    if (!alreadyGenerated) {
                        allTypes.add(targetType);
                    }
                } else {
                    if(!importExists(generatedSchema.getImports(), schemaLocation)){
                        Import theImport = new Import();
                        theImport.setSchemaLocation(schemaLocation);
                        theImport.setNamespace(targetType.getURI());
                        generatedSchema.getImports().add(theImport);
                    }
                }
            } else if (schemaLocationResolver != null) {
                schemaLocation = schemaLocationResolver.resolveSchemaLocation(sourceType, targetType);
                if (schemaLocation != null) {
                    if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) {
                        if(!importExists(generatedSchema.getIncludes(), schemaLocation)){
                            Include include = new Include();
                            include.setSchemaLocation(schemaLocation);
                            generatedSchema.getIncludes().add(include);
                            // 20060713 remove type from List of types when adding an include
                            allTypes.remove(targetType);
                        }
                    } else {
                        if(!importExists(generatedSchema.getImports(), schemaLocation)){
                            Import theImport = new Import();
                            theImport.setSchemaLocation(schemaLocation);
                            theImport.setNamespace(targetType.getURI());
                            generatedSchema.getImports().add(theImport);
                        }
                    }
                } else {
                    if (!alreadyGenerated) {
                        //we can #1 add to list of allTypes or #2 make an appropriate include
                        if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) {
                            allTypes.add(targetType);
                        }
                    }
                }
            } else {
                if (!alreadyGenerated) {
                    //we can #1 add to list of allTypes or #2 make an appropriate include
                    if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) {
                        allTypes.add(targetType);
                    }
                }
            }
        }
    }

    private Element buildElementForComplexType(Schema schema, ComplexType type) {
        Element elem = new Element();
        String name = type.getName();
        if (name == null) {
            return null;
        }
        String lowerName = Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length());

        Object exists = schema.getTopLevelElements().get(lowerName);
        if (exists != null) {
            elem.setName(name);
        } else {
            elem.setName(lowerName);
        }

        elem.setType(type.getName());

        return elem;
    }

    private String getPrefixStringForURI(String uri) {
        if(null == uri || SDOConstants.EMPTY_STRING.equals(uri)) {
            return SDOConstants.EMPTY_STRING;
        }
        String prefix = getPrefixForURI(uri);
        if (prefix == null) {
            return SDOConstants.EMPTY_STRING;
        } else {
            return prefix + ":";
        }
    }

    private String getPrefixForURI(String uri) {
        String prefix = null;
        if (uri.equals(generatedSchema.getTargetNamespace())) {
            return null;
        } else if (uri.equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
            return XMLConstants.SCHEMA_PREFIX;
        } else if (uri.equals(SDOConstants.SDO_URL)) {
            prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri);
            if (prefix == null) {
                prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDO_PREFIX);
                generatedSchema.getNamespaceResolver().put(prefix, uri);
            }
        } else if (uri.equals(SDOConstants.SDOJAVA_URL)) {
            prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri);
            if (prefix == null) {
                prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDOJAVA_PREFIX);
                generatedSchema.getNamespaceResolver().put(prefix, uri);
            }
        } else if (uri.equals(SDOConstants.SDOXML_URL)) {
            prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri);
            if (prefix == null) {
                prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDOXML_PREFIX);
                generatedSchema.getNamespaceResolver().put(prefix, uri);
            }
        }
        if (prefix == null) {
            prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri);
        }
        if (prefix != null) {
            return prefix;
        } else {
            String generatedPrefix = generatedSchema.getNamespaceResolver().generatePrefix();
            generatedSchema.getNamespaceResolver().put(generatedPrefix, uri);
            return generatedPrefix;
        }
    }

    private Type getAutomaticDataTypeForType(Type theType) {
        // Section 10.1 of the spec
        //For the SDO Java Types, the corresponding base SDO Type is used. For the SDO Java
        // Types, and for SDO Date, an sdo:dataType annotation is generated on the XML attribute
        // or element referring to the SDO Type.
        if (theType == SDOConstants.SDO_BOOLEANOBJECT) {
            return SDOConstants.SDO_BOOLEANOBJECT;
        } else if (theType == SDOConstants.SDO_BYTEOBJECT) {
            return SDOConstants.SDO_BYTEOBJECT;
        } else if (theType == SDOConstants.SDO_CHARACTEROBJECT) {
            return SDOConstants.SDO_CHARACTEROBJECT;
        } else if (theType == SDOConstants.SDO_DOUBLEOBJECT) {
            return SDOConstants.SDO_DOUBLEOBJECT;
        } else if (theType == SDOConstants.SDO_INTOBJECT) {
            return SDOConstants.SDO_INTOBJECT;
        } else if (theType == SDOConstants.SDO_FLOATOBJECT) {
            return SDOConstants.SDO_FLOATOBJECT;
        } else if (theType == SDOConstants.SDO_LONGOBJECT) {
            return SDOConstants.SDO_LONGOBJECT;
        } else if (theType == SDOConstants.SDO_SHORTOBJECT) {
            return SDOConstants.SDO_SHORTOBJECT;
        } else if (theType == SDOConstants.SDO_DATE) {
            return SDOConstants.SDO_DATE;
        } else if (theType == SDOConstants.SDO_DATETIME) {
            return SDOConstants.SDO_DATETIME;
        }
        return null;
    }

     private boolean importExists(java.util.List imports, String schemaName){
        for(int i=0;i < imports.size();i++){
            //Cast to the parent class, since this could be an Include or an Import
            Include nextImport = (Include)imports.get(i);
            if(nextImport.getSchemaLocation() != null && nextImport.getSchemaLocation().equals(schemaName)){
                return true;
            }
        }
        return false;
    }
}
