/*
 * 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.jaxb.compiler;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.internal.jaxb.AccessorFactoryWrapper;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexType;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleType;
import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticle;



import org.eclipse.persistence.jaxb.DefaultXMLNameTransformer;
import org.eclipse.persistence.jaxb.javamodel.Helper;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;


import org.eclipse.persistence.jaxb.xmlmodel.XmlAccessOrder;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType;

import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNamedObjectGraph;
import org.eclipse.persistence.jaxb.xmlmodel.XmlNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement;
import org.eclipse.persistence.jaxb.xmlmodel.XmlType;
import org.eclipse.persistence.jaxb.xmlmodel.XmlVirtualAccessMethods;
import org.eclipse.persistence.oxm.XMLNameTransformer;

/**
 * INTERNAL:
 * <p>
 * <b>Purpose:</b>Used to store meta data about JAXB 2.0 Annotated classes during schema and mapping
 * generation processes.
 *
 * <p>
 * <b>Responsibilities:</b>
 * <ul>
 * <li>Store information about Class Name and the associated Schema Type name</li>
 * <li>Store information about Property Order for mapping and schema generation</li>
 * <li>Store information about XmlAdapters, XmlAccessType and other JAXB 2.0 annotation artifacts</li>
 * </ul>
 *
 * @since Oracle TopLink 11.1.1.0.0
 * @author mmacivor
 * @see org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor
 * @see org.eclipse.persistence.jaxb.compiler.EnumTypeInfo
 *
 */

public class TypeInfo {
    private Descriptor descriptor;
    private String javaClassName;
    private ComplexType complexType;
    private String elementRefsPropertyName;
    private Schema schema;
    private SimpleType simpleType;
    private ArrayList<String> propOrder; // store as a collection so it can be added to if needed
    private String classNamespace;
    private String schemaTypeName;
    private TypeDefParticle compositor;
    private ArrayList<String> propertyNames;
    private ArrayList<Property> propertyList;// keep the keys in a list to preserve order
    private HashMap<String, Property> properties;
    private HashMap<String, Property> originalProperties;
    private Map<String, List<Property>> additionalProperties;
    private Property idProperty; // if there is an XmlID annotation, set the property for mappings gen
    private HashMap<String, JavaClass> packageLevelAdaptersByClass;
    private String objectFactoryClassName;
    private String factoryMethodName;
    private String[] factoryMethodParamTypes;
    private Property xmlValueProperty;
    private String classExtractorName;
    private Map<Object, Object> userProperties;
    private List<Property> xmlKeyProperties;
    private List<Property> predicateProperties;

    private List<XmlNamedObjectGraph> objectGraphs;

    private boolean isMixed;
    private boolean isTransient;
    private boolean isPreBuilt;
    private boolean isPostBuilt;
    private boolean isSetXmlTransient;
    private boolean isXmlElementNillable;
    private XmlNullPolicy xmlNullPolicy;

    private List<String> xmlSeeAlso;
    private XmlRootElement xmlRootElement;
    private XmlType xmlType;
    private XmlAccessType xmlAccessType;
    private XmlAccessOrder xmlAccessOrder;
    private XmlJavaTypeAdapter xmlJavaTypeAdapter;
    private String xmlCustomizer;
    private XmlVirtualAccessMethods xmlExtensible;

    private String anyAttributePropertyName;
    private String anyElementPropertyName;

    private boolean isBinaryDataInlined;

    private String xmlDiscriminatorNode;
    private String xmlDiscriminatorValue;

    private AccessorFactoryWrapper xmlAccessorFactory;
    private AccessorFactoryWrapper packageLevelXmlAccessorFactory;

    private static String EMPTY_STRING = "";

    private XMLNameTransformer xmlNameTransformer;

    private boolean isLocationAware = false;
    private JavaClass javaClass;

    public static final XMLNameTransformer DEFAULT_NAME_TRANSFORMER = new DefaultXMLNameTransformer();

