/*
 * 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
//     05/16/2008-1.0M8 Guy Pelletier
//       - 218084: Implement metadata merging functionality between mapping files
//     08/27/2008-1.1 Guy Pelletier
//       - 211329: Add sequencing on non-id attribute(s) support to the EclipseLink-ORM.XML Schema
//     09/23/2008-1.1 Guy Pelletier
//       - 241651: JPA 2.0 Access Type support
//     10/01/2008-1.1 Guy Pelletier
//       - 249329: To remain JPA 1.0 compliant, any new JPA 2.0 annotations should be referenced by name
//     12/12/2008-1.1 Guy Pelletier
//       - 249860: Implement table per class inheritance support.
//     02/06/2009-2.0 Guy Pelletier
//       - 248293: JPA 2.0 Element Collections (part 2)
//     03/27/2009-2.0 Guy Pelletier
//       - 241413: JPA 2.0 Add EclipseLink support for Map type attributes
//     04/24/2009-2.0 Guy Pelletier
//       - 270011: JPA 2.0 MappedById support
//     09/29/2009-2.0 Guy Pelletier
//       - 282553: JPA 2.0 JoinTable support for OneToOne and ManyToOne
//     03/08/2010-2.1 Guy Pelletier
//       - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM
//     03/29/2010-2.1 Guy Pelletier
//       - 267217: Add Named Access Type to EclipseLink-ORM
//     04/09/2010-2.1 Guy Pelletier
//       - 307050: Add defaults for access methods of a VIRTUAL access type
//     04/27/2010-2.1 Guy Pelletier
//       - 309856: MappedSuperclasses from XML are not being initialized properly
//     05/14/2010-2.1 Guy Pelletier
//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
//     08/19/2010-2.2 Guy Pelletier
//       - 282733: Add plural converter annotations
//     09/03/2010-2.2 Guy Pelletier
//       - 317286: DB column lenght not in sync between @Column and @JoinColumn
//     09/16/2010-2.2 Guy Pelletier
//       - 283028: Add support for letting an @Embeddable extend a @MappedSuperclass
//     12/01/2010-2.2 Guy Pelletier
//       - 331234: xml-mapping-metadata-complete overriden by metadata-complete specification
//     01/04/2011-2.3 Guy Pelletier
//       - 330628: @PrimaryKeyJoinColumn(...) is not working equivalently to @JoinColumn(..., insertable = false, updatable = false)
//     01/25/2011-2.3 Guy Pelletier
//       - 333913: @OrderBy and <order-by/> without arguments should order by primary
//     03/24/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 1)
//     04/05/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 3)
//     07/11/2011-2.4 Guy Pelletier
//       - 343632: Can't map a compound constraint because of exception:
//                 The reference column name [y] mapped on the element [field x]
//                 does not correspond to a valid field on the mapping reference
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     11/19/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.internal.jpa.metadata.accessors;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.persistence.annotations.Converter;
import org.eclipse.persistence.annotations.Converters;
import org.eclipse.persistence.annotations.HashPartitioning;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
import org.eclipse.persistence.annotations.ObjectTypeConverters;
import org.eclipse.persistence.annotations.Partitioned;
import org.eclipse.persistence.annotations.Partitioning;
import org.eclipse.persistence.annotations.PinnedPartitioning;
import org.eclipse.persistence.annotations.RangePartitioning;
import org.eclipse.persistence.annotations.ReplicationPartitioning;
import org.eclipse.persistence.annotations.SerializedConverter;
import org.eclipse.persistence.annotations.SerializedConverters;
import org.eclipse.persistence.annotations.StructConverter;
import org.eclipse.persistence.annotations.StructConverters;
import org.eclipse.persistence.annotations.TypeConverter;
import org.eclipse.persistence.annotations.TypeConverters;
import org.eclipse.persistence.annotations.UnionPartitioning;
import org.eclipse.persistence.annotations.ValuePartitioning;
import org.eclipse.persistence.annotations.RoundRobinPartitioning;
import org.eclipse.persistence.descriptors.SingleTableMultitenantPolicy;
import org.eclipse.persistence.exceptions.ValidationException;

import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;

import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAccessibleObject;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotatedElement;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotation;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;

import org.eclipse.persistence.internal.jpa.metadata.columns.PrimaryKeyJoinColumnMetadata;

import org.eclipse.persistence.internal.jpa.metadata.converters.ConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.ObjectTypeConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.SerializedConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.StructConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.TypeConverterMetadata;

import org.eclipse.persistence.internal.jpa.metadata.mappings.AccessMethodsMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.PartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.HashPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.PinnedPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.RangePartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.ReplicationPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.RoundRobinPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.UnionPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.ValuePartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.tables.TableMetadata;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings;

import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProject;
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
import org.eclipse.persistence.internal.jpa.metadata.ORMetadata;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;

import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ACCESS;

/**
 * INTERNAL:
 * Common metadata accessor level for mappings and classes.
 *
 * Key notes:
 * - any metadata mapped from XML to this class must be compared in the
 *   equals method.
 * - any metadata mapped from XML to this class must be handled in the merge
 *   method. (merging is done at the accessor/mapping level)
 * - any metadata mapped from XML to this class must be initialized in the
 *   initXMLObject  method.
 * - methods should be preserved in alphabetical order.
 *
 * @author Guy Pelletier
 * @since TopLink EJB 3.0 Reference Implementation
 */
