/*
 * 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.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;

import org.eclipse.persistence.jaxb.compiler.facets.Facet;
import org.eclipse.persistence.internal.jaxb.GenericsClassHelper;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.jaxb.javamodel.*;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl;
import org.eclipse.persistence.jaxb.xmlmodel.XmlAbstractNullPolicy;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementRef;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElements;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes;
import org.eclipse.persistence.jaxb.xmlmodel.XmlMarshalNullRepresentation;
import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation;
import org.eclipse.persistence.oxm.XMLField;

/**
 *  INTERNAL:
 *  <p><b>Purpose:</b>To store information about a property on a class during JAXB 2.0 Generation
 *  <p><b>Responsibilities:</b><ul>
 *  <li>Store information about the java property such as property name, if it's a method or field,
 *  and it's type.</li>
 *  <li>Store some schema-specific information such as the schema name, the schema type, and mimeType</li>
 *  <li>Store some JAXB 2.0 Runtime specific information such as JAXB 2.0 Adapter classes</li>
 *  </ul>
 *  <p>This class is used to store information about a property on a JAXB 2.0 annotated class. It is
 *  created by the AnnotationsProcessor during pre-processing and stored on a TypeInfo object
 *
 *  @see org.eclipse.persistence.jaxb.compiler.TypeInfo
 *  @see org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor
 *
 *  @author mmacivor
 */
public class Property implements Cloneable {
    private String propertyName;
    private QName schemaName;
    private boolean isMethodProperty;
    private QName schemaType;
    private boolean isSwaAttachmentRef;
    private boolean isMtomAttachment;
    private boolean isInlineBinaryData;
    private String mimeType;
    private JavaClass type;
    private JavaHasAnnotations element;
    private JavaClass genericType;
    private boolean isAttribute = false;
    private boolean isAnyAttribute = false;
    private boolean isAnyElement = false;
    private Helper helper;
    private Map<Object, Object> userProperties;
    private List<Facet> facets = new ArrayList<Facet>();
    private boolean isXmlValueExtension;
    private boolean isXmlIdExtension;

    //Original get and set methods for this property
    //Used to keep track of overrides
    private String originalGetMethodName;
    private String originalSetMethodName;

    private String getMethodName;
    private String setMethodName;
    private boolean isRequired = false;
    private boolean isNillable = false;
    private boolean isXmlList = false;
    private boolean isTransient;
    private String defaultValue;
    private boolean isMixedContent = false;
    private boolean xmlElementType = false;
    private JavaClass originalType;
    private String fixedValue;
    private Boolean isReadOnly;
    private Boolean isWriteOnly;
    private Boolean isCdata;
    private boolean isVirtual = false;
    private XmlTransformation xmlTransformation;
    private XmlAbstractNullPolicy nullPolicy;
    private XmlJavaTypeAdapter xmlJavaTypeAdapter;
    private XmlElementWrapper xmlElementWrapper;
    private boolean isXmlValue = false;
    private boolean isXmlId = false;
    private boolean isXmlIdRef = false;
    private boolean isXmlTransformation = false;
    private boolean isXmlLocation = false;

    private String inverseReferencePropertyName;
    private String inverseReferencePropertyGetMethodName;
    private String inverseReferencePropertySetMethodName;
    private JavaClass inverseReferencePropertyContainerClass;
    private boolean isInverseReference;
    private boolean isWriteableInverseReference;

    // XmlAnyElement specific attributes
    private boolean lax;
    private String domHandlerClassName;
    private String variableAttributeName;
    private String variableClassName;
    private boolean variableNodeAttribute;

    // XmlMap specific attributes
    private JavaClass keyType;
    private JavaClass valueType;
    private JavaClass valueGenericType;
    public static final String DEFAULT_KEY_NAME =  "key";
    public static final String DEFAULT_VALUE_NAME =  "value";
    private boolean isMap = false;
    private String xmlPath;

    // XmlElements specific attributes
    private Collection<Property> choiceProperties;
    private XmlElements xmlElements;
    private boolean isChoice = false;

    // XmlElementRef specific attributes
    private ArrayList<ElementDeclaration> referencedElements;
    private List<XmlElementRef> xmlElementRefs;
    private boolean isReference = false;

    // XmlJoinNodes specific attributes
    private XmlJoinNodes xmlJoinNodes;
    private List<XmlJoinNodes> xmlJoinNodesList;
    private boolean isSuperClassProperty;

    private boolean isTransientType;
    private static final String MARSHAL_METHOD_NAME = "marshal";

    private JavaClass xmlAdapterClass;
    private JavaClass objectClass;

    private boolean isTyped;
    private Integer minOccurs;
    private Integer maxOccurs;
    private boolean notNullAnnotated;


    public Property() {}

    public Property(Helper helper) {
        this.helper = helper;

        xmlAdapterClass = helper.getJavaClass(XmlAdapter.class);
        objectClass = helper.getJavaClass(Object.class);
    }

    public void setHelper(Helper helper) {
        this.helper = helper;
    }