    /**
     * This constructor sets the Helper to be used throughout XML and Annotations
     * processing.  Other fields are initialized here as well.
     *
     * @param helper
     */
    public TypeInfo(Helper helper, JavaClass javaClass) {
        propertyNames = new ArrayList<String>();
        properties = new HashMap<String, Property>();
        originalProperties = new HashMap<String, Property>();
        propertyList = new ArrayList<Property>();
        xmlNameTransformer = DEFAULT_NAME_TRANSFORMER;
        isSetXmlTransient = false;
        isXmlElementNillable = false;
        isPreBuilt = false;
        isPostBuilt = false;
        this.javaClass = javaClass;
    }

    /**
     * Return the XmlDescriptor set on this TypeInfo.
     *
     * @return the XmlDescriptor set on this TypeInfo, or null if none
     */
    public Descriptor getDescriptor() {
        return descriptor;
    }

    /**
     * Set the XmlDescriptor on this TypeInfo.
     *
     * @param desc
     */
    public void setDescriptor(Descriptor desc) {
        descriptor = desc;
    }

    public ComplexType getComplexType() {
        return complexType;
    }

    public void setComplexType(ComplexType type) {
        complexType = type;
    }

    public SimpleType getSimpleType() {
        return simpleType;
    }

    public void setSimpleType(SimpleType type) {
        simpleType = type;
    }

    public String[] getPropOrder() {
        if (propOrder == null) {
            return new String[0];
        }
        return propOrder.toArray(new String[propOrder.size()]);
    }

    /**
     * Indicates that the propOrder has been set, i.e. is non-null
     *
     * @return true if propOrder is non-null, false otherwise
     */
    public boolean isSetPropOrder() {
        return propOrder != null;
    }

    public void setPropOrder(String[] order) {
        if (order == null) {
            propOrder = null;
        } else if (order.length == 0) {
            propOrder = new ArrayList<String>();
        } else {
            propOrder = new ArrayList(order.length);
            for (String next : order) {
                propOrder.add(next);
            }
        }
    }

    public String getClassNamespace() {
        return classNamespace;
    }

    public void setClassNamespace(String namespace) {
        classNamespace = namespace;
    }

    public boolean isComplexType() {
        return complexType != null;
    }

    /**
     * Indicates mixed content
     */
    public boolean isMixed() {
        return isMixed;
    }

    /**
     * Set mixed content indicator
     */
    public void setMixed(boolean isMixed) {
        this.isMixed = isMixed;
    }

    public TypeDefParticle getCompositor() {
        return compositor;
    }

    public void setCompositor(TypeDefParticle particle) {
        compositor = particle;
    }

    public ArrayList<String> getPropertyNames() {
        return propertyNames;
    }

    /**
     * Return the TypeProperty 'idProperty'. This method will typically be used in conjunction with
     * isIDSet method to determine if an @XmlID exists, and hence 'idProperty' is non-null.
     *
     * @return
     */
    public Property getIDProperty() {
        return idProperty;
    }

    /**
     * Return the Map of Properties for this TypeInfo.
     *
     * @return
     */
    public HashMap<String, Property> getProperties() {
        return properties;
    }

    /**
     * Put a Property in the Map of Properties for this TypeInfo. Here, the
     * original property is put in the originalProperties map, the
     * properties map, and the propertyList list.  It is assumed that
     * the originalProperties map will remain unchanged during processing.
     *
     */
    public void addProperty(String name, Property property) {
        if(originalProperties.get(name) != null) {
            // Duplicate property, see if either is transient and only keep the non-transient one
            Property existingProperty = originalProperties.get(name);
            if (existingProperty.isTransient() && property.isTransient()) {
                // Both transient, keep the one that matches AccessType
                if (this.getXmlAccessType().equals(XmlAccessType.FIELD)) {
                    if (!property.isMethodProperty()) {
                        // Existing property must be method property
                        // Remove it and use the new property
                        propertyList.remove(existingProperty);
                        propertyNames.remove(name);
                    } else {
                        return;
                    }
                } else {
                    if (property.isMethodProperty()) {
                        // Existing property must be field property
                        // Remove it and use the new property
                        propertyList.remove(existingProperty);
                        propertyNames.remove(name);
                    } else {
                        return;
                    }
                }
            } else if (existingProperty.isTransient() || existingProperty.isSuperClassProperty()) {
                // Continue, and overwrite it
                propertyList.remove(existingProperty);
                propertyNames.remove(name);
            } else if (property.isTransient()) {
                // Do nothing
                return;
            } else {
                // Neither is transient - truly a duplicate property collision
                throw org.eclipse.persistence.exceptions.JAXBException.duplicatePropertyName(name, this.getJavaClassName());
            }
        }
        originalProperties.put(name, property);
        properties.put(name, property);
        propertyNames.add(name);
        propertyList.add(property);
    }

