/*
 * Copyright (c) 2011, 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
//     05/19/2014-2.6 Tomas Kraus
//       - 437578: Added cacheable field and updated setting isolation from parent.
package org.eclipse.persistence.descriptors;

import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;
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.CacheCoordinationType;
import org.eclipse.persistence.annotations.CacheKeyType;
import org.eclipse.persistence.annotations.DatabaseChangeNotificationType;
import org.eclipse.persistence.config.CacheIsolationType;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.interceptors.CacheInterceptor;

/**
 * <p><b>Purpose</b>:
 * CachePolicy defines the cache configuration.
 * EclipseLink supports an integrated shared (L2) object cache.
 * Caching is enabled by default.<br>
 * To disable caching use:<br>
 * <code>setCacheIsolation(CacheIsolationType.ISOLATED)</code>
 *
 * @see ClassDescriptor
 */
public class CachePolicy implements Cloneable, Serializable {
    protected Class<? extends IdentityMap> identityMapClass;
    protected int identityMapSize;
    protected boolean shouldAlwaysRefreshCache;
    protected boolean shouldOnlyRefreshCacheIfNewerVersion;
    protected boolean shouldDisableCacheHits;

    protected Class<? extends IdentityMap> remoteIdentityMapClass;
    protected int remoteIdentityMapSize;
    protected boolean shouldAlwaysRefreshCacheOnRemote;
    protected boolean shouldDisableCacheHitsOnRemote;

    // Used only to evaluate cache isolation type in this class methods.
    /**
     * Entity @Cacheable annotation value.
     * This value contains Boolean value equal to annotation value or null when
     * no annotation was set for entity. Parent values are ignored, value refers
     * to current class only.
     * This value is set only when SharedCacheMode allows to override caching
     * on entity level (DISABLE_SELECTIVE  or ENABLE_SELECTIVE). Default value
     * is <code>null</code> what means no annotation is present in current class.
     */
    private Boolean cacheable = null;
    // this attribute is used to determine what classes should be isolated from the shared cache
    // and the severity of their isolation.
    protected CacheIsolationType cacheIsolation;

    /** Configures how objects will be sent via cache synchronization, if synchronization is enabled. */
    protected int cacheSynchronizationType = UNDEFINED_OBJECT_CHANGE_BEHAVIOR;
    public static final int UNDEFINED_OBJECT_CHANGE_BEHAVIOR = 0;
    public static final int SEND_OBJECT_CHANGES = 1;
    public static final int INVALIDATE_CHANGED_OBJECTS = 2;
    public static final int SEND_NEW_OBJECTS_WITH_CHANGES = 3;
    public static final int DO_NOT_SEND_CHANGES = 4;

    /** Configures how the unit of work uses the session cache. */
    protected int unitOfWorkCacheIsolationLevel = UNDEFINED_ISOLATATION;
    /* Required to resolve initialization. */
    protected boolean wasDefaultUnitOfWorkCacheIsolationLevel;
    public static final int UNDEFINED_ISOLATATION = -1;
    public static final int USE_SESSION_CACHE_AFTER_TRANSACTION = 0;
    public static final int ISOLATE_NEW_DATA_AFTER_TRANSACTION = 1; // this is the default behaviour even when undefined.
    public static final int ISOLATE_CACHE_AFTER_TRANSACTION = 2;
    public static final int ISOLATE_FROM_CLIENT_SESSION = 3;  // Entity Instances only exist in UOW and shared cache.
    public static final int ISOLATE_CACHE_ALWAYS = 4;

    /** Allow cache key type to be configured. */
    protected CacheKeyType cacheKeyType;

    //Added for interceptor support.
    protected Class<? extends CacheInterceptor> cacheInterceptorClass;
    //Added for interceptor support.
    protected String cacheInterceptorClassName;

    /** This flag controls how the MergeManager should merge an Entity when merging into the shared cache.*/
    protected boolean fullyMergeEntity;

    /**
     * In certain cases and cache types it is more efficient to preFetch the cache keys from the cache when
     * building the results of the query.  Set this flag to true to prefetch the results.
     */
    protected boolean prefetchCacheKeys;

    protected Map<List<DatabaseField>, CacheIndex> cacheIndexes;

    /** Allows configuration of database change event notification. */
    protected DatabaseChangeNotificationType databaseChangeNotificationType;

    /**
     * PUBLIC:
     * Return a new descriptor.
     */
    public CachePolicy() {
        this.identityMapSize = -1;
        this.remoteIdentityMapSize = -1;
    }

    /**
     * Returns what type of database change notification an entity/descriptor should use.
     * This is only relevant if the persistence unit/session has been configured with a DatabaseEventListener,
     * such as the OracleChangeNotificationListener that receives database change events.
     * This allows for the EclipseLink cache to be invalidated or updated from database changes.
     */
    public DatabaseChangeNotificationType getDatabaseChangeNotificationType() {
        return databaseChangeNotificationType;
    }

    /**
     * Configures what type of database change notification an entity/descriptor should use.
     * This is only relevant if the persistence unit/session has been configured with a DatabaseEventListener,
     * such as the OracleChangeNotificationListener that receives database change events.
     * This allows for the EclipseLink cache to be invalidated or updated from database changes.
     */
    public void setDatabaseChangeNotificationType(DatabaseChangeNotificationType databaseChangeNotificationType) {
        this.databaseChangeNotificationType = databaseChangeNotificationType;
    }