    /**
     * Set an XmlAdapter on this Property.  The type, generic type and
     * original type will be set as required based on the XmlAdapter's
     * marshal method return type and input parameters.
     *
     * @param adapterCls
     */
    public void setAdapterClass(JavaClass adapterCls) {

        if (adapterCls.instanceOf() == JavaClassInstanceOf.JAVA_CLASS_IMPL) {
            Type[] parameterizedTypeArguments = GenericsClassHelper.getParameterizedTypeArguments(((JavaClassImpl)adapterCls).getJavaClass(), XmlAdapter.class);
            if (null != parameterizedTypeArguments && null != parameterizedTypeArguments[0]) {
                JavaClass valueTypeClass = getJavaClassFromType(parameterizedTypeArguments[0]);
                JavaClass boundType = getJavaClassFromType(parameterizedTypeArguments[1]);

                if (valueTypeClass.isInterface()) {
                    valueTypeClass = objectClass; // during unmarshalling we'll need to instantiate this, so -> no interfaces
                }

                setTypeFromAdapterClass(valueTypeClass, boundType);
                return;
            }
        }

        // If no generic superclass was found, use the old method of looking at
        // marshal method return type.  This mechanism is used for Dynamic JAXB.
        ArrayList<JavaMethod> marshalMethods = new ArrayList<JavaMethod>();

        // Look for marshal method
        for (JavaMethod method : (Collection<JavaMethod>) adapterCls.getMethods()) {
            if (!method.isBridge() && method.getName().equals(MARSHAL_METHOD_NAME)) {
                final JavaClass[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length != 1)
                    continue;
                JavaClass returnType = method.getReturnType();

                // Try and find a marshal method where Object is not the return type,
                // to avoid processing an inherited default marshal method
                if (!returnType.getQualifiedName().equals(objectClass.getQualifiedName()) && !returnType.isInterface()) { // if it's interface, we'll use OBJECT instead later
                    setTypeFromAdapterClass(returnType, parameterTypes[0]);
                    return;
                }
                // Found a marshal method with an Object return type; add
                // it to the list in case we need to process it later
                marshalMethods.add(method);
            }
        }
        // At this point we didn't find a marshal method with a non-Object return type
        for (JavaMethod method : marshalMethods) {
            JavaClass paramType = method.getParameterTypes()[0];
            // look for non-Object parameter type
            if (!paramType.getQualifiedName().equals(objectClass.getQualifiedName())) {
                setTypeFromAdapterClass(objectClass, paramType);
                return;
            }
        }
        if (!marshalMethods.isEmpty())
            setTypeFromAdapterClass(objectClass, null);
        // else impossible? - looks like provided adapted doesn't contain marshal(...) method
    }

    private JavaClass getJavaClassFromType(Type t) {
        if (t instanceof Class) {
            return helper.getJavaClass((Class) t);
        } else if (t instanceof ParameterizedType) {
            ParameterizedType paramValueType = (ParameterizedType) t;
            Type rawType = paramValueType.getRawType();
            if (rawType instanceof Class) {
                return helper.getJavaClass((Class) rawType);
            }
        } else if (t instanceof TypeVariable<?>) {
            TypeVariable<?> valueTypeVariable = (TypeVariable<?>) t;
            return helper.getJavaClass((Class) valueTypeVariable.getBounds()[0]);
        } else if (t instanceof GenericArrayType) {
            GenericArrayType genericArrayValueType = (GenericArrayType) t;
            Type rawType = genericArrayValueType.getGenericComponentType();
            if (rawType instanceof Class) {
                return helper.getJavaClass(Array.newInstance((Class) rawType, 1).getClass());
            }
        }
        return objectClass;
    }

    /**
     * This convenience method will set the generic type, type and original type
     * for this Porperty as required based on a given 'new' type and parameter
     * type. This method will typically be called when setting the type during
     * adapter processing.
     *
     * @param newType
     * @param parameterType
     */
    private void setTypeFromAdapterClass(JavaClass newType, JavaClass parameterType) {
        boolean isArray = this.getType().isArray() && !this.getType().getRawName().equals("byte[]");
        boolean isParamTypeArray = false;
        if(parameterType != null) {
            isParamTypeArray = parameterType.isArray() && !parameterType.getRawName().equals("byte[]");
        }
        if ((helper.isCollectionType(this.getType()) || isArray) && !(helper.isCollectionType(parameterType) || isParamTypeArray)) {
            this.setGenericType(newType);
        } else {
            this.setOriginalType(this.getType());
            this.setType(newType);
        }
    }

    public JavaHasAnnotations getElement() {
        return element;
    }

    public void setElement(JavaHasAnnotations element) {
        this.element = element;
    }

    public String getPropertyName() {
        return propertyName;
    }

    public void setPropertyName(String propertyName) {
        this.propertyName = propertyName;
    }

    public QName getSchemaName() {
        return this.schemaName;
    }

    public void setSchemaName(QName schemaName) {
        this.schemaName = schemaName;
    }