public abstract class MetadataAccessor extends ORMetadata {
    private AccessMethodsMetadata m_accessMethods;

    private List<ConverterMetadata> m_converters = new ArrayList<ConverterMetadata>();
    private List<ObjectTypeConverterMetadata> m_objectTypeConverters = new ArrayList<ObjectTypeConverterMetadata>();
    private List<StructConverterMetadata> m_structConverters = new ArrayList<StructConverterMetadata>();
    private List<TypeConverterMetadata> m_typeConverters = new ArrayList<TypeConverterMetadata>();
    private List<SerializedConverterMetadata> m_serializedConverters = new ArrayList<SerializedConverterMetadata>();
    private List<PropertyMetadata> m_properties = new ArrayList<PropertyMetadata>();

    private MetadataDescriptor m_descriptor;

    private PartitioningMetadata m_partitioning;
    private ReplicationPartitioningMetadata m_replicationPartitioning;
    private RoundRobinPartitioningMetadata m_roundRobinPartitioning;
    private PinnedPartitioningMetadata m_pinnedPartitioning;
    private RangePartitioningMetadata m_rangePartitioning;
    private ValuePartitioningMetadata m_valuePartitioning;
    private UnionPartitioningMetadata m_unionPartitioning;
    private HashPartitioningMetadata m_hashPartitioning;
    private String m_partitioned;

    private String m_access;
    private String m_name;

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public MetadataAccessor(String xmlElement) {
        super(xmlElement);
    }

