/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     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.
     * - Map<String, Long> -> ["java.util.Map", "java.lang.String", "java.lang.Long"]
     * - 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();
    }
}
