/*
 * 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
//
//     04/30/2009-2.0 Michael O'Brien
//       - 266912: JPA 2.0 Metamodel API (part of Criteria API)
//         Add Set<RelationalDescriptor> mappedSuperclassDescriptors
//         to support the Metamodel API
//     06/17/2009-2.0 Michael O'Brien
//       - 266912: change mappedSuperclassDescriptors Set to a Map
//          keyed on MetadataClass - avoiding the use of a hashCode/equals
//          override on RelationalDescriptor, but requiring a contains check prior to a put
//     09/23/2009-2.0 Michael O'Brien
//       - 266912: Add metamodelIdClassMap to store IdClass types for exclusive
//         use by the IdentifiableTypeImpl class in the JPA 2.0 Metamodel API
//     06/30/2011-2.3.1 Guy Pelletier
//       - 341940: Add disable/enable allowing native queries
//     09/09/2011-2.3.1 Guy Pelletier
//       - 356197: Add new VPD type to MultitenantType
//     09/14/2011-2.3.1 Guy Pelletier
//       - 357533: Allow DDL queries to execute even when Multitenant entities are part of the PU
//     14/05/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
//     31/05/2012-2.4 Guy Pelletier
//       - 381196: Multitenant persistence units with a dedicated emf should allow for DDL generation.
//     08/11/2012-2.5 Guy Pelletier
//       - 393867: Named queries do not work when using EM level Table Per Tenant Multitenancy
//     04/11/2018 - Will Dazey
//       - 533148 : Add the eclipselink.jpa.sql-call-deferral property
package org.eclipse.persistence.sessions;

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

import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.config.CacheIsolationType;
import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.MultitenantPolicy;
import org.eclipse.persistence.descriptors.partitioning.PartitioningPolicy;
import org.eclipse.persistence.internal.helper.ConcurrentFixedCache;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
import org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.QueryResultsCachePolicy;
import org.eclipse.persistence.queries.SQLResultSetMapping;
import org.eclipse.persistence.sessions.server.ConnectionPolicy;
import org.eclipse.persistence.sessions.server.Server;
import org.eclipse.persistence.sessions.server.ServerSession;

/**
 * <b>Purpose</b>: Maintain all of the EclipseLink configuration information for a system.
 * <p><b>Responsibilities</b>:<ul>
 * <li> Project options and defaults
 * <li> Database login information
 * <li> Descriptors
 * <li> Validate Descriptors
 * <li> Maintain sequencing information {@literal &} other project options
 * </ul>
 *
 * @see DatabaseLogin
 */
public class Project extends CoreProject<ClassDescriptor, Login, DatabaseSession> implements Serializable, Cloneable {
    protected String name;
    protected Login datasourceLogin;
    protected Map<Class<?>, ClassDescriptor> descriptors;
    protected List<ClassDescriptor> orderedDescriptors;

    // Currently only one is supported.
    protected MultitenantPolicy multitenantPolicy;

    /** Holds the default set of read-only classes that apply to each UnitOfWork. */
    protected Vector<Class<?>> defaultReadOnlyClasses;

    /** Cache the EJBQL descriptor aliases. */
    protected Map<String, ClassDescriptor> aliasDescriptors;

    /** Cache if any descriptor is isolated. (set during initialization) */
    protected boolean hasIsolatedClasses;
    /** Cache if all descriptors are isolated in the unit of work. (set during initialization) */
    protected boolean hasNonIsolatedUOWClasses;
    /** Cache if any descriptor has history. (set during initialization) */
    protected boolean hasGenericHistorySupport;
    /** Cache if any descriptor is using ProxyIndirection. (set during initialization */
    protected boolean hasProxyIndirection;

    /** This a collection of 'maps' that allow users to map custom SQL to query results */
    protected Map<String, SQLResultSetMapping> sqlResultSetMappings;

    /** PERF: Provide an JPQL parse cache to optimize dynamic JPQL. */
    protected transient ConcurrentFixedCache jpqlParseCache;

    /** Define the default setting for configuring if dates and calendars are mutable. */
    protected boolean defaultTemporalMutable = false;

    /** Indicates whether there is at least one descriptor that has at least on mapping that
     *  require a call on deleted objects to update change sets.
     */
    protected transient boolean hasMappingsPostCalculateChangesOnDeleted = false;

    /** Default value for ClassDescriptor.identityMapClass. */
    protected Class<? extends IdentityMap> defaultIdentityMapClass = AbstractIdentityMap.getDefaultIdentityMapClass();

    /** Default value for ClassDescriptor.identityMapSize. */
    protected int defaultIdentityMapSize = 100;

    /** Default value for ClassDescriptor.isIsolated. */
    protected CacheIsolationType defaultCacheIsolation;

    /** Default value for query caching options for all named queries. */
    protected QueryResultsCachePolicy defaultQueryResultsCachePolicy;

    /** Default value for ClassDescriptor.idValidation. */
    protected IdValidation defaultIdValidation;

    /** List of queries - once Project is initialized, these are copied to the Session. */
    protected List<DatabaseQuery> queries;

    /** List of named AttributeGroups - once Project is initialized, these are copied to the Session. */
    protected Map<String, AttributeGroup> attributeGroups = null;

    /** List of queries from JPA that need special processing before execution. */
    protected List<DatabaseQuery> jpaQueries;

    /** List of queries from JPA that may special processing and handling before execution. */
    protected List<DatabaseQuery> jpaTablePerTenantQueries;

    /** Flag that allows native queries or not */
    protected boolean allowNativeSQLQueries = true;

    /** Flag that allows DDL generation of table per tenant multitenant descriptors */
    protected boolean allowTablePerMultitenantDDLGeneration = false;

    /** Flag that allows call deferral to be disabled */
    protected boolean allowSQLDeferral = true;

    /** Flag that allows transform named stored procedure parameters into positional/index based */
    protected boolean namingIntoIndexed = false;

    /** Flag that allows extended logging of JPA L2 cache or not. */
    protected boolean allowExtendedCacheLogging = false;

    /** Flag that allows extended thread logging or not. */
    protected boolean allowExtendedThreadLogging = false;

