/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     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
//     07/15/2008-1.0.1 Guy Pelletier
//       - 240679: MappedSuperclass Id not picked when on get() method accessor
//     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
//     01/28/2009-2.0 Guy Pelletier
//       - 248293: JPA 2.0 Element Collections (part 1)
//     02/06/2009-2.0 Guy Pelletier
//       - 248293: JPA 2.0 Element Collections (part 2)
//     02/26/2009-2.0 Guy Pelletier
//       - 264001: dot notation for mapped-by and order-by
//     03/27/2009-2.0 Guy Pelletier
//       - 241413: JPA 2.0 Add EclipseLink support for Map type attributes
//     04/03/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
//     04/09/2010-2.1 Guy Pelletier
//       - 307050: Add defaults for access methods of a VIRTUAL access type
//     05/04/2010-2.1 Guy Pelletier
//       - 309373: Add parent class attribute to EclipseLink-ORM
//     05/14/2010-2.1 Guy Pelletier
//       - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml
//     06/01/2010-2.1 Guy Pelletier
//       - 315195: Add new property to avoid reading XML during the canonical model generation
//     06/14/2010-2.2 Guy Pelletier
//       - 264417: Table generation is incorrect for JoinTables in AssociationOverrides
//     07/05/2010-2.1.1 Guy Pelletier
//       - 317708: Exception thrown when using LAZY fetch on VIRTUAL mapping
//     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
//     12/02/2010-2.2 Guy Pelletier
//       - 251554: ExcludeDefaultMapping annotation needed
//     03/24/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 1)
//     09/11/2017-2.1 Will Dazey
//       - 520387: multiple owning descriptors for an embeddable are not set
package org.eclipse.persistence.internal.jpa.metadata.accessors.classes;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.annotations.Cache;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
import org.eclipse.persistence.internal.jpa.metadata.MetadataLogger;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProject;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotation;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;

import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ACCESS_FIELD;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_ACCESS_PROPERTY;

/**
 * INTERNAL:
 * An embeddable accessor.
 *
 * 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 EclipseLink 1.0
 */
public class EmbeddableAccessor extends ClassAccessor {
    // Embedding accessors is a map of those classes that embed this embeddable.
    // All embedding accessors are owning descriptors, but not vice versa.
    private Map<String, ClassAccessor> m_embeddingAccessors = new HashMap<String, ClassAccessor>();

    /**
     * INTERNAL:
     */
    public EmbeddableAccessor() {
        super("<embeddable>");
    }

    /**
     * INTERNAL:
     */
    public EmbeddableAccessor(MetadataAnnotation annotation, MetadataClass cls, MetadataProject project) {
        super(annotation, cls, project);
    }

    /**
     * INTERNAL:
     * Embedding accessors are those accessors that actually embed the
     * embeddable class with an embedded mapping. We use this list to extract
     * and validate the access type of this embeddable when the embeddable
     * does not specify an explicit access type.
     */
    protected void addEmbeddingAccessor(ClassAccessor embeddingAccessor) {
       m_embeddingAccessors.put(embeddingAccessor.getJavaClassName(), embeddingAccessor);
    }

    /**
     * INTERNAL:
     */
    public void addEmbeddingAccessors(Map<String, ClassAccessor> embeddingAccessors) {
        m_embeddingAccessors.putAll(embeddingAccessors);
    }

    /**
     * INTERNAL:
     */
    public void addOwningDescriptor(MetadataDescriptor owningDescriptor) {
        getOwningDescriptors().add(owningDescriptor);
    }

    /**
     * INTERNAL:
     */
    public void addOwningDescriptors(List<MetadataDescriptor> owningDescriptors) {
        getOwningDescriptors().addAll(owningDescriptors);
    }