    /**
     * Sets the TypeProperty 'idProperty'. This indicates that an @XmlID annotation is set on a
     * given field/method.
     */
    public void setIDProperty(Property idProperty) {
        this.idProperty = idProperty;
    }

    /**
     * Set the Map of Properties for this TypeInfo.
     *
     * @param properties
     */
    public void setProperties(ArrayList<Property> properties) {
        if (properties != null) {
            for (int i = 0; i < properties.size(); i++) {
                Property next = properties.get(i);
                this.addProperty(next.getPropertyName(), next);
            }
        }
    }

    /**
     * Order the properties based on the XmlAccessOrder, if set.
     */
    public void orderProperties() {
        if (!isSetXmlAccessOrder()) {
            return;
        }
        if (xmlAccessOrder == XmlAccessOrder.ALPHABETICAL) {
            if (this.propertyNames != null) {
                Collections.sort(this.propertyNames);
            }
        }
    }

    /**
     * Indicates if this type info represents an enumeration.  Since
     * EnumTypeInfo is used for enum types, this method will always
     * return false.
     *
     * @return false
     */
    public boolean isEnumerationType() {
        return false;
    }

    /**
     * Indicates if an @XmlID is set on a field/property. If so, the TypeProperty 'idProperty' will
     * be non-null.
     *
     * @return
     */
    public boolean isIDSet() {
        return idProperty != null;
    }

    public ArrayList<Property> getPropertyList() {
        return propertyList;
    }

    public String getSchemaTypeName() {
        return schemaTypeName;
    }

    public void setSchemaTypeName(String typeName) {
        schemaTypeName = typeName;
    }

    public void setSchema(Schema theSchema) {
        this.schema = theSchema;
    }

    public Schema getSchema() {
        return schema;
    }

    /**
     * Return the xmladapter class for a given bound type class.
     *
     * @param boundType
     * @return
     */
    public JavaClass getPackageLevelAdapterClass(JavaClass boundType) {
        if(hasPackageLevelAdaptersByClass()) {
            return getPackageLevelAdaptersByClass().get(boundType.getQualifiedName());
        }
        return null;
    }

    public boolean isAnonymousComplexType() {
        return this.schemaTypeName == null || this.schemaTypeName.equals("");
    }

    /**
     * Return the xmladapter class for a given bound type class name.
     *
     * @param boundTypeName
     * @return
     */
    public JavaClass getPackageLevelAdapterClass(String boundTypeName) {
        if(hasPackageLevelAdaptersByClass()) {
            return getPackageLevelAdaptersByClass().get(boundTypeName);
        }
        return null;
    }

    /**
     * Return the Map of XmlAdapters for this TypeInfo.
     *
     * @return
     */
    public HashMap<String, JavaClass> getPackageLevelAdaptersByClass() {
        if(!hasPackageLevelAdaptersByClass()) {
            packageLevelAdaptersByClass = new HashMap<String, JavaClass>();
        }
        return packageLevelAdaptersByClass;
    }

    boolean hasPackageLevelAdaptersByClass() {
        return null != packageLevelAdaptersByClass;
    }

    /**
     * Put a bound type class to adapter class entry in the Map.
     *
     * @param adapterClass
     * @param boundType
     */
    public void addPackageLevelAdapterClass(JavaClass adapterClass, JavaClass boundType) {
        getPackageLevelAdaptersByClass().put(boundType.getQualifiedName(), adapterClass);
    }

    public boolean hasRootElement() {
        return xmlRootElement != null;
    }