    /** Flag that allows add to extended thread logging output thread stack trace or not.*/
    protected boolean allowExtendedThreadLoggingThreadDump = false;

    /**
     * Mapped Superclasses (JPA 2) collection of parent non-relational descriptors keyed on MetadataClass
     * without creating a compile time dependency on JPA.
     * The descriptor values of this map must not be replaced by a put() so that the
     * mappings on the initial descriptor are not overwritten.<p>
     * These descriptors are only to be used by Metamodel generation.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    protected Map<String, ClassDescriptor> mappedSuperclassDescriptors;

    /**
     * Store the IdClass Id attributes for exclusive use by the Metamodel API
     * Keyed on the fully qualified accessible object owner class name.
     * Value is a List of the fully qualified id class name or id attribute name.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    protected Map<String, List<String>> metamodelIdClassMap;

    /** Map of named partitioning policies, keyed by their name. */
    protected Map<String, PartitioningPolicy> partitioningPolicies;

    /** Ensures that only one thread at a time can add/remove descriptors */
    protected Object descriptorsLock = Boolean.TRUE;

    /** VPD connection settings */
    protected String vpdIdentifier;
    protected String vpdLastIdentifierClassName; // Used for validation exception.

    /** used for Caching JPA projects */
    protected Collection<String> classNamesForWeaving;
    protected Collection<String> structConverters;

     /** Force all queries and relationships to use deferred lock strategy during object building and L2 cache population. */
    protected boolean queryCacheForceDeferredLocks = false;

    /**
     * PUBLIC:
     * Create a new project.
     */
    public Project() {
        this.name = "";
        this.descriptors = new HashMap<>();
        this.defaultReadOnlyClasses = NonSynchronizedVector.newInstance();
        this.orderedDescriptors = new ArrayList<>();
        this.hasIsolatedClasses = false;
        this.hasGenericHistorySupport = false;
        this.hasProxyIndirection = false;
        this.jpqlParseCache = new ConcurrentFixedCache(200);
        this.queries = new ArrayList<>();
        this.mappedSuperclassDescriptors = new HashMap<>(2);
        this.metamodelIdClassMap = new HashMap<>();
        this.attributeGroups = new HashMap<>();
    }

    /**
     * PUBLIC:
     * Create a new project that will connect through the login information.
     * This method can be used if the project is being create in code instead of being read from a file.
     */
    public Project(Login login) {
        this();
        this.datasourceLogin = login;
    }

    /**
     * PUBLIC:
     * Create a new project that will connect through JDBC using the login information.
     * This method can be used if the project is being create in code instead of being read from a file.
     */
    public Project(DatabaseLogin login) {
        this();
        this.datasourceLogin = login;
    }

    /**
     * PUBLIC:
     * Return the default values for query caching options for all named queries.
     */
    public QueryResultsCachePolicy getDefaultQueryResultsCachePolicy() {
        return defaultQueryResultsCachePolicy;
    }

    /**
     * PUBLIC:
     * Set the default values for query caching options for all named queries.
     * By default no query caching is used.
     */
    public void setDefaultQueryResultsCachePolicy(QueryResultsCachePolicy defaultQueryResultsCachePolicy) {
        this.defaultQueryResultsCachePolicy = defaultQueryResultsCachePolicy;
    }

    /**
     * PUBLIC:
     * Get property to Force all queries and relationships to use deferred lock strategy during object building and L2 cache population.
     */
    public boolean isQueryCacheForceDeferredLocks() {
        return queryCacheForceDeferredLocks;
    }

    /**
     * PUBLIC:
     * Set property to Force all queries and relationships to use deferred lock strategy during object building and L2 cache population.
     * By default there is false value - use use mixed object cache locking strategy (depends on relationship and fetch type) */
    public void setQueryCacheForceDeferredLocks(boolean queryCacheForceDeferredLocks) {
        this.queryCacheForceDeferredLocks = queryCacheForceDeferredLocks;
    }

    /**
     * PUBLIC:
     * Return the default setting for configuring if dates and calendars are mutable.
     * Mutable means that changes to the date's year/month/day are detected.
     * By default they are treated as not mutable.
     */
    public boolean getDefaultTemporalMutable() {
        return defaultTemporalMutable;
    }