    /**
     * INTERNAL:
     */
    public MetadataAccessor(MetadataAnnotation annotation, MetadataAccessibleObject accessibleObject, MetadataDescriptor descriptor, MetadataProject project) {
        super(annotation, accessibleObject, project);
        setDescriptor(descriptor);
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean equals(Object objectToCompare) {
        if (objectToCompare instanceof MetadataAccessor) {
            MetadataAccessor accessor = (MetadataAccessor) objectToCompare;

            if (! valuesMatch(m_accessMethods, accessor.getAccessMethods())) {
                return false;
            }

            if (! valuesMatch(m_converters, accessor.getConverters())) {
                return false;
            }

            if (! valuesMatch(m_objectTypeConverters, accessor.getObjectTypeConverters())) {
                return false;
            }

            if (! valuesMatch(m_structConverters, accessor.getStructConverters())) {
                return false;
            }

            if (! valuesMatch(m_typeConverters, accessor.getTypeConverters())) {
                return false;
            }

            if (! valuesMatch(m_serializedConverters, accessor.getSerializedConverters())) {
                return false;
            }

            if (! valuesMatch(m_properties, accessor.getProperties())) {
                return false;
            }

            if (! valuesMatch(m_access, accessor.getAccess())) {
                return false;
            }

            return valuesMatch(m_name, accessor.getName());
        }

        return false;
    }

    @Override
    public int hashCode() {
        int result = m_accessMethods != null ? m_accessMethods.hashCode() : 0;
        result = 31 * result + (m_converters != null ? m_converters.hashCode() : 0);
        result = 31 * result + (m_objectTypeConverters != null ? m_objectTypeConverters.hashCode() : 0);
        result = 31 * result + (m_structConverters != null ? m_structConverters.hashCode() : 0);
        result = 31 * result + (m_typeConverters != null ? m_typeConverters.hashCode() : 0);
        result = 31 * result + (m_serializedConverters != null ? m_serializedConverters.hashCode() : 0);
        result = 31 * result + (m_properties != null ? m_properties.hashCode() : 0);
        result = 31 * result + (m_access != null ? m_access.hashCode() : 0);
        result = 31 * result + (m_name != null ? m_name.hashCode() : 0);
        return result;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public String getAccess() {
        return m_access;
    }

    /**
     * INTERNAL:
     * Returns the accessible object for this accessor.
     */
    @Override
    public MetadataAnnotatedElement getAccessibleObject() {
        return (MetadataAnnotatedElement) super.getAccessibleObject();
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public AccessMethodsMetadata getAccessMethods() {
        return m_accessMethods;
    }

    /**
     * INTERNAL:
     * Return the annotated element for this accessor.
     */
    public MetadataAnnotatedElement getAnnotatedElement() {
        return getAccessibleObject();
    }

    /**
     * INTERNAL:
     * Return the annotated element name for this accessor.
     */
    public String getAnnotatedElementName() {
        return getAnnotatedElement().toString();
    }

    /**
     * INTERNAL:
     * Return the annotation if it exists. This method should only be called
     * for non JPA annotations as loading those annotations classes is ok (and
     * available).
     *
     * JPA annotations should be referenced only by name as to not introduce a
     * compile dependency.
     */
    public MetadataAnnotation getAnnotation(Class annotation) {
       return getAnnotation(annotation.getName());
    }

    /**
     * INTERNAL:
     * Return the annotation if it exists.
     */
    protected abstract MetadataAnnotation getAnnotation(String annotation);

    /**
     * INTERNAL:
     * Return the attribute name for this accessor.
     */
    public String getAttributeName() {
        return getAccessibleObject().getAttributeName();
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<ConverterMetadata> getConverters() {
        return m_converters;
    }

    /**
     * INTERNAL:
     * Return the upper cased attribute name for this accessor. Used when
     * defaulting.
     */
    protected String getDefaultAttributeName() {
        return (getProject().useDelimitedIdentifier()) ? getAttributeName() : getAttributeName().toUpperCase(Locale.ROOT);
    }

    /**
     * INTERNAL:
     * Return the MetadataDescriptor for this accessor.
     */
    public MetadataDescriptor getDescriptor() {
        return m_descriptor;
    }

    /**
     * INTERNAL:
     * Return the java class tied to this class accessor's descriptor.
     */
    public MetadataClass getDescriptorJavaClass() {
        return m_descriptor.getJavaClass();
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public HashPartitioningMetadata getHashPartitioning() {
        return m_hashPartitioning;
    }

    /**
     * INTERNAL:
     * To satisfy the abstract getIdentifier() method from ORMetadata.
     */
    @Override
    public String getIdentifier() {
        return getName();
    }

    /**
     * INTERNAL:
     * Return the java class associated with this accessor's descriptor.
     */
    public MetadataClass getJavaClass() {
        return m_descriptor.getJavaClass();
    }

    /**
     * INTERNAL:
     * Return the java class that defines this accessor.
     */
    protected String getJavaClassName() {
        return getJavaClass().getName();
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public String getName() {
        return m_name;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<ObjectTypeConverterMetadata> getObjectTypeConverters() {
        return m_objectTypeConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public String getPartitioned() {
        return m_partitioned;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public PartitioningMetadata getPartitioning() {
        return m_partitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public PinnedPartitioningMetadata getPinnedPartitioning() {
        return m_pinnedPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<PropertyMetadata> getProperties() {
        return m_properties;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public RangePartitioningMetadata getRangePartitioning() {
        return m_rangePartitioning;
    }

    /**
     * INTERNAL:
     * Return the referenced field.  If the referencedColumnName is not
     * specified, it will default to the primary key of the referenced table.
     */
    protected DatabaseField getReferencedField(String referencedColumnName, MetadataDescriptor referenceDescriptor, String context) {
        return getReferencedField(referencedColumnName, referenceDescriptor, context, false);
    }

    /**
     * INTERNAL:
     * Return the referenced field.  If the referencedColumnName is not
     * specified, it will default to the primary key of the referenced table.
     */
    protected DatabaseField getReferencedField(String referencedColumnName, MetadataDescriptor referenceDescriptor, String context, boolean isForAggregateCollection) {
        DatabaseField referenceField;

        if (referencedColumnName == null || referencedColumnName.equals("")) {
            referenceField = referenceDescriptor.getPrimaryKeyField();

            // <hack> If we are an inheritance subclass in a joined strategy,
            // for an aggregate collection, we need to return the multi table
            // primary key field if there is one. All other mappings seem to be
            // happy with the primary key field ... this seems to be a bug with
            // AggregateCollectionMapping in that it doesn't resolve the
            // primary key fields correctly </hack>
            // TODO: have a look at this again at some point.
            if (referenceDescriptor.isInheritanceSubclass() && isForAggregateCollection) {
                referenceField = referenceDescriptor.getPrimaryKeyJoinColumnAssociationField(referenceField);
            }

            // Log the defaulting field name based on the given context.
            getLogger().logConfigMessage(context, getAnnotatedElementName(), referenceField.getName());
        } else {
            // Let's try to look up the referenced field using the referenced
            // column name.
            referenceField = referenceDescriptor.getField(referencedColumnName);

            if (referenceField == null) {
                // Ok so we still haven't found the referenced field. We will
                // need to take the delimeters and the upper cassing flag into
                // consideration. To do that, we must use a DatabaseField since
                // the logic resides there. It would be nice to avoid creating
                // database fields to look up actual referenced fields but for
                // now this will do (better than what we had before :-) ).
                DatabaseField lookupField = new DatabaseField();
                setFieldName(lookupField, referencedColumnName);
                referenceField = referenceDescriptor.getField(lookupField.getNameForComparisons());

                if (referenceField == null) {
                    // So here's the thing, there are a few reasons why we
                    // wouldn't have a reference field at this point:
                    //
                    // 1 - if we are processing a mapping accessor (e.g. element
                    // collection) for a mapped superclass descriptor
                    // (metamodel) where the mapped superclass may or may not
                    // define a source ID field. So we just don't know and can't
                    // know in this context)
                    //
                    // 2 - the user has mapped a reference column to a non id
                    // field. See bug 343632 for more information. It's an
                    // example of going beyond the spec since the user has
                    // mapped a reference column name to another relationship
                    // mapping. We can't lookup the field for this mapping since
                    // we can't guaranty that its accessor has been processed.
                    // Basic (id) accessors are all processed in stage one,
                    // relationship accessors are processed only in stage 3
                    // after we know all the basics (ids) have been processed.
                    //
                    // 3 - the field just doesn't exist. In this case, the user
                    // will eventually get a DB error on persist.
                    //
                    // By returning the lookup field, what do we lose? Well, we
                    // could lose some field definitions (precision, length,
                    // scale) which would generate different DDL (if turned on).
                    //
                    // What do we gain? We continue to do our best to lookup
                    // reference fields and keep them in sync. We do that
                    // correctly up to what the spec requires. Anything beyond
                    // that we just assume the field is valid and return it (as
                    // we did in the past, before bug 317286) and users can map
                    // to non-id fields.
                    //
                    referenceField = lookupField;
                    referenceField.setTable(referenceDescriptor.getPrimaryKeyTable());

                    // Log warning to the user that we will use the referenced
                    // column name they provided.
                    getLogger().logWarningMessage(MetadataLogger.REFERENCED_COLUMN_NOT_FOUND, referencedColumnName, getAnnotatedElement());
                }
            }
        }

        return referenceField;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public ReplicationPartitioningMetadata getReplicationPartitioning() {
        return m_replicationPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public RoundRobinPartitioningMetadata getRoundRobinPartitioning() {
        return m_roundRobinPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<StructConverterMetadata> getStructConverters() {
        return m_structConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<TypeConverterMetadata> getTypeConverters() {
        return m_typeConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<SerializedConverterMetadata> getSerializedConverters() {
        return m_serializedConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public UnionPartitioningMetadata getUnionPartitioning() {
        return m_unionPartitioning;
    }

    /**
     * INTERNAL:
     * Return the upper case java class that defines this accessor.
     */
    protected String getUpperCaseShortJavaClassName() {
        return Helper.getShortClassName(getJavaClassName()).toUpperCase(Locale.ROOT);
    }

    /**
     * INTERNAL:
     * Helper method to return a string value if specified, otherwise returns
     * the default value.
     */
    protected Integer getValue(Integer value, Integer defaultValue) {
        return org.eclipse.persistence.internal.jpa.metadata.MetadataHelper.getValue(value, defaultValue);
    }

    /**
     * INTERNAL:
     * Helper method to return a string value if specified, otherwise returns
     * the default value.
     */
    protected String getValue(String value, String defaultValue) {
        return org.eclipse.persistence.internal.jpa.metadata.MetadataHelper.getValue(value, defaultValue);
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public ValuePartitioningMetadata getValuePartitioning() {
        return m_valuePartitioning;
    }

    /**
     * INTERNAL:
     */
    public boolean hasAccess() {
        return m_access != null;
    }

    /**
     * INTERNAL:
     */
    public boolean hasAccessMethods() {
        return m_accessMethods != null;
    }

    /**
     * INTERNAL:
     * Called from annotation and xml initialization.
     */
    public void initAccess() {
        // Look for an annotation as long as an access type hasn't already been
        // loaded from XML (meaning m_access will not be null at this point)
        if (m_access == null) {
            MetadataAnnotation access = getAnnotation(JPA_ACCESS);
            if (access != null) {
                setAccess(access.getAttributeString("value"));
            }
        }
    }

    /**
     * INTERNAL:
     * This method should be subclassed in those methods that need to do
     * extra initialization.
     */
    public void initXMLAccessor(MetadataDescriptor descriptor, MetadataProject project) {
        setProject(project);
        setDescriptor(descriptor);
    }

    /**
     * INTERNAL:
     */
    @Override
    public void initXMLObject(MetadataAccessibleObject accessibleObject, XMLEntityMappings entityMappings) {
        super.initXMLObject(accessibleObject, entityMappings);

        // Initialize single objects.
        initXMLObject(m_accessMethods, accessibleObject);

        initXMLObject(m_partitioning, accessibleObject);
        initXMLObject(m_replicationPartitioning, accessibleObject);
        initXMLObject(m_roundRobinPartitioning, accessibleObject);
        initXMLObject(m_pinnedPartitioning, accessibleObject);
        initXMLObject(m_rangePartitioning, accessibleObject);
        initXMLObject(m_valuePartitioning, accessibleObject);
        initXMLObject(m_hashPartitioning, accessibleObject);
        initXMLObject(m_unionPartitioning, accessibleObject);

        // Initialize lists of objects.
        initXMLObjects(m_converters, accessibleObject);
        initXMLObjects(m_objectTypeConverters, accessibleObject);
        initXMLObjects(m_structConverters, accessibleObject);
        initXMLObjects(m_typeConverters, accessibleObject);
        initXMLObjects(m_serializedConverters, accessibleObject);
        initXMLObjects(m_properties, accessibleObject);
    }

    /**
     * INTERNAL:
     * Return true if the annotation exists. This method should only be called
     * for non native annotations (i.e. JPA) as loading native annotations
     * classes is ok since we know they are available from the jar.
     *
     * JPA annotations should be referenced only by name as to not introduce a
     * compile dependency.
     */
    public boolean isAnnotationPresent(Class<? extends Annotation> annotation) {
        return isAnnotationPresent(annotation.getName());
    }

    /**
     * INTERNAL:
     * Return the annotation if it exists.
     */
    public abstract boolean isAnnotationPresent(String annotation);

    /**
     * Subclasses must handle this flag.
     */
    public abstract boolean isProcessed();

    /**
     * INTERNAL:
     * We currently limit this merging to the ClassAccessor level.
     */
    @Override
    public void merge(ORMetadata metadata) {
        MetadataAccessor accessor = (MetadataAccessor) metadata;

        // Simple object merging.
        m_access = (String) mergeSimpleObjects(m_access, accessor.getAccess(), accessor, "@access");

        // ORMetadata object merging.
        m_accessMethods = (AccessMethodsMetadata) mergeORObjects(m_accessMethods, accessor.getAccessMethods());

        // ORMetadata list merging.
        m_converters = mergeORObjectLists(m_converters, accessor.getConverters());
        m_objectTypeConverters = mergeORObjectLists(m_objectTypeConverters, accessor.getObjectTypeConverters());
        m_structConverters = mergeORObjectLists(m_structConverters, accessor.getStructConverters());
        m_typeConverters = mergeORObjectLists(m_typeConverters, accessor.getTypeConverters());
        m_serializedConverters = mergeORObjectLists(m_serializedConverters, accessor.getSerializedConverters());
        m_properties = mergeORObjectLists(m_properties, accessor.getProperties());

        m_partitioned = (String) mergeSimpleObjects(m_partitioned, accessor.getPartitioned(), accessor, "<partitioned>");
        m_partitioning = (PartitioningMetadata) mergeORObjects(m_partitioning, accessor.getPartitioning());
        m_replicationPartitioning = (ReplicationPartitioningMetadata) mergeORObjects(m_replicationPartitioning, accessor.getReplicationPartitioning());
        m_roundRobinPartitioning = (RoundRobinPartitioningMetadata) mergeORObjects(m_roundRobinPartitioning, accessor.getRoundRobinPartitioning());
        m_pinnedPartitioning = (PinnedPartitioningMetadata) mergeORObjects(m_pinnedPartitioning, accessor.getPinnedPartitioning());
        m_rangePartitioning = (RangePartitioningMetadata) mergeORObjects(m_rangePartitioning, accessor.getRangePartitioning());
        m_valuePartitioning = (ValuePartitioningMetadata) mergeORObjects(m_valuePartitioning, accessor.getValuePartitioning());
        m_hashPartitioning = (HashPartitioningMetadata) mergeORObjects(m_hashPartitioning, accessor.getHashPartitioning());
        m_unionPartitioning = (UnionPartitioningMetadata) mergeORObjects(m_unionPartitioning, accessor.getUnionPartitioning());
    }

    /**
     * INTERNAL:
     * Every accessor knows how to process themselves since they have all the
     * information they need.
     */
    public abstract void process();

    /**
     * INTERNAL:
     * Process and add the globally defined converters to the project.
     */
    public void processConverters() {
        // Process the custom converters if defined.
        processCustomConverters();

        // Process the object type converters if defined.
        processObjectTypeConverters();

        // Process the type converters if defined.
        processTypeConverters();

        // Process the serialized converters if defined.
        processSerializedConverters();

        // Process the struct converters if defined
        processStructConverters();
    }

    /**
     * INTERNAL:
     * Process the XML defined converters and check for a Converter annotation.
     */
    protected void processCustomConverters() {
        // Check for XML defined converters.
        for (ConverterMetadata converter : m_converters) {
            getProject().addConverter(converter);
        }

        // Check for a Converters annotation
        MetadataAnnotation converters = getAnnotation(Converters.class);
        if (converters != null) {
            for (Object converter : converters.getAttributeArray("value")) {
                getProject().addConverter(new ConverterMetadata((MetadataAnnotation) converter, this));
            }
        }

        // Check for a Converter annotation.
        MetadataAnnotation converter = getAnnotation(Converter.class);
        if (converter != null) {
            getProject().addConverter(new ConverterMetadata(converter, this));
        }
    }

    /**
     * INTERNAL:
     * Process the XML defined object type converters and check for an
     * ObjectTypeConverter annotation.
     */
    protected void processObjectTypeConverters() {
        // Check for XML defined object type converters.
        for (ObjectTypeConverterMetadata objectTypeConverter : m_objectTypeConverters) {
            getProject().addConverter(objectTypeConverter);
        }

        // Check for an ObjectTypeConverters annotation
        if (isAnnotationPresent(ObjectTypeConverters.class)) {
            for (Object objectTypeConverter : getAnnotation(ObjectTypeConverters.class).getAttributeArray("value")) {
                getProject().addConverter(new ObjectTypeConverterMetadata((MetadataAnnotation) objectTypeConverter, this));
            }
        }

        // Check for an ObjectTypeConverter annotation.
        if (isAnnotationPresent(ObjectTypeConverter.class)) {
            getProject().addConverter(new ObjectTypeConverterMetadata(getAnnotation(ObjectTypeConverter.class), this));
        }
    }

    /**
     * Set the policy on the descriptor or mapping.
     */
    public void processPartitioned(String name) {
        if (this instanceof ClassAccessor) {
            if (getDescriptor().getClassDescriptor().getPartitioningPolicy() != null) {
                // We must be processing a mapped superclass setting for an
                // entity that has its own setting. Ignore it and log a warning.
                getLogger().logConfigMessage(MetadataLogger.IGNORE_MAPPED_SUPERCLASS_ANNOTATION, Partitioned.class, getJavaClass(), getDescriptor().getJavaClass());
            }
            getDescriptor().getClassDescriptor().setPartitioningPolicyName(name);
        } else if (this instanceof MappingAccessor) {
            ((ForeignReferenceMapping)((MappingAccessor)this).getMapping()).setPartitioningPolicyName(name);
        }
    }

    /**
     * Process the partitioning policies defined on this element.
     */
    protected void processPartitioning() {
        boolean found = false;
        // Check for XML defined partitioning.
        if (m_replicationPartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_replicationPartitioning);
        }
        if (m_roundRobinPartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_roundRobinPartitioning);
        }
        if (m_partitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_partitioning);
        }
        if (m_rangePartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_rangePartitioning);
        }
        if (m_valuePartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_valuePartitioning);
        }
        if (m_hashPartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_hashPartitioning);
        }
        if (m_unionPartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_unionPartitioning);
        }
        if (m_pinnedPartitioning != null) {
            found = true;
            getProject().addPartitioningPolicy(m_pinnedPartitioning);
        }

        // Check for partitioning annotations.
        MetadataAnnotation annotation = getAnnotation(Partitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new PartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(ReplicationPartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new ReplicationPartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(RoundRobinPartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new RoundRobinPartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(UnionPartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new UnionPartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(RangePartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new RangePartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(ValuePartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new ValuePartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(ValuePartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new ValuePartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(PinnedPartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new PinnedPartitioningMetadata(annotation, this));
        }
        annotation = getAnnotation(HashPartitioning.class);
        if (annotation != null) {
            found = true;
            getProject().addPartitioningPolicy(new HashPartitioningMetadata(annotation, this));
        }
        boolean processed = false;
        if (m_partitioned != null) {
            processed = true;
            processPartitioned(m_partitioned);
        }
        annotation = getAnnotation(Partitioned.class);
        if (!processed && annotation != null) {
            processed = true;
            processPartitioned(annotation.getAttributeString("value"));
        }
        if (found && !processed) {
            getLogger().logWarningMessage(MetadataLogger.WARNING_PARTIONED_NOT_SET, getJavaClass(), getAccessibleObject());
        }
    }

    /**
     * INTERNAL:
     * Process the primary key join columms for this accessors annotated element.
     */
    protected List<PrimaryKeyJoinColumnMetadata> processPrimaryKeyJoinColumns(List<PrimaryKeyJoinColumnMetadata> primaryKeyJoinColumns) {
        // If the primary key join columns were not specified (that is empty),
        // this call will add any defaulted columns as necessary.
        if (primaryKeyJoinColumns.isEmpty()) {
            if (getDescriptor().hasCompositePrimaryKey()) {
                // Add a default one for each part of the composite primary
                // key. Foreign and primary key to have the same name.
                for (DatabaseField primaryKeyField : getDescriptor().getPrimaryKeyFields()) {
                    PrimaryKeyJoinColumnMetadata primaryKeyJoinColumn = new PrimaryKeyJoinColumnMetadata(getProject());
                    primaryKeyJoinColumn.setReferencedColumnName(primaryKeyField.getName());
                    primaryKeyJoinColumn.setName(primaryKeyField.getName());
                    primaryKeyJoinColumns.add(primaryKeyJoinColumn);
                }
            } else {
                // Add a default one for the single case, not setting any
                // foreign and primary key names. They will default based
                // on which accessor is using them.
                primaryKeyJoinColumns.add(new PrimaryKeyJoinColumnMetadata(getProject()));
            }
        } else {
            // If we are a multitenant entity and the number of primary key join
            // columns does not equal the number of primary key fields we must
            // add the multitenant primary key tenant discriminator fields.
            if (getDescriptor().hasSingleTableMultitenant() && primaryKeyJoinColumns.size() != getDescriptor().getPrimaryKeyFields().size()) {
                SingleTableMultitenantPolicy policy = (SingleTableMultitenantPolicy) getDescriptor().getClassDescriptor().getMultitenantPolicy();
                Map<DatabaseField, String> tenantFields = policy.getTenantDiscriminatorFields();

                // Go through the key sets ...
                for (DatabaseField tenantField : tenantFields.keySet()) {
                    if (tenantField.isPrimaryKey()) {
                        PrimaryKeyJoinColumnMetadata primaryKeyJoinColumn = new PrimaryKeyJoinColumnMetadata();
                        primaryKeyJoinColumn.setName(tenantField.getName());
                        primaryKeyJoinColumn.setReferencedColumnName(tenantField.getName());
                        primaryKeyJoinColumn.setProject(getProject());
                        primaryKeyJoinColumns.add(primaryKeyJoinColumn);
                    }
                }
            }
        }

        // Now validate what we have.
        if (getDescriptor().hasCompositePrimaryKey()) {
            // All the primary and foreign key field names should be specified.
            // The number of join columns need not match the number of primary
            // key columns since we allow joining to partials.
            for (PrimaryKeyJoinColumnMetadata pkJoinColumn : primaryKeyJoinColumns) {
                if (pkJoinColumn.isPrimaryKeyFieldNotSpecified() || pkJoinColumn.isForeignKeyFieldNotSpecified()) {
                    throw ValidationException.incompletePrimaryKeyJoinColumnsSpecified(getAnnotatedElement());
                }
            }
        } else {
            if (primaryKeyJoinColumns.size() > 1) {
                throw ValidationException.excessivePrimaryKeyJoinColumnsSpecified(getAnnotatedElement());
            }
        }

        return primaryKeyJoinColumns;
    }

    /**
     * INTERNAL:
     * Process the XML defined struct converters and check for a StructConverter
     * annotation.
     */
    protected void processStructConverters() {
        // Check for XML defined struct converters.
        for (StructConverterMetadata structConverter : m_structConverters) {
            getProject().addConverter(structConverter);
        }

        // Check for a StructConverters annotation
        if (isAnnotationPresent(StructConverters.class)) {
            for (Object structConverter : getAnnotation(StructConverters.class).getAttributeArray("value")) {
                getProject().addConverter(new StructConverterMetadata((MetadataAnnotation) structConverter, this));
            }
        }

        // Check for a StructConverter annotation.
        if (isAnnotationPresent(StructConverter.class)) {
            getProject().addConverter(new StructConverterMetadata(getAnnotation(StructConverter.class), this));
        }
    }

    /**
     * INTERNAL:
     * Common table processing for table, secondary table, join table and
     * collection table.
     */
    protected void processTable(TableMetadata table, String defaultName) {
        // Process the default values.
        getProject().processTable(table, defaultName, m_descriptor.getDefaultCatalog(), m_descriptor.getDefaultSchema(), this);
    }

    /**
     * INTERNAL:
     * Process a the XML defined type converters and check for a TypeConverter
     * annotation.
     */
    protected void processTypeConverters() {
        // Check for XML defined type converters.
        for (TypeConverterMetadata typeConverter : m_typeConverters) {
            getProject().addConverter(typeConverter);
        }

        // Check for a TypeConverters annotation
        if (isAnnotationPresent(TypeConverters.class)) {
            for (Object typeConverter : getAnnotation(TypeConverters.class).getAttributeArray("value")) {
                getProject().addConverter(new TypeConverterMetadata((MetadataAnnotation) typeConverter, this));
            }
        }

        // Check for an TypeConverter annotation.
        if (isAnnotationPresent(TypeConverter.class)) {
            getProject().addConverter(new TypeConverterMetadata(getAnnotation(TypeConverter.class), this));
        }
    }

    /**
     * INTERNAL:
     * Process a the XML defined serialized converters and check for a SerializedConverter
     * annotation.
     */
    protected void processSerializedConverters() {
        // Check for XML defined serialized converters.
        for (SerializedConverterMetadata serializedConverter : m_serializedConverters) {
            getProject().addConverter(serializedConverter);
        }

        // Check for a SerializedConverters annotation
        if (isAnnotationPresent(SerializedConverters.class)) {
            for (Object serializedConverter : getAnnotation(SerializedConverters.class).getAttributeArray("value")) {
                getProject().addConverter(new SerializedConverterMetadata((MetadataAnnotation) serializedConverter, this));
            }
        }

        // Check for an TypeConverter annotation.
        if (isAnnotationPresent(SerializedConverter.class)) {
            getProject().addConverter(new SerializedConverterMetadata(getAnnotation(SerializedConverter.class), this));
        }
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setAccess(String access) {
        m_access = access;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setAccessMethods(AccessMethodsMetadata accessMethods){
        m_accessMethods = accessMethods;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setConverters(List<ConverterMetadata> converters) {
        m_converters = converters;
    }

    /**
     * INTERNAL:
     * Set the metadata descriptor for this accessor. When setting the
     * descriptor on entities, the owning descriptor is set to this descriptor.
     */
    public void setDescriptor(MetadataDescriptor descriptor) {
        m_descriptor = descriptor;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setHashPartitioning(HashPartitioningMetadata hashPartitioning) {
        m_hashPartitioning = hashPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setName(String name) {
        m_name = name;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setObjectTypeConverters(List<ObjectTypeConverterMetadata> objectTypeConverters) {
        m_objectTypeConverters = objectTypeConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setPartitioned(String partitioned) {
        m_partitioned = partitioned;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setPartitioning(PartitioningMetadata partitioning) {
        m_partitioning = partitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setPinnedPartitioning(PinnedPartitioningMetadata pinnedPartitioning) {
        m_pinnedPartitioning = pinnedPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setProperties(List<PropertyMetadata> properties) {
        m_properties = properties;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setRangePartitioning(RangePartitioningMetadata rangePartitioning) {
        m_rangePartitioning = rangePartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setReplicationPartitioning(ReplicationPartitioningMetadata replicationPartitioning) {
        m_replicationPartitioning = replicationPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setRoundRobinPartitioning(RoundRobinPartitioningMetadata roundRobinPartitioning) {
        m_roundRobinPartitioning = roundRobinPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setStructConverters(List<StructConverterMetadata> structConverters) {
        m_structConverters = structConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setTypeConverters(List<TypeConverterMetadata> typeConverters) {
        m_typeConverters = typeConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setSerializedConverters(List<SerializedConverterMetadata> serializedConverters) {
        m_serializedConverters = serializedConverters;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setUnionPartitioning(UnionPartitioningMetadata unionPartitioning) {
        m_unionPartitioning = unionPartitioning;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setValuePartitioning(ValuePartitioningMetadata valuePartitioning) {
        m_valuePartitioning = valuePartitioning;
    }
}