    /**
     * Indicates if this TypeInfo contains an XmlElementRefs property.
     *
     * @return
     */
    public boolean hasElementRefs() {
        return elementRefsPropertyName != null;
    }

    /**
     * Return the XmlElementRefs property name, if one has been set.
     *
     * @return
     */
    public String getElementRefsPropName() {
        return elementRefsPropertyName;
    }

    /**
     * Set the XmlElementRefs property name.
     */
    public void setElementRefsPropertyName(String propName) {
        elementRefsPropertyName = propName;
    }

    public String getObjectFactoryClassName() {
        return objectFactoryClassName;
    }

    public void setObjectFactoryClassName(String factoryClass) {
        this.objectFactoryClassName = factoryClass;
    }

    public String getFactoryMethodName() {
        return this.factoryMethodName;
    }

    public void setFactoryMethodName(String factoryMethod) {
        this.factoryMethodName = factoryMethod;
    }

    public String[] getFactoryMethodParamTypes() {
        return this.factoryMethodParamTypes;
    }

    public void setFactoryMethodParamTypes(String[] paramTypes) {
        this.factoryMethodParamTypes = paramTypes;
    }

    /**
     * Indicates if an xmlValueProperty is set on this TypeInfo, i.e.
     * is non-null.
     *
     * @return
     */
    public boolean isSetXmlValueProperty() {
        return xmlValueProperty != null;
    }

    public Property getXmlValueProperty() {
        return xmlValueProperty;
    }

    public void setXmlValueProperty(Property xmlValueProperty) {
        this.xmlValueProperty = xmlValueProperty;
    }

    /**
     * Indicates if the class represented by this TypeInfo is marked XmlTransient.
     *
     * @return
     */
    public boolean isTransient() {
        return isTransient;
    }

    /**
     * Used to indicate that the class represented by this TypeInfo is marked
     * XmlTransient.
     */
    public void setTransient(boolean isTransient) {
        this.isTransient = isTransient;
    }

    /**
     * Return all non-transient properties that exist in the propOrder array.
     *
     * @return
     */
    public List<Property> getNonTransientPropertiesInPropOrder() {
        List<Property> propertiesInOrder = new ArrayList<Property>();
        String[] propOrder = getPropOrder();
        if (propOrder.length == 0 || propOrder[0].equals(EMPTY_STRING)) {
            ArrayList<String> propertyNames = getPropertyNames();
            for (int i = 0; i < propertyNames.size(); i++) {
                addPropertyToList(propertiesInOrder, propertyNames.get(i), null);
            }
        } else {
            ArrayList<String> propertyNamesCopy = new ArrayList<String>(getPropertyNames());
            for (int i = 0; i < propOrder.length; i++) {
                // generate mappings based on the propOrder.
                addPropertyToList(propertiesInOrder, propOrder[i], propertyNamesCopy);
            }
            // attributes may not be in the prop order in which
            // case we need to generate those mappings also
            for (int i = 0; i < propertyNamesCopy.size(); i++) {
                addPropertyToList(propertiesInOrder, propertyNamesCopy.get(i), null);
            }
        }
        return propertiesInOrder;
    }

    /**
     * Convenience method that adds non-null, non-transient properties to a given
     * {@code List<Property>}.  The propertyName parameter is used to lookup the Property.
     * If propertyNamesCopy is non-null, the Property will be removed from that
     * List.  Any additional properties that exist for propertyName (as in the
     * case of multiple mappings to the same field) will be added as well.
     *
     */
    private void addPropertyToList(List<Property> propertiesInOrder, String propertyName, ArrayList<String> propertyNamesCopy) {
        Property next = getProperties().get(propertyName);
        if (next != null && !next.isTransient()) {
            if (propertyNamesCopy != null) {
                propertyNamesCopy.remove(propertyName);
            }
            propertiesInOrder.add(next);
            // check for additional properties (i.e. multiple mappings to the same field)
            if(hasAdditionalProperties()) {
                List<Property> addProps = getAdditionalProperties().get(propertyName);
                if (addProps != null) {
                    for (Property addProp : addProps) {
                        if (!addProp.isTransient()) {
                            propertiesInOrder.add(addProp);
                        }
                    }
                }
            }
        }
    }