    /**
     * PUBLIC:
     * Set the default setting for configuring if dates and calendars are mutable.
     * Mutable means that changes to the date's year/month/day are detected.
     * By default they are treated as not mutable.
     */
    public void setDefaultTemporalMutable(boolean defaultTemporalMutable) {
        this.defaultTemporalMutable = defaultTemporalMutable;
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed JPQL queries.
     */
    public List<DatabaseQuery> getJPAQueries() {
        // PERF: lazy init, not normally required.
        if (jpaQueries == null) {
            jpaQueries = new ArrayList<>();
        }

        return jpaQueries;
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed JPQL queries to table per tenant
     * entities.
     */
    public List<DatabaseQuery> getJPATablePerTenantQueries() {
        // PERF: lazy init, not normally required.
        if (jpaTablePerTenantQueries == null) {
            jpaTablePerTenantQueries = new ArrayList<>();
        }

        return jpaTablePerTenantQueries;
    }

    /**
     * INTERNAL:
     * Return the JPQL parse cache.
     * This is used to optimize dynamic JPQL.
     */
    public ConcurrentFixedCache getJPQLParseCache() {
        if (jpqlParseCache==null) {
            jpqlParseCache = new ConcurrentFixedCache(200);
        }
        return jpqlParseCache;
    }

    /**
     * ADVANCED:
     * Set the JPQL parse cache max size.
     * This is used to optimize dynamic JPQL.
     */
    public void setJPQLParseCacheMaxSize(int maxSize) {
        setJPQLParseCache(new ConcurrentFixedCache(maxSize));
    }

    /**
     * ADVANCED:
     * Return the JPQL parse cache max size.
     * This is used to optimize dynamic JPQL.
     */
    public int getJPQLParseCacheMaxSize() {
        return getJPQLParseCache().getMaxSize();
    }

    /**
     * INTERNAL:
     * Set the JPQL parse cache.
     * This is used to optimize dynamic JPQL.
     */
    protected void setJPQLParseCache(ConcurrentFixedCache jpqlParseCache) {
        this.jpqlParseCache = jpqlParseCache;
    }

    /**
     * INTERNAL:
     * List of queries that upon initialization are copied over to the session
     */
    public List<DatabaseQuery> getQueries() {
        return queries;
    }
    /**
     * INTERNAL:
     */
    public void setQueries(List<DatabaseQuery> queries) {
        this.queries = queries;
    }

    /**
     * INTERNAL:
     * List of named AttributesGroups that will be copied to the session at initialization time.
     */
    public Map<String, AttributeGroup> getAttributeGroups(){
        return this.attributeGroups;
    }

    /**
     * INTERNAL:
     * Set the VPD identifier for this project. This identifier should be
     * populated from a descriptor VPDMultitenantPolicy and should not be
     * set directly.
     */
    public void setVPDIdentifier(String vpdIdentifier) {
        this.vpdIdentifier = vpdIdentifier;
    }

    /**
     * INTERNAL:
     * Set from individual descriptors from the project that set a VPD
     * identifier and used in validation exception.
     */
    public void setVPDLastIdentifierClassName(String vpdLastIdentifierClassName) {
        this.vpdLastIdentifierClassName = vpdLastIdentifierClassName;
    }

    /**
     * PUBLIC:
     * Add the read-only class which apply to each UnitOfWork created by default.
     */
    public void addDefaultReadOnlyClass(Class<?> readOnlyClass) {
        getDefaultReadOnlyClasses().addElement(readOnlyClass);
    }

    /**
     * PUBLIC:
     * Add the descriptor to the project.
     */
    @Override
    public void addDescriptor(ClassDescriptor descriptor) {
        getOrderedDescriptors().add(descriptor);
        String alias = descriptor.getAlias();
        if (alias != null) {
            addAlias(alias, descriptor);
        }

        // Avoid loading class definition at this point if we haven't done so yet.
        if ((descriptors != null) && !descriptors.isEmpty()) {
            getDescriptors().put(descriptor.getJavaClass(), descriptor);
        }
    }

    /**
     * INTERNAL: Used by the BuilderInterface when reading a Project from INI files.
     * @param descriptor The descriptor to be added to the session and the project.
     * @param session     The current database session.
     */
    public void addDescriptor(final ClassDescriptor descriptor, final DatabaseSessionImpl session) {
        synchronized (this.descriptorsLock) {
            if (session.isConnected()) {
                final String alias = descriptor.getAlias();
                // Descriptor aliases may be concurrently accessed by other threads.
                // Make a clone, add new descriptor to the clone, override original with the clone.
                if (alias != null) {
                    @SuppressWarnings({"unchecked"})
                    final Map<String, ClassDescriptor> aliasDescriptorsClone = getAliasDescriptors() != null
                            ? (Map<String, ClassDescriptor>)((HashMap<String, ClassDescriptor>) getAliasDescriptors()).clone()
                            : new HashMap<>();
                    aliasDescriptorsClone.put(alias, descriptor);
                    setAliasDescriptors(aliasDescriptorsClone);
                }
                // Descriptors may be concurrently accessed by other threads.
                // Make a clone, add new descriptor to the clone, override original with the clone.
                @SuppressWarnings({"unchecked"})
                final Map<Class<?>, ClassDescriptor> descriptorsClone = (Map<Class<?>, ClassDescriptor>)((HashMap<Class<?>, ClassDescriptor>) getDescriptors()).clone();
                descriptorsClone.put(descriptor.getJavaClass(), descriptor);
                setDescriptors(descriptorsClone);
                session.copyDescriptorsFromProject();
                session.initializeDescriptorIfSessionAlive(descriptor);
                getOrderedDescriptors().add(descriptor);
            } else {
                addDescriptor(descriptor);
            }
        }
    }

    /**
     * INTERNAL:
     * Add the descriptors to the session.
     * All persistent classes must have a descriptor registered for them with the session.
     * This method allows for a batch of descriptors to be added at once so that EclipseLink
     * can resolve the dependencies between the descriptors and perform initialization optimally.
     * @param descriptors The descriptors to be added to the session and the project.
     * @param session     The current database session.
     */
    public void addDescriptors(final Collection descriptors, final DatabaseSessionImpl session) {
        synchronized (this.descriptorsLock) {
            if (session.isConnected()) {
                // Descriptor aliases may be concurrently accessed by other threads.
                // Make a clone, add new descriptors to the clone, override original with the clone.
                @SuppressWarnings({"unchecked"})
                final Map<String, ClassDescriptor> aliasDescriptorsClone = getAliasDescriptors() != null
                        ? (Map<String, ClassDescriptor>)((HashMap<String, ClassDescriptor>) getAliasDescriptors()).clone()
                        : new HashMap<>();
                // Descriptors may be concurrently accessed by other threads.
                // Make a clone, add new descriptors to the clone, override original with the clone.
                @SuppressWarnings({"unchecked"})
                final Map<Class<?>, ClassDescriptor> descriptorsClone = (Map<Class<?>, ClassDescriptor>)((HashMap<Class<?>, ClassDescriptor>) getDescriptors()).clone();
                for (ClassDescriptor descriptor : (Collection<ClassDescriptor>) descriptors) {
                    descriptorsClone.put(descriptor.getJavaClass(), descriptor);
                    final String alias = descriptor.getAlias();
                    if (alias != null) {
                        aliasDescriptorsClone.put(alias, descriptor);
                    }
                }
                if (!aliasDescriptorsClone.isEmpty()) {
                    setAliasDescriptors(aliasDescriptorsClone);
                }
                setDescriptors(descriptorsClone);
                session.copyDescriptorsFromProject();
                session.initializeDescriptors(descriptors);
            } else {
                final Map<Class<?>, ClassDescriptor> projectDescriptors = getDescriptors();
                for (ClassDescriptor descriptor : (Collection<ClassDescriptor>) descriptors) {
                    final String alias = descriptor.getAlias();
                    projectDescriptors.put(descriptor.getJavaClass(), descriptor);
                    if (alias != null) {
                        addAlias(alias, descriptor);
                    }
                }
            }
            getOrderedDescriptors().addAll(descriptors);
        }
    }

    /**
     * PUBLIC:
     * Merge the descriptors from another project into this one.
     * All persistent classes must have a descriptor registered for them with the session.
     * This method allows for a batch of descriptors to be added at once so that EclipseLink
     * can resolve the dependencies between the descriptors and perform initialization optimally.
     */
    public void addDescriptors(Project project, DatabaseSessionImpl session) {
        addDescriptors(project.getDescriptors().values(), session);
    }

    /**
     * PUBLIC:
     * Add a named SQLResultSetMapping to this project.  These SQLResultSetMappings
     * can be later used by ResultSetMappingQueries to map Custom sql results to
     * results as defined by the SQLResultSetMappings.
     */
    public void addSQLResultSetMapping(SQLResultSetMapping sqlResultSetMapping){
        if (sqlResultSetMapping == null || sqlResultSetMapping.getName() == null){
            return;
        }
        if (this.sqlResultSetMappings == null){
            this.sqlResultSetMappings = new HashMap<>();
        }
        this.sqlResultSetMappings.put(sqlResultSetMapping.getName(), sqlResultSetMapping);
    }

    /**
     * PUBLIC:
     * Set all this project's descriptors to conform all read queries within the context of the unit of work.
     */
    public void conformAllDescriptors() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.setShouldAlwaysConformResultsInUnitOfWork(true);
        }
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this project to actual class-based settings.
     * This will also reset any class references to the version of the class from the class loader.
     */
    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader){
        Iterator<ClassDescriptor> ordered = orderedDescriptors.iterator();
        while (ordered.hasNext()){
            ClassDescriptor descriptor = ordered.next();
            descriptor.convertClassNamesToClasses(classLoader);
        }
        for (AttributeGroup group : this.getAttributeGroups().values()){
            group.convertClassNamesToClasses(classLoader);
        }
        // Clear old descriptors to allow rehash on new classes.
        this.descriptors = new HashMap<>();
        // convert class names to classes for each SQLResultSetMapping
        if (this.sqlResultSetMappings != null) {
            for (SQLResultSetMapping mapping : this.sqlResultSetMappings.values()) {
                mapping.convertClassNamesToClasses(classLoader);
            }
        }
        if (this.partitioningPolicies != null) {
            for (PartitioningPolicy policy : this.partitioningPolicies.values()) {
                policy.convertClassNamesToClasses(classLoader);
            }
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to assume existence for non-null primary keys.
     */
    public void assumeExistenceForDoesExist() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.getQueryManager().assumeExistenceForDoesExist();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to check the cache for existence.
     */
    public void checkCacheForDoesExist() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.getQueryManager().checkCacheForDoesExist();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to check the database for existence.
     */
    public void checkDatabaseForDoesExist() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.getQueryManager().checkDatabaseForDoesExist();
        }
    }

