/*
 * Copyright (c) 1998, 2020 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:
//     Matt MacIvor - 2.5.1 - Initial Implementation
package org.eclipse.persistence.internal.jaxb.json.schema;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.jaxb.json.schema.model.JsonSchema;
import org.eclipse.persistence.internal.jaxb.json.schema.model.JsonType;
import org.eclipse.persistence.internal.jaxb.json.schema.model.Property;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.QNameInheritancePolicy;
import org.eclipse.persistence.internal.oxm.XMLBinaryDataHelper;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.InverseReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.oxm.record.namespaces.MapNamespacePrefixMapper;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.NamespacePrefixMapper;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
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.XMLAnyObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentMapping;
import org.eclipse.persistence.sessions.Project;

/**
 * INTERNAL:
 * <p><b>Purpose:</b> This class generates an instance of JsonSchema based on an EclipseLink
 * project and given a root class. The descriptor for the root class' mappings are traversed and
 * the associated schema artifacts are created.
 *
 */
public class JsonSchemaGenerator {
    Project project;
    JsonSchema schema;
    Map contextProperties;
    String attributePrefix;
    Class rootClass;
    boolean namespaceAware;
    NamespaceResolver resolver;
    String NAMESPACE_SEPARATOR = ".";
    NamespacePrefixMapper prefixMapper = null;
    Property[] xopIncludeProp = null;
    XMLContext xmlContext;
    Property rootProperty = null;
    private JAXBContext jaxbContext;

    private static String DEFINITION_PATH="#/definitions";

    private static HashMap<Class, JsonType> javaTypeToJsonType;


    public JsonSchemaGenerator(JAXBContext jaxbContext, Map properties) {
        //this.project = project;
        this.xmlContext = jaxbContext.getXMLContext();
        this.jaxbContext = jaxbContext;
        this.contextProperties = properties;
        if(properties != null) {
            attributePrefix = (String)properties.get(JAXBContextProperties.JSON_ATTRIBUTE_PREFIX);
            Object prefixMapperValue = properties.get(JAXBContextProperties.NAMESPACE_PREFIX_MAPPER);
            if(prefixMapperValue != null) {
                if(prefixMapperValue instanceof Map){
                    prefixMapper = new MapNamespacePrefixMapper((Map)prefixMapperValue);
                }else{
                    prefixMapper = (NamespacePrefixMapper)prefixMapperValue;
                }
            }
            if(prefixMapper != null) {
                //check for customer separator
                String namespaceSeparator = (String) properties.get(JAXBContextProperties.JSON_NAMESPACE_SEPARATOR);
                if(namespaceSeparator != null) {
                    this.NAMESPACE_SEPARATOR = namespaceSeparator;
                }
            }
        }
    }