    /**
     * INTERNAL:
     * Allow the inheritance properties of the descriptor to be initialized.
     * The descriptor's parent must first be initialized.
     */
    public void initializeFromParent(CachePolicy parentPolicy, ClassDescriptor descriptor, ClassDescriptor descriptorDescriptor, AbstractSession session) throws DescriptorException {
        // If the parent is isolated, then the child must also be isolated.
        if (!parentPolicy.isSharedIsolation()) {
            // Do not override cache isolation when explicitly enabled by @Cacheable(true) annotation in current class.
            boolean copyParrent = cacheable == null || !cacheable;
            if (!isIsolated() && (getCacheIsolation() != parentPolicy.getCacheIsolation()) && copyParrent) {
                session.log(SessionLog.WARNING, SessionLog.METADATA, "overriding_cache_isolation",
                        new Object[]{descriptorDescriptor.getAlias(),
                                parentPolicy.getCacheIsolation(), descriptor.getAlias(),
                                getCacheIsolation()});
                setCacheIsolation(parentPolicy.getCacheIsolation());
            }
        }
        // Child must maintain the same indexes as the parent.
        for (CacheIndex index : parentPolicy.getCacheIndexes().values()) {
            addCacheIndex(index);
        }
        if ((getDatabaseChangeNotificationType() == null) && (parentPolicy.getDatabaseChangeNotificationType() != null)) {
            setDatabaseChangeNotificationType(parentPolicy.getDatabaseChangeNotificationType());
        }
        if ((getCacheSynchronizationType() == UNDEFINED_OBJECT_CHANGE_BEHAVIOR)
                && (parentPolicy.getCacheSynchronizationType() != UNDEFINED_OBJECT_CHANGE_BEHAVIOR)) {
            setCacheSynchronizationType(parentPolicy.getCacheSynchronizationType());
        }
    }

    /**
     * INTERNAL:
     * Initialize the cache isolation setting.
     * This may need to be called multiple times as notifyReferencingDescriptorsOfIsolation() can change the cache isolation.
     */
    public void postInitialize(ClassDescriptor descriptor, AbstractSession session) throws DescriptorException {
        if (!isSharedIsolation()) {
            descriptor.notifyReferencingDescriptorsOfIsolation(session);
        }

        // PERF: If using isolated cache, then default uow isolation to always (avoids merge/double build).
        if ((getUnitOfWorkCacheIsolationLevel() == UNDEFINED_ISOLATATION) || this.wasDefaultUnitOfWorkCacheIsolationLevel) {
            this.wasDefaultUnitOfWorkCacheIsolationLevel = true;
            if (isIsolated()) {
                setUnitOfWorkCacheIsolationLevel(ISOLATE_CACHE_ALWAYS);
            } else if (isProtectedIsolation()) {
                setUnitOfWorkCacheIsolationLevel(ISOLATE_FROM_CLIENT_SESSION);
            } else {
                setUnitOfWorkCacheIsolationLevel(ISOLATE_NEW_DATA_AFTER_TRANSACTION);
            }
        }

        // Record that there is an isolated class in the project.
        if (!isSharedIsolation()) {
            session.getProject().setHasIsolatedClasses(true);
        }
        if (!shouldIsolateObjectsInUnitOfWork() && !descriptor.shouldBeReadOnly()) {
            session.getProject().setHasNonIsolatedUOWClasses(true);
        }
    }

    /**
     * INTERNAL:
     * Allow the inheritance properties of the descriptor to be initialized.
     * The descriptor's parent must first be initialized.
     */
    public void initialize(ClassDescriptor descriptor, AbstractSession session) throws DescriptorException {
        if (hasCacheIndexes()) {
            for (CacheIndex index : getCacheIndexes().values()) {
                for (int count = 0; count < index.getFields().size(); count++) {
                    index.getFields().set(count, descriptor.buildField(index.getFields().get(count)));
                }
            }
        }
        for (DatabaseMapping mapping : descriptor.getMappings()) {
            if (!mapping.isCacheable()) {
                if (isSharedIsolation()) {
                    setCacheIsolation(CacheIsolationType.PROTECTED);
                }
            }

            if (mapping.isForeignReferenceMapping()) {
                ClassDescriptor referencedDescriptor = mapping.getReferenceDescriptor();
                if (referencedDescriptor!= null) {
                    if (isSharedIsolation() && !referencedDescriptor.getCachePolicy().isSharedIsolation()) {
                        setCacheIsolation(CacheIsolationType.PROTECTED);
                    }
                }
            }

            if (mapping.isAggregateObjectMapping()) {
                ClassDescriptor referencedDescriptor = mapping.getReferenceDescriptor();
                if (referencedDescriptor != null) {
                    if (isSharedIsolation() && !referencedDescriptor.getCachePolicy().isSharedIsolation()) {
                        setCacheIsolation(CacheIsolationType.PROTECTED);
                    }
                }
            }
        }

        if (this.databaseChangeNotificationType == null) {
            this.databaseChangeNotificationType = DatabaseChangeNotificationType.INVALIDATE;
        }
        if (this.cacheSynchronizationType == UNDEFINED_OBJECT_CHANGE_BEHAVIOR) {
            this.cacheSynchronizationType = SEND_OBJECT_CHANGES;
        }
        if ((this.databaseChangeNotificationType != DatabaseChangeNotificationType.NONE)
                && session.isDatabaseSession() && ((DatabaseSession)session).getDatabaseEventListener() != null) {
            ((DatabaseSession)session).getDatabaseEventListener().initialize(descriptor, session);
        }
    }

