/*
 * Creado el 21-feb-06
 */
package es.ejie.frmk.infraestructura.poolCache;

import java.util.Map;

import es.ejie.frmk.Q70FactoriaConstantes;
import es.ejie.frmk.control.excepciones.Q70FrameworkException;
import es.ejie.frmk.infraestructura.utilidades.concurrencia.Q70Lock;


/**
 * La clase permite guardar instancias de objetos en memoria.
 * <p>
 * La persistencia en memoria viene en base a las especificaciones dadas por configuración:
 * <ul>
 * <li>Tiempo de vida: tiempo máximo de los objetos en caché para que el servicio de limpieza los elimine.</li>
 * <li>Tiempo de inactividad: tiempo transcurrido sin ser utilizado un objeto para que el servicio de limpieza lo elimine.</li>
 * <li>Tamaño: número de objetos que puede contener la caché antes de aplicar el algoritmo LRU de gestión de caché.</li>
 * <li>Tamaño Maximo: Máximo número de objetos que puede contener cualquier caché.</li>
 * <li>Memoria Maxima: Máximo número bytes que puede ocupar la caché propia de la aplicación.</li>
 * </ul>
 * Cuando un componente o una aplicación quiera guardar en caché un objeto, no tiene más que invocar al método <code>addElement</code>: el objeto es almacenado con la clave dada y el timestamp de ese instante, con objeto de controlar el tiempo de vida del mismo.
 * Cuando se quiera recuperar el objeto basta con invocar al método <code>getElement</code> indicando la clave con la que se almacenó el objeto. En ese momento, también se actualiza el timestamp correspondiente al instante de última utilización con objeto de controlar el tiempo de inactividad.
 * <p>
 * El Gestor de Cachés dispone de una tarea que actúa como servicio de limpieza eliminando de la caché todos los objetos que han cumplido su tiempo de vida o el tiempo de inactividad.
 * Del mismo modo, cuando el número de objetos en caché alcanza el tamaño máximo especificado en la configuración, los objetos serán eliminados de caché en función de un algoritmo LRU.
 * 
 * @version 2.0 Fecha: 21-feb-06
 */
public class Q70GestorCacheAplicacion extends Q70GestorCacheBase {	
	private static Q70GestorCacheAplicacion instancia = null;
	
	/** Referencia al componente de servidor para poder pedir la configuración de las cachés por defecto. **/
	private static Q70GestorCacheServidorInterface gestorCacheServidor = Q70GestorCacheServidor.getSingleton();

	private Q70GestorCacheAplicacion() {
		setLock(new Q70Lock(Q70Constantes.ID_COMPONENTE));
	}
	
	/** 
	 * Método estático que devuelve la única instancia de la clase <code>Q70GestorCacheAplicacion</code>.
	 * @return <code>instancia</code> Instancia de Q70GestorCacheAplicacion
	 */
	public static Q70GestorCacheAplicacion getSingleton() {
		if (instancia == null) {
			instancia = new Q70GestorCacheAplicacion();
		}
		return instancia;
	}

	/**
	 * Inicializa las cachés propias del componente.
	 * Pide la configuración de las caches por defecto al componente de servidor.
	 * Crea las caches por defecto.
	 * Guarda una referencia de sus caches por defecto en el servidor. 
	 * @throws Q70FrameworkException 
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheBase#inicializar()
	 */
	public void inicializar() throws Q70FrameworkException {
		if (!getLock().isBloqueo()) {
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"inicializar","Se ha entrado por un método que necesita que el bloqueo del componente esté activo.",null);
		}
		//Inicializamos la caché propia de la aplicación
		super.inicializar();
		
		//Inicializamos la cachés por defecto
		Q70BeanConfiguracionCaches configuracionCachesPorDefecto = gestorCacheServidor.getConfiguracionCachesPorDefecto(this.getConfiguracion());
		Map cachesPorDefecto = createCachesPorDefecto(configuracionCachesPorDefecto);
		gestorCacheServidor.addCachesPorDefecto(this,cachesPorDefecto);
	}
	
	/**
	 * Libera las cachés por defecto del servidor. Libera el componente.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheBase#liberar()
	 */
	public void liberar() throws Q70FrameworkException
	{
		if (!getLock().isBloqueo()) {
			throw new Q70FrameworkException(Q70FactoriaConstantes.ID_GESTOR_LOGS,this.getClass().toString(),"liberar","Se ha entrado por un método que necesita que el bloqueo del componente esté activo.",null);
		}
		gestorCacheServidor.removeCachesPorDefecto(this);
		super.liberar();
	}

	/**
	 * Elimina la referencia a la instancia del componente.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheBase#doDestruir()
	 */
	protected void doDestruir() {
		instancia = null;
	}
}