    /**
     * INTERNAL:
     * Clones the descriptor
     */
    @Override
    public Project clone() {
        try {
            return (Project) super.clone();
        } catch (CloneNotSupportedException exception) {
            throw new InternalError(exception.toString());
        }
    }

    /**
     * PUBLIC:
     * Factory method to create session.
     * This returns an implementor of the DatabaseSession interface, which can be used to login
     * and add descriptors from other projects.  The Session interface however should be used for
     * reading and writing once connected for complete portability.
     */
    @Override
    public DatabaseSession createDatabaseSession() {
        return new DatabaseSessionImpl(this);
    }

    /**
     * PUBLIC:
     * Factory method to create a server session.
     * This returns an implementor of the Server interface, which can be used to login
     * and add descriptors from other projects, configure connection pooling and acquire client sessions.
     * <br>
     * By default the ServerSession has a single shared read/write connection pool
     * with 32 min/max connections and an initial of 1 connection.
     */
    public Server createServerSession() {
        return new ServerSession(this);
    }

    /**
     * PUBLIC:
     * Factory method to create a server session.
     * This returns an implementor of the Server interface, which can be used to login
     * and add descriptors from other projects, configure connection pooling and acquire client sessions.
     * Configure the min and max number of connections for the default shared read/write pool.
     */
    public Server createServerSession(int min, int max) {
        return new ServerSession(this, min, max);
    }

    /**
     * PUBLIC:
     * Factory method to create a server session.
     * This returns an implementor of the Server interface, which can be used to login
     * and add descriptors from other projects, configure connection pooling and acquire client sessions.
     * Configure the min and max number of connections for the default shared read/write pool.
     */
    public Server createServerSession(int initial, int min, int max) {
        return new ServerSession(this, initial, min, max);
    }

    /**
     * PUBLIC:
     * Factory method to create a server session.
     * This returns an implementor of the Server interface, which can be used to login
     * and add descriptors from other projects, configure connection pooling and acquire client sessions.
     * Configure the default connection policy to be used.
     * This policy is used on the "acquireClientSession()" protocol.
     * <br>
     * By default the ServerSession has a single shared read/write connection pool
     * with 32 min/max connections and an initial of 1 connection.
     */
    public Server createServerSession(ConnectionPolicy defaultConnectionPolicy) {
        return new ServerSession(this, defaultConnectionPolicy);
    }

    /**
     * PUBLIC:
     * Returns the default set of read-only classes.
     */
    public Vector getDefaultReadOnlyClasses() {
        return defaultReadOnlyClasses;
    }

    /**
     * PUBLIC:
     * Return default value for descriptor cache type.
     */
    public Class<? extends IdentityMap> getDefaultIdentityMapClass() {
        return this.defaultIdentityMapClass;
    }

    /**
     * PUBLIC:
     * Return default value descriptor cache size.
     */
    public int getDefaultIdentityMapSize() {
        return this.defaultIdentityMapSize;
    }

    /**
     * PUBLIC:
     * Return the project level default for class cache isolation;
     */
    public CacheIsolationType getDefaultCacheIsolation(){
        return this.defaultCacheIsolation;
    }