    public JsonSchema generateSchema(Class rootClass) {
        this.rootClass = rootClass;
        schema = new JsonSchema();
        schema.setTitle(rootClass.getName());

        if(rootClass.isEnum()) {
            Class generatedWrapper = jaxbContext.getClassToGeneratedClasses().get(rootClass.getName());
            if(generatedWrapper != null) {
                rootClass = generatedWrapper;
            } else {
                schema.setType(JsonType.STRING);
                return schema;
            }
        }
        //Check for simple type
        JsonType rootType = getJsonTypeForJavaType(rootClass);
        if(rootType != JsonType.OBJECT) {
            if(rootType == JsonType.BINARYTYPE) {
                schema.setAnyOf(getXopIncludeProperties());
                return schema;
            } else {
                schema.setType(rootType);
                return schema;
            }
        }

        Map<String, Property> properties = null;
        //Check for root level list or array
        if(rootClass.isArray() || isCollection(rootClass)) {
            schema.setType(JsonType.ARRAY);
            schema.setItems(new Property());
            Class itemType = Object.class;

            if(rootClass.isArray()) {
                itemType = rootClass.getComponentType();
            } else {
                Type pType = rootClass.getGenericSuperclass();
                if(pType instanceof ParameterizedType) {
                    itemType = (Class)((ParameterizedType)pType).getActualTypeArguments()[0];
                }
            }
            rootType = getJsonTypeForJavaType(itemType);
            schema.getItems().setType(rootType);
            if(rootType != JsonType.OBJECT) {
                return schema;
            }
            rootClass = itemType;
            properties = schema.getItems().getProperties();

        } else {
            schema.setType(JsonType.OBJECT);
            properties = schema.getProperties();
        }
        this.project = this.xmlContext.getSession(rootClass).getProject();

        XMLDescriptor descriptor = (XMLDescriptor)project.getDescriptor(rootClass);

        Boolean includeRoot = Boolean.TRUE;
        if(contextProperties != null) {
            includeRoot = (Boolean) this.contextProperties.get(JAXBContextProperties.JSON_INCLUDE_ROOT);
            if(includeRoot == null) {
                includeRoot = Boolean.TRUE;
            }
        }
        if(Boolean.TRUE.equals(includeRoot)) {
            XMLField field = descriptor.getDefaultRootElementField();
            if(field != null) {
                rootProperty = new Property();
                rootProperty.setType(JsonType.OBJECT);
                rootProperty.setName(getNameForFragment(field.getXPathFragment()));
                properties.put(rootProperty.getName(), rootProperty);
                properties = rootProperty.getProperties();
            }
        }

        boolean allowsAdditionalProperties = hasAnyMappings(descriptor);
        if(descriptor.hasInheritance()) {
            //handle inheritence
            //schema.setAnyOf(new Property[descriptor.getInheritancePolicy().getAllChildDescriptors().size()]);
            List<ClassDescriptor> descriptors = this.getAllDescriptorsForInheritance(descriptor);
            Property[] props = new Property[descriptors.size()];
            for(int i = 0; i < props.length; i++) {
                XMLDescriptor nextDescriptor = (XMLDescriptor)descriptors.get(i);

                Property ref = new Property();
                ref.setRef(getReferenceForDescriptor(nextDescriptor, true));
                props[i] = ref;
            }
            if(rootProperty != null) {
                rootProperty.setAnyOf(props);
                rootProperty.setProperties(null);
                rootProperty.setType(null);
                rootProperty.setAdditionalProperties(null);
                rootProperty.setAdditionalProperties(null);
            } else {
                this.schema.setAnyOf(props);
                this.schema.setProperties(null);
                this.schema.setType(null);
                this.schema.setAdditionalProperties(null);
            }
        } else {
            JsonType type = populateProperties(properties, descriptor);
            if(type != null) {
                if(type == JsonType.BINARYTYPE) {
                    if(rootProperty != null) {
                        rootProperty.setAnyOf(getXopIncludeProperties());
                        rootProperty.setProperties(null);
                        rootProperty.setAdditionalProperties(null);
                        rootProperty.setType(null);
                    } else {
                        this.schema.setAnyOf(getXopIncludeProperties());
                        this.schema.setProperties(null);
                        this.schema.setType(null);
                        this.schema.setAdditionalProperties(null);
                    }
                } else if(type == JsonType.ENUMTYPE) {
                    if(rootProperty != null) {
                        rootProperty.setType(JsonType.STRING);
                        rootProperty.setProperties(null);
                        rootProperty.setEnumeration(getEnumeration(descriptor));
                    } else {
                        this.schema.setType(JsonType.STRING);
                        this.schema.setProperties(null);
                        this.schema.setEnumeration(getEnumeration(descriptor));
                }
                } else {
                    if(rootProperty != null) {
                        rootProperty.setType(type);
                    } else {
                        schema.setType(type);
                    }
                }
            } else {
                if(rootProperty != null) {
                    rootProperty.setAdditionalProperties(allowsAdditionalProperties);
                } else {
                    this.schema.setAdditionalProperties(allowsAdditionalProperties);
                }
            }
        }
        return schema;
    }

    private List<String> getEnumeration(XMLDescriptor desc) {
        return getEnumeration(getTextMapping(desc));
    }

    private List<String> getEnumeration(DatabaseMapping textMapping) {
        JAXBEnumTypeConverter converter = null;
        if(textMapping.isAbstractDirectMapping()) {
            converter = (JAXBEnumTypeConverter) ((DirectMapping)textMapping).getConverter();
        } else if(textMapping.isAbstractCompositeDirectCollectionMapping()) {
            converter = (JAXBEnumTypeConverter) ((DirectCollectionMapping)textMapping).getValueConverter();
        }
        if(converter == null) {
            return null;
        }
        List<String> enumeration = new ArrayList<String>();
        for(Object nextValue: converter.getAttributeToFieldValues().values()) {
            enumeration.add(nextValue.toString());
        }
        return enumeration;
    }

