package eu.dnetlib.enabling.database.objects;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import eu.dnetlib.enabling.database.rmi.DatabaseException;
import eu.dnetlib.enabling.database.utils.DatabaseUtils;

public abstract class AbstractDAO<T> extends HibernateDaoSupport {
	
	protected DatabaseUtils dbUtils;
	
	protected String tableName;
	private Class<T> clazz;

	private static final Log log = LogFactory.getLog(AbstractDAO.class); // NOPMD by marko on 11/24/08 5:02 PM
	
	protected AbstractDAO(String tableName, Class<T> clazz) {
		this.tableName = tableName;
		this.clazz = clazz;
	}
		
	@Transactional(readOnly = true)
	public int count() {
		return getAll().size();		
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<T> getAll() {
		return getHibernateTemplate().find("from " + tableName);
	}
	
	@Transactional
	public void delete(Serializable primaryKey) throws DatabaseException {
		log.info("Deleting " + primaryKey);
		delete(getElement(primaryKey));
	}
		
	public void delete(T element) throws DatabaseException {
		// NB: The related elements are automatically deleted  
		getHibernateTemplate().delete(element);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public T getElement(Serializable primaryKey) {
		log.info("Loading " + clazz + ", key: " + primaryKey);
		return (T) getHibernateTemplate().get(clazz, primaryKey);
	}

	public void insert(T elem) throws DatabaseException {
		getHibernateTemplate().saveOrUpdate(elem);
	}

	@Required
	public void setDbUtils(DatabaseUtils dbUtils) {
		this.dbUtils = dbUtils;
	}

}
