/*
 * 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<String, String> 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<Namespace> generatedNamespaces = generatedSchema.getNamespaceResolver().getNamespaces();
        XMLDescriptor desc = ((XMLDescriptor)p.getDescriptor(Schema.class));
        for (int i = 0; i < generatedNamespaces.size(); i++) {
            Namespace next = 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<String, String> 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<Namespace> namespaces = generatedSchema.getNamespaceResolver().getNamespaces();
        for (int i = 0; i < namespaces.size(); i++) {
            Namespace next = 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 instanceof String) {
            String sdoJavaPrefix = getPrefixForURI(SDOConstants.SDOJAVA_URL);
            QName qname = new QName(SDOConstants.SDOJAVA_URL, SDOConstants.SDOJAVA_INSTANCECLASS, sdoJavaPrefix);
            simpleType.getAttributesMap().put(qname, (String) 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 = 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());

        Element 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;
    }
}
