package it.mice.voila.runtime.hibernate.interceptor;

import java.io.Serializable;
import java.util.Iterator;

import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.Interceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class CustomInterceptorDelegator extends EmptyInterceptor {
	
	private static final ThreadLocal<Interceptor> delegatorHolder = new ThreadLocal<Interceptor>() {
		protected Interceptor initialValue() {
			return defaultDelegateInterceptor;
		}
	};
	private static Interceptor defaultDelegateInterceptor;
	
	/**
	 * @return the defaultDelegateInterceptor
	 */
	public Interceptor getDefaultDelegateInterceptor() {
		return defaultDelegateInterceptor;
	}

	/**
	 * @param defaultDelegateInterceptor the defaultDelegateInterceptor to set
	 */
	public void setDefaultDelegateInterceptor(Interceptor defaultDelegateInterceptor) {
		this.defaultDelegateInterceptor = defaultDelegateInterceptor;
	}

	public static void setDelegate(Interceptor interceptor) {
		delegatorHolder.set(interceptor);
	}

	public static void cleanup() {
		delegatorHolder.set(defaultDelegateInterceptor);
	}
	
	/**
	 * @param entity
	 * @param id
	 * @param state
	 * @param propertyNames
	 * @param types
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onLoad(java.lang.Object,
	 *      java.io.Serializable, java.lang.Object[], java.lang.String[],
	 *      org.hibernate.type.Type[])
	 */
	public boolean onLoad(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) throws CallbackException {
		return delegatorHolder.get().onLoad(entity, id, state, propertyNames, types);
	}

	/**
	 * @param entity
	 * @param id
	 * @param currentState
	 * @param previousState
	 * @param propertyNames
	 * @param types
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onFlushDirty(java.lang.Object,
	 *      java.io.Serializable, java.lang.Object[], java.lang.Object[],
	 *      java.lang.String[], org.hibernate.type.Type[])
	 */
	public boolean onFlushDirty(Object entity, Serializable id,
			Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) throws CallbackException {
		return delegatorHolder.get().onFlushDirty(entity, id, currentState,
				previousState, propertyNames, types);
	}

	/**
	 * @param entity
	 * @param id
	 * @param state
	 * @param propertyNames
	 * @param types
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onSave(java.lang.Object,
	 *      java.io.Serializable, java.lang.Object[], java.lang.String[],
	 *      org.hibernate.type.Type[])
	 */
	public boolean onSave(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) throws CallbackException {
		return delegatorHolder.get().onSave(entity, id, state, propertyNames, types);
	}

	/**
	 * @param entity
	 * @param id
	 * @param state
	 * @param propertyNames
	 * @param types
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onDelete(java.lang.Object,
	 *      java.io.Serializable, java.lang.Object[], java.lang.String[],
	 *      org.hibernate.type.Type[])
	 */
	public void onDelete(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) throws CallbackException {
		delegatorHolder.get().onDelete(entity, id, state, propertyNames, types);
	}

	/**
	 * @param collection
	 * @param key
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onCollectionRecreate(java.lang.Object,
	 *      java.io.Serializable)
	 */
	public void onCollectionRecreate(Object collection, Serializable key)
			throws CallbackException {
		delegatorHolder.get().onCollectionRecreate(collection, key);
	}

	/**
	 * @param collection
	 * @param key
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onCollectionRemove(java.lang.Object,
	 *      java.io.Serializable)
	 */
	public void onCollectionRemove(Object collection, Serializable key)
			throws CallbackException {
		delegatorHolder.get().onCollectionRemove(collection, key);
	}

	/**
	 * @param collection
	 * @param key
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#onCollectionUpdate(java.lang.Object,
	 *      java.io.Serializable)
	 */
	public void onCollectionUpdate(Object collection, Serializable key)
			throws CallbackException {
		delegatorHolder.get().onCollectionUpdate(collection, key);
	}

	/**
	 * @param entities
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#preFlush(java.util.Iterator)
	 */
	public void preFlush(Iterator entities) throws CallbackException {
		delegatorHolder.get().preFlush(entities);
	}

	/**
	 * @param entities
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#postFlush(java.util.Iterator)
	 */
	public void postFlush(Iterator entities) throws CallbackException {
		delegatorHolder.get().postFlush(entities);
	}

	/**
	 * @param entity
	 * @return
	 * @see org.hibernate.Interceptor#isTransient(java.lang.Object)
	 */
	public Boolean isTransient(Object entity) {
		return delegatorHolder.get().isTransient(entity);
	}

	/**
	 * @param entity
	 * @param id
	 * @param currentState
	 * @param previousState
	 * @param propertyNames
	 * @param types
	 * @return
	 * @see org.hibernate.Interceptor#findDirty(java.lang.Object,
	 *      java.io.Serializable, java.lang.Object[], java.lang.Object[],
	 *      java.lang.String[], org.hibernate.type.Type[])
	 */
	public int[] findDirty(Object entity, Serializable id,
			Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) {
		return delegatorHolder.get().findDirty(entity, id, currentState, previousState,
				propertyNames, types);
	}

	/**
	 * @param entityName
	 * @param entityMode
	 * @param id
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#instantiate(java.lang.String,
	 *      org.hibernate.EntityMode, java.io.Serializable)
	 */
	public Object instantiate(String entityName, EntityMode entityMode,
			Serializable id) throws CallbackException {
		return delegatorHolder.get().instantiate(entityName, entityMode, id);
	}

	/**
	 * @param object
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#getEntityName(java.lang.Object)
	 */
	public String getEntityName(Object object) throws CallbackException {
		return delegatorHolder.get().getEntityName(object);
	}

	/**
	 * @param entityName
	 * @param id
	 * @return
	 * @throws CallbackException
	 * @see org.hibernate.Interceptor#getEntity(java.lang.String,
	 *      java.io.Serializable)
	 */
	public Object getEntity(String entityName, Serializable id)
			throws CallbackException {
		return delegatorHolder.get().getEntity(entityName, id);
	}

	/**
	 * @param tx
	 * @see org.hibernate.Interceptor#afterTransactionBegin(org.hibernate.Transaction)
	 */
	public void afterTransactionBegin(Transaction tx) {
		delegatorHolder.get().afterTransactionBegin(tx);
	}

	/**
	 * @param tx
	 * @see org.hibernate.Interceptor#beforeTransactionCompletion(org.hibernate.Transaction)
	 */
	public void beforeTransactionCompletion(Transaction tx) {
		delegatorHolder.get().beforeTransactionCompletion(tx);
	}

	/**
	 * @param tx
	 * @see org.hibernate.Interceptor#afterTransactionCompletion(org.hibernate.Transaction)
	 */
	public void afterTransactionCompletion(Transaction tx) {
		delegatorHolder.get().afterTransactionCompletion(tx);
	}

	/**
	 * @param sql
	 * @return
	 * @see org.hibernate.Interceptor#onPrepareStatement(java.lang.String)
	 */
	public String onPrepareStatement(String sql) {
		return delegatorHolder.get().onPrepareStatement(sql);
	}

}