    public boolean isMethodProperty() {
        return isMethodProperty;
    }

    public void setMethodProperty(boolean isMethod) {
        isMethodProperty = isMethod;
    }

    public void setType(JavaClass cls) {
        if(cls == null){
            return;
        }
        if(type != null && type == cls){
            return;
        }
        String clsName= cls.getRawName();
        if(helper.isCollectionType(cls)){
               genericType = getGenericType(cls, 0, helper);
            type = cls;
        }else if(cls.isArray()  && !clsName.equals("byte[]") ){
            type = cls;
            genericType = cls.getComponentType();
        }else{
            type = cls;
            genericType = null;
        }

        boolean isNewTypeMap = helper.getJavaClass(java.util.Map.class).isAssignableFrom(type);
        setIsMap(isNewTypeMap);

        if(isMap()){
            if(type.getPackageName().startsWith("java.")) {
                Object[] types = type.getActualTypeArguments().toArray();

                 if(types.length >=2){
                     keyType = (JavaClass)types[0];
                     valueType = (JavaClass)types[1];
                     if (helper.isCollectionType(valueType)) {
                         valueGenericType = getGenericType(valueType, 0, helper);
                     } else if (valueType.isArray() && !"byte[]".equals(valueType.getRawName())) {
                         valueGenericType = valueType.getComponentType();
                     } else {
                         valueGenericType = null;
                     }
                 }else{
                     keyType = helper.getJavaClass(Object.class);
                     valueType = helper.getJavaClass(Object.class);
                 }
            } else {
                keyType = getGenericType(type, 0, helper);
                valueType = getGenericType(type, 1, helper);
            }
        }

    }

    private JavaClass getGenericType(JavaClass cls, int argument, Helper helper){
        Collection typeArgs = cls.getActualTypeArguments();
        Object[] typeArgsArray = typeArgs.toArray();
        JavaClass genericType = null;
        if(cls.getPackageName().startsWith("java.")) {
            if(typeArgs.size() > argument){
                Iterator iterator = typeArgs.iterator();
                for(int x=0; x<argument; x++) {
                    iterator.next();
                }
                return (JavaClass) iterator.next();
            } else {
                return helper.getJavaClass(Object.class);
            }
        }else{
            Map<String, JavaClass> variableToType = null;

            if(cls instanceof JavaClassImpl){
                variableToType = new HashMap<String, JavaClass>();
                TypeVariable[] tvs = ((JavaClassImpl)cls).getJavaClass().getTypeParameters();
                if(tvs.length == typeArgsArray.length){
                    for (int x = 0; x < tvs.length; x++) {
                        variableToType.put(tvs[x].getName(), (JavaClass)typeArgsArray[x]);
                    }
                }
            }

            Type genericTypeType = getGenericType(cls.getGenericSuperclass(), argument, variableToType);

            if(null == genericTypeType) {
                for(Type genericInterface : cls.getGenericInterfaces()) {
                    genericTypeType = getGenericType(genericInterface, argument, variableToType);
                    if(null != genericTypeType) {
                        break;
                    }
                }
            }
            if(genericTypeType instanceof TypeVariable) {
                TypeVariable typeVariable = (TypeVariable) genericTypeType;
                JavaClass existing = variableToType.get(typeVariable.getName());
                if( existing != null){
                    return existing;
                }else{
                    Type[] typeVariableBounds = typeVariable.getBounds();
                    if(typeVariableBounds.length > 0) {
                        genericTypeType = typeVariableBounds[0];
                    }
                }
            }

            if(genericTypeType instanceof Class) {
                genericType = helper.getJavaClass((Class) genericTypeType);
            }
            if(null == genericType || genericTypeType == Object.class) {
                if(typeArgs.size() > argument){
                    Iterator iterator = typeArgs.iterator();
                    for(int x=0; x<argument; x++) {
                        iterator.next();
                    }
                    genericType = (JavaClass) iterator.next();
                } else {
                    genericType = helper.getJavaClass(Object.class);
                }
            }
            return genericType;
        }

    }

    private Type getGenericType(Type type, int argument, Map<String, JavaClass> variableToType) {
        if(type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type rawType = parameterizedType.getRawType();
            if(rawType instanceof Class) {
                Class rawTypeClass = (Class) rawType;
                Type[] typeArgs = parameterizedType.getActualTypeArguments();
                TypeVariable[] tvs = rawTypeClass.getTypeParameters();
                if(tvs.length == typeArgs.length){
                    for (int x = 0; x < tvs.length; x++) {
                        String name = tvs[x].getName();
                        Type theType = typeArgs[x];
                        if(!variableToType.containsKey(name) && theType instanceof Class){
                            variableToType.put(name, helper.getJavaClass((Class)theType));
                        }
                    }
                }

                if(rawTypeClass.getPackage().getName().startsWith("java.")) {
                    Type actualType = parameterizedType.getActualTypeArguments()[argument];
                    return actualType;
                }
                Type genericType = getGenericType(rawType, argument, variableToType);
                if(genericType != null) {
                    return genericType;
                } else {
                    return parameterizedType.getActualTypeArguments()[argument];
                }
            } else {
                return getGenericType(parameterizedType.getRawType(), argument,variableToType);
            }
        } else if(type instanceof Class) {
            Class clazz = (Class) type;
            for(Type genericInterface : clazz.getGenericInterfaces()) {
                Type genericType = getGenericType(genericInterface, argument, variableToType);
                if(null != genericType) {
                    return genericType;
                }
            }
            return getGenericType(clazz.getGenericSuperclass(), argument, variableToType);
        }
        return null;
    }

