/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */
package org.apache.openjpa.kernel;

import java.util.BitSet;
import java.util.Collection;

import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.lib.util.Closeable;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.ValueStrategies;

/**
 * Interface to be implemented by data store mechanisms to interact with
 * this runtime.
 *
 * @author Abe White
 */
public interface StoreManager
    extends Closeable {

    public static final int VERSION_LATER = 1;
    public static final int VERSION_EARLIER = 2;
    public static final int VERSION_SAME = 3;
    public static final int VERSION_DIFFERENT = 4;

    public static final int FORCE_LOAD_NONE = 0;
    public static final int FORCE_LOAD_DFG = 1;
    public static final int FORCE_LOAD_REFRESH = 3;
    public static final int FORCE_LOAD_ALL = 2;

    /**
     * Set a reference to the corresponding context. This method
     * will be called before the store manager is used. The store manager
     * is responsible for pulling any necessary configuration data from the
     * context, including the transaction mode and connection retain mode.
     */
    public void setContext(StoreContext ctx);

    /**
     * Notification that an optimistic transaction has started. This method
     * does not replace the {@link #begin} method, which will still be called
     * when a true data store transaction should begin.
     */
    public void beginOptimistic();

    /**
     * Notification that an optimistic transaction was rolled back before
     * a data store transaction ever began.
     */
    public void rollbackOptimistic();

    /**
     * Begin a data store transaction. After this method is called,
     * it is assumed that all further operations are operating in a single
     * transaction that can be committed or rolled back. If optimistic
     * transactions are in use, this method will only be called when the
     * system requires a transactionally consistent connection due to a
     * user request to flush or commit the transaction. In this case, it
     * is possible that the optimistic transaction does not have the latest
     * versions of all instances (i.e. another transaction has modified the
     * same instances and committed since the optimistic transaction started).
     * On commit, an exception must be thrown on any attempt to overwrite
     * data for an instance with an older version.
     *
     * @since 0.2.5
     */
    public void begin();

    /**
     * Commit the current data store transaction.
     */
    public void commit();

    /**
     * Rollback the current data store transaction.
     */
    public void rollback();

    /**
     * Verify that the given instance exists in the data store; return false
     * if it does not.
     */
    public boolean exists(OpenJPAStateManager sm, Object edata);

    /**
     * Update the version information in the given state manager to the
     * version stored in the data store.
     *
     * @param sm the instance to check
     * @param edata the current execution data, or null if not
     * given to the calling method of the context
     * @return true if the instance still exists in the
     * datastore and is up-to-date, false otherwise
     */
    public boolean syncVersion(OpenJPAStateManager sm, Object edata);

    /**
     * Initialize the given state manager. The object id of the
     * state manager will be set, and the state manager's metadata be set to
     * the class of the instance to load, or possibly one of its superclasses.
     * Initialization involves first calling the
     * {@link OpenJPAStateManager#initialize} method with
     * a new instance of the correct type constructed with the
     * {@link org.apache.openjpa.enhance.PCRegistry#newInstance(Class,
     * org.apache.openjpa.enhance.StateManager, boolean)} method
     * (this will reset the state manager's metadata if the actual type was a
     * subclass). After instance initialization, load any the fields for the
     * given fetch configuration that can be efficiently retrieved. If any of
     * the configured fields are not loaded in this method, they will be
     * loaded with a subsequent call to {@link #load}. If this method is
     * called during a data store transaction, the instance's database record
     * should be locked. Version information can be loaded if desired through
     * the {@link OpenJPAStateManager#setVersion} method.
     *
     * @param sm the instance to initialize
     * @param state the lifecycle state to initialize the state manager with
     * @param fetch configuration for how to load the instance
     * @param edata the current execution data, or null if not
     * given to the calling method of the broker
     * @return true if the matching instance exists in the data
     * store, false otherwise
     */
    public boolean initialize(OpenJPAStateManager sm, PCState state,
        FetchConfiguration fetch, Object edata);

    /**
     * Load the given state manager.
     * Note that any collection or map types loaded into the state manager
     * will be proxied with the correct type; therefore the store manager
     * does not have to load the same concrete collection/map types as the
     * instance declares. However, array types must be consistent with the
     * array type stored by the persistence capable instance. If this method
     * is called during a data store transaction, the instance should be
     * locked. If the given state manager does not have its version set
     * already, version information can be loaded if desired through the
     * {@link OpenJPAStateManager#setVersion} method.
     *
     * @param sm the instance to load
     * @param fields set of fields to load; all field indexes in this
     * set must be loaded; this set is mutable
     * @param fetch the fetch configuration to use when loading
     * related objects
     * @param lockLevel attempt to load simple fields at this lock level;
     * relations should be loaded at the read lock level
     * of the fetch configuration
     * @param edata the current execution data, or null if not
     * given to the calling method of the broker
     * @return false if the object no longer exists in the
     * database, true otherwise
     */
    public boolean load(OpenJPAStateManager sm, BitSet fields,
        FetchConfiguration fetch, int lockLevel, Object edata);

    /**
     * Initialize, load, or validate the existance of all of the given
     * objects. This method is called from various broker methods that act
     * on multiple objects, such as {@link StoreContext#retrieveAll}. It gives
     * the store manager an opportunity to efficiently batch-load data for
     * several objects. Each of the given state managers will be in one of
     * three states, each requiring a different action:
     * <ul>
     * <li><code>stateManager.getO () == null</code>: An
     * uninitialized state manager. Perform the same actions as in
     * {@link #initialize}.
     * <li><code>load != FORCE_LOAD_NONE || stateManager.getPCState ()
     * == PCState.HOLLOW</code>: A hollow state manager, or one whose
     * fields must be loaded because this is a refresh or retrieve action.
     * Peform the same actions as in {@link #load}, choosing the fields
     * to load based on the fetch configuration, or loading all fields
     * if <code>load == FORCE_LOAD_ALL</code>. Any required fields left
     * unloaded will cause a subsequent invocation of {@link #load} on
     * the individual object in question.</li>
     * <li><code>load == FORCE_LOAD_NONE &amp;&amp;
     * stateManager.getPCState () != PCState.HOLLOW</code>: A non-hollow
     * state manager. Perform the same actions as in {@link #exists},
     * and load additional state if desired. Non-hollow objects will only
     * be included outside of refresh invocations if a user calls
     * <code>findAll</code> with the <code>validate</code>
     * parameter set to <code>true</code>.</li>
     * </ul> 
     * Store managers that cannot efficiently batch load can simply test
     * for these conditions and delegate to the proper methods.
     *
     * @param sms the state manager instances to load
     * @param state the lifecycle state to initialize uninitialized
     * state managers with; may be null if no uninitialized
     * instances are included in <code>sms</code>
     * @param load one of the FORCE_LOAD_* constants describing the
     * fields to force-load if this is a refresh or retrieve action
     * @param fetch the current fetch configuration to use when loading
     * related objects
     * @param edata the current execution data, or null if not
     * given to the calling method of the broker
     * @return a collection of the state manager identities for
     * which no data store record exists
     * @see org.apache.openjpa.util.ImplHelper#loadAll
     */
    public Collection loadAll(Collection sms, PCState state, int load,
        FetchConfiguration fetch, Object edata);

    /**
     * Notification that the given state manager is about to change its
     * lifecycle state. The store manager is not required to do anything in
     * this method, but some back ends may need to.
     *
     * @since 0.3.0
     */
    public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
        PCState toState);

    /**
     * Flush the given state manager collection to the datastore, returning
     * a collection of exceptions encountered during flushing.
     * The given collection may include states that do not require data
     * store action, such as persistent-clean instances or persistent-dirty
     * instances that have not been modified since they were last flushed.
     * For datastore updates and inserts, the dirty, non-flushed fields of
     * each state should be flushed. New instances without an assigned object
     * id should be given one via {@link OpenJPAStateManager#setObjectId}. New
     * instances with value-strategy fields that have not been assigned yet
     * should have their fields set. Datastore version information should be
     * updated during flush, and the state manager's version indicator
     * updated through the {@link OpenJPAStateManager#setNextVersion} method.
     * The current version will roll over to this next version upon successful
     * commit.
     *
     * @see org.apache.openjpa.util.ApplicationIds#assign()
     */
    public Collection flush(Collection sms);

    /**
     * Assign an object id to the given new instance. Return false if the
     * instance cannot be assigned an identity because a flush is required
     * (for example, the identity is determined by the datastore on insert).
     * For application identity instances, the assigned object id should be
     * based on field state. The implementation is responsible for using the
     * proper value strategy according to the instance metadata. This method
     * is called the first time a user requests the oid of a new instance
     * before flush.
     *
     * @param preFlush whether this assignment is being requested by the
     * system as part of pre-flush activities, and can
     * be ignored if it is more efficient to assign within {@link #flush}
     * @see org.apache.openjpa.util.ImplHelper#generateFieldValue
     * @see org.apache.openjpa.util.ImplHelper#generateIdentityValue
     * @see org.apache.openjpa.util.ApplicationIds#assign()
     * @since 0.3.3
     */
    public boolean assignObjectId(OpenJPAStateManager sm, boolean preFlush);

    /**
     * Assign a value to the given field. Return false if the value cannot
     * be assigned because a flush is required (for example, the field value
     * is determined by the datastore on insert). This method is called the
     * first time a user requests the value of a field with a value-strategy
     * on a new instance before flush.
     *
     * @param preFlush whether this assignment is being requested by the
     * system as part of pre-flush activities, and can
     * be ignored if it is more efficient to assign within {@link #flush}
     * @see org.apache.openjpa.util.ImplHelper#generateFieldValue
     * @since 0.4.0
     */
    public boolean assignField(OpenJPAStateManager sm, int field,
        boolean preFlush);

    /**
     * Return the persistent class for the given data store identity value.
     * If the given value is not a datastore identity object, return null.
     *
     * @since 0.3.0
     */
    public Class getManagedType(Object oid);

    /**
     * Return the class used by this StoreManager for datastore identity
     * values. The given metadata may be null, in which case the return
     * value should the common datastore identity class for all classes, or
     * null if this store manager does not use a common identity class.
     */
    public Class getDataStoreIdType(ClassMetaData meta);

    /**
     * Copy the given object id value. Use the described type of the given
     * metadata, which may be a subclass of the given oid's described type.
     */
    public Object copyDataStoreId(Object oid, ClassMetaData meta);

    /**
     * Create a new unique datastore identity for the given type from
     * the given oid value (presumably pk, stringified oid, or oid instance).
     */
    public Object newDataStoreId(Object oidVal, ClassMetaData meta);

    /**
     * Return a connection to the data store suitable for client use. If
     * this method is called during a data store transaction, thie connection
     * must be transactional. If no connection is in use, this method should
     * create one to return.
     */
    public Object getClientConnection();

    /**
     * Instruct the store to retain a connection for continued use. This
     * will be invoked automatically based on the user's configured connection
     * retain mode.
     */
    public void retainConnection();

    /**
     * Instruct the store to release a retained connection. This
     * will be invoked automatically based on the user's configured connection
     * retain mode.
     */
    public void releaseConnection();

    /**
     * Cancel all pending data store statements.
     *
     * @return true if any statements cancelled, false otherwise
     * @since 0.3.1
     */
    public boolean cancelAll();

    /**
     * Return a provider for all instances of the given candidate class,
     * optionally including subclasses. The given candidate may be an
     * unmapped type with mapped subclasses. If the provider is iterated
     * within a data store transaction, returned instances should be locked.
     */
    public ResultObjectProvider executeExtent(ClassMetaData meta,
        boolean subclasses, FetchConfiguration fetch);

    /**
     * Return a query implementation suitable for this store. If the query
     * is iterated within a data store transaction, returned instances should
     * be locked. Return null if this store does not support native execution
     * of the given language. OpenJPA can execute JPQL in memory even without
     * back end support.
     *
     * @param language the query language
     */
    public StoreQuery newQuery(String language);

    /**
     * Return a fetch configuration suitable for this runtime. Typically
     * will be or extend <code>FetchConfigurationImpl</code>.
     */
    public FetchConfiguration newFetchConfiguration();

    /**
     * Compare the two version objects.
     *
     * @param state the state manager for the object
     * @param v1 the first version object to compare
     * @param v2 the second version object to compare
     * @return <ul>
     * <li>{@link #VERSION_LATER} if <code>v1</code>
     * is later than <code>v2</code></li>
     * <li>{@link #VERSION_EARLIER} if <code>v1</code>
     * is earlier than <code>v2</code></li>
     * <li>{@link #VERSION_SAME} if <code>v1</code>
     * is the same as <code>v2</code></li>
     * <li>{@link #VERSION_DIFFERENT} if <code>v1</code>
     * is different from <code>v2</code>, but the time
     * difference of the versions cannot be determined</li>
     * </ul>
     */
    public int compareVersion(OpenJPAStateManager state, Object v1, Object v2);

    /**
     * Return a sequence that generates datastore identity values for the
     * given class. This method will only be called when the identity strategy
     * for the class is one of:
     * <ul>
     * <li>{@link ValueStrategies#NATIVE}</li>
     * <li>{@link ValueStrategies#AUTOASSIGN}</li>
     * <li>{@link ValueStrategies#INCREMENT}</li>
     * </ul>
     * If the identity strategy cannot be represented as a sequence, return
     * null.
     *
     * @since 0.4.0
     */
    public Seq getDataStoreIdSequence(ClassMetaData forClass);

    /**
     * Return a sequence that generates values for the given field. This
     * method will only be called when the value strategy for the field
     * is one of:
     * <ul>
     * <li>{@link ValueStrategies#NATIVE}</li>
     * <li>{@link ValueStrategies#AUTOASSIGN}</li>
     * <li>{@link ValueStrategies#INCREMENT}</li>
     * </ul> If the value strategy cannot be represented as a sequence, return
     * null.
     *
     * @since 0.4.0
     */
    public Seq getValueSequence(FieldMetaData forField);

    /**
     * Free any resources this store manager is using.
     *
     * @since 0.2.5
     */
    public void close ();
}
