/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.fw.persistent;

import gov.va.med.fw.persistent.hibernate.AbstractDAOAction;
import gov.va.med.fw.persistent.hibernate.QueryAndParams;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.FlushModeType;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.support.SQLExceptionTranslator;

/**
 * Project: Framework
 * 
 * @author DNS   LEV
 * @version 1.0
 */
public interface DAOOperations extends DAO {

	/**
	 * Executes a generic data base operation
	 * 
	 * @param action
	 *            An action to be executed in a session
	 * @return A return value from an action
	 * @throws DAOException
	 *             thrown if failed to execute an action
	 */
	public Object execute(AbstractDAOAction action) throws DAOException;

	/**
	 * Clear all data in the current session
	 * 
	 * @throws DAOException
	 *             Thrown if failed to clear a sesion
	 */
	public void clear() throws DAOException;

	/**
	 * Closes an iterator of result set generated from a database operation
	 * 
	 * @param it
	 *            An iterator to be closed
	 * @throws DAOException
	 *             Thrown if failed to close an iterator
	 */
	public void closeIterator(Iterator<?> it) throws DAOException;

	/**
	 * Check if an entity exist in the Hibernate session
	 * 
	 * @param entity
	 *            An entity to check for existence in a session
	 * @return true if an entity is in the session. false otherwise
	 * @throws DAOException
	 *             thrown if failed to check for an entity
	 */
	// public boolean contains(Object entity) throws DAOException;
	/**
	 * Deletes a collection of entities from a database
	 * 
	 * @param entities
	 *            A collection to be deleted
	 * @throws DAOException
	 *             thrown if failed to delete from a database
	 */
	public void deleteAll(Collection<?> entities) throws DAOException;

	/**
	 * Evicts an entity from a session. This method detaches a persistent entity
	 * from a session.
	 * 
	 * @param entity
	 *            An entity to be detach from a session
	 * @throws DAOException
	 *             Thrown if failed to detach an entity from a session
	 */
	public void evict(Object entity) throws DAOException;

	/**
	 * Execute the action specified by the given action object within a Session.
	 * 
	 * @param action
	 *            callback object that specifies the Hibernate action
	 * @param exposeNativeSession
	 *            whether to expose the native Hibernate Session to callback
	 *            code
	 * @return a result object returned by the action, or null
	 * @throws DAOException
	 *             in case of Hibernate errors
	 */
	public Object execute(AbstractDAOAction action, boolean exposeNativeSession)
			throws DAOException;

	/**
	 * Execute the action specified by the given action object within a Session.
	 * 
	 * @param action
	 *            callback object that specifies the Hibernate action
	 * @param exposeNativeSession
	 *            whether to expose the native Hibernate Session to callback
	 *            code
	 * @return a result object returned by the action, or null
	 * @throws DAOException
	 *             in case of Hibernate errors
	 */
	public List executeFind(AbstractDAOAction action) throws DAOException;

	/**
	 * Execute a query for persistent instances, binding one value to a "?"
	 * parameter in the query string
	 * 
	 * @param queryString
	 *            A query expression
	 * @param value
	 *            A value of a parameter
	 * @return A result entity
	 * @throws DAOException
	 *             in case of Hibernate errors
	 */
	public List find(String queryString, Object value) throws DAOException;

	/**
	 * Execute a query for persistent instances, binding an array of values to
	 * "?" parameters in the query string
	 * 
	 * @param queryString
	 *            A query expression
	 * @param values
	 *            An array of parameter values
	 * @return A result entity
	 * @throws DAOException
	 *             in case of Hibernate errors
	 */
	// public List find(String queryString, Object[] values) throws
	// DAOException;
	/**
	 * @param queryName
	 * @param paramName
	 * @param value
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedParam(String queryName, String paramName, Object value)
			throws DAOException;

	/**
	 * @param queryString
	 * @param paramNames
	 * @param values
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedParams(String queryString, String[] paramNames, Object[] values)
			throws DAOException;

	/**
	 * @param queryName
	 * @param value
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedQuery(String queryName, Object value) throws DAOException;

	/**
	 * @param queryName
	 * @param values
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	// public List findByNamedQuery(String queryName, Object[] values) throws
	// DAOException;
	/**
	 * @param queryName
	 * @param paramName
	 * @param value
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)
			throws DAOException;

	/**
	 * Execute a named query for persistent instances, binding a number of
	 * values to ":" named parameters in the query string. A named query is
	 * defined in a Hibernate mapping file
	 * 
	 * @param queryName
	 *            the name of a Hibernate query in a mapping file
	 * @param paramNames
	 *            the names of the parameters
	 * @param values
	 *            the values of the parameters
	 * @return a List containing 0 or more persistent instances
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values)
			throws DAOException;

	/**
	 * @param queryName
	 * @param valueBean
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByNamedQueryAndValueBean(String queryName, Object valueBean)
			throws DAOException;

	/**
	 * @param queryString
	 * @param valueBean
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List findByValueBean(String queryString, Object valueBean) throws DAOException;

	/**
	 * Return a Query String given a named query name.
	 * 
	 * @param queryName
	 * @return String - a Query string
	 * @throws DAOException
	 */
	public String getQueryString(String queryName) throws DAOException;

