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

import commonj.sdo.Property;
import commonj.sdo.Type;
import commonj.sdo.helper.HelperContext;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.xml.namespace.QName;
import org.eclipse.persistence.sdo.helper.AttributeMimeTypePolicy;
import org.eclipse.persistence.sdo.helper.InstanceClassConverter;
import org.eclipse.persistence.sdo.helper.ListWrapper;
import org.eclipse.persistence.sdo.helper.SDOMethodAttributeAccessor;
import org.eclipse.persistence.sdo.helper.SDOXSDHelper;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.FixedMimeTypePolicy;
import org.eclipse.persistence.oxm.mappings.MimeTypePolicy;
import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLMapping;
import org.eclipse.persistence.oxm.mappings.XMLNillableMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLTransformationMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.IsSetNullPolicy;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.eclipse.persistence.sdo.helper.SDOFragmentMappingAttributeAccessor;
import org.eclipse.persistence.sdo.helper.metadata.NamespaceURITransformer;
import org.eclipse.persistence.sdo.helper.metadata.QNameTransformer;

/**
 * <p><b>Purpose</b>:A representation of a Property in the {@link Type type} of a {@link commonj.sdo.DataObject data object}.
 * <p><b>Responsibilities</b>:<ul>
 * <li> A property represents an element or attribute in XML
 * </ul>
 */
public class SDOProperty implements Property, Serializable {
    private String propertyName;// unique name for this Type within Type
    private SDOType type;// the Type of this Property
    private SDOType containingType;
    private boolean isContainment;// if this Property is containment
    private boolean hasMany;// if this Property is many-valued
    private boolean readOnly;// if this Property is read-only
    private List aliasNames;// a list of alias names for this Property
    private Object defaultValue;// default value of this Property
    private boolean isDefaultSet;// flag whether the default was defined in the schema
    private int indexInType = -1;
    private int indexInDeclaredProperties = -1;
    private SDOProperty opposite;// the opposite Property
    private boolean xsd;
    private String xsdLocalName;
    private Boolean isElement;
    private boolean global;
    private boolean namespaceQualified;
    private transient DatabaseMapping xmlMapping;
    private Map<Property, Object> propertyValues;
    private boolean nullable;
    private QName xsdType;
    private boolean valueProperty;
    private List appInfoElements;
    private Map appInfoMap;
    private boolean nameCollision;
    private String uri;
    private boolean isSubstitutable;
    private Collection<SDOProperty> substitutableElements;
    private boolean finalized;
    private static boolean isActivationAvailable;

    static {
        isActivationAvailable = false;
        try {
            PrivilegedAccessHelper.getClassForName("jakarta.activation.DataHandler");
            PrivilegedAccessHelper.getClassForName("jakarta.mail.internet.MimeMultipart");
            isActivationAvailable = true;
        } catch(ClassNotFoundException ex) {
            //ignore this exception and let the boolean remain false;
        }
    }
    // hold the context containing all helpers so that we can preserve inter-helper relationships
    private HelperContext aHelperContext;

    public SDOProperty(HelperContext aContext) {
        aHelperContext = aContext;
    }

    public SDOProperty(HelperContext aContext, String aName) {
        this(aContext);
        setName(aName);
    }

    public SDOProperty(HelperContext aContext, String aName, SDOType aType) {
        this(aContext, aName);
        setType(aType);
    }

    public SDOProperty(HelperContext aContext, String aName, SDOType aType, boolean hasMany) {
        this(aContext, aName);
        setType(aType);
        this.hasMany = hasMany;
    }

    public SDOProperty(HelperContext aContext, String aUri, String aName, SDOType aType) {
        this(aContext, aName, aType);
        this.setUri(aUri);
    }

    /**
     * Returns the name of the Property.
     * @return the Property name.
     */
    @Override
    public String getName() {
        return propertyName;
    }

    /**
     * Returns the type of the Property.
     * @return the Property type.
     */
    @Override
    public SDOType getType() {
        return type;
    }

    /**
     * Returns whether the Property is many-valued.
     * @return <code>true</code> if the Property is many-valued.
     */
    @Override
    public boolean isMany() {
        return hasMany;
    }

