/*
 * 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.ofbiz.entity;

import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;

import org.ofbiz.entity.cache.Cache;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.datasource.GenericHelper;
import org.ofbiz.entity.datasource.GenericHelperInfo;
import org.ofbiz.entity.eca.EntityEcaHandler;
import org.ofbiz.entity.model.DynamicViewEntity;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelField;
import org.ofbiz.entity.model.ModelFieldType;
import org.ofbiz.entity.model.ModelFieldTypeReader;
import org.ofbiz.entity.model.ModelGroupReader;
import org.ofbiz.entity.model.ModelReader;
import org.ofbiz.entity.util.DistributedCacheClear;
import org.ofbiz.entity.util.EntityCrypto;
import org.ofbiz.entity.util.EntityFindOptions;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityStoreOptions;
import org.ofbiz.entity.util.SequenceUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public interface Delegator {

    enum OperationType {INSERT, UPDATE, DELETE}

    void clearAllCacheLinesByDummyPK(Collection<GenericPK> dummyPKs);

    void clearAllCacheLinesByValue(Collection<GenericValue> values);

    /**
     * This method is a shortcut to completely clear all entity engine caches.
     * For performance reasons this should not be called very often.
     */
    void clearAllCaches();

    void clearAllCaches(boolean distribute);

    /**
     * Remove a CACHED Generic Entity from the cache by its primary key, does
     * NOT check to see if the passed GenericPK is a complete primary key. Also
     * tries to clear the corresponding all cache entry.
     *
     * @param primaryKey
     *            The primary key to clear by.
     */
    void clearCacheLine(GenericPK primaryKey);

    void clearCacheLine(GenericPK primaryKey, boolean distribute);

    /**
     * Remove a CACHED GenericValue from as many caches as it can. Automatically
     * tries to remove entries from the all cache, the by primary key cache, and
     * the by and cache. This is the ONLY method that tries to clear
     * automatically from the by and cache.
     *
     * @param value
     *            The GenericValue to clear by.
     */
    void clearCacheLine(GenericValue value);

    void clearCacheLine(GenericValue value, boolean distribute);

    /**
     * Remove all CACHED Generic Entity (List) from the cache
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     */
    void clearCacheLine(String entityName);

    /**
     * Remove a CACHED Generic Entity (List) from the cache, either a PK, ByAnd,
     * or All
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     */
    void clearCacheLine(String entityName, Map<String, ? extends Object> fields);

    /**
     * Remove a CACHED Generic Entity (List) from the cache, either a PK, ByAnd,
     * or All
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     */
    void clearCacheLine(String entityName, Object... fields);

    void clearCacheLineByCondition(String entityName, EntityCondition condition);

    void clearCacheLineByCondition(String entityName, EntityCondition condition, boolean distribute);

    /**
     * Remove a CACHED Generic Entity from the cache by its primary key. Checks
     * to see if the passed GenericPK is a complete primary key, if it is then
     * the cache line will be removed from the primaryKeyCache; if it is NOT a
     * complete primary key it will remove the cache line from the andCache. If
     * the fields map is empty, then the allCache for the entity will be
     * cleared.
     *
     * @param dummyPK
     *            The dummy primary key to clear by.
     */
    void clearCacheLineFlexible(GenericEntity dummyPK);

    void clearCacheLineFlexible(GenericEntity dummyPK, boolean distribute);

    Delegator cloneDelegator();

    Delegator cloneDelegator(String delegatorName);

    /**
     * Creates a Entity in the form of a GenericValue and write it to the
     * datasource
     *
     * @param primaryKey
     *            The GenericPK to create a value in the datasource from
     * @return GenericValue instance containing the new instance
     */
    GenericValue create(GenericPK primaryKey) throws GenericEntityException;

    /**
     * Creates a Entity in the form of a GenericValue and write it to the
     * datasource
     *
     * @param value
     *            The GenericValue to create a value in the datasource from
     * @return GenericValue instance containing the new instance
     */
    GenericValue create(GenericValue value) throws GenericEntityException;

    /**
     * Creates a Entity in the form of a GenericValue and write it to the
     * database
     *
     * @return GenericValue instance containing the new instance
     */
    GenericValue create(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException;

    /**
     * Creates a Entity in the form of a GenericValue and write it to the
     * database
     *
     * @return GenericValue instance containing the new instance
     */
    GenericValue create(String entityName, Object... fields) throws GenericEntityException;

    /**
     * Creates or stores an Entity
     *
     * @param value
     *            The GenericValue instance containing the new or existing
     *            instance
     * @return GenericValue instance containing the new or updated instance
     */
    GenericValue createOrStore(GenericValue value) throws GenericEntityException;

    /**
     * Sets the sequenced ID (for entity with one primary key field ONLY), and
     * then does a create in the database as normal. The reason to do it this
     * way is that it will retry and fix the sequence if somehow the sequencer
     * is in a bad state and returning a value that already exists.
     *
     * @param value
     *            The GenericValue to create a value in the datasource from
     * @return GenericValue instance containing the new instance
     */
    GenericValue createSetNextSeqId(GenericValue value) throws GenericEntityException;

    /**
     * Creates a Entity in the form of a GenericValue and write it to the
     * database
     *
     * @return GenericValue instance containing the new instance
     */
    GenericValue createSingle(String entityName, Object singlePkValue) throws GenericEntityException;

    @Deprecated
    Object decryptFieldValue(String entityName, String encValue) throws EntityCryptoException;

    Object decryptFieldValue(String entityName, ModelField.EncryptMethod encryptMethod, String encValue) throws EntityCryptoException;

    Object encryptFieldValue(String entityName, ModelField.EncryptMethod encryptMethod, Object fieldValue) throws EntityCryptoException;

    /**
     * Finds GenericValues by the conditions specified in the EntityCondition
     * object, the the EntityCondition javadoc for more details.
     *
     * @param entityName
     *            The name of the Entity as defined in the entity XML file
     * @param whereEntityCondition
     *            The EntityCondition object that specifies how to constrain
     *            this query before any groupings are done (if this is a view
     *            entity with group-by aliases)
     * @param havingEntityCondition
     *            The EntityCondition object that specifies how to constrain
     *            this query after any groupings are done (if this is a view
     *            entity with group-by aliases)
     * @param fieldsToSelect
     *            The fields of the named entity to get from the database; if
     *            empty or null all fields will be retreived
     * @param orderBy
     *            The fields of the named entity to order the query by;
     *            optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @param findOptions
     *            An instance of EntityFindOptions that specifies advanced query
     *            options. See the EntityFindOptions JavaDoc for more details.
     * @return EntityListIterator representing the result of the query: NOTE
     *         THAT THIS MUST BE CLOSED (preferably in a finally block) WHEN YOU
     *         ARE DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT
     *         WILL MAINTAIN A DATABASE CONNECTION.
     */
    EntityListIterator find(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Set<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException;

    /**
     * Finds all Generic entities 
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param useCache
     *            Whether to cache the results
     * @return List containing all Generic entities
     */
    List<GenericValue> findAll(String entityName, boolean useCache) throws GenericEntityException;

    /**
     * Finds Generic Entity records by all of the specified fields (ie: combined
     * using AND), looking first in the cache; uses orderBy for lookup, but only
     * keys results on the entityName and fields
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     * @param orderBy
     *            The fields of the named entity to order the query by;
     *            optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @param useCache
     *            Whether to cache the results
     * @return List of GenericValue instances that match the query
     */
    List<GenericValue> findByAnd(String entityName, Map<String, ? extends Object> fields, List<String> orderBy, boolean useCache) throws GenericEntityException;

    /**
     * Find a Generic Entity by its Primary Key and only returns the values
     * requested by the passed keys (names).
     *
     * @param primaryKey
     *            The primary key to find by.
     * @param keys
     *            The keys, or names, of the values to retrieve; only these
     *            values will be retrieved
     * @return The GenericValue corresponding to the primaryKey
     */
    GenericValue findByPrimaryKeyPartial(GenericPK primaryKey, Set<String> keys) throws GenericEntityException;

    /**
     * Gets the hit count of GenericValues for the given EntityCondition objects.
     * 
     * @param entityName
     * @param whereEntityCondition
     * @param havingEntityCondition
     * @param findOptions
     * @return long value with hit count
     * @throws GenericEntityException
     */
    long findCountByCondition(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, EntityFindOptions findOptions) throws GenericEntityException;

    /**
     * Finds GenericValues by the conditions specified in the EntityCondition
     * object, the the EntityCondition javadoc for more details.
     *
     * @param entityName
     *            The name of the Entity as defined in the entity XML file
     * @param entityCondition
     *            The EntityCondition object that specifies how to constrain
     *            this query before any groupings are done (if this is a view
     *            entity with group-by aliases)
     * @param fieldsToSelect
     *            The fields of the named entity to get from the database; if
     *            empty or null all fields will be retrieved
     * @param orderBy
     *            The fields of the named entity to order the query by;
     *            optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @param findOptions
     *            An instance of EntityFindOptions that specifies advanced query
     *            options. See the EntityFindOptions JavaDoc for more details.
     * @return List of GenericValue objects representing the result
     */
    List<GenericValue> findList(String entityName, EntityCondition entityCondition, Set<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions, boolean useCache) throws GenericEntityException;

    /**
     * Finds GenericValues by the conditions specified in the EntityCondition
     * object, the the EntityCondition javadoc for more details.
     *
     * @param dynamicViewEntity
     *            The DynamicViewEntity to use for the entity model for this
     *            query; generally created on the fly for limited use
     * @param whereEntityCondition
     *            The EntityCondition object that specifies how to constrain
     *            this query before any groupings are done (if this is a view
     *            entity with group-by aliases)
     * @param havingEntityCondition
     *            The EntityCondition object that specifies how to constrain
     *            this query after any groupings are done (if this is a view
     *            entity with group-by aliases)
     * @param fieldsToSelect
     *            The fields of the named entity to get from the database; if
     *            empty or null all fields will be retreived
     * @param orderBy
     *            The fields of the named entity to order the query by;
     *            optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @param findOptions
     *            An instance of EntityFindOptions that specifies advanced query
     *            options. See the EntityFindOptions JavaDoc for more details.
     * @return EntityListIterator representing the result of the query: NOTE
     *         THAT THIS MUST BE CLOSED WHEN YOU ARE DONE WITH IT, AND DON'T
     *         LEAVE IT OPEN TOO LONG BEACUSE IT WILL MAINTAIN A DATABASE
     *         CONNECTION.
     */
    EntityListIterator findListIteratorByCondition(DynamicViewEntity dynamicViewEntity, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Collection<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException;

    /**
     * Find a Generic Entity by its primary key.
     *
     * @param entityName The Name of the Entity as defined in the entity XML file
     * @param useCache Retrieve the Generic Entity from the cache when <code>true</code>
     * @param fields The fields of the named entity to query by with their corresponding values
     * @return The Generic Entity corresponding to the primary key
     * @throws GenericEntityException
     */
    GenericValue findOne(String entityName, boolean useCache, Object... fields) throws GenericEntityException;

    /**
     * Find a Generic Entity by its Primary Key
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     * @return The GenericValue corresponding to the primaryKey
     */
    GenericValue findOne(String entityName, Map<String, ? extends Object> fields, boolean useCache) throws GenericEntityException;

    Cache getCache();

    String getCurrentSessionIdentifier();

    String getCurrentUserIdentifier();

    String getDelegatorName();

    String getDelegatorBaseName();

    String getDelegatorTenantId();

    <T> EntityEcaHandler<T> getEntityEcaHandler();

    /**
     * Gets a field type instance by name from the helper that corresponds to
     * the specified entity
     *
     * @param entity
     *            The entity
     * @param type
     *            The name of the type
     * @return ModelFieldType instance for the named type from the helper that
     *         corresponds to the specified entity
     */
    ModelFieldType getEntityFieldType(ModelEntity entity, String type) throws GenericEntityException;

    /**
     * Gets field type names from the helper that corresponds to the specified
     * entity
     *
     * @param entity
     *            The entity
     * @return Collection of field type names from the helper that corresponds
     *         to the specified entity
     */
    Collection<String> getEntityFieldTypeNames(ModelEntity entity) throws GenericEntityException;

    /**
     * Gets the helper name that corresponds to this delegator and the specified
     * entityName
     *
     * @param entityName
     *            The name of the entity to get the helper for
     * @return String with the helper name that corresponds to this delegator
     *         and the specified entityName
     */
    String getEntityGroupName(String entityName);

    /**
     * Gets the an instance of helper that corresponds to this delegator and the
     * specified entity
     *
     * @param entity
     *            The entity to get the helper for
     * @return GenericHelper that corresponds to this delegator and the
     *         specified entity
     */
    GenericHelper getEntityHelper(ModelEntity entity) throws GenericEntityException;

    /**
     * Gets the an instance of helper that corresponds to this delegator and the
     * specified entityName
     *
     * @param entityName
     *            The name of the entity to get the helper for
     * @return GenericHelper that corresponds to this delegator and the
     *         specified entityName
     */
    GenericHelper getEntityHelper(String entityName) throws GenericEntityException;

    /**
     * Gets the helper name that corresponds to this delegator and the specified
     * entity
     *
     * @param entity
     *            The entity to get the helper for
     * @return String with the helper name that corresponds to this delegator
     *         and the specified entity
     */
    String getEntityHelperName(ModelEntity entity);

    /**
     * Gets the helper name that corresponds to this delegator and the specified
     * entityName
     *
     * @param entityName
     *            The name of the entity to get the helper name for
     * @return String with the helper name that corresponds to this delegator
     *         and the specified entityName
     */
    String getEntityHelperName(String entityName);

    GenericValue getFromPrimaryKeyCache(GenericPK primaryKey);

    /**
     * Gets the helper name that corresponds to this delegator and the specified
     * entityName
     *
     * @param groupName
     *            The name of the group to get the helper name for
     * @return String with the helper name that corresponds to this delegator
     *         and the specified entityName
     */
    String getGroupHelperName(String groupName);

    GenericHelperInfo getGroupHelperInfo(String entityGroupName);

    /**
     * Gets the instance of ModelEntity that corresponds to this delegator and
     * the specified entityName
     *
     * @param entityName
     *            The name of the entity to get
     * @return ModelEntity that corresponds to this delegator and the specified
     *         entityName
     */
    ModelEntity getModelEntity(String entityName);

    /**
     * Gets a Map of entity name & entity model pairs that are in the named
     * group
     *
     * @param groupName
     *            The name of the group
     * @return Map of entityName String keys and ModelEntity instance values
     */
    Map<String, ModelEntity> getModelEntityMapByGroup(String groupName) throws GenericEntityException;

    ModelFieldTypeReader getModelFieldTypeReader(ModelEntity entity);

    /**
     * Gets the instance of ModelGroupReader that corresponds to this delegator
     *
     * @return ModelGroupReader that corresponds to this delegator
     */
    ModelGroupReader getModelGroupReader();

    /**
     * Gets the instance of ModelReader that corresponds to this delegator
     *
     * @return ModelReader that corresponds to this delegator
     */
    ModelReader getModelReader();

    /**
     * Get the named Related Entity for the GenericValue from the persistent
     * store across another Relation. Helps to get related Values in a
     * multi-to-multi relationship.
     *
     * @param relationNameOne
     *            String containing the relation name which is the combination
     *            of relation.title and relation.rel-entity-name as specified in
     *            the entity XML definition file, for first relation
     * @param relationNameTwo
     *            String containing the relation name for second relation
     * @param value
     *            GenericValue instance containing the entity
     * @param orderBy
     *            The fields of the named entity to order the query by; may be
     *            null; optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @return List of GenericValue instances as specified in the relation
     *         definition
     */
    List<GenericValue> getMultiRelation(GenericValue value, String relationNameOne, String relationNameTwo, List<String> orderBy) throws GenericEntityException;

    /**
     * Get the next guaranteed unique seq id from the sequence with the given
     * sequence name; if the named sequence doesn't exist, it will be created
     *
     * @param seqName
     *            The name of the sequence to get the next seq id from
     * @return String with the next sequenced id for the given sequence name
     */
    String getNextSeqId(String seqName);

    /**
     * Get the next guaranteed unique seq id from the sequence with the given
     * sequence name; if the named sequence doesn't exist, it will be created
     *
     * @param seqName
     *            The name of the sequence to get the next seq id from
     * @param staggerMax
     *            The maximum amount to stagger the sequenced ID, if 1 the
     *            sequence will be incremented by 1, otherwise the current
     *            sequence ID will be incremented by a value between 1 and
     *            staggerMax
     * @return Long with the next seq id for the given sequence name
     */
    String getNextSeqId(String seqName, long staggerMax);

    /**
     * Get the next guaranteed unique seq id from the sequence with the given
     * sequence name; if the named sequence doesn't exist, it will be created
     *
     * @param seqName
     *            The name of the sequence to get the next seq id from
     * @return Long with the next sequenced id for the given sequence name
     */
    Long getNextSeqIdLong(String seqName);

    /**
     * Get the next guaranteed unique seq id from the sequence with the given
     * sequence name; if the named sequence doesn't exist, it will be created
     *
     * @param seqName
     *            The name of the sequence to get the next seq id from
     * @param staggerMax
     *            The maximum amount to stagger the sequenced ID, if 1 the
     *            sequence will be incremented by 1, otherwise the current
     *            sequence ID will be incremented by a value between 1 and
     *            staggerMax
     * @return Long with the next seq id for the given sequence name
     */
    Long getNextSeqIdLong(String seqName, long staggerMax);

    /**
     * Gets the name of the server configuration that corresponds to this
     * delegator
     *
     * @return server configuration name
     */
    String getOriginalDelegatorName();

    /**
     * Get the named Related Entity for the GenericValue from the persistent
     * store
     *
     * @param relationName
     *            String containing the relation name which is the combination
     *            of relation.title and relation.rel-entity-name as specified in
     *            the entity XML definition file
     * @param byAndFields
     *            the fields that must equal in order to keep; may be null
     * @param orderBy
     *            The fields of the named entity to order the query by; may be
     *            null; optionally add a " ASC" for ascending or " DESC" for
     *            descending
     * @param value
     *            GenericValue instance containing the entity
     * @param useCache
     *            Whether to cache the results
     * @return List of GenericValue instances as specified in the relation
     *         definition
     */
    List<GenericValue> getRelated(String relationName, Map<String, ? extends Object> byAndFields, List<String> orderBy, GenericValue value, boolean useCache) throws GenericEntityException;

    /**
     * Get a dummy primary key for the named Related Entity for the GenericValue.
     *
     * @param relationName
     *            String containing the relation name which is the combination
     *            of relation.title and relation.rel-entity-name as specified in
     *            the entity XML definition file
     * @param byAndFields
     *            the fields that must equal in order to keep; may be null
     * @param value
     *            GenericValue instance containing the entity
     * @return GenericPK containing a possibly incomplete PrimaryKey object
     *         representing the related entity or entities
     */
    GenericPK getRelatedDummyPK(String relationName, Map<String, ? extends Object> byAndFields, GenericValue value) throws GenericEntityException;

    /**
     * Get related entity where relation is of type one, uses findByPrimaryKey
     *
     * @param relationName
     *            String containing the relation name which is the combination
     *            of relation.title and relation.rel-entity-name as specified in
     *            the entity XML definition file
     * @param value
     *            GenericValue instance containing the entity
     * @param useCache
     *            Whether to cache the results
     * @return GenericValue that is the related entity
     * @throws IllegalArgumentException
     *             if the list found has more than one item
     */
    GenericValue getRelatedOne(String relationName, GenericValue value, boolean useCache) throws GenericEntityException;

    void initEntityEcaHandler();

    void initDistributedCacheClear();

    GenericPK makePK(Element element);

    /** Creates a Primary Key in the form of a GenericPK without persisting it */
    GenericPK makePK(String entityName);

    /** Creates a Primary Key in the form of a GenericPK without persisting it */
    GenericPK makePK(String entityName, Map<String, ? extends Object> fields);

    /** Creates a Primary Key in the form of a GenericPK without persisting it */
    GenericPK makePK(String entityName, Object... fields);

    /** Creates a Primary Key in the form of a GenericPK without persisting it */
    GenericPK makePKSingle(String entityName, Object singlePkValue);

    Delegator makeTestDelegator(String delegatorName);

    /**
     * Creates a Entity in the form of a GenericValue without persisting it;
     * only valid fields will be pulled from the fields Map
     */
    GenericValue makeValidValue(String entityName, Map<String, ? extends Object> fields);

    /**
     * Creates a Entity in the form of a GenericValue without persisting it;
     * only valid fields will be pulled from the fields Map
     */
    GenericValue makeValidValue(String entityName, Object... fields);

    GenericValue makeValue(Element element);

    /** Creates a Entity in the form of a GenericValue without persisting it */
    GenericValue makeValue(String entityName);

    /** Creates a Entity in the form of a GenericValue without persisting it */
    GenericValue makeValue(String entityName, Map<String, ? extends Object> fields);

    /** Creates a Entity in the form of a GenericValue without persisting it */
    GenericValue makeValue(String entityName, Object... fields);

    List<GenericValue> makeValues(Document document);

    /** Creates a Entity in the form of a GenericValue without persisting it */
    GenericValue makeValueSingle(String entityName, Object singlePkValue);

    void putAllInPrimaryKeyCache(List<GenericValue> values);

    void putInPrimaryKeyCache(GenericPK primaryKey, GenericValue value);

    // ======= XML Related Methods ========
    List<GenericValue> readXmlDocument(URL url) throws SAXException, ParserConfigurationException, java.io.IOException;

    /**
     * Refresh the Entity for the GenericValue from the persistent store
     *
     * @param value
     *            GenericValue instance containing the entity to refresh
     */
    void refresh(GenericValue value) throws GenericEntityException;

    /**
     * Refresh the Entity for the GenericValue from the cache
     *
     * @param value
     *            GenericValue instance containing the entity to refresh
     */
    void refreshFromCache(GenericValue value) throws GenericEntityException;

    /** Refreshes the ID sequencer clearing all cached bank values. */
    void refreshSequencer();

    /**
     * Remove the Entities from the List from the persistent store. <br/>The
     * List contains GenericEntity objects, can be either GenericPK or
     * GenericValue. <br/>If a certain entity contains a complete primary key,
     * the entity in the datasource corresponding to that primary key will be
     * removed, this is like a removeByPrimary Key. <br/>On the other hand, if a
     * certain entity is an incomplete or non primary key, if will behave like
     * the removeByAnd method. <br/>These updates all happen in one transaction,
     * so they will either all succeed or all fail, if the data source supports
     * transactions.
     *
     * @param dummyPKs
     *            Collection of GenericEntity instances containing the entities
     *            or by and fields to remove
     * @return int representing number of rows effected by this operation
     */
    int removeAll(List<? extends GenericEntity> dummyPKs) throws GenericEntityException;

    int removeAll(String entityName) throws GenericEntityException;

    /**
     * Removes/deletes Generic Entity records found by all of the specified
     * fields (ie: combined using AND)
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     * @return int representing number of rows effected by this operation
     */
    int removeByAnd(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException;

    /**
     * Removes/deletes Generic Entity records found by all of the specified
     * fields (ie: combined using AND)
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param fields
     *            The fields of the named entity to query by with their
     *            corresponding values
     * @return int representing number of rows effected by this operation
     */
    int removeByAnd(String entityName, Object... fields) throws GenericEntityException;

    /**
     * Removes/deletes Generic Entity records found by the condition
     *
     * @param entityName
     *            The Name of the Entity as defined in the entity XML file
     * @param condition
     *            The condition used to restrict the removing
     * @return int representing number of rows effected by this operation
     */
    int removeByCondition(String entityName, EntityCondition condition) throws GenericEntityException;

    /**
     * Remove a Generic Entity corresponding to the primaryKey
     *
     * @param primaryKey
     *            The primary key of the entity to remove.
     * @return int representing number of rows effected by this operation
     */
    int removeByPrimaryKey(GenericPK primaryKey) throws GenericEntityException;

    /**
     * Remove the named Related Entity for the GenericValue from the persistent
     * store
     *
     * @param relationName
     *            String containing the relation name which is the combination
     *            of relation.title and relation.rel-entity-name as specified in
     *            the entity XML definition file
     * @param value
     *            GenericValue instance containing the entity
     * @return int representing number of rows effected by this operation
     */
    int removeRelated(String relationName, GenericValue value) throws GenericEntityException;

    /**
     * Remove a Generic Value from the database
     *
     * @param value
     *            The GenericValue object of the entity to remove.
     * @return int representing number of rows effected by this operation
     */
    int removeValue(GenericValue value) throws GenericEntityException;

    void rollback();

    void setDistributedCacheClear(DistributedCacheClear distributedCacheClear);

    void setEntityCrypto(EntityCrypto crypto);

    <T> void setEntityEcaHandler(EntityEcaHandler<T> entityEcaHandler);

    /**
     * Look at existing values for a sub-entity with a sequenced secondary ID,
     * and get the highest plus 1
     */
    void setNextSubSeqId(GenericValue value, String seqFieldName, int numericPadding, int incrementBy);

    /**
     * Allows you to pass a SequenceUtil class (possibly one that overrides the
     * getNextSeqId method); if null is passed will effectively refresh the
     * sequencer.
     */
    void setSequencer(SequenceUtil sequencer);

    /**
     * Store the Entity from the GenericValue to the persistent store
     *
     * @param value
     *            GenericValue instance containing the entity
     * @return int representing number of rows effected by this operation
     */
    int store(GenericValue value) throws GenericEntityException;

    /**
     * Store the Entities from the List GenericValue instances to the persistent
     * store. <br/>This is different than the normal store method in that the
     * store method only does an update, while the storeAll method checks to see
     * if each entity exists, then either does an insert or an update as
     * appropriate. <br/>These updates all happen in one transaction, so they
     * will either all succeed or all fail, if the data source supports
     * transactions. This is just like to othersToStore feature of the
     * GenericEntity on a create or store.
     *
     * @param values
     *            List of GenericValue instances containing the entities to
     *            store
     * @return int representing number of rows effected by this operation
     */
    int storeAll(List<GenericValue> values) throws GenericEntityException;

    /**
     * Store the Entities from the List GenericValue instances to the persistent
     * store. <br/>This is different than the normal store method in that the
     * store method only does an update, while the storeAll method checks to see
     * if each entity exists, then either does an insert or an update as
     * appropriate. <br/>These updates all happen in one transaction, so they
     * will either all succeed or all fail, if the data source supports
     * transactions. This is just like to othersToStore feature of the
     * GenericEntity on a create or store.
     *
     * @param storeOptions
     *            An instance of EntityStoreOptions that specifies advanced store
     *            options or null for default values.
     *            See the EntityStoreOptions JavaDoc for more details.
     * @param values
     *            List of GenericValue instances containing the entities to
     *            store
     * @return int representing number of rows effected by this operation
     */
    int storeAll(List<GenericValue> values, EntityStoreOptions storeOptions) throws GenericEntityException;

    /**
     * Store a group of values
     *
     * @param entityName
     *            The name of the Entity as defined in the entity XML file
     * @param fieldsToSet
     *            The fields of the named entity to set in the database
     * @param condition
     *            The condition that restricts the list of stored values
     * @return int representing number of rows effected by this operation
     * @throws GenericEntityException
     */
    int storeByCondition(String entityName, Map<String, ? extends Object> fieldsToSet, EntityCondition condition) throws GenericEntityException;
   
    /**
     * Get use of Distributed Cache Clear mechanism status
     * @return boolean true if this delegator uses a Distributed Cache Clear mechanism 
     */
    boolean useDistributedCacheClear();   
}