    public JavaClass getType() {
        return type;
    }

    public JavaClass getGenericType() {
        return genericType;
    }

    public void setGenericType(JavaClass genericType) {
        this.genericType = genericType;
    }

    public QName getSchemaType() {
        return schemaType;
    }

    public void setSchemaType(QName type) {
        schemaType = type;
    }

    public boolean isSwaAttachmentRef() {
        return isSwaAttachmentRef;
    }

    public void setIsSwaAttachmentRef(boolean b) {
        isSwaAttachmentRef = b;
    }

    public boolean isMtomAttachment() {
        return isMtomAttachment;
    }

    public void setIsMtomAttachment(boolean b) {
        isMtomAttachment = b;
    }

    /**
     * Indicates if XOP encoding should be disabled for datatypes that
     * are bound to base64-encoded binary data in XML.
     *
     * @return true if XOP encoding should be disabled for datatypes
     * that are bound to base64-encoded binary data in XML; false if
     * not
     */
    public boolean isInlineBinaryData() {
        return isInlineBinaryData;
    }

    /**
     * Sets the flag that indicates if XOP encoding should  be disabled
     * for datatypes that are bound to base64-encoded binary data in
     * XML.

     * @param b if true, XOP encoding will be disabled for datatypes
     * that are bound to base64-encoded binary data in XML.
     */
    public void setisInlineBinaryData(boolean b) {
        isInlineBinaryData = b;
    }

    public boolean isRequired() {
        return isRequired;
    }



    public boolean isTransientType() {
        return isTransientType;
    }

    public void setTransientType(boolean isTransientType) {
        this.isTransientType = isTransientType;
    }

    public void setIsRequired(boolean b) {
        isRequired = b;
    }

    public String getMimeType() {
        return mimeType;
    }

    public void setMimeType(String mType) {
        mimeType = mType;
    }

    public boolean isAttribute() {
        return isAttribute || isAnyAttribute;
    }

    public boolean isAnyAttribute() {
        return isAnyAttribute;
    }

    public void setIsAttribute(boolean attribute) {
        isAttribute = attribute;
    }

    public void setIsAnyAttribute(boolean anyAtribute) {
        isAnyAttribute = anyAtribute;
    }

    public String getGetMethodName() {
        return getMethodName;
    }

    public void setGetMethodName(String methodName) {
        getMethodName = methodName;
    }

    public String getSetMethodName() {
        return setMethodName;
    }

    public void setSetMethodName(String methodName) {
        setMethodName = methodName;
    }

    public String getOriginalGetMethodName() {
        return originalGetMethodName;
    }

    public void setOriginalGetMethodName(String methodName) {
        originalGetMethodName = methodName;
    }

    public String getOriginalSetMethodName() {
        return originalSetMethodName;
    }

    public void setOriginalSetMethodName(String methodName) {
        originalSetMethodName = methodName;
    }

    /**
     * Indicates if this property represents a choice property.
     *
     * @return
     */
    public boolean isChoice() {
        return isChoice;
    }

    /**
     * Set flag to indicate whether this property represents a choice
     * property.
     *
     * @param choice
     */
    public void setChoice(boolean choice) {
        isChoice = choice;
    }

    /**
     * Returns indicator for XmlAnyElement
     *
     * @return
     */
    public boolean isAny() {
        return isAnyElement;
    }

    /**
     * Set indicator for XmlAnyElement.
     *
     * @param isAnyElement
     */
    public void setIsAny(boolean isAnyElement) {
        this.isAnyElement = isAnyElement;
    }

    /**
     * Indicates if this Property is a reference property.
     *
     * @return
     */
    public boolean isReference() {
        return isReference;
    }

    /**
     * Set flag to indicate whether this property represents a reference
     * property.
     *
     * @param isReference
     */
    public void setIsReference(boolean isReference) {
        this.isReference = isReference;
    }

    public boolean isNillable() {
        return isNillable;
    }

    public void setNillable(boolean isNillable) {
        this.isNillable = isNillable;
    }

    public boolean isTransient() {
        return isTransient;
    }

    public void setTransient(boolean isTransient) {
        this.isTransient = isTransient;
    }