    /**
     * Indicates if XmlTransient is set.
     *
     * @return
     */
    public boolean isSetXmlTransient() {
        return isSetXmlTransient;
    }

    /**
     * Set the XmlTransient for this TypeInfo.
     *
     * @param isTransient
     */
    public void setXmlTransient(boolean isTransient) {
        isSetXmlTransient = true;
        setTransient(isTransient);
    }

    /**
     * Indicates if XmlElementNillable is set.
     *
     * @return
     */
    public boolean isXmlElementNillable() {
        return isXmlElementNillable;
    }

    /**
     * Set the XmlElementNillable for this TypeInfo.
     *
     * @param isXmlElementNillable
     */
    public void setXmlElementNillable(boolean isXmlElementNillable) {
        this.isXmlElementNillable = isXmlElementNillable;
    }

    /**
     * Return XmlNullPolicy for this TypeInfo.
     *
     * @return xmlNullPolicy
     */
    public XmlNullPolicy getXmlNullPolicy() {
        return xmlNullPolicy;
    }

    /**
     * Set the XmlNullPolicy for this TypeInfo.
     *
     * @param xmlNullPolicy
     */
    public void setXmlNullPolicy(XmlNullPolicy xmlNullPolicy) {
        this.xmlNullPolicy = xmlNullPolicy;
    }

    /**
     * Indicates if xmlSeeAlso has been set, i.e. is non-null
     *
     * @return true is xmlSeeAlso has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetXmlSeeAlso() {
        return xmlSeeAlso != null;
    }

    /**
     * Return the List of XmlSeeAlso class names for this TypeInfo.
     *
     * @return
     */
    public List<String> getXmlSeeAlso() {
        return xmlSeeAlso;
    }

    /**
     * Set the List of XmlSeeAlso class names for this TypeInfo.
     *
     * @param xmlSeeAlso
     */
    public void setXmlSeeAlso(List<String> xmlSeeAlso) {
        this.xmlSeeAlso = xmlSeeAlso;
    }

    /**
     * Indicates if xmlRootElement has been set, i.e. is non-null
     *
     * @return true is xmlRootElement has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetXmlRootElement() {
        return xmlRootElement != null;
    }

    /**
     * Return the xmlRootElement set on this TypeInfo.
     *
     * @return
     */
    public XmlRootElement getXmlRootElement() {
        return xmlRootElement;
    }

    /**
     * Set the xmlRootElement for this TypeInfo.
     *
     * @param xmlRootElement
     */
    public void setXmlRootElement(XmlRootElement xmlRootElement) {
        this.xmlRootElement = xmlRootElement;
    }

    /**
     * Indicates if xmlType has been set, i.e. is non-null
     *
     * @return true is xmlType has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetXmlType() {
        return xmlType != null;
    }

    /**
     * Return the xmlType set on this TypeInfo.
     *
     * @return
     */
    public XmlType getXmlType() {
        return xmlType;
    }

    /**
     * Set the xmlType for this TypeInfo.
     *
     * @param xmlType
     */
    public void setXmlType(XmlType xmlType) {
        this.xmlType = xmlType;
    }

    /**
     * Indicates if xmlAccessType has been set, i.e. is non-null
     *
     * @return true is xmlAccessType has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetXmlAccessType() {
        return xmlAccessType != null;
    }

    /**
     * Return the xmlAccessType for this TypeInfo.
     *
     * @return
     */
    public XmlAccessType getXmlAccessType() {
        return xmlAccessType;
    }

    /**
     * Set the xmlAccessType for this TypeInfo.
     *
     * @param xmlAccessType
     */
    public void setXmlAccessType(XmlAccessType xmlAccessType) {
        this.xmlAccessType = xmlAccessType;
    }

    /**
     * Indicates if xmlAccessOrder has been set, i.e. is non-null
     *
     * @return true is xmlAccessOrder has been set, i.e. is non-null, false otherwise
     */
    public boolean isSetXmlAccessOrder() {
        return xmlAccessOrder != null;
    }

