/*
 * 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:
//     05/16/2008-1.0M8 Guy Pelletier
//       - 218084: Implement metadata merging functionality between mapping files
//     05/23/2008-1.0M8 Guy Pelletier
//       - 211330: Add attributes-complete support to the EclipseLink-ORM.XML Schema
//     06/20/2008-1.0 Guy Pelletier
//       - 232975: Failure when attribute type is generic
//     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
//     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
//     06/25/2009-2.0 Michael O'Brien
//       - 266912: change MappedSuperclass handling in stage2 to pre process accessors
//          in support of the custom descriptors holding mappings required by the Metamodel
//     03/08/2010-2.1 Guy Pelletier
//       - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM
//     08/11/2010-2.2 Guy Pelletier
//       - 312123: JPA: Validation error during Id processing on parameterized generic OneToOne Entity relationship from MappedSuperclass
//     12/01/2010-2.2 Guy Pelletier
//       - 331234: xml-mapping-metadata-complete overriden by metadata-complete specification
//     12/02/2010-2.2 Guy Pelletier
//       - 251554: ExcludeDefaultMapping annotation needed
//     12/02/2010-2.2 Guy Pelletier
//       - 324471: Do not default to VariableOneToOneMapping for interfaces unless a managed class implementing it is found
//     01/25/2011-2.3 Guy Pelletier
//       - 333488: Serializable attribute being defaulted to a variable one to one mapping and causing exception
//     03/24/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 1)
//     07/16/2013-2.5.1 Guy Pelletier
//       - 412384: Applying Converter for parameterized basic-type for joda-time's DateTime does not work
package org.eclipse.persistence.internal.jpa.metadata.accessors.objects;

import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.ECLIPSELINK_OXM_PACKAGE_PREFIX;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ACCESS;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_BASIC;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ELEMENT_COLLECTION;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_EMBEDDABLE;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_EMBEDDED;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_EMBEDDED_ID;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ENUMERATED;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ID;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_LOB;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_MANY_TO_MANY;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_MANY_TO_ONE;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ONE_TO_MANY;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ONE_TO_ONE;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_TEMPORAL;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_VERSION;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.annotations.Array;
import org.eclipse.persistence.annotations.BasicCollection;
import org.eclipse.persistence.annotations.BasicMap;
import org.eclipse.persistence.annotations.ReadTransformer;
import org.eclipse.persistence.annotations.Structure;
import org.eclipse.persistence.annotations.TransientCompatibleAnnotations;
import org.eclipse.persistence.annotations.VariableOneToOne;
import org.eclipse.persistence.annotations.WriteTransformer;
import org.eclipse.persistence.annotations.WriteTransformers;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;

/**
 * INTERNAL:
 * Parent object that is used to hold onto a valid JPA decorated method, field
 * or class.
 *
 * @author Guy Pelletier
 * @since EclipseLink 1.0
 */
@SuppressWarnings("deprecation")
public class MetadataAnnotatedElement extends MetadataAccessibleObject {
    public static final String DEFAULT_RAW_CLASS = "java.lang.String";

    /** The name of the element, i.e. class name, field name, method name. */
    private String m_name;

    /** Defines elements modifiers, i.e. private/static/transient. */
    private int m_modifiers;

    /** Used to cache the type metadata class, but cannot be cached in the case of generics. */
    private MetadataClass m_rawClass;

    /** Used to cache the full type metadata class including some generic specifications. */
    private MetadataClass m_rawClassWithGenerics;

    /**
     * Defines the generic types of the elements type.
     * This is null if no generics are used.
     * This is a list of class/type names from the class/field/method signature.
     * The size of the list varies depending on how many generics are present,
     * i.e.
     * - {@code Map<String, Long> -> ["java.util.Map", "java.lang.String", "java.lang.Long"]}
     * - {@code Beverage<T> extends Object -> [T, :, java.lang.Object, java.lang.Object]}
     */
    private List<String> m_genericType;