    private boolean hasAnyMappings(XMLDescriptor descriptor) {
        for(DatabaseMapping next:descriptor.getMappings()) {
            if(next instanceof XMLAnyAttributeMapping ||
                    next instanceof XMLAnyObjectMapping ||
                    next instanceof XMLAnyCollectionMapping ||
                    next instanceof XMLFragmentCollectionMapping ||
                    next instanceof XMLFragmentMapping

             ) {
                return true;
            } else if(next instanceof CompositeCollectionMapping) {
                CompositeCollectionMapping ccm = (CompositeCollectionMapping)next;
                if(ccm.getReferenceDescriptor() == null && ((XMLField)ccm.getField()).isSelfField()) {
                    return true;
                }
            } else if(next instanceof CompositeObjectMapping) {
                CompositeObjectMapping ccm = (CompositeObjectMapping)next;
                if(ccm.getReferenceDescriptor() == null && ((XMLField)ccm.getField()).isSelfField()) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Populates the map of properties based on the mappings in this descriptor. If the descriptor represents a
     * simple type (a single direct mapping with xpath of text) then the name of the simple type is returned.
     * Otherwise null is returned.
     *
     * @param properties
     * @param descriptor
     * @return null for a complex type, the simple type name for a simple type.
     */
    private JsonType populateProperties(Map<String, Property> properties, XMLDescriptor descriptor) {

        List<DatabaseMapping> mappings = descriptor.getMappings();
        if(mappings == null || mappings.isEmpty()) {
            return null;
        }

        if(isSimpleType(descriptor)) {
            //check for simple type
            DatabaseMapping mapping = getTextMapping(descriptor);
            if(mapping.isAbstractDirectMapping()) {
                DirectMapping directMapping = (DirectMapping)mapping;
                if(directMapping.getConverter() instanceof JAXBEnumTypeConverter) {
                    return JsonType.ENUMTYPE;
                }
                return getJsonTypeForJavaType(directMapping.getAttributeClassification());
            } else if(mapping.isAbstractCompositeDirectCollectionMapping()) {
                DirectCollectionMapping directMapping = (DirectCollectionMapping)mapping;
                if(directMapping.getValueConverter() instanceof JAXBEnumTypeConverter) {
                    return JsonType.ENUMTYPE;
                }
                Class type = directMapping.getAttributeElementClass();
                if(type == null) {
                    type = CoreClassConstants.STRING;
                }
                return getJsonTypeForJavaType(type);
            } else {
                //only other option is binary
                return JsonType.BINARYTYPE;
            }
        }
        for(DatabaseMapping next:mappings) {
            if(next instanceof ChoiceObjectMapping) {
                ChoiceObjectMapping coMapping = (ChoiceObjectMapping)next;
                for(Object nestedMapping:coMapping.getChoiceElementMappingsByClass().values()) {
                    Property prop = generateProperty((Mapping)nestedMapping, descriptor, properties);
                    if(prop != null && !(properties.containsKey(prop.getName()))) {
                        properties.put(prop.getName(), prop);
                    }
                }
            } else if(next instanceof ChoiceCollectionMapping) {
                ChoiceCollectionMapping coMapping = (ChoiceCollectionMapping)next;
                for(Object nestedMapping:coMapping.getChoiceElementMappingsByClass().values()) {
                    Property prop = generateProperty((Mapping)nestedMapping, descriptor, properties);
                    if(prop != null && !(properties.containsKey(prop.getName()))) {
                        properties.put(prop.getName(), prop);
                    }
                }
            } else {
                Property prop = generateProperty((Mapping)next, descriptor, properties);
                if(prop != null && !(properties.containsKey(prop.getName()))) {
                    properties.put(prop.getName(), prop);
                }
            }
        }
        return null;
    }

    private DatabaseMapping getTextMapping(XMLDescriptor descriptor) {
        for(DatabaseMapping next:descriptor.getMappings()) {
            if(next.isAbstractDirectMapping()) {
                DirectMapping mapping = (DirectMapping)next;
                if(((XMLField)mapping.getField()).getXPathFragment().nameIsText()) {
                    return next;
                }
            }
            if(next.isAbstractCompositeDirectCollectionMapping()) {
                DirectCollectionMapping mapping = (DirectCollectionMapping)next;
                if(((XMLField)mapping.getField()).getXPathFragment().nameIsText()) {
                    return next;
                }
            }
            if(next instanceof BinaryDataMapping) {
                BinaryDataMapping mapping = (BinaryDataMapping)next;
                if(((XMLField)mapping.getField()).isSelfField()) {
                    return next;
                }
            }
            if(next instanceof BinaryDataCollectionMapping) {
                BinaryDataCollectionMapping mapping = (BinaryDataCollectionMapping)next;
                if(((XMLField)mapping.getField()).isSelfField()) {
                    return next;
                }
            }
        }
        return null;
    }

    private boolean isSimpleType(XMLDescriptor descriptor) {
        DatabaseMapping mapping = null;
        if(descriptor.getMappings().size() == 1) {
            mapping = descriptor.getMappings().get(0);
        } else if(descriptor.getMappings().size() == 2) {
            boolean hasInverseRef = false;
            for(DatabaseMapping next:descriptor.getMappings()) {
                if(next instanceof InverseReferenceMapping) {
                    hasInverseRef = true;
                } else {
                    mapping = next;
                }
            }
            if(!hasInverseRef) {
                return false;
            }
        } else {
            return false;
        }

        if(mapping.isAbstractDirectMapping()) {
            if(((XMLField)mapping.getField()).getXPathFragment().nameIsText()) {
                return true;
            }
        }
        if(mapping.isAbstractCompositeDirectCollectionMapping()) {
            if(((XMLField)mapping.getField()).getXPathFragment().nameIsText()) {
                return true;
            }
        }
        if(mapping instanceof BinaryDataMapping) {
            if(((XMLField)mapping.getField()).isSelfField()) {
                return true;
            }
        }
        if(mapping instanceof BinaryDataCollectionMapping) {
            if(((XMLField)mapping.getField()).isSelfField()) {
                return true;
            }
        }
        return false;
    }

    private Property generateProperty(Mapping next, XMLDescriptor descriptor, Map<String, Property> properties) {
        Property prop = null;
        if(next.isCollectionMapping()) {
            if(next instanceof CollectionReferenceMapping) {
                CollectionReferenceMapping mapping = (CollectionReferenceMapping)next;
                Set<XMLField> sourceFields = mapping.getSourceToTargetKeyFieldAssociations().keySet();
                XMLDescriptor reference = (XMLDescriptor) mapping.getReferenceDescriptor();
                for(XMLField nextField: sourceFields) {
                    XPathFragment frag = nextField.getXPathFragment();
                    String propertyName = getNameForFragment(frag);

                    XMLField targetField = (XMLField) mapping.getSourceToTargetKeyFieldAssociations().get(nextField);
                    Class type = CoreClassConstants.STRING;
                    if(reference != null) {
                        type = getTypeForTargetField(targetField, reference);
                    }

                    prop = properties.get(propertyName);
                    if(prop == null) {
                        prop = new Property();
                        prop.setName(propertyName);
                    }
                    Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                    nestedProperty.setType(JsonType.ARRAY);
                    nestedProperty.setItem(new Property());
                    nestedProperty.getItem().setType(getJsonTypeForJavaType(type));
                    if(!properties.containsKey(prop.getName())) {
                        properties.put(prop.getName(), prop);
                    }
                }
                return prop;
            } else if(next.isAbstractCompositeCollectionMapping()) {
                CompositeCollectionMapping mapping = (CompositeCollectionMapping)next;
                XMLField field = (XMLField)mapping.getField();
                XPathFragment frag = field.getXPathFragment();
                String propName = getNameForFragment(frag);
                //for paths, there may already be an existing property
                prop = properties.get(propName);
                if(prop == null) {
                    prop = new Property();
                    prop.setName(propName);
                }
                Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                nestedProperty.setType(JsonType.ARRAY);
                nestedProperty.setItem(new Property());
                XMLDescriptor referenceDescriptor = (XMLDescriptor)mapping.getReferenceDescriptor();
                if(referenceDescriptor != null && referenceDescriptor.hasInheritance()) {
                    //handle inheritence
                    //schema.setAnyOf(new Property[descriptor.getInheritancePolicy().getAllChildDescriptors().size()]);
                    List<ClassDescriptor> descriptors = getAllDescriptorsForInheritance(referenceDescriptor);
                    Property[] props = new Property[descriptors.size()];
                    for(int i = 0; i < props.length; i++) {
                        XMLDescriptor nextDescriptor = null;
                        nextDescriptor = (XMLDescriptor)descriptors.get(i);
                        Property ref = new Property();
                        ref.setRef(getReferenceForDescriptor(nextDescriptor, true));
                        props[i] = ref;
                    }
                    nestedProperty.getItem().setAnyOf(props);
                } else {
                    nestedProperty.getItem().setRef(getReferenceForDescriptor(referenceDescriptor, false));
                    //populateProperties(nestedProperty.getItem().getProperties(), (XMLDescriptor)mapping.getReferenceDescriptor());
                }
            } else if(next.isAbstractCompositeDirectCollectionMapping()) {
                DirectCollectionMapping mapping = (DirectCollectionMapping)next;
                XMLField field = (XMLField)mapping.getField();
                XPathFragment frag = field.getXPathFragment();
                List<String> enumeration = null;
                if(mapping.getValueConverter() instanceof JAXBEnumTypeConverter) {
                    enumeration = getEnumeration((DatabaseMapping)next);
                }
                String propertyName = getNameForFragment(frag);
                if(frag.nameIsText()) {
                    propertyName = (String)this.contextProperties.get(MarshallerProperties.JSON_VALUE_WRAPPER);
                }

                if(frag.isAttribute() && this.attributePrefix != null) {
                    propertyName = attributePrefix + propertyName;
                }
                prop = properties.get(propertyName);
                if(prop == null) {
                    prop = new Property();
                    prop.setName(propertyName);
                }
                Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                nestedProperty.setType(JsonType.ARRAY);
                nestedProperty.setItem(new Property());
                if(enumeration != null) {
                    nestedProperty.getItem().setEnumeration(enumeration);
                }
                Class type = mapping.getAttributeElementClass();
                if(type == null) {
                    type = CoreClassConstants.STRING;
                }
                nestedProperty.getItem().setType(getJsonTypeForJavaType(type));
                return prop;
            } else if(next instanceof BinaryDataCollectionMapping) {
                BinaryDataCollectionMapping mapping = (BinaryDataCollectionMapping)next;
                XMLField field = (XMLField)mapping.getField();
                XPathFragment frag = field.getXPathFragment();

                String propertyName = getNameForFragment(frag);
                if(frag.isSelfFragment()) {
                    propertyName = Constants.VALUE_WRAPPER;
                    if(this.contextProperties != null)  {
                        String valueWrapper = (String) this.contextProperties.get(JAXBContextProperties.JSON_VALUE_WRAPPER);
                        if(valueWrapper != null) {
                            propertyName = valueWrapper;
                        }
                    }
                }

                if(frag.isAttribute() && this.attributePrefix != null) {
                    propertyName = attributePrefix + propertyName;
                }
                prop = properties.get(propertyName);
                if(prop == null) {
                    prop = new Property();
                    prop.setName(propertyName);
                }
                Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                nestedProperty.setType(JsonType.ARRAY);
                nestedProperty.setItem(new Property());

                if(mapping.shouldInlineBinaryData()) {
                    nestedProperty.getItem().setType(JsonType.STRING);
                } else {
                    nestedProperty.getItem().setAnyOf(getXopIncludeProperties());
                }
                return prop;
            }
        } else {
            if(next.isAbstractDirectMapping()) {
                //handle direct mapping
                DirectMapping directMapping = (DirectMapping)next;
                XMLField field = (XMLField)directMapping.getField();
                XPathFragment frag = field.getXPathFragment();
                List<String> enumeration = null;
                if(directMapping.getConverter() instanceof JAXBEnumTypeConverter) {
                    enumeration = getEnumeration((DatabaseMapping)directMapping);
                }
                String propertyName = getNameForFragment(frag);
                if(frag.nameIsText()) {
                    propertyName = Constants.VALUE_WRAPPER;
                    if(this.contextProperties != null)  {
                        String valueWrapper = (String) this.contextProperties.get(JAXBContextProperties.JSON_VALUE_WRAPPER);
                        if(valueWrapper != null) {
                            propertyName = valueWrapper;
                        }
                    }
                }
                if(frag.isAttribute() && this.attributePrefix != null) {
                    propertyName = attributePrefix + propertyName;
                }
                prop = properties.get(propertyName);
                if(prop == null) {
                    prop = new Property();
                    prop.setName(propertyName);
                }
                Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                if(enumeration != null) {
                    nestedProperty.setEnumeration(enumeration);
                }
                if(directMapping instanceof BinaryDataMapping) {
                    BinaryDataMapping binaryMapping = (BinaryDataMapping)directMapping;
                    if(binaryMapping.shouldInlineBinaryData() || binaryMapping.isSwaRef()) {
                        nestedProperty.setType(JsonType.STRING);
                    } else {
                        if(this.xopIncludeProp == null) {
                            initXopIncludeProp();
                        }
                        nestedProperty.setAnyOf(this.xopIncludeProp);
                    }
                } else {
                    nestedProperty.setType(getJsonTypeForJavaType(directMapping.getAttributeClassification()));
                }
                return prop;
            } else if(next instanceof ObjectReferenceMapping) {
                ObjectReferenceMapping mapping = (ObjectReferenceMapping)next;
                Set<XMLField> sourceFields = mapping.getSourceToTargetKeyFieldAssociations().keySet();
                XMLDescriptor reference = (XMLDescriptor) mapping.getReferenceDescriptor();
                for(XMLField nextField: sourceFields) {
                    XPathFragment frag = nextField.getXPathFragment();
                    String propName = getNameForFragment(frag);
                    XMLField targetField = (XMLField) mapping.getSourceToTargetKeyFieldAssociations().get(nextField);
                    Class type = CoreClassConstants.STRING;
                    if(reference != null) {
                        type = getTypeForTargetField(targetField, reference);
                    }

                    prop = properties.get(propName);
                    if(prop == null) {
                        prop = new Property();
                        prop.setName(propName);
                    }
                    Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                    //nestedProperty.setType(JsonType.ARRAY);
                    //nestedProperty.setItem(new Property());
                    nestedProperty.setType(getJsonTypeForJavaType(type));
                    if(!properties.containsKey(prop.getName())) {
                        properties.put(prop.getName(), prop);
                    }
                }
                return prop;
            } else if(next.isAbstractCompositeObjectMapping()) {
                CompositeObjectMapping mapping = (CompositeObjectMapping)next;
                XMLDescriptor nextDescriptor = (XMLDescriptor)mapping.getReferenceDescriptor();
                XMLField field = (XMLField)mapping.getField();
                XPathFragment firstFragment = field.getXPathFragment();
                if(firstFragment.isSelfFragment() || firstFragment.nameIsText()) {
                    if(nextDescriptor != null) {
                        populateProperties(properties, nextDescriptor);
                    }
                } else {
                    String propName = getNameForFragment(firstFragment);
                    prop = properties.get(propName);
                    if(prop == null) {
                        prop = new Property();
                        prop.setName(propName);
                    }
                    //prop.setType(JsonType.OBJECT);
                    prop.setName(propName);
                    Property nestedProperty = getNestedPropertyForFragment(firstFragment, prop);
                    XMLDescriptor referenceDescriptor = (XMLDescriptor)mapping.getReferenceDescriptor();
                    if(referenceDescriptor != null && referenceDescriptor.hasInheritance()) {
                        //handle inheritence
                        //schema.setAnyOf(new Property[descriptor.getInheritancePolicy().getAllChildDescriptors().size()]);
                        List<ClassDescriptor> descriptors = getAllDescriptorsForInheritance(referenceDescriptor);
                        Property[] props = new Property[descriptors.size()];
                        for(int i = 0; i < props.length; i++) {
                            XMLDescriptor nextDesc = (XMLDescriptor)descriptors.get(i);
                            Property ref = new Property();
                            ref.setRef(getReferenceForDescriptor(nextDesc, true));
                            props[i] = ref;
                        }
                        nestedProperty.setAnyOf(props);
                    } else {
                        nestedProperty.setRef(getReferenceForDescriptor(referenceDescriptor, false));
                        //populateProperties(nestedProperty.getItem().getProperties(), (XMLDescriptor)mapping.getReferenceDescriptor());
                    }                    //populateProperties(nestedProperty.getProperties(), nextDescriptor);
                }
            } else if(next instanceof BinaryDataMapping) {
                BinaryDataMapping binaryMapping = (BinaryDataMapping)next;
                XMLField field = (XMLField)binaryMapping.getField();
                XPathFragment frag = field.getXPathFragment();
                String propertyName = getNameForFragment(frag);
                if(frag.isSelfFragment()) {
                    propertyName = Constants.VALUE_WRAPPER;
                    if(this.contextProperties != null)  {
                        String valueWrapper = (String) this.contextProperties.get(MarshallerProperties.JSON_VALUE_WRAPPER);
                        if(valueWrapper != null) {
                            propertyName = valueWrapper;
                        }
                    }
                }
                if(frag.isAttribute() && this.attributePrefix != null) {
                    propertyName = attributePrefix + propertyName;
                }
                prop = properties.get(propertyName);
                if(prop == null) {
                    prop = new Property();
                    prop.setName(propertyName);
                }
                Property nestedProperty = getNestedPropertyForFragment(frag, prop);
                if(binaryMapping.shouldInlineBinaryData() || binaryMapping.isSwaRef()) {
                    nestedProperty.setType(JsonType.STRING);
                } else {
                    if(this.xopIncludeProp == null) {
                        initXopIncludeProp();
                    }
                    nestedProperty.setAnyOf(this.xopIncludeProp);
                }
                return prop;
            }
        }

        return prop;
    }

    private String getNameForFragment(XPathFragment frag) {
        String name = frag.getLocalName();

        if(this.prefixMapper != null) {
            String namespaceUri = frag.getNamespaceURI();
            if(namespaceUri != null && namespaceUri.length() != 0) {
                String prefix = prefixMapper.getPreferredPrefix(namespaceUri, null, true);
                if(prefix != null) {
                    name = prefix + NAMESPACE_SEPARATOR + name;
                }
            }
        }
        return name;
    }

    private void initXopIncludeProp() {
        this.xopIncludeProp = new Property[2];
        Property p = new Property();
        p.setType(JsonType.STRING);
        this.xopIncludeProp[0] = p;

        p = new Property();
        this.xopIncludeProp[1] = p;
        p.setType(JsonType.OBJECT);
        Property includeProperty = new Property();
        includeProperty.setName("Include");
        includeProperty.setType(JsonType.OBJECT);
        p.getProperties().put(includeProperty.getName(), includeProperty);

        Property hrefProp = new Property();
        String propName = "href";
        if(this.attributePrefix != null) {
            propName = this.attributePrefix + propName;
        }
        hrefProp.setName(propName);
        hrefProp.setType(JsonType.STRING);
        includeProperty.getProperties().put(propName, hrefProp);


    }



    private String getReferenceForDescriptor(XMLDescriptor referenceDescriptor, boolean generateRoot) {
        if(referenceDescriptor == null) {
            return null;
        }
        String className = referenceDescriptor.getJavaClass().getSimpleName();
        String referenceName = DEFINITION_PATH + "/" + className;

        if(referenceDescriptor.getJavaClass() == this.rootClass && !generateRoot) {
            String ref = "#";
            if(this.rootProperty != null) {
                ref += "/properties/" + rootProperty.getName();
            }
            return ref;
        }
        if(!this.schema.getDefinitions().containsKey(className)) {
            Property definition = new Property();
            definition.setName(className);
            this.schema.getDefinitions().put(definition.getName(), definition);
            definition.setType(JsonType.OBJECT);
            if(referenceDescriptor.hasInheritance() && referenceDescriptor.getInheritancePolicy().hasClassIndicator()) {
                XMLField f = (XMLField)referenceDescriptor.getInheritancePolicy().getClassIndicatorField();
                Property indicatorProp = new Property();
                indicatorProp.setName(getNameForFragment(f.getXPathFragment()));
                indicatorProp.setType(JsonType.STRING);
                definition.getProperties().put(indicatorProp.getName(), indicatorProp);
            }
            JsonType jType = populateProperties(definition.getProperties(), referenceDescriptor);
            if(jType != null) {
                if(jType == JsonType.BINARYTYPE) {
                    definition.setAnyOf(getXopIncludeProperties());
                    definition.setProperties(null);
                    definition.setAdditionalProperties(null);
                    definition.setType(null);
                } else {
                    //this represents a simple type
                    definition.setType(jType);
                    definition.setProperties(null);
                }
            }
            definition.setAdditionalProperties(hasAnyMappings(referenceDescriptor));
        }
        // TODO Auto-generated method stub
        return referenceName;
    }

    private Class getTypeForTargetField(XMLField targetField, XMLDescriptor reference) {
        for(DatabaseMapping next: reference.getMappings()) {
            if(next.isDirectToFieldMapping()) {
                DirectMapping directMapping = (DirectMapping)next;
                if(directMapping.getField().equals(targetField)) {
                    return directMapping.getAttributeClassification();
                }
            }
        }
        return null;
    }

    private JsonType getJsonTypeForJavaType(Class attributeClassification) {
        if(attributeClassification.isEnum()) {
            return JsonType.ENUMTYPE;
        }
        HashMap<Class, JsonType> types = getJavaTypeToJsonType();
        JsonType jsonType = types.get(attributeClassification);
        if(jsonType == null) {
            return JsonType.OBJECT;
        }
        return jsonType;
    }

    private static HashMap<Class, JsonType> getJavaTypeToJsonType() {
        if(javaTypeToJsonType == null) {
            initJavaTypeToJsonType();
        }
        return javaTypeToJsonType;
    }

    private static void initJavaTypeToJsonType() {
        javaTypeToJsonType = new HashMap<Class, JsonType>();
        javaTypeToJsonType.put(CoreClassConstants.APBYTE, JsonType.ARRAY);
        javaTypeToJsonType.put(CoreClassConstants.BIGDECIMAL, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.BIGINTEGER, JsonType.INTEGER);
        javaTypeToJsonType.put(CoreClassConstants.PBOOLEAN, JsonType.BOOLEAN);
        javaTypeToJsonType.put(CoreClassConstants.PBYTE, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.CALENDAR, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.PDOUBLE, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.PFLOAT, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.PINT, JsonType.INTEGER);
        javaTypeToJsonType.put(CoreClassConstants.PLONG, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.PSHORT, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.STRING, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.CHAR, JsonType.STRING);
        // other pairs
        javaTypeToJsonType.put(CoreClassConstants.ABYTE, JsonType.ARRAY);
        javaTypeToJsonType.put(CoreClassConstants.BOOLEAN, JsonType.BOOLEAN);
        javaTypeToJsonType.put(CoreClassConstants.BYTE, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.CLASS, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.GREGORIAN_CALENDAR, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.DOUBLE, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.FLOAT, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.INTEGER, JsonType.INTEGER);
        javaTypeToJsonType.put(CoreClassConstants.LONG, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.OBJECT, JsonType.OBJECT);
        javaTypeToJsonType.put(CoreClassConstants.SHORT, JsonType.NUMBER);
        javaTypeToJsonType.put(CoreClassConstants.UTILDATE, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.SQLDATE, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.TIME, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.TIMESTAMP, JsonType.STRING);
        javaTypeToJsonType.put(CoreClassConstants.DURATION, JsonType.STRING);
        javaTypeToJsonType.put(Constants.QNAME_CLASS, JsonType.STRING);
        javaTypeToJsonType.put(Constants.URI, JsonType.STRING);
        javaTypeToJsonType.put(Constants.UUID, JsonType.STRING);

        javaTypeToJsonType.put(XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER, JsonType.BINARYTYPE);
        javaTypeToJsonType.put(XMLBinaryDataHelper.getXMLBinaryDataHelper().IMAGE, JsonType.BINARYTYPE);
        javaTypeToJsonType.put(XMLBinaryDataHelper.getXMLBinaryDataHelper().SOURCE, JsonType.BINARYTYPE);
        javaTypeToJsonType.put(XMLBinaryDataHelper.getXMLBinaryDataHelper().MULTIPART, JsonType.BINARYTYPE);

    }

    private Property getNestedPropertyForFragment(XPathFragment frag, Property prop) {
        if(frag.getNextFragment() == null  || frag.getNextFragment().nameIsText() ) {
            return prop;
        }
        Map<String, Property> currentProperties = prop.getProperties();
        prop.setProperties(currentProperties);
        prop.setType(JsonType.OBJECT);
        frag = frag.getNextFragment();
        String propertyName = getNameForFragment(frag);
        if(frag.isAttribute() && this.attributePrefix != null) {
            propertyName = this.attributePrefix + "propertyName";
        }
        while(frag != null && !frag.nameIsText()) {
            Property nestedProperty = prop.getProperty(propertyName);
            if(nestedProperty == null) {
                nestedProperty = new Property();
                nestedProperty.setName(propertyName);
            }
            currentProperties.put(nestedProperty.getName(), nestedProperty);
            if(frag.getNextFragment() == null || frag.getNextFragment().nameIsText()) {
                return nestedProperty;
            } else {
                nestedProperty.setType(JsonType.OBJECT);

                currentProperties = nestedProperty.getProperties();
            }
            frag = frag.getNextFragment();
            propertyName = getNameForFragment(frag);
        }
        return null;
    }

    private Property[] getXopIncludeProperties() {
        if(this.xopIncludeProp == null) {
            this.initXopIncludeProp();
        }
        return this.xopIncludeProp;
    }

    private boolean isCollection(Class type) {
        if (CoreClassConstants.Collection_Class.isAssignableFrom(type)
                || CoreClassConstants.List_Class.isAssignableFrom(type)
                || CoreClassConstants.Set_Class.isAssignableFrom(type)) {
            return true;
        }
        return false;
    }

    private List<ClassDescriptor> getAllDescriptorsForInheritance(XMLDescriptor descriptor) {
        ArrayList<ClassDescriptor> descriptors = new ArrayList<ClassDescriptor>();
        QNameInheritancePolicy policy = (QNameInheritancePolicy) descriptor.getInheritancePolicy();
        descriptors.add(descriptor);
        descriptors.addAll(policy.getAllChildDescriptors());
        ClassDescriptor parent = policy.getParentDescriptor();
        while(parent != null) {
            descriptors.add(parent);
            parent = parent.getInheritancePolicy().getParentDescriptor();
        }
        return descriptors;

    }

}