    /**
     * INTERNAL
     * Ensure any embeddable classes that are discovered during pre-process
     * are added to the project. The newly discovered embeddable accesors will
     * also be pre-processed now as well.
     */
    @Override
    protected void addPotentialEmbeddableAccessor(MetadataClass potentialEmbeddableClass, ClassAccessor embeddingAccessor) {
        if (potentialEmbeddableClass != null) {
            // Get embeddable accessor will add the embeddable to the  project
            // if it is a valid embeddable. That is, if the class has an
            // Embeddable annotation of the class is used as an IdClass for
            // another entity within the persistence unit.
            EmbeddableAccessor embeddableAccessor = getProject().getEmbeddableAccessor(potentialEmbeddableClass, true);

            if (embeddableAccessor != null) {
                embeddableAccessor.addEmbeddingAccessor(embeddingAccessor);
                embeddableAccessor.addOwningDescriptors(getOwningDescriptors());
                if(!embeddableAccessor.isPreProcessed()) {
                    embeddableAccessor.preProcess();
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Build a list of classes that are decorated with a MappedSuperclass
     * annotation or that are tagged as a mapped-superclass in an XML document.
     *
     * This method will also do a couple other things as well since we are
     * traversing the parent classes:
     *  - Build a map of generic types specified and will be used to resolve
     *    actual class types for mappings.
     *  - save mapped-superclass descriptors on the project for later use
     *    by the Metamodel API
     *
     * We don't support embeddable inheritance yet. When that is added, this
     * method will need to change and in fact we may be able to re-use the
     * existing discover method from EntityAccessor (with minor tweaks).
     */
    protected void discoverMappedSuperclassesAndInheritanceParents(boolean addMappedSuperclassAccessors) {
        // Clear any previous discovery.
        clearMappedSuperclassesAndInheritanceParents();

        MetadataClass parentClass = getJavaClass().getSuperclass();
        List<String> genericTypes = getJavaClass().getGenericType();

        while (parentClass != null && ! parentClass.isObject()) {
            // Our parent might be a mapped superclass, check and add as needed.
            addPotentialMappedSuperclass(parentClass, addMappedSuperclassAccessors);

            // Resolve any generic types from the generic parent onto the
            // current entity accessor.
            resolveGenericTypes(genericTypes, parentClass);

            // Grab the generic types from the parent class.
            genericTypes = parentClass.getGenericType();

            // Finally, get the next parent and keep processing ...
            parentClass = parentClass.getSuperclass();
        }
    }

    /**
     * INTERNAL:
     */
    public Map<String, ClassAccessor> getEmbeddingAccessors() {
        return m_embeddingAccessors;
    }

    /**
     * INTERNAL:
     * So, here's the deal ... this method typically gets called when defaulting
     * pk's name, primary table names etc. for various mappings. The problem
     * however is that we go beyond the spec and allow more mappings to be
     * specified on embeddable classes. For example, a M-M would default its
     * join table and join columns using the info from its owning descriptor.
     * The problem then is ... what to do when this embedabble has multiple
     * owning descriptors? That is, is shared. Right now, their pk names from
     * the owners better be same or mappings must be fully specified and not use
     * any defaults. I think that is somewhat ok given we're going beyond the
     * spec and TopLink doesn't even support it anyway???
     *
     * So the stance is, we'll allow the extra mappings on embeddables that are
     * not shared, however on shared cases there are restrictions. Users should
     * use mapped superclasses when they have a need to share complex
     * embeddables.
     *
     * Or they can write customizers to modify their embeddable descriptors
     * after initialize (after they have been cloned)
     *
     * Future: the metadata processing 'could' set all necessary (per owning
     * descriptor) metadata and have the descriptor initialize code handle it.
     * Metadata processing would process embeddable classes as it currently does
     * for MappedSuperclasses. Clone them and process under each owning entity
     * context. At descriptor initialize time, we would avoid cloning the
     * aggregate descriptor and use the one metadata processing provided.
     * Investigate further at a later date ...
     *
     * Callers to this method are ...
     * BasicCollectionAccessor - processCollectionTable - defaults pk names from the owning descriptor.
     * RelationshipAccessor - processJoinTable - defaults the join table name and the source field name
     * OneToManyAccessor - processUnidirectionalOneToManyMapping - defaults the pk field and table.
     * MappingAccessor - processAssociationOverride and updatePrimaryKeyField.
     * ObjectAccessor - processId
     */
    @Override
    public MetadataDescriptor getOwningDescriptor() {
        if (getOwningDescriptors() != null && getOwningDescriptors().size() > 0) {
            // Return the first owning descriptor. In most cases this will be OK
            // since in most cases there is only one.
            return getOwningDescriptors().get(0);
        }
        return this.getDescriptor();
    }

    /**
     * INTERNAL:
     * Return true if this accessor represents an embeddable accessor.
     */
    @Override
    public boolean isEmbeddableAccessor() {
        return true;
    }

    /**
     * INTERNAL:
     * The pre-process method is called during regular deployment and metadata
     * processing.
     *
     * This method is called after each entity of the persistence unit has had
     * an opportunity to pre-process itself first since we'll rely on owning
     * entities for things like access type etc. The pre-process will run some
     * validation.
     *
     * The order of processing is important, care must be taken if changes must
     * be made.
     */
    @Override
    public void preProcess() {
        // Perform the parent discovery process before processing any further.
        discoverMappedSuperclassesAndInheritanceParents(true);

        // Process the correct access type before any other processing.
        processAccessType();

        // Process a virtual class specification after determining access type.
        processVirtualClass();

        // Process the default access methods after determining access type.
        processAccessMethods();

        // Process a @Struct and @EIS annotation to create the correct type of descriptor.
        processStruct();
        processNoSql();

        // Process our parents metadata after processing our own.
        super.preProcess();
    }

    /**
     * INTERNAL:
     * The pre-process for canonical model method is called (and only called)
     * during the canonical model generation. The use of this pre-process allows
     * us to remove some items from the regular pre-process that do not apply
     * to the canonical model generation.
     *
     * The order of processing is important, care must be taken if changes must
     * be made.
     */
    @Override
    public void preProcessForCanonicalModel() {
        // Perform the parent discovery process before processing any further.
        discoverMappedSuperclassesAndInheritanceParents(false);

        // Process our parents metadata after processing our own.
        super.preProcessForCanonicalModel();
    }

    /**
     * INTERNAL
     * Sub classes (Entity and Embeddable) must override this method to control
     * the metadata that is processed for their context.
     */
    @Override
    protected void preProcessMappedSuperclassMetadata(MappedSuperclassAccessor mappedSuperclass) {
        // Process the global converters.
        mappedSuperclass.processConverters();

        // Add the accessors and converters from this mapped superclass.
        mappedSuperclass.addAccessors();
    }

    /**
     * INTERNAL:
     * Process the metadata from this embeddable class.
     */
    @Override
    public void process() {
        // If a Cache annotation is present throw an exception.
        if (isAnnotationPresent(Cache.class)) {
            throw ValidationException.cacheNotSupportedWithEmbeddable(getJavaClass());
        }

        // Process our parents metadata after processing our own.
        super.process();

        // Process the mapping accessors on this embeddable now.
        processMappingAccessors();
    }

    /**
     * INTERNAL:
     * For VIRTUAL access we need to look for default access methods that we
     * need to use with our mapping attributes.
     */
    public void processAccessMethods() {
        // If we use virtual access and do not have any access methods
        // specified then get the default access methods from our owning
        // entity.
        if (hasAccessMethods()) {
            getDescriptor().setDefaultAccessMethods(getAccessMethods());
        } else {
            // The embeddable does not define default access methods. We
            // need to look at our owning entities and 1) validate that
            // they all use the same default access methods and 2) grab
            // the default access methods from them.
            ClassAccessor embeddingAccessor = null;
            for (ClassAccessor currentEmbeddingAccessor : m_embeddingAccessors.values()) {
                if (embeddingAccessor == null) {
                    embeddingAccessor = currentEmbeddingAccessor;
                    continue;
                }

                if (! embeddingAccessor.getDescriptor().getDefaultAccessMethods().equals(currentEmbeddingAccessor.getDescriptor().getDefaultAccessMethods())) {
                    throw ValidationException.conflictingAccessMethodsForEmbeddable(getJavaClassName(), embeddingAccessor.getJavaClassName(), embeddingAccessor.getDescriptor().getDefaultAccessMethods(), currentEmbeddingAccessor.getJavaClassName(), currentEmbeddingAccessor.getDescriptor().getDefaultAccessMethods());
                }
            }

            // Set the default access methods on the descriptor and log a
            // message if there is an embedding accessor. Otherwise we'll
            // use the default set on our descriptor.
            if (embeddingAccessor != null) {
                getDescriptor().setDefaultAccessMethods(embeddingAccessor.getDescriptor().getDefaultAccessMethods());
            }
        }
    }

    /**
     * INTERNAL:
     * Process the access type of this embeddable. If this embeddable is not
     * embedded by at least one entity, it will not be processed. Therefore,
     * embedding accessors can not be empty at this point.
     */
    @Override
    protected void processAccessType() {
        // Validate that this embeddable is not used within entities with
        // conflicting access types when the embeddable doesn't have its own
        // explicit setting. When the embeddable is shared, the access type
        // must be the same across the board.
        if (! hasAccess()) {
            ClassAccessor embeddingAccessor = null;

            // The access type of the embeddable is determined from the class
            // that is embedding it. If there are multiple embedding
            // accessors we will validate that there are no conflicting types.
            for (ClassAccessor currentEmbeddingAccessor : m_embeddingAccessors.values()) {
                if (embeddingAccessor == null) {
                    embeddingAccessor = currentEmbeddingAccessor;
                    continue;
                }

                if (! embeddingAccessor.getAccessType().equals(currentEmbeddingAccessor.getAccessType())) {
                    throw ValidationException.conflictingAccessTypeForEmbeddable(getJavaClassName(), embeddingAccessor.getJavaClassName(), embeddingAccessor.getAccessType(), currentEmbeddingAccessor.getJavaClassName(), currentEmbeddingAccessor.getAccessType());
                }
            }

            // Set the default access type on the descriptor and log a message
            // that we are defaulting the access type for this embeddable.
            if (embeddingAccessor == null) {
                // We don't have an owning entity (only possible during
                // canonical model generation) so look at the mapped
                // superclasses. Ultimate default will be FIELD.
                String defaultAccessType = JPA_ACCESS_FIELD;
                for (MappedSuperclassAccessor mappedSuperclass : getMappedSuperclasses()) {
                    if (! mappedSuperclass.hasAccess()) {
                        if (mappedSuperclass.hasObjectRelationalFieldMappingAnnotationsDefined()) {
                            defaultAccessType = JPA_ACCESS_FIELD;
                        } else if (mappedSuperclass.hasObjectRelationalMethodMappingAnnotationsDefined()) {
                            defaultAccessType = JPA_ACCESS_PROPERTY;
                        }

                        break;
                    }
                }

                getDescriptor().setDefaultAccess(defaultAccessType);
            } else {
                // Use the access type from the embedding accessor.
                getDescriptor().setDefaultAccess(embeddingAccessor.getAccessType());
            }

            getLogger().logConfigMessage(MetadataLogger.ACCESS_TYPE, getDescriptor().getDefaultAccess(), getJavaClass());

            getDescriptor().setAccessTypeOnClassDescriptor(getAccessType());
        }
    }

    /**
     * INTERNAL
     * From an embeddable we need pair down what we process as things like
     * ID metadata does not apply.
     */
    @Override
    protected void processMappedSuperclassMetadata(MappedSuperclassAccessor mappedSuperclass) {
        // Process the attribute override metadata.
        mappedSuperclass.processAttributeOverrides();

        // Process the association override metadata.
        mappedSuperclass.processAssociationOverrides();

        // Process the change tracking metadata.
        mappedSuperclass.processChangeTracking();

        // Process the customizer metadata.
        mappedSuperclass.processCustomizer();

        // Process the copy policy metadata.
        mappedSuperclass.processCopyPolicy();

        // Process the property metadata.
        mappedSuperclass.processProperties();
    }
}