    /**
     * PUBLIC:
     * Return the cache index for the field names.
     */
    public CacheIndex getCacheIndex(List<DatabaseField> fields) {
        return getCacheIndexes().get(fields);
    }

    /**
     * PUBLIC:
     * Add the cache index to the descriptor's cache settings.
     * This allows for cache hits to be obtained on non-primary key fields.
     * The primary key is always indexed in the cache.
     * Cache indexes are defined by their database column names.
     */
    public void addCacheIndex(CacheIndex index) {
        getCacheIndexes().put(index.getFields(), index);
    }

    /**
     * PUBLIC:
     * Add the cache index to the descriptor's cache settings.
     * This allows for cache hits to be obtained on non-primary key fields.
     * The primary key is always indexed in the cache.
     * Cache indexes are defined by their database column names.
     */
    public void addCacheIndex(String... fields) {
        addCacheIndex(new CacheIndex(fields));
    }

    /**
     * PUBLIC:
     * Add the cache index to the descriptor's cache settings.
     * This allows for cache hits to be obtained on non-primary key fields.
     * The primary key is always indexed in the cache.
     * Cache indexes are defined by their database column names.
     */
    public void addCacheIndex(DatabaseField[] fields) {
        addCacheIndex(new CacheIndex(fields));
    }

    public boolean hasCacheIndexes() {
        return (this.cacheIndexes != null) && (!this.cacheIndexes.isEmpty());
    }

    public Map<List<DatabaseField>, CacheIndex> getCacheIndexes() {
        if (this.cacheIndexes == null) {
            this.cacheIndexes = new HashMap<>();
        }
        return this.cacheIndexes;
    }

    public void setCacheIndexes(Map<List<DatabaseField>, CacheIndex> cacheIndexes) {
        this.cacheIndexes = cacheIndexes;
    }

    @Override
    public CachePolicy clone() {
        try {
            return (CachePolicy)super.clone();
        } catch (CloneNotSupportedException cnse) {
            throw new InternalError(cnse.getMessage());
        }
    }