    /** Defines the field type, or method return type class name. */
    private String m_type;

    /**
     * Used with the APT processor. Stores the PrimitiveType if this annotated
     * element is a primitive. We can't make it a primitive type here because
     * it introduces a JDK 1.6 dependency. The APT processor will need to cast
     * it back.
     */
    Object m_primitiveType;

    /** Defines the attribute name of a field, or property name of a method. */
    private String m_attributeName;

    /** Stores any annotations defined for the element, keyed by annotation name. */
    private Map<String, MetadataAnnotation> m_annotations;

    /** Stores any meta-annotations defined for the element, keyed by meta-annotation name. */
    private final Map<String, MetadataAnnotation> m_metaAnnotations;

    /**
     * INTERNAL:
     */
    public MetadataAnnotatedElement(MetadataFactory factory) {
        super(factory);

        m_annotations = new HashMap<String, MetadataAnnotation>();
        m_metaAnnotations = new HashMap<>();
    }

    /**
     * INTERNAL:
     */
    public void addAnnotation(MetadataAnnotation annotation) {
        m_annotations.put(annotation.getName(), annotation);
    }

    /**
     * INTERNAL:
     */
    public void addMetaAnnotation(MetadataAnnotation annotation) {
        m_metaAnnotations.put(annotation.getName(), annotation);
    }