    /**
     * Return the xmlAccessOrder for this TypeInfo.
     *
     * @return
     */
    public XmlAccessOrder getXmlAccessOrder() {
        return xmlAccessOrder;
    }

    /**
     * Set the xmlAccessOrder for this TypeInfo.
     *
     * @param xmlAccessOrder
     */
    public void setXmlAccessOrder(XmlAccessOrder xmlAccessOrder) {
        this.xmlAccessOrder = xmlAccessOrder;
    }

    /**
     * Indicates if this TypeInfo has completed the preBuildTypeInfo phase of
     * processing.
     *
     * @return true if this TypeInfo has completed the preBuildTypeInfo phase of
     * processing, false otherwise
     */
    public boolean isPreBuilt() {
        return isPreBuilt;
    }

    /**
     * Set indicator that this TypeInfo has completed the preBuildTypeInfo
     * phase of processing.
     *
     */
    public void setPreBuilt(boolean isPreBuilt) {
        this.isPreBuilt = isPreBuilt;
    }

    /**
     * Indicates if this TypeInfo has completed the postBuildTypeInfo phase of
     * processing.
     *
     * @return true if this TypeInfo has completed the postBuildTypeInfo phase of
     * processing, false otherwise
     */
    public boolean isPostBuilt() {
        return isPostBuilt;
    }

    /**
     * Set indicator that this TypeInfo has completed the postBuildTypeInfo
     * phase of processing.
     *
     */
    public void setPostBuilt(boolean isPostBuilt) {
        this.isPostBuilt = isPostBuilt;
    }

    /**
     * Indicates if an XmlJavaTypeAdapter has been set, i.e. the
     * xmlJavaTypeAdapter property is non-null.
     *
     * @return true if xmlJavaTypeAdapter is non-null, false otherwise
     * @see XmlJavaTypeAdapter
     */
    public boolean isSetXmlJavaTypeAdapter() {
        return getXmlJavaTypeAdapter() != null;
    }