    /**
      * Return whether or not this is an open content property.
      * @return true if this property is an open content property.
      */
    @Override
    public boolean isOpenContent() {
        int idx = getIndexInType();
        if (idx == -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns whether the Property is containment, i.e., whether it represents by-value composition.
     * @return <code>true</code> if the Property is containment.
     */
    @Override
    public boolean isContainment() {
        return isContainment;
    }

    /**
     * Returns the containing type of this Property.
     * @return the Property's containing type.
     * @see Type#getProperties()
     */
    @Override
    public SDOType getContainingType() {
        return containingType;
    }

    /**
     * Returns the default value this Property will have in a {@link commonj.sdo.DataObject data object} where the Property hasn't been set.
     * @return the default value.
     */
    @Override
    public Object getDefault() {
        if (null == defaultValue) {
            // return an Object wrapper for numeric primitives or null
            return type.getPseudoDefault();
        } else {
            return defaultValue;
        }
    }

    /**
     * Returns true if values for this Property cannot be modified using the SDO APIs.
     * When true, DataObject.set(Property property, Object value) throws an exception.
     * Values may change due to other factors, such as services operating on DataObjects.
     * @return true if values for this Property cannot be modified.
     */
    @Override
    public boolean isReadOnly() {
        return readOnly;
    }

    /**
     * Returns the opposite Property if the Property is bi-directional or null otherwise.
     * @return the opposite Property if the Property is bi-directional or null
     */
    @Override
    public SDOProperty getOpposite() {
        return opposite;
    }

    public boolean hasAliasNames() {
        return aliasNames != null && aliasNames.size() > 0;
    }

    /**
     * Return a list of alias names for this Property.
     * @return a list of alias names for this Property.
     */
    @Override
    public List getAliasNames() {
        if (aliasNames == null) {
            aliasNames = new ArrayList();
        }
        return aliasNames;
    }

    /**
     * INTERNAL:
     * Assign a string as a unique name of this Property among Properties that belongs
     * to a DataObject.
     * @param name    a string representing unique name of a property of a DataObject.
     */
    public void setName(String name) {
        if(null != name) {
            name = name.intern();
        }
        propertyName = name;
    }

    /**
     * INTERNAL:
     * Assign a Type to this Property.
     * @param type   the type of this property.
     */
    public void setType(Type type) {
        this.type = (SDOType) type;
        if(isNullable()){
            updateType();
        }
    }

    /**
     * INTERNAL:
     * Set this Property's Containment which shows parent-child relationship in a tree
     * of DataObjects.
     * @param containment     a boolean value showing if this Property is containment.
     */
    public void setContainment(boolean containment) {
        isContainment = containment;
    }

    /**
     * INTERNAL:
     * Set this property as single-valued(false) or many-valued(true).
     * Default is false.
     * @param many    a boolean value if this property is many-valued or not.
     */
    public void setMany(boolean many) {
        hasMany = many;
    }

    /**
     * INTERNAL:
     * Set this Property as read-only Property.
     * @param readOnly    boolean value implying this Property is readonly.
     */
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    /**
     * INTERNAL:
     * Set this Property's alias name list which are unique within the Type.
     * @param names     a list of alias name of this Property.
     */
    public void setAliasNames(List names) {
        aliasNames = names;
    }

    /**
     * INTERNAL:
     * Set the containing type of this Property.
     * @param type       a Type which is the containing type of this Property
     */
    public void setContainingType(Type type) {
        containingType = (SDOType) type;
    }

    /**
     * INTERNAL:
     * Set the default value of this Property.
     * @param aDefaultValue     an Object to be the default value of this type.
     */
    public void setDefault(Object aDefaultValue) {
        defaultValue = aDefaultValue;
        isDefaultSet = true;
    }

    /**
     * INTERNAL:
    * Set the opposite Property.  If not null then this Property is a of a bi-directional Property.
    * @param property the opposite Property if the Property is bi-directional, otherwise null
    */
    public void setOpposite(Property property) {
        opposite = (SDOProperty) property;
    }

    /**
      * INTERNAL:
      * Set if this property was declared in an XML schema.
      * @param xsd a boolean representing if this property was declared in an XML schema
      */
    public void setXsd(boolean xsd) {
        this.xsd = xsd;
    }

    /**
      * INTERNAL:
      * Returns if this property was declared in an XML schema.  Defaults to false.
      * @return if this property was declared in an XML schema
      */
    public boolean isXsd() {
        return xsd;
    }

    /**
      * INTERNAL:
      * Set the local name of this property.
      * @param xsdLocalName a String representing the local name of this property if it was declared in an XML schema
      */
    public void setXsdLocalName(String xsdLocalName) {
        this.xsdLocalName = xsdLocalName;
    }

    /**
      * INTERNAL:
      * Returns the local name of the Property.
      * @return the local name of the property.
      */
    public String getXsdLocalName() {
        return xsdLocalName;
    }

    /**
     * INTERNAL:
     * Set if the element or attribute corresponding to this Property is namespace qualified in the XSD.
     *  @param namespaceQualified a boolean representing if the element or attribute corresponding to this Property is namespace qualified in the XSD.
     **/
    public void setNamespaceQualified(boolean namespaceQualified) {
        this.namespaceQualified = namespaceQualified;
    }

    /**
      * INTERNAL:
      * Returns if the element or attribute corresponding to this Property should be namespace qualified in the XSD.
      * @return if the element or attribute corresponding to this Property should be namespace qualified in the XSD.
      */
    public boolean isNamespaceQualified() {
        return namespaceQualified;
    }

    /**
      * INTERNAL:
      */
    public void setXmlMapping(DatabaseMapping xmlMapping) {
        this.xmlMapping = xmlMapping;
    }

    /**
      * INTERNAL:
      */
    public DatabaseMapping getXmlMapping() {
        return xmlMapping;
    }

    /**
      * INTERNAL:
      */
    public void setGlobal(boolean global) {
        this.global = global;
    }

    /**
      * INTERNAL:
      */
    public boolean isGlobal() {
        return global;
    }

    /**
     * INTERNAL:
     * Return true if the property is an element, false if the property is an
     * attribute, and null if it has not been specified.  This property has been
     * added as a performance optimization to reduce the number of Maps created
     * for the propertyValues property.
     */
    protected Boolean isElement() {
        return isElement;
    }

    /**
      * INTERNAL:
      * Alter the default state of the policy to act as a nillable null policy
     * @param aMapping
     * @param propertyName
      */
    private void setIsSetNillablePolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) {
        AbstractNullPolicy aNullPolicy = setIsSetPolicyOnMapping(aMapping, propertyName);
        // Alter unmarshal policy state
        aNullPolicy.setNullRepresentedByEmptyNode(false);
        aNullPolicy.setNullRepresentedByXsiNil(true);
        // Alter marshal policy state
        aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.XSI_NIL);
    }