    /**
     * INTERNAL:
     */
    public void addGenericType(String genericType) {
        if (m_genericType == null) {
            m_genericType = new ArrayList<String>();
        }

        m_genericType.add(genericType);
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean equals(Object object) {
        if (object == null) {
            return false;
        }

        if (getName() == null) {
            return ((MetadataAnnotatedElement)object).getName() == null;
        }

        return (object.getClass() == getClass()) && getName().equals(((MetadataAnnotatedElement)object).getName());
    }

    /**
     * INTERNAL:
     * Return the annotated element for this accessor. Note: This method does
     * not check against a metadata complete.
     */
    public MetadataAnnotation getAnnotation(Class annotation) {
        return getAnnotation(annotation.getName());
    }

    /**
     * INTERNAL:
     * Return the annotated element for this accessor. Note: This method does
     * not check against a meta-data complete.
     * @param annotation annotation name
     */
    public MetadataAnnotation getAnnotation(final String annotation) {
        return getAnnotation(annotation, new HashSet<>());
    }

    /**
     * INTERNAL:
     * Return the annotated element for this accessor. Note: This method does
     * not check against a meta-data complete.
     * @param annotation annotation name
     * @param names meta-annotations names cycle detection set, shall not be {@code null}
     */
    protected final MetadataAnnotation getAnnotation(final String annotation, final Set<String> names) {
        if (m_annotations == null && m_metaAnnotations == null) {
            return null;
        }
        MetadataAnnotation metadataAnnotation = m_annotations.get(annotation);
        if (metadataAnnotation == null) {
            for (MetadataAnnotation a: m_metaAnnotations.values()) {
                if (names.contains(a.getName())) {
                    if (annotation.equals(a.getName())) {
                        return a;
                    } else {
                        continue;
                    }
                }
                names.add(getName());
                MetadataAnnotation ma = m_factory.getMetadataClass(a.getName()).getAnnotation(annotation, names);
                if (ma != null) {
                    return ma;
                }
            }
        }
        return metadataAnnotation;
    }

    /**
     * INTERNAL:
     * Return the annotated element for this accessor.
     */
    public MetadataAnnotation getAnnotation(String annotationClassName, ClassAccessor classAccessor) {
        MetadataAnnotation annotation = getAnnotation(annotationClassName);

        if (annotation != null && classAccessor.ignoreAnnotations()) {
            getLogger().logConfigMessage(MetadataLogger.IGNORE_ANNOTATION, annotation, this);
            return null;
        }

        return annotation;
    }

    /**
     * INTERNAL:
     * Return the annotations of this accessible object.
     * @return annotations defined for the element, keyed by annotation name.
     *         Never returns {@code null}.
     */
    public Map<String, MetadataAnnotation> getAnnotations() {
        return m_annotations;
    }

    /**
     * INTERNAL:
     */
    @Override
    public String getAttributeName() {
        return m_attributeName;
    }

    /**
     * INTERNAL:
     */
    protected int getDeclaredAnnotationsCount(ClassAccessor classAccessor) {
        if (classAccessor.ignoreAnnotations() || m_annotations == null) {
            return 0;
        }

        return m_annotations.size();
    }

    /**
     * INTERNAL:
     */
    public List<String> getGenericType() {
        return m_genericType;
    }

    /**
     * INTERNAL:
     * This should only be called for accessor's of type Map. It will return
     * the map key type if generics are used, null otherwise.
     */
    public MetadataClass getMapKeyClass(MetadataDescriptor descriptor) {
        if (isGenericCollectionType()) {
            // The Map key may be a generic itself, or just the class value.
            String type = descriptor.getGenericType(m_genericType.get(2));
            if (type != null) {
                return getMetadataClass(type);
            }
            return getMetadataClass(m_genericType.get(1));
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     */
    public int getModifiers() {
        return m_modifiers;
    }

    /**
     * INTERNAL:
     */
    @Override
    public String getName() {
        return m_name;
    }

    /**
     * INTERNAL:
     * If this annotated element was built from java model elements and is
     * a primitive type, this primitive type will be set.
     */
    public Object getPrimitiveType() {
        return m_primitiveType;
    }

    /**
     * INTERNAL:
     * Return the raw class for this accessible object. E.g. For an
     * accessible object with a type of java.util.Collection&lt;Employee&gt;, this
     * method will return java.util.Collection.
     * @see #getReferenceClassFromGeneric(MetadataDescriptor) to get Employee.class back.
     * @see #getRawClassWithGenerics(MetadataDescriptor) to get java.util.CollectionEmployee back.
     */
    public MetadataClass getRawClass(MetadataDescriptor descriptor) {
        if (m_rawClass == null) {
            if (isGenericType()) {
                // Seems that every generic annotated element has the T char
                // in the 0 position. The actual generic type is therefore in
                // the 1 position.
                String type = descriptor.getGenericType(getGenericType().get(1));
                if (type == null) {
                    // If the generic type can not be resolved, take a stab
                    // by returning a default class. One known case where this
                    // will hit is when processing generic accessors from a
                    // mapped superclass for the internal meta model. I wonder
                    // if returning null here would be better? Forcing the
                    // caller to have a plan B in place.
                    // @see e.g. RelationshipAccessor.getReferenceDescriptor()
                    return getMetadataClass(DEFAULT_RAW_CLASS);
                }
                return getMetadataClass(type);
            }
            return getMetadataClass(getType());
        }

        return m_rawClass;
    }

    /**
     * INTERNAL:
     * Return the complete raw class with generics for this accessible object.
     * E.g. For an accessible object with a type of
     * java.util.Collection&lt;Employee&gt;, this method will return
     * java.util.CollectionEmployee. Note, the generics are appended to the name
     * of the class.
     * @see #getReferenceClassFromGeneric(MetadataDescriptor) to get Employee.class back.
     * @see #getRawClass(MetadataDescriptor) to get java.util.Collection back.
     */
    public MetadataClass getRawClassWithGenerics(MetadataDescriptor descriptor) {
        if (m_rawClassWithGenerics == null) {
            MetadataClass rawClass = getRawClass(descriptor);

            if (getGenericType() != null && (! getGenericType().isEmpty()) && getGenericType().size() > 1) {
                StringBuilder rawClassName = new StringBuilder(32);
                rawClassName.append(rawClass.getName());

                for (int i = 1; i < getGenericType().size(); i++) {
                    rawClassName.append(getGenericType().get(i));
                }

                m_rawClassWithGenerics = getMetadataClass(rawClassName.toString());
            } else {
                m_rawClassWithGenerics = rawClass;
            }
        }

        return m_rawClassWithGenerics;
    }

    /**
     * INTERNAL:
     * Return the reference class from the generic specification on this
     * accessible object.
     * Here is what you will get back from this method given the following
     * scenarios:
     * 1 - public Collection&lt;String&gt; getTasks() =&gt; String.class
     * 2 - public Map&lt;String, Integer&gt; getTasks() =&gt; Integer.class
     * 3 - public Employee getEmployee() =&gt; null
     * 4 - public Collection getTasks() =&gt; null
     * 5 - public Map getTasks() =&gt; null
     * 6 - public Collection&lt;byte[]&gt; getAudio() =&gt; byte[].class
     * 7 - public Map&lt;X,Y&gt; on a MappedSuperclass where Y is defined in the Entity superclass&lt;T&gt; =&gt; Void.class (in all bug 266912 cases)
     */
    public MetadataClass getReferenceClassFromGeneric(MetadataDescriptor descriptor) {
        // TODO: investigate multiple levels of generics.
        if (isGenericCollectionType()) {
            // TODO: This is guessing, need to be more logical.
            // Collection<String> -> [Collection, String], get element class.
            String elementClass = m_genericType.get(1);
            if (m_genericType.size() > 2) {
                MetadataClass collectionClass = getMetadataClass(m_genericType.get(0));
                if (collectionClass.extendsInterface(Map.class)) {
                    // If size is greater than 4 then assume it is a double generic Map,
                    // Map<T, Phone> -> [Map, T, Z, T, X]
                    if (m_genericType.size() > 4) {
                        elementClass = m_genericType.get(4);
                    } else if (m_genericType.size() == 4) {
                        // If size is greater than 3 then assume it is a generic Map,
                        // Map<T, Phone> -> [Map, T, Z, Phone]
                        elementClass = m_genericType.get(3);
                    } else if (m_genericType.size() == 3) {
                        // If size is greater than 2 then assume it is a Map,
                        // Map<String, Phone> -> [Map, String, Phone]
                        elementClass = m_genericType.get(2);
                    }
                } else if (elementClass.length() == 1) {
                    // Assume Collection with a generic,
                    // Collection<T> -> [Collection T Z]
                    elementClass = m_genericType.get(2);
                }
            }
            if (elementClass.length() == 1) {
                // Assume is a generic type variable, find real type.
                elementClass = descriptor.getGenericType(elementClass);
            }
            MetadataClass metadataClass = getMetadataClass(elementClass);
            // 266912: We do not currently handle resolution of the parameterized
            // generic type when the accessor is a MappedSuperclass elementClass
            // will be null in this case so a lookup of the metadataClass will
            // also return null on our custom descriptor
            if (metadataClass == null && descriptor.isMappedSuperclass()) {
                // default to Void for all use case 7 instances above
                return new MetadataClass(getMetadataFactory(), Void.class);
            } else {
                return metadataClass;
            }
        } else {
            return null;
        }
    }

    /**
     * INTERNAL:
     */
    public String getType() {
        return m_type;
    }

    /**
     * INTERNAL:
     * Return true if this accessible object has 1 or more declared
     * persistence annotations.
     */
    public boolean hasDeclaredAnnotations(ClassAccessor classAccessor) {
        return getDeclaredAnnotationsCount(classAccessor) > 0;
    }

    /**
     * INTERNAL:
     */
    @Override
    public int hashCode() {
        return getName().hashCode();
    }

    /**
     * INTERNAL:
     * Return true if this accessible object has 2 or more declared
     * persistence annotations.
     */
    public boolean areAnnotationsCompatibleWithTransient(ClassAccessor classAccessor) {
        List<String> annotations = TransientCompatibleAnnotations.getTransientCompatibleAnnotations();
        for (String key: m_annotations.keySet()){
            if (!key.startsWith(ECLIPSELINK_OXM_PACKAGE_PREFIX) && !annotations.contains(key)){
                return false;
            }
        }
        return true;
    }

    /**
     * INTERNAL:
     * Indicates whether the specified annotation is actually not present on
     * this accessible object. Used for defaulting. Need this check since the
     * isAnnotationPresent calls can return a false when true because of the
     * meta-data complete feature.
     */
    public boolean isAnnotationNotPresent(Class annotation, ClassAccessor accessor) {
        return isAnnotationNotPresent(annotation.getName(), accessor);
    }

    /**
     * INTERNAL:
     * Indicates whether the specified annotation is actually not present on
     * this accessible object. Used for defaulting. Need this check since the
     * isAnnotationPresent calls can return a false when true because of the
     * meta-data complete feature.
     */
    public boolean isAnnotationNotPresent(String annotation, ClassAccessor accessor) {
        return ! isAnnotationPresent(annotation, accessor);
    }

    /**
     * INTERNAL:
     * Indicates whether the specified annotation is present on java class
     * for the given descriptor metadata.
     */
    public boolean isAnnotationPresent(Class annotationClass, ClassAccessor accessor) {
        return isAnnotationPresent(annotationClass.getName(), accessor);
    }

    /**
     * INTERNAL:
     * Indicates whether the specified annotation is present on this accessible
     * object. NOTE: Calling this method directly does not take any metadata
     * complete flag into consideration. Look at the other isAnnotationPresent
     * methods that takes a class accessor.
     */
    public boolean isAnnotationPresent(String annotation) {
        return getAnnotation(annotation) != null;
    }

    /**
     * INTERNAL:
     * Indicates whether the specified annotation is present on java class
     * for the given descriptor metadata.
     */
    public boolean isAnnotationPresent(String annotationName, ClassAccessor accessor) {
        MetadataAnnotation annotation = getAnnotation(annotationName);

        if (annotation != null && accessor.ignoreAnnotations()) {
            getLogger().logConfigMessage(MetadataLogger.IGNORE_ANNOTATION, annotation, this);
            return false;
        } else {
            return annotation != null;
        }
    }

    /**
     * INTERNAL:
     * Return true if this field accessor represents an array relationship.
     */
    public boolean isArray(ClassAccessor classAccessor) {
        return isAnnotationPresent(Array.class, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a basic mapping.
     */
    public boolean isBasic(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_BASIC, classAccessor) ||
               isAnnotationPresent(JPA_LOB, classAccessor) ||
               isAnnotationPresent(JPA_TEMPORAL, classAccessor) ||
               isAnnotationPresent(JPA_ENUMERATED, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a basic collection mapping.
     */
    public boolean isBasicCollection(ClassAccessor classAccessor) {
        return isAnnotationPresent(BasicCollection.class, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a basic collection mapping.
     */
    public boolean isBasicMap(ClassAccessor classAccessor) {
        return isAnnotationPresent(BasicMap.class, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an id mapping.
     */
    public boolean isDerivedId(ClassAccessor classAccessor) {
        return isId(classAccessor) && (isOneToOne(classAccessor) || isManyToOne(classAccessor));
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an id mapping.
     */
    public boolean isDerivedIdClass(ClassAccessor classAccessor) {
        return classAccessor.getDescriptor().isEmbeddable() && classAccessor.getProject().isIdClass(getRawClass(classAccessor.getDescriptor()));
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an element collection mapping.
     */
    public boolean isElementCollection(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_ELEMENT_COLLECTION, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an aggregate mapping. True is
     * returned if an Embedded annotation is found or if an Embeddable
     * annotation is found on the raw/reference class.
     */
    public boolean isEmbedded(ClassAccessor classAccessor) {
        if (isAnnotationNotPresent(JPA_EMBEDDED, classAccessor) && isAnnotationNotPresent(JPA_EMBEDDED_ID, classAccessor) && ! classAccessor.excludeDefaultMappings()) {
            MetadataClass rawClass = getRawClass(classAccessor.getDescriptor());
            return (rawClass.isAnnotationPresent(JPA_EMBEDDABLE) || classAccessor.getProject().hasEmbeddable(rawClass));
        } else {
            // Still need to make the call since we may need to ignore it
            // because of meta-data complete.
            return isAnnotationPresent(JPA_EMBEDDED, classAccessor);
        }
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an aggregate id mapping.
     */
    public boolean isEmbeddedId(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_EMBEDDED_ID, classAccessor);
    }

    /**
     * INTERNAL:
     * Method to return whether a collection type is a generic.
     */
    public boolean isGenericCollectionType() {
        return (m_genericType != null) && (m_genericType.size() > 1);
    }

    /**
     * INTERNAL:
     * Method to return whether a type is a generic.
     */
    public boolean isGenericType() {
        return (m_genericType != null) && (m_genericType.size() > 1) && (m_genericType.get(0).length() == 1);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an id mapping.
     */
    public boolean isId(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_ID, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this field accessor represents a m-m relationship.
     */
    public boolean isManyToMany(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_MANY_TO_MANY, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a m-1 relationship.
     */
    public boolean isManyToOne(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_MANY_TO_ONE, classAccessor);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a 1-m relationship.
     */
    public boolean isOneToMany(ClassAccessor classAccessor) {
        if (isAnnotationNotPresent(JPA_ONE_TO_MANY, classAccessor) && ! classAccessor.excludeDefaultMappings()) {
            if (isGenericCollectionType() && isSupportedToManyCollectionClass(getRawClass(classAccessor.getDescriptor())) && classAccessor.getProject().hasEntity(getReferenceClassFromGeneric(classAccessor.getDescriptor()))) {
                getLogger().logConfigMessage(MetadataLogger.ONE_TO_MANY_MAPPING, this);
                return true;
            }

            return false;
        } else {
            // Still need to make the call since we may need to ignore it
            // because of meta-data complete.
            return isAnnotationPresent(JPA_ONE_TO_MANY, classAccessor);
        }
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a 1-1 relationship.
     */
    public boolean isOneToOne(ClassAccessor classAccessor) {
        if (isAnnotationNotPresent(JPA_ONE_TO_ONE, classAccessor) && ! classAccessor.excludeDefaultMappings()) {
            if (classAccessor.getProject().hasEntity(getRawClass(classAccessor.getDescriptor())) && ! isEmbedded(classAccessor)) {
                getLogger().logConfigMessage(MetadataLogger.ONE_TO_ONE_MAPPING, this);
                return true;
            } else {
                return false;
            }
        } else {
            // Still need to make the call since we may need to ignore it
            // because of meta-data complete.
            return isAnnotationPresent(JPA_ONE_TO_ONE, classAccessor);
        }
    }

    /**
     * INTERNAL:
     * Return true if this field accessor represents a structure relationship.
     */
    public boolean isStructure(ClassAccessor classAccessor) {
        return isAnnotationPresent(Structure.class, classAccessor);
    }

    /**
     * INTERNAL:
     * Method to return whether the given class is a supported collection class.
     */
    public boolean isSupportedCollectionClass(MetadataClass metadataClass) {
        return metadataClass.isCollection();
    }

    /**
     * INTERNAL:
     * Method to return whether the given class is a supported map class.
     */
    public boolean isSupportedMapClass(MetadataClass metadataClass) {
        return metadataClass.isMap();
    }

    /**
     * INTERNAL:
     * Method to return whether the given class is a supported to many
     * collection class.
     */
    public boolean isSupportedToManyCollectionClass(MetadataClass metadataClass) {
        return isSupportedCollectionClass(metadataClass) || isSupportedMapClass(metadataClass);
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an transformation mapping.
     */
    public boolean isTransformation(ClassAccessor classAccessor) {
        return isAnnotationPresent(ReadTransformer.class, classAccessor) ||
               isAnnotationPresent(WriteTransformers.class, classAccessor) ||
               isAnnotationPresent(WriteTransformer.class, classAccessor);
    }

    /**
     * INTERNAL:
     * When processing the inverse accessors to an explicit access setting,
     * their must be an Access(FIELD) or Access(PROPERTY) present for the
     * element to be processed. Otherwise, it is ignored.
     */
    protected boolean isValidPersistenceElement(boolean mustBeExplicit, String explicitType, ClassAccessor classAccessor) {
        if (mustBeExplicit) {
            MetadataAnnotation annotation = getAnnotation(JPA_ACCESS, classAccessor);

            if (annotation == null) {
                return false;
            } else {
                String access = annotation.getAttributeString("value");

                if (! access.equals(explicitType)) {
                    throw ValidationException.invalidExplicitAccessTypeSpecified(this, classAccessor.getDescriptorJavaClass(), explicitType);
                }
            }
        }

        return true;
    }

    /**
     * INTERNAL:
     * Return true if the modifiers are not transient, static or abstract.
     */
    protected boolean isValidPersistenceElement(int modifiers) {
        return ! (Modifier.isTransient(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers));
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a variable 1-1 relationship.
     * The method will return true if one of the following conditions is met:
     *  - There is a VariableOneToOne annotation present, or
     *  - The raw class is an interface and not a collection or map, nor a
     *    ValueHolderInterface (and an exclude default mappings flag is not set)
     */
    public boolean isVariableOneToOne(ClassAccessor classAccessor) {
        if (isAnnotationNotPresent(VariableOneToOne.class, classAccessor) && ! classAccessor.excludeDefaultMappings()) {
            MetadataClass rawClass = getRawClass(classAccessor.getDescriptor());

            if (rawClass.isInterface() &&
                    ! rawClass.isMap() &&
                    ! rawClass.isCollection() &&
                    ! rawClass.isSerializableInterface() &&
                    ! rawClass.extendsInterface(ValueHolderInterface.class) &&
                    classAccessor.getProject().hasEntityThatImplementsInterface(rawClass.getName())) {
                getLogger().logConfigMessage(MetadataLogger.VARIABLE_ONE_TO_ONE_MAPPING, this);
                return true;
            }

            return false;
        } else {
            // Still need to make the call since we may need to ignore it
            // because of meta-data complete.
            return isAnnotationPresent(VariableOneToOne.class, classAccessor);
        }
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents a version mapping.
     */
    public boolean isVersion(ClassAccessor classAccessor) {
        return isAnnotationPresent(JPA_VERSION, classAccessor);
    }

    /**
     * INTERNAL:
     * Set the annotations of this accessible object.
     */
    public void setAnnotations(Map<String, MetadataAnnotation> annotations) {
        m_annotations = annotations;
    }

    /**
     * INTERNAL:
     */
    public void setAttributeName(String attributeName) {
        m_attributeName = attributeName;
    }

    /**
     * INTERNAL:
     */
    public void setGenericType(List<String> genericType) {
        m_genericType = genericType;
    }

    /**
     * INTERNAL:
     */
    public void setModifiers(int modifiers) {
        m_modifiers = modifiers;
    }

    /**
     * INTERNAL:
     */
    public void setName(String name) {
        m_name = name;
    }

    /**
     * INTERNAL:
     * If this annotated element was built from java model elements and is
     * a primitive type this method will be called.
     */
    public void setPrimitiveType(Object primitiveType) {
        m_primitiveType = primitiveType;
        m_type = primitiveType.toString();
    }

    /**
     * INTERNAL:
     */
    public void setType(String type) {
        m_type = type;
    }

    /**
     * INTERNAL:
     */
    @Override
    public String toString() {
        String className = getClass().getSimpleName();
        return className.substring("Metadata".length(), className.length()).toLowerCase() + " " + getName();
    }
}