    /**
     * @param defaultValue the defaultValue to set
     */
    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }

    /**
     * @return the defaultValue
     */
    public String getDefaultValue() {
        return defaultValue;
    }

    /**
     * @return the isSetDefaultValue
     */
    public boolean isSetDefaultValue() {
        return defaultValue != null;
    }

    public boolean isMixedContent() {
        return isMixedContent;
    }

    public void setMixedContent(boolean b) {
        this.isMixedContent = b;
    }

    public void setHasXmlElementType(boolean hasXmlElementType) {
        this.xmlElementType = hasXmlElementType;
    }

    public boolean isXmlElementType() {
        return xmlElementType;
    }

    /**
     * Return the generic type if it was set (collection or array item type) otherwise return the
     * type of this property
     *
     * @return
     */
    public JavaClass getActualType() {
        if (genericType != null) {
            return genericType;
        }
        return type;
    }

    /**
     * Get the original type of the property.  This is typically used when
     * the type has been changed via @XmlElement annotation and the
     * original type is desired.
     *
     * @return
     */
    public JavaClass getOriginalType() {
        if (originalType == null) // in case of adapter which returns the same type - original type is the same as type
            return type;
        return originalType;
    }

    /**
     * Set the original type of the property.  This is typically used when
     * the type will been changed via @XmlElement annotation and the
     * original type may be needed.
     */
    public void  setOriginalType(JavaClass type) {
        originalType = type;
    }

    /**
     * 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 Property.
     *
     * @return xmlJavaTypeAdapter, or null if not set
     * @see XmlJavaTypeAdapter
     */
    public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
        return xmlJavaTypeAdapter;
    }

    /**
     * Set an XmlJavaTypeAdapter on this Property.  This call sets the adapterClass
     * property to the given adapter's value.
     *
     * @param xmlJavaTypeAdapter
     * @see XmlJavaTypeAdapter
     */
    public void setXmlJavaTypeAdapter(XmlJavaTypeAdapter xmlJavaTypeAdapter) {
        this.xmlJavaTypeAdapter = xmlJavaTypeAdapter;
        if (xmlJavaTypeAdapter == null) {
            setType(originalType);
        } else {
            // set the adapter class
            setAdapterClass(helper.getJavaClass(xmlJavaTypeAdapter.getValue()));
        }
    }

    /**
     * Indicates if an XmlElementWrapper has been set, i.e. the
     * xmlElementWrapper property is non-null.

     * @return true if xmlElementWrapper is non-null, false otherwise
     */
    public boolean isSetXmlElementWrapper() {
        return getXmlElementWrapper() != null;
    }

    /**
     * Return the XmlElementWrapper set on this property.
     *
     * @return XmlElementWrapper instance if non-null, null otherwise
     */
    public XmlElementWrapper getXmlElementWrapper() {
        return xmlElementWrapper;
    }

    /**
     * Set the XmlElementWrapper for this property.
     *
     * @param xmlElementWrapper
     */
    public void setXmlElementWrapper(XmlElementWrapper xmlElementWrapper) {
        this.xmlElementWrapper = xmlElementWrapper;
    }

    /**
     * Set the isXmlValue property.
     *
     * @param isXmlValue
     */
    public void setIsXmlValue(boolean isXmlValue) {
        this.isXmlValue = isXmlValue;
    }

    /**
     * Indicates if this property is an XmlValue.
     *
     * @return
     */
    public boolean isXmlValue() {
        return this.isXmlValue;
    }

    /**
     * Set the isXmlValueExtension property.
     *
     * @param isXmlValueExtension
     */
    public void setIsXmlValueExtension(boolean isXmlValueExtension) {
        this.isXmlValueExtension = isXmlValueExtension;
    }

    /**
     * Indicates if this property is an XmlValueExtension.
     *
     * @return
     */
    public boolean isXmlValueExtension() {
        return this.isXmlValueExtension;
    }

    /**
     * Set the isXmlList property.
     *
     * @param isXmlList
     */
    public void setIsXmlList(boolean isXmlList) {
        this.isXmlList = isXmlList;
        if(isXmlList){
            this.setNillable(false);
        }
    }

    /**
     * Indicates if this property is an XmlList.
     *
     * @return
     */
    public boolean isXmlList() {
        return this.isXmlList;
    }

    public String getInverseReferencePropertyName() {
        return this.inverseReferencePropertyName;
    }

    public void setInverseReferencePropertyName(String name) {
        this.inverseReferencePropertyName = name;
    }

    public String getInverseReferencePropertyGetMethodName() {
        return this.inverseReferencePropertyGetMethodName;
    }

    public String getInverseReferencePropertySetMethodName() {
        return this.inverseReferencePropertySetMethodName;
    }

    public void setInverseReferencePropertyGetMethodName(String methodName) {
        this.inverseReferencePropertyGetMethodName = methodName;
    }

    public void setInverseReferencePropertySetMethodName(String methodName) {
        this.inverseReferencePropertySetMethodName = methodName;
    }

    public JavaClass getInverseReferencePropertyContainerClass() {
        return this.inverseReferencePropertyContainerClass;
    }

    public void setInverseReferencePropertyContainerClass(JavaClass cls) {
        this.inverseReferencePropertyContainerClass = cls;
    }

    /**
     * Indicates if this property is an ID field.
     *
     * @return
     */
    public boolean isXmlId() {
        return isXmlId;
    }

    /**
     * Sets the indicator that identifies this property as an ID field.
     *
     * @param isXmlId
     */
    public void setIsXmlId(boolean isXmlId) {
        this.isXmlId = isXmlId;
    }

    /**
     * Indicates if this property is an ID extension field.
     *
     * @return
     */
    public boolean isXmlIdExtension() {
        return isXmlIdExtension;
    }

    /**
     * Sets the indicator that identifies this property as an ID extension field.
     *
     * @param isXmlIdExtension
     */
    public void setIsXmlIdExtension(boolean isXmlIdExtension) {
        this.isXmlIdExtension = isXmlIdExtension;
    }

    /**
     * Indicates if this property is a reference to an ID field.
     *
     * @return
     */
    public boolean isXmlIdRef() {
        return isXmlIdRef;
    }

    /**
     * Sets the indicator that identifies this property as a reference
     * to an ID field.
     *
     * @param isXmlIdRef
     */
    public void setIsXmlIdRef(boolean isXmlIdRef) {
        this.isXmlIdRef = isXmlIdRef;
    }

    // XmlAnyElement specific methods

    /**
     * Used with XmlAnyElement.
     *
     * @return
     */
    public boolean isLax() {
        return lax;
    }

    /**
     * Used with XmlAnyElement.
     *
     * @param b
     */
    public void setLax(boolean b) {
        lax = b;
    }

    /**
     * Return the DomHandler class name.
     * Used with XmlAnyElement.
     *
     * @return
     */
    public String getDomHandlerClassName() {
        return domHandlerClassName;
    }

    /**
     * Set the DomHandler class name.
     * Used with XmlAnyElement.
     *
     * @param domHandlerClassName
     */
    public void setDomHandlerClassName(String domHandlerClassName) {
        this.domHandlerClassName = domHandlerClassName;
    }

    public JavaClass getKeyType() {
        return keyType;
    }

    public void setKeyType(JavaClass keyType) {
        this.keyType = keyType;
    }

    public JavaClass getValueType() {
        return valueType;
    }

    /**
     * Return the generic type if it was set (collection or array item type) otherwise return the
     * type of this property
     *
     * @return
     */
    public JavaClass getActualValueType() {
        if (valueGenericType != null) {
            return valueGenericType;
        }
        return valueType;
    }

    public void setValueType(JavaClass valueType) {
        this.valueType = valueType;
    }

    public JavaClass getValueGenericType() {
        return valueGenericType;
    }

    public void setValueGenericType(JavaClass valueGenericType) {
        this.valueGenericType = valueGenericType;
    }

    public boolean isMap() {
        return isMap;
    }

    private void setIsMap(boolean isMap) {
        this.isMap = isMap;
    }

    public boolean isInverseReference() {
        return isInverseReference;
    }

    public void setInverseReference(boolean isInverseReference, boolean isWriteable) {
        this.isInverseReference = isInverseReference;
        this.isWriteableInverseReference = isWriteable;
    }

    public boolean isWriteableInverseReference(){
        return isWriteableInverseReference;
    }

    /**
     * Return the XmlElements object set for this Property.  Typically
     * this will only be set if we are dealing with a 'choice'.
     *
     * @return
     */
    public XmlElements getXmlElements() {
        return xmlElements;
    }

    /**
     * Set the XmlElements object for this Property.  Typically
     * this will only be set if we are dealing with a 'choice'.
     *
     * @param xmlElements
     */
    public void setXmlElements(XmlElements xmlElements) {
        this.xmlElements = xmlElements;
    }

    /**
     * Return the choice properties set on this property.  Typically this
     * will only contain properties if we are dealing with a 'choice'.
     *
     * @return
     */
    public Collection<Property> getChoiceProperties() {
        return this.choiceProperties;
    }

    /**
     * Set the choice properties for this property.  Typically this
     * will only contain properties if we are dealing with a 'choice'.
     *
     * @param properties
     */
    public void setChoiceProperties(Collection<Property> properties) {
        this.choiceProperties = properties;
    }

    /**
     * Return the List of XmlElementRef(s) for this Property.
     *
     * @return
     */
    public List<XmlElementRef> getXmlElementRefs() {
        return xmlElementRefs;
    }

    /**
     * Set the List of XmlElementRef(s) for this Property.
     *
     * @param xmlElementRefs
     */
    public void setXmlElementRefs(List<XmlElementRef> xmlElementRefs) {
        this.xmlElementRefs = xmlElementRefs;
    }

    /**
     * Add an ElementDeclaration to the list of referenced elements. Typically this
     * will only contain ElementDeclarations if we are dealing with a 'reference'.
     *
     * @param element
     */
    public void addReferencedElement(ElementDeclaration element) {
        if (referencedElements == null) {
            referencedElements = new ArrayList<ElementDeclaration>();
        }
        if (!referencedElements.contains(element)) {
            referencedElements.add(element);
        }
    }

    /**
     * Return the list of referenced elements.  Typically this will only
     * contain ElementDeclarations if we are dealing with a 'reference'.
     *
     * @return
     */
    public List<ElementDeclaration> getReferencedElements() {
        return referencedElements;
    }

    public String getFixedValue() {
        return fixedValue;
    }

    public void setFixedValue(String fixedValue) {
        this.fixedValue = fixedValue;
    }

    /**
     * Indicates if this property is mapped by position, i.e. 'name="data[1]"',
     * or is mapped by attribute value (predicate mapping), i.e.
     * 'personal-info[@pi-type='last-name']/name[@name-type='surname']/text()'
     *
     */
    public boolean isPositional() {
        if (getXmlPath() == null) {
            return false;
        }
        Field field = new XMLField(getXmlPath());
        XPathFragment frag = field.getXPathFragment();
        // loop until we have the last non-null, non-attribute, non-text fragment
        while (true) {
            if (frag.getNextFragment() != null && !frag.getNextFragment().isAttribute() && !frag.getNextFragment().nameIsText()) {
                frag = frag.getNextFragment();
            } else {
                break;
            }
        }
        return frag.containsIndex() || frag.getPredicate() != null;
    }

    /**
     * Flag the mapping for this Property as read-only.
     *
     * @param isReadOnly the true/false value to set
     */
    public void setReadOnly(boolean isReadOnly) {
        this.isReadOnly = isReadOnly;
    }

    /**
     * Indicates if the mapping for this Property is read-only.
     *
     * @return true if read-only, false if not
     */
    public boolean isReadOnly() {
        if (isReadOnly == null) {
            return false;
        }
        return isReadOnly;
    }

    /**
     * Indicates if the isReadOnly flag was set via external metadata.
     *
     * @return
     */
    public boolean isSetReadOnly() {
        return isReadOnly != null;
    }

    /**
     * Flag the mapping for this Property as write-only.
     *
     * @param isWriteOnly the true/false value to set
     */
    public void setWriteOnly(boolean isWriteOnly) {
        this.isWriteOnly = isWriteOnly;
    }

    /**
     * @return true if write-only, false if not
     */
    public boolean isWriteOnly() {
        if (isWriteOnly == null) {
            return false;
        }
        return isWriteOnly;
    }

    /**
     * Indicates if the isWriteOnly flag was set via external metadata.
     *
     * @return
     */
    public boolean isSetWriteOnly() {
        return isWriteOnly != null;
    }

    /**
     * Flag the mapping for this Property as containing character data.
     *
     * @param isCdata the true/false value to set
     */
    public void setCdata(boolean isCdata) {
        this.isCdata = isCdata;
    }

    /**
     * @return true if character data, false if not
     */
    public boolean isCdata() {
        if (isCdata == null) {
            return false;
        }
        return isCdata;
    }

    /**
     * Indicates if the isCdata flag was set via external metadata.
     *
     * @return
     */
    public boolean isSetCdata() {
        return isCdata != null;
    }

    /**
     * Return the xpath for this property.
     *
     * @return
     */
    public String getXmlPath() {
        return xmlPath;
    }

    /**
     * Set the xpath for this property.
     *
     * @param xmlPath
     */
    public void setXmlPath(String xmlPath) {
        this.xmlPath = xmlPath;
    }

    /**
     * Indicates if an xpath is set for this property.
     *
     * @return
     */
    public boolean isSetXmlPath() {
        return xmlPath != null;
    }

    /**
     * Returns the null policy for this property.
     *
     * @return null policy or null if not set
     */
    public XmlAbstractNullPolicy getNullPolicy() {
        return nullPolicy;
    }

    /**
     * Set the null policy for this property.
     *
     * @param nullPolicy
     */
    public void setNullPolicy(XmlAbstractNullPolicy nullPolicy) {
        this.nullPolicy = nullPolicy;
    }

    /**
     * Indicates if a null policy is set for this property.
     *
     * @return
     */
    public boolean isSetNullPolicy() {
        return nullPolicy != null;
    }

    /**
     * Indicates if nillable='true' should be set on a given schema component.
     * This will typically be called by SchemaGenerator.
     * The value returned will be true if one of the following is true:
     *
     * - isNillable
     * - isSetNullPolicy {@literal &&} xsi-nil-represents-null == 'true'
     * - isSetNullPolicy {@literal &&} null-representation-for-xml == 'XSI_NIL'
     *
     * @return
     */
    public boolean shouldSetNillable() {
        if (isNillable()) {
            return true;
        }
        if (isSetNullPolicy()) {
            return (getNullPolicy().isXsiNilRepresentsNull() || getNullPolicy().getNullRepresentationForXml() == XmlMarshalNullRepresentation.XSI_NIL);
        }
        return false;
    }

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

    /**
     * Indicates if a map of userProperties is set for this property.
     *
     * @return true if the userProperties property has been set,
     *         i.e. is non-null, otherwise false
     */
    public boolean isSetUserProperties() {
        return userProperties != null;
    }

    /**
     * Return the XmlTransformation set on this property.
     *
     * @return the XmlTransformation set on this property, or null if one has not been set.
     */
    public XmlTransformation getXmlTransformation() {
        return xmlTransformation;
    }

    /**
     * Set the XmlTransformation for this property.  The info contained in
     * the XmlTransformation will be used to construct an
     * XmlTransformationMapping.
     *
     * @param xmlTransformation
     */
    public void setXmlTransformation(XmlTransformation xmlTransformation) {
        this.xmlTransformation = xmlTransformation;
    }

    /**
     * Indicates if an XmlTransformation is set for this porperty.
     *
     * @return true if the xmlTransformation property has been set,
     *         i.e. is non-null, otherwise false
     */
    public boolean isSetXmlTransformation() {
        return xmlTransformation != null;
    }

    /**
     * Indicates if this property represents an XmlTransformation.
     *
     * @return value of isXmlTransformation property
     */
    public boolean isXmlTransformation() {
        return isXmlTransformation;
    }

    /**
     * Set flag that indicates if this property represents an XmlTransformation.
     *
     * @param isXmlTransformation
     */
    public void setIsXmlTransformation(boolean isXmlTransformation) {
        this.isXmlTransformation = isXmlTransformation;
    }

    /**
     * Set XmlJoinNodes for this property.
     *
     * @param xmlJoinNodes the xmlJoinNodes to set
     */
    public void setXmlJoinNodes(XmlJoinNodes xmlJoinNodes) {
        this.xmlJoinNodes = xmlJoinNodes;
        if(xmlJoinNodes != null && !CompilerHelper.hasNonAttributeJoinNodes(this)) {
            this.isAttribute = true;
        }
    }

    /**
     * Return the XmlJoinNodes for this property.
     *
     * @return the xmlJoinNodes
     */
    public XmlJoinNodes getXmlJoinNodes() {
        return xmlJoinNodes;
    }

    /**
     * Indicates if this property has XmlJoinNodes set.
     *
     * return true if xmlJoinNodes is non-null, otherwise false
     */
    public boolean isSetXmlJoinNodes() {
        return this.xmlJoinNodes != null;
    }

    /**
     * Return a shallow copy of this Property.
     * Simply calls super.clone().
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            // will never get here
        }
        return null;
    }

    /**
     * Return the list of XmlJoinNodes for this Property, if any.
     * This will typically be set when processing an XmlElements
     * declaration containing XmlJoinNodes.
     *
     */
    public List<XmlJoinNodes> getXmlJoinNodesList() {
        return xmlJoinNodesList;
    }

    /**
     * Set the list of XmlJoinNodes for this Property. This method
     * will typically be called when processing an XmlElements
     * declaration containing XmlJoinNodes.
     *
     */
    public void setXmlJoinNodesList(List<XmlJoinNodes> xmlJoinNodesList) {
        this.xmlJoinNodesList = xmlJoinNodesList;
        if(xmlJoinNodesList != null && !(xmlJoinNodesList.isEmpty()) && !CompilerHelper.hasNonAttributeJoinNodes(this)) {
            this.isAttribute = true;
        }
    }

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

    public boolean isVirtual() {
        return isVirtual;
    }

    public void setExtension(boolean value) {
        this.isVirtual = value;
    }

    public boolean isXmlLocation() {
        return isXmlLocation;
    }

    public void setXmlLocation(boolean isXmlLocation) {
        this.isXmlLocation = isXmlLocation;
    }

    /**
     * This event is called when all of the metadata for this property 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.element = null;
    }

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

    public void setIsSuperClassProperty(boolean b) {
        this.isSuperClassProperty = b;
    }

    public String getVariableAttributeName() {
        return variableAttributeName;
    }

    public void setVariableAttributeName(String variableAttributeName) {
        this.variableAttributeName = variableAttributeName;
    }

    public String getVariableClassName() {
        return variableClassName;
    }

    public void setVariableClassName(String variableClassName) {
        this.variableClassName = variableClassName;
     }

    public boolean isVariableNodeAttribute() {
        return variableNodeAttribute;
    }

    public void setVariableNodeAttribute(boolean variableNodeAttribute) {
         this.variableNodeAttribute = variableNodeAttribute;
    }

    public boolean isTyped() {
        return isTyped;
    }

    public void setTyped(boolean isTyped) {
        this.isTyped = isTyped;
    }

    public List<Facet> getFacets() {
        return facets;
    }

    public void addFacet(Facet facet) {
        facets.add(facet);
    }

    public void setMinOccurs(int minOccurs) {
        this.minOccurs = minOccurs;
    }

    public Integer getMinOccurs() {
        return minOccurs;
    }

    public void setMaxOccurs(int maxOccurs) {
        this.maxOccurs = maxOccurs;
    }

    public Integer getMaxOccurs() {
        return maxOccurs;
    }

    public void setNotNullAnnotated(boolean notNullAnnotated) {
        this.notNullAnnotated = notNullAnnotated;
    }

    public boolean isNotNullAnnotated() {
        return notNullAnnotated;
    }
}