    /**
     * INTERNAL:
     * Some attributes have default values defined in Project.
     * If such the value for the attribute hasn't been set then the default value is assigned.
     */
    public void assignDefaultValues(AbstractSession session) {
        if(this.identityMapSize == -1) {
            this.identityMapSize = session.getProject().getDefaultIdentityMapSize();
        }
        if(this.identityMapClass == null) {
            this.identityMapClass = session.getProject().getDefaultIdentityMapClass();
        }
        if(this.cacheIsolation == null) {
            this.cacheIsolation = session.getProject().getDefaultCacheIsolation();
        }
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this Descriptor to actual class-based
     * settings. This method is used when converting a project that has been built
     * with class names to a project with classes.
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        try {
            if (this.cacheInterceptorClass == null && this.cacheInterceptorClassName != null){
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try {
                        this.cacheInterceptorClass = AccessController.doPrivileged(new PrivilegedClassForName<>(this.cacheInterceptorClassName, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(this.cacheInterceptorClassName, exception.getException());
                   }
                } else {
                    this.cacheInterceptorClass = PrivilegedAccessHelper.getClassForName(this.cacheInterceptorClassName, true, classLoader);
                }
            }
        } catch (ClassNotFoundException exc){
            throw ValidationException.classNotFoundWhileConvertingClassNames(this.cacheInterceptorClassName, exc);
        }
    }

    /**
     * @return the fullyMergeEntity
     */
    public boolean getFullyMergeEntity() {
        return fullyMergeEntity;
    }

    /**
     * ADVANCED:
     * Set what cache key type to use to store the object in the cache.
     */
    public void setCacheKeyType(CacheKeyType cacheKeyType) {
        this.cacheKeyType = cacheKeyType;
    }

    /**
     * ADVANCED:
     * Return what cache key type to use to store the object in the cache.
     */
    public CacheKeyType getCacheKeyType() {
        return cacheKeyType;
    }

    /**
     * A CacheInterceptor is an adaptor that when overridden and assigned to a Descriptor all interaction
     * between EclipseLink and the internal cache for that class will pass through the Interceptor.
     * Advanced users could use this interceptor to audit, profile or log cache access.  This Interceptor
     * could also be used to redirect or augment the TopLink cache with an alternate cache mechanism.
     * EclipseLink's configurated IdentityMaps will be passed to the Interceptor constructor.
     *
     * As with IdentityMaps an entire class inheritance hierarchy will share the same interceptor.
     * @see org.eclipse.persistence.sessions.interceptors.CacheInterceptor
     */
    @SuppressWarnings({"unchecked"})
    public <T extends CacheInterceptor> Class<T> getCacheInterceptorClass(){
        return (Class<T>) this.cacheInterceptorClass;
    }

    /**
     * A CacheInterceptor is an adaptor that when overridden and assigned to a Descriptor all interaction
     * between EclipseLink and the internal cache for that class will pass through the Interceptor.
     * Advanced users could use this interceptor to audit, profile or log cache access.  This Interceptor
     * could also be used to redirect or augment the TopLink cache with an alternate cache mechanism.
     * EclipseLink's configurated IdentityMaps will be passed to the Interceptor constructor.
     *
     * As with IdentityMaps an entire class inheritance hierarchy will share the same interceptor.
     * @see org.eclipse.persistence.sessions.interceptors.CacheInterceptor
     */
    public String getCacheInterceptorClassName(){
        return this.cacheInterceptorClassName;
    }

    /**
     * PUBLIC:
     * Get a value indicating the type of cache synchronization that will be used on objects of
     * this type. Possible values are:
     * SEND_OBJECT_CHANGES
     * INVALIDATE_CHANGED_OBJECTS
     * SEND_NEW_OBJECTS+WITH_CHANGES
     * DO_NOT_SEND_CHANGES
     * @return int
     *
     */
    public int getCacheSynchronizationType() {
        return cacheSynchronizationType;
    }

    /**
     * INTERNAL:
     * Return the class of identity map to be used by this descriptor.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    @SuppressWarnings({"unchecked"})
    public <T extends IdentityMap> Class<T> getIdentityMapClass() {
        return (Class<T>) identityMapClass;
    }

    /**
     * PUBLIC:
     * Return the size of the identity map.
     */
    public int getIdentityMapSize() {
        return identityMapSize;
    }

    /**
     * INTERNAL:
     * Return the class of identity map to be used by this descriptor.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    @SuppressWarnings({"unchecked"})
    public <T extends IdentityMap> Class<T> getRemoteIdentityMapClass() {
        if (remoteIdentityMapClass == null) {
            remoteIdentityMapClass = getIdentityMapClass();
        }
        return (Class<T>) remoteIdentityMapClass;
    }

    /**
     * PUBLIC:
     * Return the size of the remote identity map.
     */
    public int getRemoteIdentityMapSize() {
        if (remoteIdentityMapSize == -1) {
            remoteIdentityMapSize = getIdentityMapSize();
        }
        return remoteIdentityMapSize;
    }

    /**
     * PUBLIC:
     * Return if for cache hits on primary key read object queries to be disabled.
     *
     * @see ClassDescriptor#disableCacheHits()
     */
    public boolean shouldDisableCacheHits() {
        return shouldDisableCacheHits;
    }

    /**
     * PUBLIC:
     * Return if the remote server session cache hits on primary key read object queries is aloowed or not.
     *
     * @see ClassDescriptor#disableCacheHitsOnRemote()
     */
    public boolean shouldDisableCacheHitsOnRemote() {
        return shouldDisableCacheHitsOnRemote;
    }

    /**
     * PUBLIC:
     * This method returns <CODE>true</CODE> if the <CODE>ClassDescriptor</CODE> is configured to only refresh the cache
     * if the data received from the database by a query is newer than the data in the cache (as determined by the
     * optimistic locking field). Otherwise, it returns <CODE>false</CODE>.
     *
     * @see #setShouldOnlyRefreshCacheIfNewerVersion
     */
    public boolean shouldOnlyRefreshCacheIfNewerVersion() {
        return shouldOnlyRefreshCacheIfNewerVersion;
    }

    /**
     * PUBLIC:
     * This method returns <CODE>true</CODE> if the <CODE>ClassDescriptor</CODE> is configured to always refresh
     * the cache if data is received from the database by any query. Otherwise, it returns <CODE>false</CODE>.
     *
     * @see #setShouldAlwaysRefreshCache
     */
    public boolean shouldAlwaysRefreshCache() {
        return shouldAlwaysRefreshCache;
    }

    /**
     * PUBLIC:
     * This method returns <CODE>true</CODE> if the <CODE>ClassDescriptor</CODE> is configured to always remotely
     * refresh the cache if data is received from the database by any query in a {@link org.eclipse.persistence.sessions.remote.RemoteSession}.
     * Otherwise, it returns <CODE>false</CODE>.
     *
     * @see #setShouldAlwaysRefreshCacheOnRemote
     */
    public boolean shouldAlwaysRefreshCacheOnRemote() {
        return shouldAlwaysRefreshCacheOnRemote;
    }

    /**
     * PUBLIC:
     * Set if cache hits on primary key read object queries should be disabled.
     *
     * @see ClassDescriptor#alwaysRefreshCache()
     */
    public void setShouldDisableCacheHits(boolean shouldDisableCacheHits) {
        this.shouldDisableCacheHits = shouldDisableCacheHits;
    }

    /**
     * PUBLIC:
     * Set if the remote session cache hits on primary key read object queries is allowed or not.
     *
     * @see ClassDescriptor#disableCacheHitsOnRemote()
     */
    public void setShouldDisableCacheHitsOnRemote(boolean shouldDisableCacheHitsOnRemote) {
        this.shouldDisableCacheHitsOnRemote = shouldDisableCacheHitsOnRemote;
    }

    /**
     * PUBLIC:
     * When the <CODE>shouldOnlyRefreshCacheIfNewerVersion</CODE> argument passed into this method is <CODE>true</CODE>,
     * this method configures a <CODE>ClassDescriptor</CODE> to only refresh the cache if the data received from the database
     * by a query is newer than the data in the cache (as determined by the optimistic locking field) and as long as one of the following is true:
     *
     * <UL>
     * <LI>the <CODE>ClassDescriptor</CODE> was configured by calling {@link ClassDescriptor#alwaysRefreshCache} or {@link ClassDescriptor#alwaysRefreshCacheOnRemote},</LI>
     * <LI>the query was configured by calling {@link org.eclipse.persistence.queries.ObjectLevelReadQuery#refreshIdentityMapResult}, or</LI>
     * <LI>the query was a call to {@link org.eclipse.persistence.sessions.Session#refreshObject}</LI>
     * </UL>
     * <P>
     *
     * However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For example, by default,
     * when a query for a single object based on its primary key is executed, OracleAS TopLink will first look in the cache for the object.
     * If the object is in the cache, the cached object is returned and data is not refreshed. To avoid cache hits, use
     * the {@link ClassDescriptor#disableCacheHits} method.<P>
     *
     * Also note that the {@link org.eclipse.persistence.sessions.UnitOfWork} will not refresh its registered objects.<P>
     *
     * When the <CODE>shouldOnlyRefreshCacheIfNewerVersion</CODE> argument passed into this method is <CODE>false</CODE>, this method
     * ensures that a <CODE>ClassDescriptor</CODE> is not configured to only refresh the cache if the data received from the database by a
     * query is newer than the data in the cache (as determined by the optimistic locking field).
     *
     * @see ClassDescriptor#onlyRefreshCacheIfNewerVersion
     * @see ClassDescriptor#dontOnlyRefreshCacheIfNewerVersion
     */
    public void setShouldOnlyRefreshCacheIfNewerVersion(boolean shouldOnlyRefreshCacheIfNewerVersion) {
        this.shouldOnlyRefreshCacheIfNewerVersion = shouldOnlyRefreshCacheIfNewerVersion;
    }

    /**
     * PUBLIC:
     * When the <CODE>shouldAlwaysRefreshCache</CODE> argument passed into this method is <CODE>true</CODE>,
     * this method configures a <CODE>ClassDescriptor</CODE> to always refresh the cache if data is received from
     * the database by any query.<P>
     *
     * However, if a query hits the cache, data is not refreshed regardless of how this setting is configured.
     * For example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink
     * will first look in the cache for the object. If the object is in the cache, the cached object is returned and
     * data is not refreshed. To avoid cache hits, use the {@link ClassDescriptor#disableCacheHits} method.<P>
     *
     * Also note that the {@link org.eclipse.persistence.sessions.UnitOfWork} will not refresh its registered objects.<P>
     *
     * Use this property with caution because it can lead to poor performance and may refresh on queries when it is not desired.
     * Normally, if you require fresh data, it is better to configure a query with {@link org.eclipse.persistence.queries.ObjectLevelReadQuery#refreshIdentityMapResult}.
     * To ensure that refreshes are only done when required, use this method in conjunction with {@link ClassDescriptor#onlyRefreshCacheIfNewerVersion}.<P>
     *
     * When the <CODE>shouldAlwaysRefreshCache</CODE> argument passed into this method is <CODE>false</CODE>, this method
     * ensures that a <CODE>ClassDescriptor</CODE> is not configured to always refresh the cache if data is received from the database by any query.
     *
     * @see ClassDescriptor#alwaysRefreshCache
     * @see ClassDescriptor#dontAlwaysRefreshCache
     */
    public void setShouldAlwaysRefreshCache(boolean shouldAlwaysRefreshCache) {
        this.shouldAlwaysRefreshCache = shouldAlwaysRefreshCache;
    }

    /**
     * PUBLIC:
     * When the <CODE>shouldAlwaysRefreshCacheOnRemote</CODE> argument passed into this method is <CODE>true</CODE>,
     * this method configures a <CODE>ClassDescriptor</CODE> to always remotely refresh the cache if data is received from
     * the database by any query in a {@link org.eclipse.persistence.sessions.remote.RemoteSession}.
     *
     * However, if a query hits the cache, data is not refreshed regardless of how this setting is configured. For
     * example, by default, when a query for a single object based on its primary key is executed, OracleAS TopLink
     * will first look in the cache for the object. If the object is in the cache, the cached object is returned and
     * data is not refreshed. To avoid cache hits, use the {@link ClassDescriptor#disableCacheHitsOnRemote} method.<P>
     *
     * Also note that the {@link org.eclipse.persistence.sessions.UnitOfWork} will not refresh its registered objects.<P>
     *
     * Use this property with caution because it can lead to poor performance and may refresh on queries when it is
     * not desired. Normally, if you require fresh data, it is better to configure a query with {@link org.eclipse.persistence.queries.ObjectLevelReadQuery#refreshIdentityMapResult}.
     * To ensure that refreshes are only done when required, use this method in conjunction with {@link ClassDescriptor#onlyRefreshCacheIfNewerVersion}.<P>
     *
     * When the <CODE>shouldAlwaysRefreshCacheOnRemote</CODE> argument passed into this method is <CODE>false</CODE>,
     * this method ensures that a <CODE>ClassDescriptor</CODE> is not configured to always remotely refresh the cache if data
     * is received from the database by any query in a {@link org.eclipse.persistence.sessions.remote.RemoteSession}.
     *
     * @see ClassDescriptor#alwaysRefreshCacheOnRemote
     * @see ClassDescriptor#dontAlwaysRefreshCacheOnRemote
     */
    public void setShouldAlwaysRefreshCacheOnRemote(boolean shouldAlwaysRefreshCacheOnRemote) {
        this.shouldAlwaysRefreshCacheOnRemote = shouldAlwaysRefreshCacheOnRemote;
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be used by this descriptor.
     * The default is the "FullIdentityMap".
     */
    public void setRemoteIdentityMapClass(Class<? extends IdentityMap> theIdentityMapClass) {
        remoteIdentityMapClass = theIdentityMapClass;
    }

    /**
     * PUBLIC:
     * Set the size of the identity map to be used by this descriptor.
     * The default is the 100.
     */
    public void setRemoteIdentityMapSize(int identityMapSize) {
        remoteIdentityMapSize = identityMapSize;
    }

    /**
     * INTERNAL:
     * Set entity @Cacheable annotation value.
     * @param cacheable Entity @Cacheable annotation value for current class
     *        or <code>null</code> if @Cacheable annotation is not set. Parent
     *        values are ignored, value shall refer to current class only.
     */
    public void setCacheable(Boolean cacheable) {
        this.cacheable = cacheable;
    }

    /**
     * PUBLIC:
     * Controls how the Entity instances will be cached.  See the CacheIsolationType for details on the options.
     * @return the isolationType
     */
    public CacheIsolationType getCacheIsolation() {
        return cacheIsolation;
    }

    /**
     * PUBLIC:
     * Controls how the Entity instances and data will be cached.  See the CacheIsolationType for details on the options.
     * To disable all second level caching simply set CacheIsolationType.ISOLATED.  Note that setting the isolation
     * will automatically set the corresponding cacheSynchronizationType.
     * ISOLATED = DO_NOT_SEND_CHANGES, PROTECTED and SHARED = SEND_OBJECT_CHANGES
     */
    public void setCacheIsolation(CacheIsolationType isolationType) {
        this.cacheIsolation = isolationType;
        if (CacheIsolationType.ISOLATED == isolationType) {
            // bug 3587273 - set the cache synchronization type so isolated objects are not sent
            // do not call the setter method because it does not allow changing the cache synchronization
            // type of isolated objects
            cacheSynchronizationType = DO_NOT_SEND_CHANGES;
        }
    }

    /**
     * INTERNAL:
     * Return if the unit of work should by-pass the session cache.
     * Objects will be built in the unit of work, and never merged into the session cache.
     */
    public boolean shouldIsolateObjectsInUnitOfWork() {
        return this.unitOfWorkCacheIsolationLevel == ISOLATE_CACHE_ALWAYS;
    }

    /**
     * INTERNAL:
     * Return if the unit of work should by-pass the IsolatedSession cache.
     * Objects will be built/merged into the unit of work and into the session cache.
     * but not built/merge into the IsolatedClientSession cache.
     */
    public boolean shouldIsolateProtectedObjectsInUnitOfWork() {
        return this.unitOfWorkCacheIsolationLevel == ISOLATE_FROM_CLIENT_SESSION;
    }

    /**
     * INTERNAL:
     * Return if the unit of work should by-pass the session cache after an early transaction.
     */
    public boolean shouldIsolateObjectsInUnitOfWorkEarlyTransaction() {
        return this.unitOfWorkCacheIsolationLevel == ISOLATE_CACHE_AFTER_TRANSACTION;
    }

    /**
     * INTERNAL:
     * Return if the unit of work should use the session cache after an early transaction.
     */
    public boolean shouldUseSessionCacheInUnitOfWorkEarlyTransaction() {
        return this.unitOfWorkCacheIsolationLevel == USE_SESSION_CACHE_AFTER_TRANSACTION;
    }

    /**
     * ADVANCED:
     * Return the unit of work cache isolation setting.
     * This setting configures how the session cache will be used in a unit of work.
     * @see #setUnitOfWorkCacheIsolationLevel(int)
     */
    public int getUnitOfWorkCacheIsolationLevel() {
        return unitOfWorkCacheIsolationLevel;
    }

    /**
     * ADVANCED:
     * This setting configures how the session cache will be used in a unit of work.
     * Most of the options only apply to a unit of work in an early transaction,
     * such as a unit of work that was flushed (writeChanges), issued a modify query, or acquired a pessimistic lock.
     * <p> USE_SESSION_CACHE_AFTER_TRANSACTION - Objects built from new data accessed after a unit of work early transaction are stored in the session cache.
     * This options is the most efficient as it allows the cache to be used after an early transaction.
     * This should only be used if it is known that this class is not modified in the transaction,
     * otherwise this could cause uncommitted data to be loaded into the session cache.
     * ISOLATE_NEW_DATA_AFTER_TRANSACTION - Default (when using caching): Objects built from new data accessed after a unit of work early transaction are only stored in the unit of work.
     * This still allows previously cached objects to be accessed in the unit of work after an early transaction,
     * but ensures uncommitted data will never be put in the session cache by storing any object built from new data only in the unit of work.
     * ISOLATE_CACHE_AFTER_TRANSACTION - After a unit of work early transaction the session cache is no longer used for this class.
     * Objects will be directly built from the database data and only stored in the unit of work, even if previously cached.
     * Note that this may lead to poor performance as the session cache is bypassed after an early transaction.
     * ISOLATE_CACHE_ALWAYS - Default (when using isolated cache): The session cache will never be used for this class.
     * Objects will be directly built from the database data and only stored in the unit of work.
     * New objects and changes will also never be merged into the session cache.
     * Note that this may lead to poor performance as the session cache is bypassed,
     * however if this class is isolated or pessimistic locked and always accessed in a transaction, this can avoid having to build two copies of the object.
     */
    public void setUnitOfWorkCacheIsolationLevel(int unitOfWorkCacheIsolationLevel) {
        this.unitOfWorkCacheIsolationLevel = unitOfWorkCacheIsolationLevel;
    }

    /**
     * @param fullyMergeEntity the fullyMergeEntity to set
     */
    public void setFullyMergeEntity(boolean fullyMergeEntity) {
        this.fullyMergeEntity = fullyMergeEntity;
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be used by this descriptor.
     * The default is the "FullIdentityMap".
     */
    public void setIdentityMapClass(Class<? extends IdentityMap> theIdentityMapClass) {
        identityMapClass = theIdentityMapClass;
    }

    /**
     * PUBLIC:
     * Set the size of the identity map to be used by this descriptor.
     * The default is the 100.
     */
    public void setIdentityMapSize(int identityMapSize) {
        this.identityMapSize = identityMapSize;
    }

    /**
     * OBSOLETE:
     * Set the type of cache coordination that will be used on objects of this type.  Possible values
     * are:<ul>
     * <li>SEND_OBJECT_CHANGES
     * <li>INVALIDATE_CHANGED_OBJECTS
     * <li>SEND_NEW_OBJECTS_WITH_CHANGES
     * <li>DO_NOT_SEND_CHANGES</ul>
     * Note: Cache Synchronization type cannot be altered for descriptors that are set as isolated using
     * the setIsIsolated method.<p>
     * This has been replaced by setCacheCoordinationType().
     * @see #setCacheCoordinationType(CacheCoordinationType)
     * @param type int  The synchronization type for this descriptor
     */
    public void setCacheSynchronizationType(int type) {
        // bug 3587273
        if (!isIsolated()) {
            cacheSynchronizationType = type;
        }
    }

    /**
     * PUBLIC:
     * Set the type of cache coordination that will be used on objects of this type.
     * Valid values defined in CacheCoordinationType.
     */
    public void setCacheCoordinationType(CacheCoordinationType type) {
        if (type == null) {
            setCacheSynchronizationType(UNDEFINED_OBJECT_CHANGE_BEHAVIOR);
        } else if (type == CacheCoordinationType.SEND_OBJECT_CHANGES) {
            setCacheSynchronizationType(SEND_OBJECT_CHANGES);
        } else if (type == CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS) {
            setCacheSynchronizationType(INVALIDATE_CHANGED_OBJECTS);
        } else if (type == CacheCoordinationType.SEND_NEW_OBJECTS_WITH_CHANGES) {
            setCacheSynchronizationType(SEND_NEW_OBJECTS_WITH_CHANGES);
        } else if (type == CacheCoordinationType.NONE) {
            setCacheSynchronizationType(DO_NOT_SEND_CHANGES);
        }
    }

    /**
     * PUBLIC:
     * A CacheInterceptor is an adaptor that when overridden and assigned to a Descriptor all interaction
     * between EclipseLink and the internal cache for that class will pass through the Interceptor.
     * Advanced users could use this interceptor to audit, profile or log cache access.  This Interceptor
     * could also be used to redirect or augment the TopLink cache with an alternate cache mechanism.
     * EclipseLink's configurated IdentityMaps will be passed to the Interceptor constructor.

     * As with IdentityMaps an entire class inheritance hierarchy will share the same interceptor.
     * @see org.eclipse.persistence.sessions.interceptors.CacheInterceptor
     */
    public void setCacheInterceptorClass(Class<? extends CacheInterceptor> cacheInterceptorClass){
        this.cacheInterceptorClass = cacheInterceptorClass;
    }

    /**
     * PUBLIC:
     * A CacheInterceptor is an adaptor that when overridden and assigned to a Descriptor all interaction
     * between EclipseLink and the internal cache for that class will pass through the Interceptor.
     * Advanced users could use this interceptor to audit, profile or log cache access.  This Interceptor
     * could also be used to redirect or augment the TopLink cache with an alternate cache mechanism.
     * EclipseLink's configurated IdentityMaps will be passed to the Interceptor constructor.

     * As with IdentityMaps an entire class inheritance hierarchy will share the same interceptor.
     * @see org.eclipse.persistence.sessions.interceptors.CacheInterceptor
     */
    public void setCacheInterceptorClassName(String cacheInterceptorClassName){
        this.cacheInterceptorClassName = cacheInterceptorClassName;
    }

    /**
     * PUBLIC:
     * Returns true if the descriptor represents an isolated class
     */
    public boolean isIsolated() {
        return CacheIsolationType.ISOLATED == this.cacheIsolation;
    }

    /**
     * PUBLIC:
     * Returns true if the descriptor represents a protected class.
     */
    public boolean isProtectedIsolation() {
        return CacheIsolationType.PROTECTED ==this.cacheIsolation;
    }

    /**
     * PUBLIC:
     * Returns true if the descriptor represents a shared class.
     */
    public boolean isSharedIsolation() {
        return this.cacheIsolation == null || CacheIsolationType.SHARED == this.cacheIsolation;
    }

    /**
     * INTERNAL:
     * Index the object by index in the cache using its row.
     */
    public void indexObjectInCache(CacheKey cacheKey, AbstractRecord databaseRow, Object domainObject, ClassDescriptor descriptor, AbstractSession session, boolean refresh) {
        if (!hasCacheIndexes()) {
            return;
        }
        for (CacheIndex index : this.cacheIndexes.values()) {
            if (!refresh || index.isUpdateable()) {
                List<DatabaseField> fields = index.getFields();
                int size = fields.size();
                Object[] values = new Object[size];
                for (int count = 0; count < size; count++) {
                    values[count] = databaseRow.get(fields.get(count));
                }
                CacheId indexValues = new CacheId(values);
                session.getIdentityMapAccessorInstance().putCacheKeyByIndex(index, indexValues, cacheKey, descriptor);
            }
        }
    }

    /**
     * INTERNAL:
     * Index the object by index in the cache using the object.
     */
    public void indexObjectInCache(CacheKey cacheKey, Object object, ClassDescriptor descriptor, AbstractSession session, boolean refresh) {
        if (!hasCacheIndexes()) {
            return;
        }
        for (CacheIndex index : this.cacheIndexes.values()) {
            if (!refresh || index.isUpdateable()) {
                List<DatabaseField> fields = index.getFields();
                int size = fields.size();
                Object[] values = new Object[size];
                for (int count = 0; count < size; count++) {
                    values[count] = descriptor.getObjectBuilder().extractValueFromObjectForField(object, fields.get(count), session);
                }
                CacheId indexValues = new CacheId(values);
                session.getIdentityMapAccessorInstance().putCacheKeyByIndex(index, indexValues, cacheKey, descriptor);
            }
        }
    }

    /**
     * INTERNAL:
     * Index the object by index in the cache using its changeSet.
     */
    public void indexObjectInCache(ObjectChangeSet changeSet, Object object, ClassDescriptor descriptor, AbstractSession session) {
        if (!hasCacheIndexes()) {
            return;
        }
        for (CacheIndex index : this.cacheIndexes.values()) {
            if ((changeSet == null) || (changeSet.isNew() && index.isInsertable()) || (!changeSet.isNew() && index.isUpdateable())) {
                List<DatabaseField> fields = index.getFields();
                int size = fields.size();
                Object[] values = new Object[size];
                for (int count = 0; count < size; count++) {
                    values[count] = descriptor.getObjectBuilder().extractValueFromObjectForField(object, fields.get(count), session);
                }
                CacheId indexValues = new CacheId(values);
                CacheKey cacheKey = null;
                Object id = null;
                if (changeSet != null) {
                    cacheKey = changeSet.getActiveCacheKey();
                    if (cacheKey == null) {
                        id = changeSet.getId();
                    }
                } else {
                    id = descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, session);
                }
                if (cacheKey == null) {
                    cacheKey = session.getIdentityMapAccessorInstance().getCacheKeyForObject(id, descriptor.getJavaClass(), descriptor, true);
                }
                session.getIdentityMapAccessorInstance().putCacheKeyByIndex(index, indexValues, cacheKey, descriptor);
            }
        }
    }

    /**
     * INTERNAL:
     * Lookup the expression in the cache if it contains any indexes.
     */
    public CacheKey checkCacheByIndex(Expression expression, AbstractRecord translationRow, ClassDescriptor descriptor, AbstractSession session) {
        if (!hasCacheIndexes()) {
            return null;
        }
        AbstractRecord record = descriptor.getObjectBuilder().extractRowFromExpression(expression, translationRow, session);
        if (record == null) {
            return null;
        }
        for (CacheIndex index : this.cacheIndexes.values()) {
            List<DatabaseField> fields = index.getFields();
            int size = fields.size();
            Object[] values = new Object[size];
            for (int count = 0; count < size; count++) {
                Object value = record.get(fields.get(count));
                if (value == null) {
                    break;
                }
                values[count] = value;
            }
            CacheId indexValues = new CacheId(values);
            CacheKey cacheKey = session.getIdentityMapAccessorInstance().getCacheKeyByIndex(index, indexValues, true, descriptor);
            if (cacheKey != null) {
                return cacheKey;
            }
        }
        return null;
    }

    /**
     * INTERNAL:
     * Lookup the expression in the cache if it contains any indexes.
     */
    public boolean isIndexableExpression(Expression expression, ClassDescriptor descriptor, AbstractSession session) {
        if (!hasCacheIndexes()) {
            return false;
        }
        for (CacheIndex index : this.cacheIndexes.values()) {
            List<DatabaseField> searchFields = index.getFields();
            int size = searchFields.size();
            Set<DatabaseField> foundFields = new HashSet<>(size);
            boolean isValid = expression.extractFields(true, false, descriptor, searchFields, foundFields);
            if (isValid && (foundFields.size() == size)) {
                return true;
            }
        }
        return false;
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be the full identity map.
     * This map caches all instances read and grows to accomodate them.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    public void useFullIdentityMap() {
        setIdentityMapClass(ClassConstants.FullIdentityMap_Class);
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be the hard cache weak identity map.
     * This map uses weak references to only cache object in-memory.
     * It also includes a secondary fixed sized hard cache to improve caching performance.
     * This is provided because some Java VM's implement soft references differently.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    public void useHardCacheWeakIdentityMap() {
        setIdentityMapClass(ClassConstants.HardCacheWeakIdentityMap_Class);
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be the soft identity map.
     * This map uses soft references to only cache all object in-memory, until memory is low.
     * Note that "low" is interpreted differently by different JVM's.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    public void useSoftIdentityMap() {
        setIdentityMapClass(ClassConstants.SoftIdentityMap_Class);
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be the no identity map.
     * This map does no caching.
     * Note: This map does not maintain object identity.
     * In general if caching is not desired a WeakIdentityMap should be used with an isolated descriptor.
     * The default is the "SoftCacheWeakIdentityMap".
     * @see ClassDescriptor#setCacheIsolation(CacheIsolationType)
     */
    public void useNoIdentityMap() {
        setIdentityMapClass(ClassConstants.NoIdentityMap_Class);
    }

    /**
     * PUBLIC:
     * Set the class of identity map to be the weak identity map.
     * The default is the "SoftCacheWeakIdentityMap".
     */
    public void useWeakIdentityMap() {
        setIdentityMapClass(ClassConstants.WeakIdentityMap_Class);
    }

    public void setPrefetchCacheKeys(boolean prefetchCacheKeys) {
        this.prefetchCacheKeys = prefetchCacheKeys;
    }

    public boolean shouldPrefetchCacheKeys() {
        return this.prefetchCacheKeys ;
    }
}