    /**
     * INTERNAL
     * Alter the default state of the policy to act as an optional non-nillable null policy
     * @param aMapping
     * @param propertyName
     */
    private void setIsSetOptionalPolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) {
        AbstractNullPolicy aNullPolicy = setIsSetPolicyOnMapping(aMapping, propertyName);
        // Alter unmarshal policy state
        aNullPolicy.setNullRepresentedByEmptyNode(false);
        aNullPolicy.setNullRepresentedByXsiNil(false);
        // Alter marshal policy state
        aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE);//.ABSENT_NODE);
    }

    /**
     * INTERNAL:
     * Create and set an IsSetNodePolicy on the mapping - leaving the policy in default state
     * @param aMapping
     * @param propertyName
     * @return
     */
    private AbstractNullPolicy setIsSetPolicyOnMapping(XMLNillableMapping aMapping, Object propertyName) {
        AbstractNullPolicy aNullPolicy = new IsSetNullPolicy();
        // Set the isSet method signature on policy
        ((IsSetNullPolicy)aNullPolicy).setIsSetMethodName(SDOConstants.SDO_ISSET_METHOD_NAME);
        // Set fields even though defaults are set
        //aNullPolicy.setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE);
        // Parameter type is always String
        ((IsSetNullPolicy)aNullPolicy).setIsSetParameterTypes(new Class[] { ClassConstants.STRING });
        ((IsSetNullPolicy)aNullPolicy).setIsSetParameters(new Object[] { propertyName });
        aMapping.setNullPolicy(aNullPolicy);
        return aNullPolicy;
    }

    /**
      * INTERNAL:
      */
    public void buildMapping(String mappingUri) {
        buildMapping(mappingUri, -1);
    }

    /**
      * INTERNAL:
      */
    public void buildMapping(String mappingUri, int indexToAdd) {
        if (getContainingType().isDataType()) {
            return;
        }

        if (getType().isChangeSummaryType()) {
            buildChangeSummaryMapping();
            addMappingToOwner(false, indexToAdd);
        } else if (isNameCollision()) {
            xmlMapping = new XMLAnyCollectionMapping();
            xmlMapping.setAttributeName(getName());
            addMappingToOwner(true, indexToAdd);
        } else {
            boolean sdoMethodAccessor = true;
            if (!getType().isDataType()) {
                if (getType().isDataObjectType()) {
                    getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME);
                    if(getXsdType() != null && !getXsdType().equals(SDOConstants.ANY_TYPE_QNAME)) {
                       if (isMany()) {
                            xmlMapping = buildXMLCompositeCollectionMapping(mappingUri);
                        } else {
                            xmlMapping = buildXMLCompositeObjectMapping(mappingUri);
                        }
                    }else{
                      sdoMethodAccessor = false;
                      if (isMany()) {
                          xmlMapping = buildXMLFragmentCollectionMapping(mappingUri);
                      } else {
                          xmlMapping = buildXMLFragmentMapping(mappingUri);
                      }
                    }
                } else {
                    if (!getType().isFinalized()) {
                        getType().getNonFinalizedReferencingProps().add(this);
                        getType().getNonFinalizedMappingURIs().add(mappingUri);
                        return;
                    }
                    if(isSubstitutable()) {
                        if(isMany()) {
                            xmlMapping = buildXMLChoiceCollectionMapping(mappingUri);
                        } else {
                            xmlMapping = buildXMLChoiceObjectMapping(mappingUri);
                        }
                    }
                    else if (isMany()) {
                        if (isContainment()) {
                            xmlMapping = buildXMLCompositeCollectionMapping(mappingUri);
                        } else {
                            xmlMapping = buildXMLCollectionReferenceMapping(mappingUri);
                        }
                    } else {
                        if (isContainment()) {
                            xmlMapping = buildXMLCompositeObjectMapping(mappingUri);
                        } else {
                            xmlMapping = buildXMLObjectReferenceMapping(mappingUri);
                        }
                    }
                }
            } else {
                if (isMany()) {
                    MimeTypePolicy mimeTypePolicy = getMimeTypePolicy();

                    //Removed check for XSD type since XSD type can't be set via typeHelper.define
                    if (isActivationAvailable && (!aHelperContext.getXSDHelper().isAttribute(this) && ((mimeTypePolicy != null) ||
                            ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler")) ||
                            (getXsdType() != null && getXsdType().equals(XMLConstants.BASE_64_BINARY_QNAME))))) {
                        xmlMapping = buildXMLBinaryDataCollectionMapping(mappingUri, mimeTypePolicy);
                    } else {
                        if(!isActivationAvailable && ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler"))) {
                            throw SDOException.unableToMapDataHandlerDueToMissingDependency(this.propertyName, this.getContainingType().getQName().toString());
                        }
                        if(isSubstitutable()) {
                            xmlMapping = buildXMLChoiceCollectionMapping(mappingUri);
                        } else {
                            xmlMapping = buildXMLCompositeDirectCollectionMapping(mappingUri);
                        }
                    }
                } else {
                    MimeTypePolicy mimeTypePolicy = getMimeTypePolicy();

                    //Removed check for XSD type since XSD type can't be set via typeHelper.define
                    if (isActivationAvailable && (!aHelperContext.getXSDHelper().isAttribute(this) && ((mimeTypePolicy != null) ||
                            ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler")) ||
                            (getXsdType() != null && getXsdType().equals(XMLConstants.BASE_64_BINARY_QNAME))))) {
                         xmlMapping = buildXMLBinaryDataMapping(mappingUri, mimeTypePolicy);
                    } else {
                        if(!isActivationAvailable && ((getType().getInstanceClass() != null) && getType().getInstanceClass().getName().equals("jakarta.activation.DataHandler"))) {
                            //throw exception
                            throw SDOException.unableToMapDataHandlerDueToMissingDependency(this.propertyName, this.getContainingType().getQName().toString());
                        }
                        if(isSubstitutable()) {
                            xmlMapping = buildXMLChoiceObjectMapping(mappingUri);
                        } else {
                            if(XMLConstants.QNAME_QNAME.equals(xsdType)) {
                                xmlMapping = buildXMLTransformationMapping(mappingUri);
                            } else {
                                xmlMapping = buildXMLDirectMapping(mappingUri);
                            }
                        }
                    }
                }
            }
            addMappingToOwner(sdoMethodAccessor, indexToAdd);
        }
    }

    /**
      * INTERNAL:
      */
    public void buildChangeSummaryMapping() {
        XMLCompositeObjectMapping aCMapping = new XMLCompositeObjectMapping();
        aCMapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(getContainingType().getURI(), false);

        aCMapping.setXPath(xpath);
        aCMapping.setGetMethodName("getChangeSummary");
        aCMapping.setSetMethodName("_setChangeSummary");
        aCMapping.setReferenceClass(SDOChangeSummary.class);
        // Handle nillable element support via the nullable property
        if (nullable) {
            setIsSetNillablePolicyOnMapping(aCMapping, propertyName);
        } else {
            // elements or attributes
            setIsSetOptionalPolicyOnMapping(aCMapping, propertyName);
        }
        setXmlMapping(aCMapping);

    }

    /**
      * INTERNAL:
      */
    public void addMappingToOwner(boolean sdoMethodAttributeAccessor, int indexToAdd) {
        if (xmlMapping != null) {
            if (sdoMethodAttributeAccessor) {
                SDOMethodAttributeAccessor accessor = null;
                if (this.getType().isDataType()) {
                    Class theClass = getType().getInstanceClass();
                    accessor = new SDOMethodAttributeAccessor(this, theClass);
                } else {
                    accessor = new SDOMethodAttributeAccessor(this);
                }
                xmlMapping.setAttributeAccessor(accessor);
            }
            if ((getContainingType() != null) && !getContainingType().isDataType()) {
                ClassDescriptor containingDescriptor = getContainingType().getXmlDescriptor();
                xmlMapping.setDescriptor(containingDescriptor);
                XMLMapping mapping = (XMLMapping)getContainingType().getXmlDescriptor().getMappingForAttributeName(getName());
                if (mapping != null) {
                    getContainingType().getXmlDescriptor().getMappings().remove(mapping);
                }
                if(indexToAdd == -1) {
                    getContainingType().getXmlDescriptor().getMappings().add(xmlMapping);
                } else {
                    //iterate over the mappings and find the correct place to insert this mapping relative to the
                    //indecies of the others.
                    SDOType containingType = getContainingType();
                    Vector<DatabaseMapping> mappings = containingType.getXmlDescriptor().getMappings();
                    boolean added = false;
                    for(int i = 0; i < mappings.size(); i++) {
                        DatabaseMapping next = mappings.get(i);
                        SDOProperty associatedProperty = containingType.getProperty(next.getAttributeName());
                        if(associatedProperty != null && indexToAdd < associatedProperty.getIndexInType()) {
                            mappings.add(i, xmlMapping);
                            added = true;
                            break;
                        }
                    }
                    if(!added) {
                        getContainingType().getXmlDescriptor().getMappings().add(xmlMapping);
                    }
                }
            }
        }
    }

    private DatabaseMapping buildXMLBinaryDataMapping(String mappingUri, MimeTypePolicy mimeTypePolicy) {
        XMLBinaryDataMapping mapping = new XMLBinaryDataMapping();
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, false);
        mapping.setMimeTypePolicy(mimeTypePolicy);
        mapping.setXPath(xpath);

        ((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);

        if (shouldAddInstanceClassConverter()) {
            InstanceClassConverter converter = new InstanceClassConverter();
            converter.setCustomClass(getType().getInstanceClass());
            mapping.setConverter(converter);
        }

        // Set the null policy on the mapping
        // Use NullPolicy or IsSetNullPolicy
        if (nullable) { // elements only
            setIsSetNillablePolicyOnMapping(mapping, propertyName);
        } else {
            // elements or attributes
            setIsSetOptionalPolicyOnMapping(mapping, propertyName);
        }
        mapping.getNullPolicy().setNullRepresentedByEmptyNode(true);

        return mapping;
    }

    private DatabaseMapping buildXMLBinaryDataCollectionMapping(String mappingUri, MimeTypePolicy mimeTypePolicy) {
        XMLBinaryDataCollectionMapping mapping = new XMLBinaryDataCollectionMapping();
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, false);

        if (!getType().getInstanceClassName().equals("jakarta.activation.DataHandler")) {
            mapping.setAttributeElementClass(getType().getInstanceClass());
        }
        mapping.setMimeTypePolicy(mimeTypePolicy);
        mapping.setXPath(xpath);

        ((XMLField)mapping.getField()).setSchemaType(XMLConstants.BASE_64_BINARY_QNAME);

        if (shouldAddInstanceClassConverter()) {
            InstanceClassConverter converter = new InstanceClassConverter();
            converter.setCustomClass(getType().getInstanceClass());
            mapping.setValueConverter(converter);
        }

        // mapping.setShouldInlineBinaryData(true);
        return mapping;
    }

    private DatabaseMapping buildXMLTransformationMapping(String mappingUri) {
        XMLTransformationMapping mapping = new XMLTransformationMapping();
        mapping.setAttributeName(getName());

        String xpath = getQualifiedXPath(mappingUri, true);
        String xpathMinusText;
        int indexOfTextXPath = xpath.lastIndexOf("/text()");
        if (indexOfTextXPath < 0) {
            xpathMinusText = xpath;
        } else {
            xpathMinusText = xpath.substring(0, indexOfTextXPath);
        }
        QNameTransformer transformer = new QNameTransformer(xpath);

        mapping.setAttributeTransformer(transformer);
        mapping.addFieldTransformer(xpath, transformer);

        NamespaceResolver nsr = new NamespaceResolver();
        nsr.put(javax.xml.XMLConstants.XMLNS_ATTRIBUTE, javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI);

        XMLField field = new XMLField();
        field.setNamespaceResolver(nsr);
        field.setXPath(xpathMinusText + "/@" + javax.xml.XMLConstants.XMLNS_ATTRIBUTE + ":" + QNameTransformer.QNAME_NAMESPACE_PREFIX);

        mapping.addFieldTransformer(field, new NamespaceURITransformer());

        return mapping;
    }

    private DatabaseMapping buildXMLDirectMapping(String mappingUri) {
        XMLDirectMapping mapping = new XMLDirectMapping();
        mapping.setNullValueMarshalled(true);
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, true);
        mapping.setXPath(xpath);

        if (getXsdType() != null) {
            ((XMLField)mapping.getField()).setSchemaType(getXsdType());
        }

        if (getType().getInstanceClass() != null) {
            if (shouldAddInstanceClassConverter()) {
                InstanceClassConverter converter = new InstanceClassConverter();
                converter.setCustomClass(getType().getInstanceClass());
                mapping.setConverter(converter);
            }
        }

        // Set the null policy on the mapping
        // Use NullPolicy or IsSetNullPolicy
        if (nullable) { // elements only
            setIsSetNillablePolicyOnMapping(mapping, propertyName);
        } else {
              // elements or attributes
            setIsSetOptionalPolicyOnMapping(mapping, propertyName);
        }
        if(this.isDefaultSet()) {
            mapping.setNullValue(getDefault());
            mapping.getNullPolicy().setNullRepresentedByEmptyNode(false);

        } else {
            mapping.getNullPolicy().setNullRepresentedByEmptyNode(true);
        }
        return mapping;
    }

    private DatabaseMapping buildXMLCompositeDirectCollectionMapping(String mappingUri) {
        XMLCompositeDirectCollectionMapping mapping = new XMLCompositeDirectCollectionMapping();
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, true);

        mapping.setXPath(xpath);
        mapping.setAttributeElementClass(getType().getInstanceClass());

        if (getXsdType() != null) {
            ((XMLField)mapping.getField()).setSchemaType(getXsdType());
        }

        if (getType().equals(SDOConstants.SDO_STRINGS)) {
            mapping.setUsesSingleNode(true);
        }

        if (getType().getInstanceClass() != null) {
            if (shouldAddInstanceClassConverter()) {
                InstanceClassConverter converter = new InstanceClassConverter();
                converter.setCustomClass(getType().getInstanceClass());
                mapping.setValueConverter(converter);
            }
        }

        return mapping;
    }

    private DatabaseMapping buildXMLCompositeCollectionMapping(String mappingUri) {
        XMLCompositeCollectionMapping mapping = new XMLCompositeCollectionMapping();
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, false);

        mapping.setXPath(xpath);

        if (!getType().isDataObjectType()) {
            QName schemaContext = getType().getXmlDescriptor().getSchemaReference().getSchemaContextAsQName(getType().getXmlDescriptor().getNamespaceResolver());
            ((XMLField)mapping.getField()).setLeafElementType(schemaContext);

            mapping.setReferenceClassName(getType().getImplClassName());
            mapping.setReferenceClass(getType().getImplClass());
        }else{
            if(getXsdType()!= null){
                ((XMLField)mapping.getField()).setLeafElementType(getXsdType());
            }
        }
        mapping.useCollectionClass(ListWrapper.class);

        // Set null policy on mapping for xsi:nil support:
        // - aNullPolicy.setNullRepresentedByEmptyNode(false);
        // - aNullPolicy.setNullRepresentedByXsiNil(true);
        setIsSetNillablePolicyOnMapping(mapping, propertyName);
        return mapping;
    }

    private DatabaseMapping buildXMLCompositeObjectMapping(String mappingUri) {
        XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping();
        mapping.setAttributeName(getName());
        String xpath = getQualifiedXPath(mappingUri, false);

        mapping.setXPath(xpath);

        if (!getType().isDataObjectType()) {
            QName schemaContext = getType().getXmlDescriptor().getSchemaReference().getSchemaContextAsQName(getType().getXmlDescriptor().getNamespaceResolver());
            ((XMLField)mapping.getField()).setLeafElementType(schemaContext);
            mapping.setReferenceClassName(getType().getImplClassName());
            mapping.setReferenceClass(getType().getImplClass());
        }else{
            if(getXsdType()!= null){
              ((XMLField)mapping.getField()).setLeafElementType(getXsdType());
            }
        }

        // Handle nillable element support via the nullable property
        if (nullable) {
            setIsSetNillablePolicyOnMapping(mapping, propertyName);
        } else {
              // elements or attributes
            setIsSetOptionalPolicyOnMapping(mapping, propertyName);
        }
        return mapping;
    }

    private DatabaseMapping buildXMLObjectReferenceMapping(String mappingUri) {
        XMLObjectReferenceMapping mapping = new XMLObjectReferenceMapping();
        mapping.setAttributeName(getName());

        if (getType().isDataObjectType()) {
            getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME);
        }
        mapping.setReferenceClassName(getType().getImplClassName());
        mapping.setReferenceClass(getType().getImplClass());

        String sourcexpath = getQualifiedXPath(getContainingType().getURI(), true);

        // Get reference ID property if it exists
        SDOProperty targetIDProp = getIDProp(getType());

        if (targetIDProp != null) {
            String targetxpath = targetIDProp.getQualifiedXPath(getType().getURI(), true);
            mapping.addSourceToTargetKeyFieldAssociation(sourcexpath, targetxpath);
        } else {
            throw SDOException.noTargetIdSpecified(getType().getURI(), getType().getName());
        }
        return mapping;
    }

    private DatabaseMapping buildXMLChoiceObjectMapping(String mappingUri) {
        XMLChoiceObjectMapping mapping = new XMLChoiceObjectMapping();
        mapping.setAttributeName(getName());

        //First add XPath for this property
        String xPath = getQualifiedXPath(mappingUri, getType().isDataType());
        mapping.addChoiceElement(xPath, getType().getImplClass());
        //For each substitutable property, create the xpath and add it.
        Iterator<SDOProperty> properties = this.getSubstitutableElements().iterator();
        while(properties.hasNext()) {
            SDOProperty nextProp = properties.next();
            xPath = nextProp.getQualifiedXPath(mappingUri, nextProp.getType().isDataType(), getContainingType());
            mapping.addChoiceElement(xPath, nextProp.getType().getImplClass());
        }
        return mapping;
    }

    private DatabaseMapping buildXMLChoiceCollectionMapping(String mappingUri) {
        XMLChoiceCollectionMapping mapping = new XMLChoiceCollectionMapping();
        mapping.setAttributeName(getName());
        mapping.useCollectionClass(ListWrapper.class);
        //First add XPath for this property
        String xPath = getQualifiedXPath(mappingUri, getType().isDataType());
        mapping.addChoiceElement(xPath, getType().getImplClass());
        //For each substitutable property, create the xpath and add it.
        Iterator<SDOProperty> properties = this.getSubstitutableElements().iterator();
        while(properties.hasNext()) {
            SDOProperty nextProp = properties.next();
            xPath = nextProp.getQualifiedXPath(mappingUri, nextProp.getType().isDataType(), getContainingType());
            mapping.addChoiceElement(xPath, nextProp.getType().getImplClass());
        }
        return mapping;
    }

    /**
     * INTERNAL:
     * Get the reference ID open content Property if it exists for this Type.
     * @return id Property or null
     */
    private SDOProperty getIDProp(Type aType) {
        return (SDOProperty)aType.getProperty((String) aType.get(SDOConstants.ID_PROPERTY));
    }

    private DatabaseMapping buildXMLCollectionReferenceMapping(String mappingUri) {
        XMLCollectionReferenceMapping mapping = new XMLCollectionReferenceMapping();
        mapping.setAttributeName(getName());

        if (getType().isDataObjectType()) {
            getType().setImplClassName(SDOConstants.SDO_DATA_OBJECT_IMPL_CLASS_NAME);
        }
        mapping.setReferenceClassName(getType().getImplClassName());
        mapping.setReferenceClass(getType().getImplClass());
        mapping.setUsesSingleNode(true);

        mapping.useCollectionClass(ArrayList.class);
        String sourcexpath = getQualifiedXPath(getContainingType().getURI(), true);

        // Get reference ID property if it exists
        SDOProperty targetIDProp = getIDProp(getType());
        if (targetIDProp != null) {
            String targetxpath = targetIDProp.getQualifiedXPath(getType().getURI(), true);
            mapping.addSourceToTargetKeyFieldAssociation(sourcexpath, targetxpath);
        } else {
            throw SDOException.noTargetIdSpecified(getType().getURI(), getType().getName());
        }
        return mapping;
    }

    private boolean shouldAddInstanceClassConverter() {
        Object value = getType().get(SDOConstants.JAVA_CLASS_PROPERTY);
        if (getType().isDataType() && (value != null)) {
            Class instanceClass = getType().getInstanceClass();
            String instanceClassName = getType().getInstanceClassName();
            if (((instanceClassName != null) && instanceClassName.equals("jakarta.activation.DataHandler")) ||//
                    (instanceClass == ClassConstants.ABYTE) ||//
                    (instanceClass == ClassConstants.APBYTE) ||//
                    (instanceClass == ClassConstants.BYTE) ||//
                    (instanceClass == ClassConstants.PBYTE) ||//
                    (instanceClass == ClassConstants.CHAR) ||//
                    (instanceClass == ClassConstants.PCHAR) ||//
                    (instanceClass == ClassConstants.DOUBLE) ||//
                    (instanceClass == ClassConstants.PDOUBLE) ||//
                    (instanceClass == ClassConstants.FLOAT) ||//
                    (instanceClass == ClassConstants.PFLOAT) ||//
                    (instanceClass == ClassConstants.LONG) ||//
                    (instanceClass == ClassConstants.PLONG) ||//
                    (instanceClass == ClassConstants.SHORT) ||//
                    (instanceClass == ClassConstants.PSHORT) ||//
                    (instanceClass == ClassConstants.INTEGER) ||//
                    (instanceClass == ClassConstants.PINT) ||//
                    (instanceClass == ClassConstants.BIGDECIMAL) ||//
                    (instanceClass == ClassConstants.BIGINTEGER) ||//
                    (instanceClass == ClassConstants.STRING) ||//
                    (instanceClass == ClassConstants.UTILDATE) ||//
                    (instanceClass == ClassConstants.CALENDAR) ||//
                    (instanceClass == ClassConstants.TIME) ||//
                    (instanceClass == ClassConstants.SQLDATE) ||//
                    (instanceClass == ClassConstants.TIMESTAMP)) {
                return false;
            }
            return true;
        }
        return false;
    }

    /**
      * INTERNAL:
      */
    public String getXPath() {
        String xpath = getXsdLocalName();
        if (xpath == null) {
            xpath = getName();
        }
        return xpath;
    }

    /**
      * INTERNAL:
      */
    public String getQualifiedXPath(String uri, boolean simple) {
        SDOType containingType = this.getContainingType();
        return getQualifiedXPath(uri, simple, containingType);
    }

    private String getQualifiedXPath(String uri, boolean simple, SDOType containingType) {
        if (valueProperty) {
            return "text()";
        }
        String xpath = getXPath();
        String prefix = null;
        if (isNamespaceQualified()) {
            prefix = containingType.getXmlDescriptor().getNonNullNamespaceResolver().resolveNamespaceURI(uri);
        }

        if (aHelperContext.getXSDHelper().isAttribute(this)) {
            if (prefix != null) {
                xpath = prefix + ":" + xpath;
            }
            xpath = "@" + xpath;
        } else {
            if (prefix != null) {
                xpath = prefix + ":" + xpath;
            }
            if (simple) {
                xpath = xpath + "/text()";
            }
        }
        return xpath;
    }

    @Override
    public Object get(Property property) {
        if(SDOConstants.XMLELEMENT_PROPERTY.equals(property)) {
            return isElement;
        }
        if(null == propertyValues) {
            return null;
        }
        return propertyValues.get(property);
    }

    @Override
    public List getInstanceProperties() {
        return new ArrayList(getPropertyValues().keySet());
    }

    /**
      * INTERNAL:
      */
    public void setPropertyValues(Map properties) {
        this.propertyValues = properties;
    }

    /**
      * INTERNAL:
      */
    public Map getPropertyValues() {
        if (propertyValues == null) {
            propertyValues = new HashMap<Property, Object>(1);
            if(null != isElement) {
                propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement);
            }

        }
        return propertyValues;
    }

    public void setInstanceProperty(Property property, Object value) {
        if(SDOConstants.XMLELEMENT_PROPERTY.equals(property)) {
            isElement = (Boolean) value;
            if(null != propertyValues) {
                propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement);
            }
        } else {
            if(null == propertyValues) {
                if(null != isElement) {
                    propertyValues = new HashMap<Property, Object>(2);
                    propertyValues.put(SDOConstants.XMLELEMENT_PROPERTY, isElement);
                } else {
                    propertyValues = new HashMap<Property, Object>(1);
                }
            }
            propertyValues.put(property, value);
            if(SDOConstants.SDOXML_URL.equals(((SDOProperty) property).getUri()) && SDOConstants.SDOXML_DATATYPE.equals(property.getName()) && value instanceof Type) {
                setType((Type)value);
            }
            if(SDOConstants.ORACLE_SDO_URL.equals(((SDOProperty) property).getUri()) && SDOConstants.XML_SCHEMA_TYPE_NAME.equals(property.getName()) && value instanceof Type) {
                Type schemaType = (Type)value;
                QName schemaTypeQName = new QName(schemaType.getURI(), schemaType.getName());
                setXsdType(schemaTypeQName);
            }
        }
    }

    /**
      * INTERNAL:
      */
    public void setIndexInType(int indexInType) {
        this.indexInType = indexInType;
    }

    /**
      * INTERNAL:
      */
    public int getIndexInType() {
        if ((indexInType == -1) && (getContainingType() != null)) {
            indexInType = getContainingType().getProperties().indexOf(this);
        }
        return indexInType;
    }

    /**
     * INTERNAL:
     */
    public void incrementIndexInType() {
        // increment index in type if it is already set
        if (indexInType != -1) {
            setIndexInType(getIndexInType() + 1);
        }
    }

    /**
      * INTERNAL:
      */
    public void setNullable(boolean nullable) {
        this.nullable = nullable;
        if(nullable && getType() != null){
            updateType();
        }
    }

    @Override
    public boolean isNullable() {
        return nullable;
    }

    /**
      * INTERNAL:
      */
    public void setXsdType(QName xsdType) {
        this.xsdType = xsdType;
    }

    /**
      * INTERNAL:
      */
    public QName getXsdType() {
        return xsdType;
    }

    /**
      * INTERNAL:
      */
    public MimeTypePolicy getMimeTypePolicy() {
        String mimeType = (String)get(SDOConstants.MIME_TYPE_PROPERTY);
        if (mimeType != null) {
            return new FixedMimeTypePolicy(mimeType);
        } else {
            mimeType = (String)get(SDOConstants.MIME_TYPE_PROPERTY_PROPERTY);
            if (mimeType != null) {
                return new AttributeMimeTypePolicy(mimeType);
            }
        }
        return null;
    }

    /**
      * INTERNAL:
      */
    public void setIndexInDeclaredProperties(int indexInDeclaredProperties) {
        this.indexInDeclaredProperties = indexInDeclaredProperties;
    }

    /**
      * INTERNAL:
      */
    public int getIndexInDeclaredProperties() {
        if ((indexInDeclaredProperties == -1) && (getContainingType() != null)) {
            indexInDeclaredProperties = getContainingType().getDeclaredProperties().indexOf(this);
        }
        return indexInDeclaredProperties;
    }

    /**
      * INTERNAL:
      */
    public void setValueProperty(boolean valueProperty) {
        this.valueProperty = valueProperty;
    }

    /**
      * INTERNAL:
      */
    public boolean isValueProperty() {
        return valueProperty;
    }

    /**
      * INTERNAL:
      */
    public void setAppInfoElements(List appInfoElements) {
        this.appInfoElements = appInfoElements;
    }

    /**
      * INTERNAL:
      */
    public List getAppInfoElements() {
        return appInfoElements;
    }

    /**
      * INTERNAL:
      */
    public Map getAppInfoMap() {
        if (appInfoMap == null) {
            appInfoMap = ((SDOXSDHelper)aHelperContext.getXSDHelper()).buildAppInfoMap(appInfoElements);
        }
        return appInfoMap;
    }

    public void setNameCollision(boolean nameCollision) {
        this.nameCollision = nameCollision;
    }

    public boolean isNameCollision() {
        return nameCollision;
    }

    /**
     * INTERNAL:
     * Return whether the default value has been set by the schema
     * either via a define by an XSD or a DataObject.
     * @return isDefaultSet
     */
    public boolean isDefaultSet() {
        return isDefaultSet;
    }

    public void setUri(String uri) {
        if(null != uri) {
            uri = uri.intern();
        }
        this.uri = uri;
    }

    public String getUri() {
        return uri;
    }

    public XMLFragmentMapping buildXMLFragmentMapping(String uri) {
        XMLFragmentMapping mapping = new XMLFragmentMapping();
        mapping.setAttributeName(getName());
        mapping.setXPath(getQualifiedXPath(uri, false));
        mapping.setAttributeAccessor(new SDOFragmentMappingAttributeAccessor(this, aHelperContext));

        return mapping;
    }

    public XMLFragmentCollectionMapping buildXMLFragmentCollectionMapping(String mappingUri) {
        XMLFragmentCollectionMapping mapping = new XMLFragmentCollectionMapping();
        mapping.setAttributeName(getName());
        mapping.setXPath(getQualifiedXPath(mappingUri, false));
        mapping.setAttributeAccessor(new SDOFragmentMappingAttributeAccessor(this, aHelperContext));

        return mapping;
    }

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

    public void setSubstitutable(boolean substitutable) {
        this.isSubstitutable = substitutable;
    }

    public Collection<SDOProperty> getSubstitutableElements() {
        return this.substitutableElements;
    }

    public void setSubstitutableElements(Collection<SDOProperty> elements) {
        this.substitutableElements = elements;
    }

    public void setFinalized(boolean isFinalized){
      finalized = isFinalized;
    }

    public boolean isFinalized(){
      return finalized;
    }

    /**
     * Return a unique hashCode (as an int) for this instance.
     */
    @Override
    public int hashCode() {
        int hash = 7;
        hash = (31 * hash) + ((null == getName()) ? 0 : getName().hashCode());
        hash = (31 * hash) + ((null == getUri()) ? 0 : getUri().hashCode());
        return hash;
    }

    /**
     * Indicate if a given SDOProperty instance is equal to this instance.
     * Equality is determined based on name, uri, and type.  In addition,
     * checking will be done to ensure that both properties are to be
     * serialized in the same manner, ie. both to XML element or both to
     * XML attribute.
     *
     * @param obj Object to compare to this SDOProperty instance
     * @return true if obj is equal to this SDOProperty instance, false if not
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        SDOProperty prop;
        try {
            prop = (SDOProperty) obj;
        } catch (ClassCastException ccx) {
            // not an SDOProperty
            return false;
        }
        // check type
        if (prop.getType() == null) {
            if (this.getType() != null) {
                return false;
            }
        } else if (this.getType() == null || !this.getType().equals(prop.getType())) {
            return false;
        }
        // check name and URI
        if (prop.getName() == null) {
            if (this.getName() != null) {
                return false;
            }
        } else if (this.getName() == null || !this.getName().equals(prop.getName())) {
            return false;
        }
        if (prop.getUri() == null) {
            if (this.getUri() != null) {
                return false;
            }
        } else if (this.getUri() == null || !this.getUri().equals(prop.getUri())) {
            return false;
        }
        // check attribute vs. element
        Boolean propIsElement = prop.isElement();
        if(null == isElement) {
            if(null != propIsElement) {
                return false;
            }
        } else {
            if(!isElement.equals(propIsElement)) {
                return false;
            }
        }
        return true;
    }

    private void updateType(){
        if (type == SDOConstants.SDO_BOOLEAN) {
            setType(SDOConstants.SDO_BOOLEANOBJECT);
        } else if (type == SDOConstants.SDO_BYTE) {
            setType(SDOConstants.SDO_BYTEOBJECT);
        } else if (type == SDOConstants.SDO_CHARACTER) {
            setType(SDOConstants.SDO_CHARACTEROBJECT);
        } else if (type == SDOConstants.SDO_DOUBLE) {
            setType(SDOConstants.SDO_DOUBLEOBJECT);
        } else if (type == SDOConstants.SDO_FLOAT) {
            setType(SDOConstants.SDO_FLOATOBJECT);
        } else if (type == SDOConstants.SDO_INT) {
            setType(SDOConstants.SDO_INTOBJECT);
        } else if (type == SDOConstants.SDO_LONG) {
            setType(SDOConstants.SDO_LONGOBJECT);
        } else if (type == SDOConstants.SDO_SHORT) {
            setType(SDOConstants.SDO_SHORTOBJECT);
        }
    }
}