    /**
     * PUBLIC:
     * Return default value for descriptor primary key validation.
     */
    public IdValidation getDefaultIdValidation() {
        return this.defaultIdValidation;
    }

    /**
     * PUBLIC:
     * Return the descriptor specified for the class.
     * If the passed Class parameter is null, null will be returned.
     */
    public ClassDescriptor getClassDescriptor(Class<?> theClass) {
        return getDescriptor(theClass);
    }

    /**
     * PUBLIC:
     * Return the descriptor specified for the class.
     */
    @Override
    public ClassDescriptor getDescriptor(Class<?> theClass) {
        if (theClass == null) {
            return null;
        }
        return getDescriptors().get(theClass);
    }

    /**
     * PUBLIC:
     * Return the descriptors in a ClassDescriptors Map keyed on the Java class.
     */
    public Map<Class<?>, ClassDescriptor> getDescriptors() {
        // Lazy initialize class references from orderedDescriptors when reading from XML.
        if (descriptors.isEmpty() && (!orderedDescriptors.isEmpty())) {
            for (Iterator<ClassDescriptor> iterator = orderedDescriptors.iterator(); iterator.hasNext();) {
                ClassDescriptor descriptor = iterator.next();
                descriptors.put(descriptor.getJavaClass(), descriptor);
            }
        }
        return descriptors;
    }

    /**
     * INTERNAL:
     * Return the descriptors in the order added.
     * Used to maintain consistent order in XML.
     */
    @Override
    public List<ClassDescriptor> getOrderedDescriptors() {
        return orderedDescriptors;
    }

    /**
     * INTERNAL:
     * Set the descriptors order.
     * Used to maintain consistent order in XML.
     */
    public void setOrderedDescriptors(List<ClassDescriptor> orderedDescriptors) {
        this.orderedDescriptors = orderedDescriptors;
        for (ClassDescriptor descriptor : orderedDescriptors) {
            String alias = descriptor.getAlias();
            if (alias != null) {
                addAlias(alias, descriptor);
            }
        }
    }

    /**
     * INTERNAL:
     * Returns all classes in this project that are needed for weaving.
     * This list currently includes entity, embeddables and mappedSuperClasses.
     */
    public Collection<String> getClassNamesForWeaving() {
        return classNamesForWeaving;
    }

    /**
     * INTERNAL:
     * Returns all classes in this project that are needed for weaving.
     * This list currently includes entity, embeddables and mappedSuperClasses.
     */
    public void setClassNamesForWeaving(Collection<String> classNamesForWeaving) {
        this.classNamesForWeaving = classNamesForWeaving;
    }

    /**
     * OBSOLETE:
     * Return the login, the login holds any database connection information given.
     * This has been replaced by getDatasourceLogin to make use of the Login interface
     * to support non-relational datasources,
     * if DatabaseLogin API is required it will need to be cast.
     */
    public DatabaseLogin getLogin() {
        return (DatabaseLogin)datasourceLogin;
    }

    /**
     * PUBLIC:
     * Return the login, the login holds any database connection information given.
     * This return the Login interface and may need to be cast to the datasource specific implementation.
     */
    @Override
    public Login getDatasourceLogin() {
        return datasourceLogin;
    }

    /**
     * PUBLIC:
     * get the name of the project.
     */
    public String getName() {
        return name;
    }

    /**
     * PUBLIC:
     * Get a named SQLResultSetMapping from this project.  These SQLResultSetMappings
     * can be used by ResultSetMappingQueries to map Custom sql results to
     * results as defined by the SQLResultSetMappings.
     */
    public SQLResultSetMapping getSQLResultSetMapping(String sqlResultSetMapping){
        if (sqlResultSetMapping == null || this.sqlResultSetMappings == null){
            return null;
        }
        return this.sqlResultSetMappings.get(sqlResultSetMapping);
    }

    /**
     * INTERNAL:
     * Returns structure converter class names that would be set on the databasePlatform instance
     * This is used to avoid the platform instance changing at login.
     */
    public Collection<String> getStructConverters() {
        return structConverters;
    }

    /**
     * INTERNAL:
     * Returns structure converter class names that would be set on the databasePlatform instance
     * This is used to avoid the platform instance changing at login.
     */
    public void setStructConverters(Collection<String> structConverters) {
        this.structConverters = structConverters;
    }

    /**
     * INTERNAL:
     * Return the name of the last class to set a VPD identifiers.
     */
    public String getVPDLastIdentifierClassName() {
        return vpdLastIdentifierClassName;
    }

    /**
     * INTERNAL:
     * Return the VPD identifier for this project.
     */
    public String getVPDIdentifier() {
        return vpdIdentifier;
    }

    /**
     * INTERNAL:
     */
    public MultitenantPolicy getMultitenantPolicy() {
        return multitenantPolicy;
    }

    /**
     * INTERNAL:
     * Answers if at least one Descriptor or Mapping had a HistoryPolicy at initialize time.
     */
    public boolean hasGenericHistorySupport() {
        return hasGenericHistorySupport;
    }

    /**
     * PUBLIC:
     * Set the read-only classes which apply to each UnitOfWork create by default.
     */
    public void setDefaultReadOnlyClasses(Collection newValue) {
        this.defaultReadOnlyClasses = new Vector(newValue);
    }

    /**
     * PUBLIC:
     * Set default value for descriptor cache type.
     */
    public void setDefaultIdentityMapClass(Class<? extends IdentityMap> defaultIdentityMapClass) {
        this.defaultIdentityMapClass = defaultIdentityMapClass;
    }

    /**
     * PUBLIC:
     * Set default value descriptor cache size.
     */
    public void setDefaultIdentityMapSize(int defaultIdentityMapSize) {
        this.defaultIdentityMapSize = defaultIdentityMapSize;
    }

    /**
     * PUBLIC:
     * Set project level default value for class cache isolation.
     */
    public void setDefaultCacheIsolation(CacheIsolationType isolationType) {
        this.defaultCacheIsolation = isolationType;
    }
    /**
     * PUBLIC:
     * Set default value for descriptor primary key validation.
     */
    public void setDefaultIdValidation(IdValidation defaultIdValidation) {
        this.defaultIdValidation = defaultIdValidation;
    }