    /**
     * Return the xmlJavaTypeAdapter set on this Type.
     *
     * @return xmlJavaTypeAdapter, or null if not set
     * @see XmlJavaTypeAdapter
     */
    public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
        return xmlJavaTypeAdapter;
    }

    /**
     * Set an XmlJavaTypeAdapter on this Type.
     *
     * @param xmlJavaTypeAdapter
     * @see XmlJavaTypeAdapter
     */
    public void setXmlJavaTypeAdapter(XmlJavaTypeAdapter xmlJavaTypeAdapter) {
        this.xmlJavaTypeAdapter = xmlJavaTypeAdapter;
    }

    /**
     * Return the XmlCustomizer class name set on this TypeInfo, or null if none
     * is set.
     *
     * @return the XmlCustomizer class name set on this TypeInfo, or null if none is set
     * @see DescriptorCustomizer
     */
    public String getXmlCustomizer() {
        return xmlCustomizer;
    }

    /**
     * Sets the XmlCustomizer class name on this TypeInfo.
     *
     * @param xmlCustomizerClassName
     * @see DescriptorCustomizer
     */
    public void setXmlCustomizer(String xmlCustomizerClassName) {
        this.xmlCustomizer = xmlCustomizerClassName;
    }

    /**
     * Indicates if the name of the XmlAnyElement property has been set.
     *
     * @return
     */
    public boolean isSetAnyElementPropertyName() {
        return getAnyElementPropertyName() != null;
    }

    /**
     * Return the name of the XmlAnyElement property, if one is set.
     *
     * @return
     */
    public String getAnyElementPropertyName() {
        return anyElementPropertyName;
    }

    /**
     * Set the name of the XmlAnyElement property
     *
     * @param anyElementPropertyName
     */
    public void setAnyElementPropertyName(String anyElementPropertyName) {
        this.anyElementPropertyName = anyElementPropertyName;
    }

    /**
     * Indicates if the name of the XmlAnyAttribute property has been set.
     *
     * @return
     */
    public boolean isSetAnyAttributePropertyName() {
        return getAnyAttributePropertyName() != null;
    }

    /**
     * Return the name of the XmlAnyAttribute property, if one is set.
     *
     * @return
     */
    public String getAnyAttributePropertyName() {
        return anyAttributePropertyName;
    }

    /**
     * Set the name of the XmlAnyAttribute property
     *
     * @param anyAttributePropertyName
     */
    public void setAnyAttributePropertyName(String anyAttributePropertyName) {
        this.anyAttributePropertyName = anyAttributePropertyName;
    }

    /**
     * Indicates if all binary data types are to be inlined for this class.
     *
     * @return
     */
    public boolean isBinaryDataToBeInlined() {
        return isBinaryDataInlined;
    }

    /**
     * Sets the flag that indicates if all binary data types are to
     * be inlined for this class.
     *
     * @param isBinaryDataInlined
     */
    public void setInlineBinaryData(boolean isBinaryDataInlined) {
        this.isBinaryDataInlined = isBinaryDataInlined;
    }

    /**
     * Indicates if a ClassExtractor class name is set,
     * i.e. is non-null
     *
     * @return true if classExtractorName != null, otherwise false
     */
    public boolean isSetClassExtractorName() {
        return classExtractorName != null;
    }

    /**
     * Return the ClassExtractor class name.
     *
     * @return classExtractorName
     */
    public String getClassExtractorName() {
        return classExtractorName;
    }

    /**
     * Set the ClassExtractor class name.
     *
     * @param classExtractorName
     */
    public void setClassExtractorName(String classExtractorName) {
        this.classExtractorName = classExtractorName;
    }

    /**
     * Return the Map of user-defined properties.
     *
     * @return
     */
    public Map<Object, Object> getUserProperties() {
        return userProperties;
    }

    /**
     * Set the Map of user-defined properties.
     *
     * @param userProperties
     */
    public void setUserProperties(Map<Object, Object> userProperties) {
        this.userProperties = userProperties;
    }

    /**
     * Return the JavaClass name for this typeinfo.
     *
     * @return
     */
    public String getJavaClassName() {
        return javaClassName;
    }

    /**
     * Set the JavaClass name for this typeinfo.
     *
     * @param javaClassName
     */
    public void setJavaClassName(String javaClassName) {
        this.javaClassName = javaClassName;
    }

    /**
     * Return the class indicator field name for this type info.
     *
     * @return
     */
    public String getXmlDiscriminatorNode() {
        return xmlDiscriminatorNode;
    }

    /**
     * Sets the class indicator field name (for use with inheritance).
     *
     * @param xmlDiscriminatorNode
     */
    public void setXmlDiscriminatorNode(String xmlDiscriminatorNode) {
        this.xmlDiscriminatorNode = xmlDiscriminatorNode;
    }

    /**
     * Indicates if the class indicator field name is set, i.e. is non-null
     *
     * @return true if xmlDiscriminatorNode != null, otherwise false
     */
    public boolean isSetXmlDiscriminatorNode() {
        return xmlDiscriminatorNode != null;
    }

    /**
     * Return the value of the class indicator field for the java-type
     * associated with this type info.
     *
     * @return
     */
    public String getXmlDiscriminatorValue() {
        return xmlDiscriminatorValue;
    }

    /**
     * Set the value of the class indicator field for the java-type
     * associated with this type info.
     *
     * @param xmlDiscriminatorValue
     */
    public void setXmlDiscriminatorValue(String xmlDiscriminatorValue) {
        this.xmlDiscriminatorValue = xmlDiscriminatorValue;
    }

    /**
     * Indicates if a class indicator field value has been set,
     * i.e. is non-null
     *
     * @return true if xmlDiscriminatorValue != null, otherwise false
     */
    public boolean isSetXmlDiscriminatorValue() {
        return xmlDiscriminatorValue != null;
    }

    /**
     * Add an XmlKey property to the list.  Each entry will be
     * set as a primary key on the owning descriptor.
     *
     * @param xmlKeyProp
     */
    public void addXmlKeyProperty(Property xmlKeyProp) {
        if (xmlKeyProperties == null) {
            xmlKeyProperties = new ArrayList<Property>();
        }
        xmlKeyProperties.add(xmlKeyProp);
    }

    /**
     * Return the list of XmlKey property entries.  Each entry
     * will be set as a primary key on the owning descriptor.
     *
     * @return
     */
    public List<Property> getXmlKeyProperties() {
        return xmlKeyProperties;
    }

    /**
     * Indicates if the list of XmlKey property entries has
     * been set, i.e. is non-null.
     *
     * @return
     */
    public boolean hasXmlKeyProperties() {
        return xmlKeyProperties != null;
    }

    /**
     * Return a Map of property names to list of properties.  This Map will
     * contain entries when one or more properties exist for a given field,
     * as in the case of multiple mappings for a single field.
     *
     */
    public Map<String, List<Property>> getAdditionalProperties() {
        if (!hasAdditionalProperties()) {
            additionalProperties = new HashMap<String, List<Property>>();
        }
        return additionalProperties;
    }

    boolean hasAdditionalProperties() {
        return null != additionalProperties;
    }

    /**
     * Return the list of original properties for this type info.  These
     * properties were created during annotations processing, and have
     * not been modified since.
     *
     * @return
     */
    public HashMap<String, Property> getOriginalProperties() {
        return originalProperties;
    }

    public XmlVirtualAccessMethods getXmlVirtualAccessMethods() {
        return xmlExtensible;
    }

    public void setXmlVirtualAccessMethods(XmlVirtualAccessMethods xmlExtensible) {
        this.xmlExtensible = xmlExtensible;
    }


    /**
     * Return the XMLNameTransformer used when converting Java names to XML names
     * @return
     */
    public XMLNameTransformer getXmlNameTransformer() {
        return xmlNameTransformer;
    }

    /**
     * Set the XMLNameTransformer used when converting Java names to XML names
     * @param xmlNameTransformer
     */
    public void setXmlNameTransformer(XMLNameTransformer xmlNameTransformer) {
        this.xmlNameTransformer = xmlNameTransformer;
    }


    /**
     * INTERNAL:
     * Return the list of predicate properties. Lazy initializes the list.
     * @return
     */
    public List<Property> getPredicateProperties() {
        if(predicateProperties == null) {
            predicateProperties = new ArrayList<Property>();
        }
        return predicateProperties;
    }

    /**
     * INTERNAL:
     * Return true if the property handed in is a duplicate of any existing predicate property.
     */
    public boolean hasPredicateProperty(Property property) {
        if(this.predicateProperties != null) {
            for(Property next:this.predicateProperties) {
                if(next.getXmlPath().equals(property.getXmlPath())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Return true if the list of predicate properties hasn't been initialized.
     * @return
     */
    public boolean hasPredicateProperties() {
        return this.predicateProperties != null && this.predicateProperties.size() > 0;
    }

    public boolean isLocationAware() {
        return this.isLocationAware;
    }

    public void setLocationAware(boolean value) {
        this.isLocationAware = value;
    }

    /**
     * This event is called when all of the metadata for this type has been
     * processed and provides a chance to deference anything that is no longer
     * needed to reduce the memory footprint of this object.
     */
    void postInitialize() {
        this.originalProperties = null;
    }

    public AccessorFactoryWrapper getXmlAccessorFactory() {
        return xmlAccessorFactory;
    }

    public void setXmlAccessorFactory(AccessorFactoryWrapper xmlAccessorFactory) {
        this.xmlAccessorFactory = xmlAccessorFactory;
    }

    public AccessorFactoryWrapper getPackageLevelXmlAccessorFactory() {
        return packageLevelXmlAccessorFactory;
    }

    public void setPackageLevelXmlAccessorFactory(AccessorFactoryWrapper packageLevelXmlAccessorFactory) {
        this.packageLevelXmlAccessorFactory = packageLevelXmlAccessorFactory;
    }

    public List<XmlNamedObjectGraph> getObjectGraphs() {
        if(this.objectGraphs == null) {
            this.objectGraphs = new ArrayList<XmlNamedObjectGraph>();
        }
        return this.objectGraphs;
    }

    public JavaClass getJavaClass() {
        return javaClass;
    }

    public void setJavaClass(JavaClass javaClass) {
        this.javaClass = javaClass;
    }

}