	/**
	 * @param queryName
	 * @param paramNames
	 * @param values
	 * @return
	 * @throws DAOException
	 */
	public Integer scroll(ScrollableCallback callback, QueryInfo query,
			QueryIncrementTracker tracker) throws DAOException;

	/**
	 * @throws org.springframework.dao.DAOException
	 */
	// public void flush() throws DAOException;
	/**
	 * @return
	 */
	public String[] getFilterNames();

	/**
	 * @return
	 */
	public FlushModeType getFlushMode();

	/**
	 * @return
	 */
	public SQLExceptionTranslator getJdbcExceptionTranslator();

	/**
	 * @return
	 */
	public String getQueryCacheRegion();

	/**
	 * @param proxy
	 * @throws org.springframework.dao.DAOException
	 */
	public void initialize(Object proxy) throws DAOException;

	/**
	 * @return
	 */
	public boolean isAllowCreate();

	/**
	 * @return
	 */
	public boolean isAlwaysUseNewSession();

	/**
	 * @return
	 */
	public boolean isCacheQueries();

	/**
	 * @return
	 */
	public boolean isCheckWriteOperations();

	/**
	 * @return
	 */
	public boolean isExposeNativeSession();

	/**
	 * @param queryString
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Iterator iterate(String queryString) throws DAOException;

	/**
	 * @param queryString
	 * @param value
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Iterator iterate(String queryString, Object value) throws DAOException;

	/**
	 * @param queryString
	 * @param values
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Iterator iterate(String queryString, Object[] values) throws DAOException;

	/**
	 * @param entityClass
	 * @param id
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Object load(Class entityClass, Serializable id) throws DAOException;

	/**
	 * @param entity
	 * @param id
	 * @throws org.springframework.dao.DAOException
	 */
	public void load(Object entity, Serializable id) throws DAOException;

	/**
	 * @param entityName
	 * @param id
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Object load(String entityName, Serializable id) throws DAOException;

	/**
	 * @param entityClass
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public List loadAll(Class entityClass) throws DAOException;

	/**
	 * @param entity
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	// public Object merge(Object entity) throws DAOException;
	/**
	 * @param entityName
	 * @param entity
	 * @return
	 * @throws org.springframework.dao.DAOException
	 */
	public Object merge(String entityName, Object entity) throws DAOException;

	/**
	 * @param entity
	 * @throws org.springframework.dao.DAOException
	 */
	// public void refresh(Object entity) throws DAOException;
	/**
	 * @param allowCreate
	 */
	public void setAllowCreate(boolean allowCreate);

	/**
	 * @param alwaysUseNewSession
	 */
	public void setAlwaysUseNewSession(boolean alwaysUseNewSession);

	/**
	 * @param beanFactory
	 * @throws org.springframework.beans.BeansException
	 */
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException;

	/**
	 * @param cacheQueries
	 */
	public void setCacheQueries(boolean cacheQueries);

	/**
	 * @param checkWriteOperations
	 */
	public void setCheckWriteOperations(boolean checkWriteOperations);

	/**
	 * @param entityInterceptorBeanName
	 */
	public void setEntityInterceptorBeanName(String entityInterceptorBeanName);

	/**
	 * @param exposeNativeSession
	 */
	public void setExposeNativeSession(boolean exposeNativeSession);

	/**
	 * @param filter
	 */
	public void setFilterName(String filter);

	/**
	 * @param filterNames
	 */

	public void setFilterNames(String[] filterNames);

	/**
	 * @param flushMode
	 */
	public void setFlushMode(FlushModeType flushModeType);

	/**
	 * @param constantName
	 */
	public void setFlushModeName(String constantName);

	/**
	 * @param jdbcExceptionTranslator
	 */
	public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator);

	/**
	 * @param queryCacheRegion
	 */
	public void setQueryCacheRegion(String queryCacheRegion);

	/**
	 * @param entity
	 * @throws org.springframework.dao.DAOException
	 */
	public Object update(Object entity) throws DAOException;

	public List find(String query, int firstRecord, int maxRecord, int fetchSize)
			throws DAOException;

	// public List find(String query, Object[] params, int firstRecord, int
	// maxRecord, int fetchSize) throws DAOException;
	public List find(String query, String[] paramNames, Object[] params, int firstRecord,
			int maxRecord, int fetchSize) throws DAOException;

	public List executeSQLQuery(QueryAndParams queryAndParams) throws DAOException;

	public int bulkUpdate(String query) throws DAOException;

	public int bulkUpdate(String query, Object[] parameters) throws DAOException;

	public void persist(Object arg0) throws DataAccessException;

	public void remove(Object arg0) throws DataAccessException;

	public Object merge(Object entity) throws DataAccessException;

	public List executeNamedSQLQuery(String queryName, Map<String, Object> params)
			throws DAOException;
}