    /**
     * INTERNAL:
     * Set the descriptors registered with this session.
     */
    public void setDescriptors(Map descriptors) {
        this.descriptors = descriptors;
        for (Iterator<ClassDescriptor> iterator = descriptors.values().iterator(); iterator.hasNext();) {
            ClassDescriptor descriptor = iterator.next();
            String alias = descriptor.getAlias();
            if (alias != null) {
                addAlias(alias, descriptor);
            }
        }
    }

    /**
     * ADVANCED:
     * This method is a 'helper' method for updating all of the descriptors
     * within this project to have a particular deferral level.  The levels are
     * as follows
     *     ClassDescriptor.ALL_MODIFICATIONS - this is the default and recommended.
     *        The writing of all changes will be deferred until the end of the
     *       transaction
     *    ClassDescriptor.UPDATE_MODIFICATIONS - this will cause the update changes to
     *        be deferred and all other changes to be written immediately.
     *    ClassDescriptor.NONE - this will cause all changes to be written on each
     *        container call.
     */
    public void setDeferModificationsUntilCommit(int deferralLevel) {
        for (Iterator<ClassDescriptor> iterator = descriptors.values().iterator(); iterator.hasNext();) {
            ClassDescriptor descriptor = iterator.next();
            if (descriptor.getCMPPolicy() != null) {
                descriptor.getCMPPolicy().setDeferModificationsUntilCommit(deferralLevel);
            }
        }
    }


    /**
     * INTERNAL:
     * Set to true during descriptor initialize if any descriptor has history.
     */
    public void setHasGenericHistorySupport(boolean hasGenericHistorySupport) {
        this.hasGenericHistorySupport = hasGenericHistorySupport;
    }

