/*
 * 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:
//     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
     * 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;
    }

}
