/*
 * 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.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.internal.oxm.XMLConversionManager;
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.NamespaceResolver;
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.
     *
     */
    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 : 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.
     *
     */
    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.
     *
     */
    public boolean isChoice() {
        return isChoice;
    }

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

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

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

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

    /**
     * Set flag to indicate whether this property represents a reference
     * property.
     *
     */
    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
     *
     */
    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.
     *
     */
    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.
     *
     * @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.
     *
     */
    public void setXmlElementWrapper(XmlElementWrapper xmlElementWrapper) {
        this.xmlElementWrapper = xmlElementWrapper;
    }

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

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

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

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

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

    /**
     * Indicates if this property is an XmlList.
     *
     */
    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.
     *
     */
    public boolean isXmlId() {
        return isXmlId;
    }

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

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

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

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

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

    // XmlAnyElement specific methods

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

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

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

    /**
     * Set the DomHandler class name.
     * Used with XmlAnyElement.
     *
     */
    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
     *
     */
    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'.
     *
     */
    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'.
     *
     */
    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'.
     *
     */
    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'.
     *
     */
    public void setChoiceProperties(Collection<Property> properties) {
        this.choiceProperties = properties;
    }

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

    /**
     * Set the List of XmlElementRef(s) for this Property.
     *
     */
    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'.
     *
     */
    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'.
     *
     */
    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<XMLConversionManager, NamespaceResolver> 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.
     *
     */
    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.
     *
     */
    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.
     *
     */
    public boolean isSetCdata() {
        return isCdata != null;
    }

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

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

    /**
     * Indicates if an xpath is set for this property.
     *
     */
    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.
     *
     */
    public void setNullPolicy(XmlAbstractNullPolicy nullPolicy) {
        this.nullPolicy = nullPolicy;
    }

    /**
     * Indicates if a null policy is set for this property.
     *
     */
    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'
     *
     */
    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.
     *
     */
    public Map<Object, Object> getUserProperties() {
        return userProperties;
    }

    /**
     * Set the Map of user-defined properties.
     *
     */
    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.
     *
     */
    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.
     *
     */
    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;
    }
}