    /**
     * INTERNAL:
     * Return whether this project has a descriptor that is both Isolated and
     * has a cache isolation level other than ISOLATE_CACHE_ALWAYS
     */
    public boolean hasIsolatedCacheClassWithoutUOWIsolation(){
        // checked cached boolean to avoid iteration
        if (!hasIsolatedClasses){
            return false;
        }
        Iterator<ClassDescriptor> i = orderedDescriptors.iterator();
        while (i.hasNext()){
            ClassDescriptor descriptor = i.next();
            if (descriptor.getCachePolicy().isIsolated() && !descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) {
                return true;
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Return if any descriptors are isolated.
     * Set to true during descriptor initialize if any descriptor is isolated.
     * Determines if an isolated client session is required.
     */
    public boolean hasIsolatedClasses() {
        return hasIsolatedClasses;
    }

    /**
     * INTERNAL:
     * Set to true during descriptor initialize if any descriptor is isolated.
     * Determines if an isolated client session is required.
     */
    public void setHasIsolatedClasses(boolean hasIsolatedClasses) {
        this.hasIsolatedClasses = hasIsolatedClasses;
    }

    /**
     * INTERNAL:
     * Return if any descriptors are not isolated to the unit of work.
     * Set to true during descriptor initialize if any descriptor is not isolated.
     * Allows uow merge to be bypassed.
     */
    public boolean hasNonIsolatedUOWClasses() {
        return hasNonIsolatedUOWClasses;
    }

    /**
     * INTERNAL:
     * Set if any descriptors are not isolated to the unit of work.
     * Set to true during descriptor initialize if any descriptor is not isolated.
     * Allows uow merge to be bypassed.
     */
    public void setHasNonIsolatedUOWClasses(boolean hasNonIsolatedUOWClasses) {
        this.hasNonIsolatedUOWClasses = hasNonIsolatedUOWClasses;
    }

    /**
     * INTERNAL:
     * Return if any descriptors use ProxyIndirection.
     * Set to true during descriptor initialize if any descriptor uses ProxyIndirection
     * Determines if ProxyIndirectionPolicy.getValueFromProxy should be called.
     */
    public boolean hasProxyIndirection() {
        return this.hasProxyIndirection;
    }

    /**
     * PUBLIC:
     * Return true if the sql result set mapping name exists.
     */
    public boolean hasSQLResultSetMapping(String sqlResultSetMapping) {
        return sqlResultSetMappings.containsKey(sqlResultSetMapping);
    }

    /**
     * PUBLIC:
     * Return true if there is a VPD identifier for this project. Will not be
     * set till after descriptor initialization.
     */
    public boolean hasVPDIdentifier(AbstractSession session) {
        return (vpdIdentifier != null && session.getProperty(vpdIdentifier) != null);
    }

    /**
     * INTERNAL:
     * Set to true during descriptor initialize if any descriptor uses ProxyIndirection
     * Determines if ProxyIndirectionPolicy.getValueFromProxy should be called.
     */
    public void setHasProxyIndirection(boolean hasProxyIndirection) {
        this.hasProxyIndirection = hasProxyIndirection;
    }
    /**
     * PUBLIC:
     * Set the login to be used to connect to the database for this project.
     */
    public void setLogin(DatabaseLogin datasourceLogin) {
        this.datasourceLogin = datasourceLogin;
    }

    /**
     * INTERNAL:
     * Set the multitenant policy.
     */
    public void setMultitenantPolicy(MultitenantPolicy policy) {
        multitenantPolicy = policy;
    }

    /**
     * PUBLIC:
     * Set the login to be used to connect to the database for this project.
     */
    @Override
    public void setLogin(Login datasourceLogin) {
        this.datasourceLogin = datasourceLogin;
    }

    /**
     * PUBLIC:
     * Set the login to be used to connect to the database for this project.
     */
    public void setDatasourceLogin(Login datasourceLogin) {
        this.datasourceLogin = datasourceLogin;
    }

    /**
     * PUBLIC:
     * Set the name of the project.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * INTERNAL:
     */
    @Override
    public String toString() {
        return Helper.getShortClassName(getClass()) + "(" + getName() + ")";
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the cache identity map.
     */
    public void useCacheIdentityMap() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useCacheIdentityMap();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the cache identity map the size.
     */
    public void useCacheIdentityMap(int cacheSize) {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useCacheIdentityMap();
            descriptor.setIdentityMapSize(cacheSize);
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the full identity map.
     */
    public void useFullIdentityMap() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useFullIdentityMap();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the full identity map with initial cache size.
     */
    public void useFullIdentityMap(int initialCacheSize) {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useFullIdentityMap();
            descriptor.setIdentityMapSize(initialCacheSize);
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use no identity map.
     */
    public void useNoIdentityMap() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useNoIdentityMap();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the soft cache weak identity map.
     */
    public void useSoftCacheWeakIdentityMap() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useSoftCacheWeakIdentityMap();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the soft cache weak identity map with soft cache size.
     */
    public void useSoftCacheWeakIdentityMap(int cacheSize) {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useSoftCacheWeakIdentityMap();
            descriptor.setIdentityMapSize(cacheSize);
        }
    }

    /**
     * INTERNAL:
     * Asks each descriptor if is uses optimistic locking.
     */
    public boolean usesOptimisticLocking() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            if (descriptor.usesOptimisticLocking()) {
                return true;
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Asks each descriptor if is uses sequencing.
     */
    public boolean usesSequencing() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            if (descriptor.usesSequenceNumbers()) {
                return true;
            }
        }
        return false;
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the weak identity map.
     */
    public void useWeakIdentityMap() {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useWeakIdentityMap();
        }
    }

    /**
     * PUBLIC:
     * Switch all descriptors to use the weak identity map.
     */
    public void useWeakIdentityMap(int initialCacheSize) {
        Iterator<ClassDescriptor> descriptors = getDescriptors().values().iterator();
        while (descriptors.hasNext()) {
            ClassDescriptor descriptor = descriptors.next();
            descriptor.useWeakIdentityMap();
            descriptor.setIdentityMapSize(initialCacheSize);
        }
    }

    /**
     * INTERNAL:
     * Default apply  login implementation.
     * Defined for generated subclasses that may not have a login.
     * BUG#2669342
     */
    public void applyLogin() {
        // Do nothing by default.
    }

    /**
     * INTERNAL:
     * Returns the alias descriptors hashtable.
     */
    public Map<String, ClassDescriptor> getAliasDescriptors() {
        return aliasDescriptors;
    }

    /**
     * PUBLIC:
     * Add an alias for the descriptor.
     */
    public void addAlias(String alias, ClassDescriptor descriptor) {
        if (aliasDescriptors == null) {
            aliasDescriptors = new HashMap<>(10);
        }
        aliasDescriptors.put(alias, descriptor);
    }

    /**
     * INTERNAL:
     * Return true if native sql is allowed on this project.
     */
    public boolean allowTablePerMultitenantDDLGeneration() {
        return this.allowTablePerMultitenantDDLGeneration;
    }

    /**
     * INTERNAL:
     * Return true if native sql is allowed on this project.
     */
    public boolean allowNativeSQLQueries() {
        return this.allowNativeSQLQueries;
    }

    /**
     * INTERNAL:
     * Return true if SQL calls can defer to EOT on this project.
     */
    public boolean allowSQLDeferral() {
        return this.allowSQLDeferral;
    }

    /**
     * INTERNAL:
     * Return true is allowed to transform named stored procedure parameters into positional/index based.
     */
    public boolean namingIntoIndexed() {
        return this.namingIntoIndexed;
    }

    /**
     * INTERNAL:
     * Return true if extended logging of JPA L2 cache usage is allowed on this project.
     */
    public boolean allowExtendedCacheLogging() {
        return this.allowExtendedCacheLogging;
    }

    /**
     * INTERNAL:
     * Return true if extended thread logging is allowed on this project.
     */
    public boolean allowExtendedThreadLogging() {
        return this.allowExtendedThreadLogging;
    }

    /**
     * INTERNAL:
     * Return true if thread dumps will be added to extended thread logging.
     */
    public boolean allowExtendedThreadLoggingThreadDump() {
        return this.allowExtendedThreadLoggingThreadDump;
    }

    /**
     * PUBLIC:
     * Return the descriptor for  the alias
     */
    public ClassDescriptor getDescriptorForAlias(String alias) {
        ClassDescriptor descriptor = null;
        if (aliasDescriptors != null) {
            descriptor = aliasDescriptors.get(alias);
        }
        return descriptor;
    }

    /**
     * INTERNAL:
     * Set the alias descriptors hashtable.
     */
    public void setAliasDescriptors(Map<String, ClassDescriptor> aHashtable) {
        aliasDescriptors = aHashtable;
    }

    /**
     * INTERNAL:
     * Set whether ddl generation should allowed for table per tenant
     * multitenant descriptors. This will only be true when a non shared emf
     * is used and all the tenant context properties are provided at deploy
     * time.
     */
    public void setAllowTablePerMultitenantDDLGeneration(boolean allowTablePerMultitenantDDLGeneration) {
        this.allowTablePerMultitenantDDLGeneration = allowTablePerMultitenantDDLGeneration;
    }

    /**
     * INTERNAL:
     * Set whether native sql is allowed on this project.
     */
    public void setAllowNativeSQLQueries(boolean allowNativeSQLQueries) {
        this.allowNativeSQLQueries = allowNativeSQLQueries;
    }

    /**
     * INTERNAL:
     * Set whether sql deferral is allowed on this project
     */
    public void setAllowSQLDeferral(boolean allowSQLDeferral) {
        this.allowSQLDeferral = allowSQLDeferral;
    }

    /**
     * INTERNAL:
     * Set whether named stored procedure parameters is allowed to transform into positional/index based.
     */
    public void setNamingIntoIndexed(boolean namingIntoIndexed) {
        this.namingIntoIndexed = namingIntoIndexed;
    }

    /**
     * INTERNAL:
     * Set whether extended logging of JPA L2 cache usage is allowed on this project.
     */
    public void setAllowExtendedCacheLogging(boolean allowExtendedCacheLogging) {
        this.allowExtendedCacheLogging = allowExtendedCacheLogging;
    }

    /**
     * INTERNAL:
     * Set whether extended thread logging is allowed on this project.
     */
    public void setAllowExtendedThreadLogging(boolean allowExtendedThreadLogging) {
        this.allowExtendedThreadLogging = allowExtendedThreadLogging;
    }

    /**
     * INTERNAL:
     * Set if thread dumps will be added to extended thread logging.
     */
    public void setAllowExtendedThreadLoggingThreadDump(boolean allowExtendedThreadLoggingThreadDump) {
        this.allowExtendedThreadLoggingThreadDump = allowExtendedThreadLoggingThreadDump;
    }

    /**
     * INTERNAL:
     * Indicates whether there is at least one descriptor that has at least on mapping that
     * require a call on deleted objects to update change sets.
     */
    public boolean hasMappingsPostCalculateChangesOnDeleted() {
        return hasMappingsPostCalculateChangesOnDeleted;
    }

    /**
     * INTERNAL:
     * Indicates whether there is at least one descriptor that has at least on mapping that
     * require a call on deleted objects to update change sets.
     */
    public void setHasMappingsPostCalculateChangesOnDeleted(boolean hasMappingsPostCalculateChangesOnDeleted) {
        this.hasMappingsPostCalculateChangesOnDeleted = hasMappingsPostCalculateChangesOnDeleted;
    }

    /**
     * INTERNAL:
     * Return whether there any mappings that are mapped superclasses.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public boolean hasMappedSuperclasses() {
        return (null != this.mappedSuperclassDescriptors && !this.mappedSuperclassDescriptors.isEmpty());
    }

    /**
     * INTERNAL:
     * Return whether the given class is mapped as superclass.
     * @since EclipseLink 2.3 for the JPA 2.0 Reference Implementation
     */
    public boolean hasMappedSuperclass(String className) {
        if (!hasMappedSuperclasses()) {
            return false;
        }

        return this.mappedSuperclassDescriptors.containsKey(className);
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed EJBQL queries.
     */
    public void addJPAQuery(DatabaseQuery query) {
        getJPAQueries().add(query);
    }

    /**
     * INTERNAL:
     * Return all pre-defined not yet parsed EJBQL queries to table per tenant entities.
     */
    public void addJPATablePerTenantQuery(DatabaseQuery query) {
        getJPATablePerTenantQueries().add(query);
    }

    /**
     * INTERNAL:
     * 266912: Add a descriptor to the Map of mappedSuperclass descriptors
     * @param key (Metadata class)
     * @param value (RelationalDescriptor)
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public void addMappedSuperclass(String key, ClassDescriptor value, boolean replace) {
        // Lazy initialization of the mappedSuperclassDescriptors field.
        if(null == this.mappedSuperclassDescriptors) {
            this.mappedSuperclassDescriptors = new HashMap<>(2);
        }
        // Avoid replacing the current RelationalDescriptor that may have mappings set
        if(replace || !this.mappedSuperclassDescriptors.containsKey(key)) {
            this.mappedSuperclassDescriptors.put(key, value);
        }
    }

    /**
     * INTERNAL:
     * Use the Metadata key parameter to lookup the
     * Descriptor from the Map of mappedSuperclass descriptors
     * @param key - theMetadata class
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public ClassDescriptor getMappedSuperclass(String key) {
        // TODO: this implementation may have side effects when we have the same class
        // in different class loaders - however currently there is only one classLoader per project
        // Lazy initialization of the mappedSuperclassDescriptors field.
        if(null == this.mappedSuperclassDescriptors) {
            this.mappedSuperclassDescriptors = new HashMap<>(2);
            return null;
        }
        return this.mappedSuperclassDescriptors.get(key);
    }

    /**
     * INTERNAL:
     * Return the Map of RelationalDescriptor objects representing mapped superclass parents
     * keyed by className of the metadata class.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public Map<String, ClassDescriptor> getMappedSuperclassDescriptors() {
        // Lazy initialization of the mappedSuperclassDescriptors field.
        if(null == this.mappedSuperclassDescriptors) {
            this.mappedSuperclassDescriptors = new HashMap<>(2);
        }
        return this.mappedSuperclassDescriptors;
    }

    /**
     * INTERNAL:
     * Add an IdClass entry to the map of ids for a particular owner
     * This function is used exclusively by the Metamodel API.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public void addMetamodelIdClassMapEntry(String ownerName, String name) {
        // Add a possible composite key to the owner - this function will handle duplicates by overwriting the entry
        if(this.metamodelIdClassMap.containsKey(ownerName)) {
            // If we have a key entry then the list will always exist
            this.metamodelIdClassMap.get(ownerName).add(name);
        } else {
            List<String> ownerList = new ArrayList<>();
            ownerList.add(name);
            this.metamodelIdClassMap.put(ownerName, ownerList);
        }
    }

    /**
     * INTERNAL:
     * Return the Map of IdClass attribute lists keyed on owner class name.
     * @since EclipseLink 1.2 for the JPA 2.0 Reference Implementation
     */
    public Map<String, List<String>> getMetamodelIdClassMap() {
        return metamodelIdClassMap;
    }

    /**
     * PUBLIC:
     * Return the map of partitioning policies, keyed by name.
     */
    public Map<String, PartitioningPolicy> getPartitioningPolicies() {
        if (this.partitioningPolicies == null) {
            this.partitioningPolicies = new HashMap<>();
        }
        return partitioningPolicies;
    }

    /**
     * PUBLIC:
     * Set the map of partitioning policies, keyed by name.
     */
    public void setPartitioningPolicies(Map<String, PartitioningPolicy> partitioningPolicies) {
        this.partitioningPolicies = partitioningPolicies;
    }

    /**
     * PUBLIC:
     * Set the map of partitioning policies, keyed by name.
     */
    public void addPartitioningPolicy(PartitioningPolicy partitioningPolicy) {
        getPartitioningPolicies().put(partitioningPolicy.getName(), partitioningPolicy);
    }

    /**
     * PUBLIC:
     * Return the partitioning policies for the name.
     */
    public PartitioningPolicy getPartitioningPolicy(String name) {
        if (this.partitioningPolicies == null) {
            return null;
        }
        return this.partitioningPolicies.get(name);
    }
}

