package es.ejie.frmk.infraestructura.poolCache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;

import es.ejie.frmk.Q70Factoria;
import es.ejie.frmk.control.excepciones.Q70FrameworkException;
import es.ejie.frmk.infraestructura.logs.incidencias.Q70LogIncidenciasInterface;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70TrazaInterface;
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 abstract class Q70GestorCacheBase implements Q70GestorCacheServidorInterface {
	
	private Q70BeanConfiguracionCaches configuracionCaches = null;
	private Map caches = null;
	private Map cachesPorDefecto = null;
	private Timer planificador = null;
	
	private static long tIntervalo = 0;
	private static int tamanoMax = 0;
	private static long memoriaMax = 0;
	
	private Q70Lock lock = null;
	
	/**
	 * @return Returns the lock.
	 */
	protected Q70Lock getLock() {
		return lock;
	}
	
	/**
	 * @param lock The lock to set.
	 */
	protected void setLock(Q70Lock lock) {
		this.lock = lock;
	}

	/**
	 * Añade un objeto a la cache propia de la aplicación. Si ya existe en la
	 * cache un objeto con la misma clave pero con distinto valor, entonces
	 * devuelve el objeto anterior y añade el nuevo (lo sobreescribe). En otro
	 * caso, devuelve null.
	 * @param clave Key del objeto a añadir a la cache.
	 * @param Objeto a añadir a la cache.
	 * @return un objeto, si ya existía un objeto en la caché y su valor era
	 *         diferente al que se va a añadir. null, en otro caso.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheInterface#addElement(java.lang.Object, java.lang.Object)
	 */
	public Object addElement(Object clave, Object objeto) {
		return addElement(Q70Constantes.CACHE_APLICACION, clave, objeto);
	}
	
	/**
	 * Añade un objeto a la cache. Si ya existe en la cache un objeto con la
	 * misma clave pero con distinto valor, entonces devuelve el objeto anterior
	 * y añade el nuevo (lo sobreescribe). En otro caso, devuelve null.
	 * @param idCache Identificativo de la caché.
	 * @param clave Key del objeto a añadir a la cache.
	 * @param Objeto a añadir a la cache.
	 * @return un objeto, si ya existía un objeto en la caché y su valor era
	 *         diferente al que se va a añadir. null, en otro caso.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#addElement(java.lang.String, java.lang.Object, java.lang.Object)
	 */
	public Object addElement(String idCache, Object clave, Object objeto) {
		getLock().entradaZonaCritica();		
		try {
			if (null == caches) return null;
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "Almacenando en la cache '"+idCache+"' el elemento con clave '"+clave +"'...");
			}
			Q70LRUMap cacheMap = (Q70LRUMap)getCache(idCache);
			if (null==cacheMap){
				return null;
			}
			boolean cachePropiaAplicacion = Q70Constantes.CACHE_APLICACION.equalsIgnoreCase(idCache);
			Q70ElementoCache cobj = (Q70ElementoCache) cacheMap.get(clave);
			if (cobj == null) {
				if (cachePropiaAplicacion) {
					cacheMap.putConRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto), memoriaMax);
				} else {
					cacheMap.putSinRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto));
				}
				return null;
			} else {
				if (traza.isTraceActive()){
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "El elemento con clave: "+clave +" ya estaba almacenado en la cache '"+idCache+"'.");
				}
				Object obj = cobj.getCachedData();
				if (obj == null) {
					if (objeto == null) {
						//Evita crear un nuevo objeto Q70ElementoCache innecesariamente
						cobj.enCacheDesde = cobj.ultimoAcceso = System.currentTimeMillis();
						return null;
					} else {
						if (cachePropiaAplicacion) {
							cacheMap.putConRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto), memoriaMax);
						} else {
							cacheMap.putSinRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto));
						}
						return null;
					}
				} else if (obj.equals(objeto)) {
					//Evita crear un nuevo objeto Q70ElementoCache innecesariamente (es el mismo)
					cobj.enCacheDesde = cobj.ultimoAcceso = System.currentTimeMillis();
					return null;
				} else {
					if (cachePropiaAplicacion) {
						cacheMap.putConRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto), memoriaMax);
					} else {
						cacheMap.putSinRestriccionMemoriaMax(clave, new Q70ElementoCache(objeto));
					}
					return obj;
				}
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}	

	/**
	 * Obtiene el objeto de la cache propia de la aplicacion cuya clave se pasa
	 * como parámetro. En caso de que no se encuentre en la cache, devuelve null.
	 * @param clave Key del objeto a recuperar de la cache.
	 * @return un objeto si se encuentra en la cache. null en caso contario.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheInterface#getElement(java.lang.Object)
	 */
	public Object getElement(Object clave){
		return getElement(Q70Constantes.CACHE_APLICACION, clave);
	}
	
	/**
	 * Obtiene el objeto cuya clave se pasa como parámetro. En caso de que no se
	 * encuentre en la cache, devuelve null.
	 * @param cache identificativo de la caché.
	 * @param clave Key del objeto a recuperar de la cache.
	 * @return un objeto si se encuentra en la cache. null en caso contario.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getElement(java.lang.String, java.lang.Object)
	 */
	public Object getElement(String idCache, Object clave) {
		getLock().entradaZonaCritica();
		try {
			if (null == caches) return null;
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			Map cacheMap = getCache(idCache);
			if (null==cacheMap){
				return null;
			}
			Q70ElementoCache cobj = (Q70ElementoCache) cacheMap.get(clave);
				
			if (cobj == null) {
				if (traza.isTraceActive()){
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "El elemento con clave: '"+clave +"' no está almacenado en la cache '"+idCache+"'.");
				}
				return null;
			} else {
				if (traza.isTraceActive()){
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "Se ha recuperado de la cache '"+idCache+"' el elemento con clave: '"+clave +"'.");
				}
				return cobj.getCachedData();
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Obtiene un ArrayList con el nombre de las clases de los objetos cacheados.
	 * @param idCache Identificativo de la caché.
	 * @return ArrayList con el nombre de las clases de los objetos cacheados.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getCachedObjects(java.lang.String)
	 */
	public ArrayList getCachedObjects(String idCache){
		getLock().entradaZonaCritica();
		try {
			Map cacheMap = getCache(idCache);
			if (null==cacheMap){
				return null;
			}
			ArrayList al = new ArrayList();
			Iterator it = cacheMap.entrySet().iterator();
			while (it.hasNext()){
				Map.Entry e = (Map.Entry)it.next();
				Q70ElementoCache cacheObj = (Q70ElementoCache) e.getValue();
				al.add(cacheObj.cachedData.getClass().getName());
			}
			return al;
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}

	/**
	 * Se elimina de la caché el objeto cuyo nombre referente se pasa como
	 * parámetro.
	 * @param idCache Identificativo de la caché.
	 * @param nombre Key del objeto cacheado a liberar.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#freeCachedObject(java.lang.String, java.lang.String)
	 */
	public void freeCachedObject(String idCache, String nombre){
		getLock().entradaZonaCritica();
		try {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			Map cacheMap = getCache(idCache);
			if (null!=cacheMap){
				cacheMap.remove(nombre);
				if (traza.isTraceActive()){
					traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "Se ha eliminado de la caché '"+idCache+"' el elemento con clave '"+nombre+"'.");
				}
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Vacía la caché.
	 * @param cache Identificativo de la caché.
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#freeCached(java.lang.String)
	 */
	public void freeCached(String idCache){
		getLock().entradaZonaCritica();
		try {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "Se ha realizado una petición de borrado de la caché '"+idCache+"'.");
			}
			Map cacheMap = getCache(idCache);
			if (null!=cacheMap){
				cacheMap.clear();
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Obtiene el número de elementos en la caché.
	 * @param cache Identificativo de la caché.
	 * @return int Número de elementos en la caché. 
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getCacheSize(java.lang.String)
	 */
	public int getCacheSize(String idCache){
		getLock().entradaZonaCritica();
		try {
			Map cacheMap = getCache(idCache);
			if (null==cacheMap){
				return 0;
			}
			return getCache(idCache).size();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * @see es.ejie.frmk.infraestructura.utilidades.configurador.Q70Administrable#activar()
	 */
	public void activar() {
		getLock().activar();
	}

	/**
	 * @see es.ejie.frmk.infraestructura.utilidades.configurador.Q70Administrable#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);
		}
		//Inicializa el planificador de limpieza de cachés
		if (planificador != null) planificador.cancel();
		planificador = new Timer(true);
		// Inicializa la lista de cachés 
		caches = new HashMap();
				
		// createCache por cada caché que no sea por defecto
		createCaches();
	}

	/**
	 * Termina el objeto <code>Timer</code>, desechando las tareas planificadas
	 * de limpieza. Elimina las caches propias del componente y elimina la
	 * configruración de todas las caches. Finalmente elimina la referencia a
	 * la instancia del componente.
	 * @see es.ejie.frmk.infraestructura.utilidades.configurador.Q70Administrable#liberar()
	 */
	public void liberar() throws Q70FrameworkException
	{
		if (!getLock().isBloqueo()) {
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"liberar","Se ha entrado por un método que necesita que el bloqueo del componente esté activo.",null);
		}
		if (planificador != null){
			planificador.cancel(); 
			planificador = null;
		}
		caches = null;
		configuracionCaches = null;
		//doDestruir();
	}

	/**
	 * Método que debe sobreescribir la clase que hereda principalmente para
	 * eliminar la referencia a la instancia del componente. 
	 */
	protected abstract void doDestruir();

	/**
	 * @see es.ejie.frmk.infraestructura.utilidades.configurador.Q70Administrable#suspender()
	 */
	public void suspender() throws Q70FrameworkException{
		try {
			getLock().suspender();
		} catch (Q70FrameworkException e) {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha producido un error en el método suspender de la clase Q70GestorCacheBase");
			}
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"suspender","Se ha producido un error en el método suspender.",e);
		}
	}

	public void destruir() throws Q70FrameworkException{
		try {
			liberar();
			doDestruir();
			activar();
		} catch (Throwable e) {
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.ERROR, "Se ha producido un error en el método destruir de la clase Q70GestorCacheBase");
			}
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"destruir","Se ha producido un error en el método destruir.",e);
		}
	}

	/**
	 * Método que recupera la configuración de todas las cachés 
	 * @return Q70BeanConfiguracionCaches configuracion caches
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getConfiguracion()
	 */
	public Q70BeanConfiguracionCaches getConfiguracion() {
		return configuracionCaches;
	}

	/**
	 * Método que establece la configuración de todas las cachés 
	 * @param Q70BeanConfiguracionCaches configuracion caches
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#setConfiguracion(es.ejie.frmk.infraestructura.poolCache.Q70BeanConfiguracionCaches)
	 */
	public void setConfiguracion(Q70BeanConfiguracionCaches configuracionCaches) throws Q70FrameworkException{
		if (!getLock().isBloqueo()) {
			throw new Q70FrameworkException(Q70Constantes.ID_COMPONENTE,this.getClass().toString(),"setConfiguracion","Se ha entrado por un método que necesita que el bloqueo del componente esté activo.",null);
		}
		this.configuracionCaches = configuracionCaches;
	}
	
	/**
	 * Méteodo que retorna una caché pasándole un identificativo.
	 * @param idCache Identificativo de la cache a crear.
	 * @return Map Mapa de Q70ElementoCache alamacenados en la cache.
	 */
	protected Map getCache(String idCache) {
		Q70Cache cache = (Q70Cache)caches.get(idCache);
		if (null==cache){
			Q70TrazaInterface traza = Q70Factoria.getTraza();
			if (traza.isTraceActive()){
				traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "No existe o no se ha creado la cache '"+idCache+"'");
			}
			return null;
		}
		return ((Q70Cache)caches.get(idCache)).getCacheMap();
	}
	
	/**
	 * Este método crea la cache y la planifica para su limpieza teniendo en
	 * cuenta el tamanoCache, tamanoMax, tAcceso, tVida, tIntervalo.
	 * @param idCache Identificativo de la cache a crear.
	 * @param Q70BeanConfiguracionCache Configuracion de la cache.
	 * @return Q70Cache Cache creada.
	 */
	protected Q70Cache createCache(String idCache, Q70BeanConfiguracionCache configuracionCache) {
		Q70TrazaInterface traza = Q70Factoria.getTraza();
		Q70LogIncidenciasInterface logInc = Q70Factoria.getLogIncidencias();
		
		Q70Cache cache = null;
		int tamanoCache = configuracionCache.getTamano().intValue();
		Long tAcceso = configuracionCache.getTAccess();
		Long tVida = configuracionCache.getTVida();
		
		if (tamanoCache > tamanoMax) {
			tamanoCache = tamanoMax;
			if (logInc.isEnabled()){
				logInc.log(new Exception("El tamaño de la cache '"+idCache+"' supera el máximo permitido."), Q70Constantes.ID_COMPONENTE, Q70TraceLevel.WARN.toString());
			}
		}		
		
		if (planificador != null) {
			cache = new Q70Cache(new Q70LRUMap(tamanoCache), tAcceso, tVida);
			caches.put(idCache, cache);
			planificador.schedule(cache, 0, tIntervalo);
		}
		
		if (traza.isTraceActive()){
			traza.trace(Q70Constantes.ID_COMPONENTE, Q70TraceLevel.DEBUG, "Se ha creado y planificado la cache '"+idCache+"'. Configuración= tamaño:"+tamanoCache+"; tAcceso:"+tAcceso+"; tVida:"+tVida+"; grupo:"+configuracionCache.getGrupoCache()+".");
		}
		
		return cache;
	}
	
	/**
	 * Este método crea las caches porpias del componente.
	 */
	private void createCaches() {
		createCaches(configuracionCaches, Q70Constantes.CACHES);
	}
	
	/**
	 * Este método crea las caches por defecto pasándole la configuración de
	 * todas las caches.
	 * @param Q70BeanConfiguracionCaches configuracion de todas las caches.
	 * @return Map HashMap con las diferentes caches por defecto.
	 */
	protected Map createCachesPorDefecto(Q70BeanConfiguracionCaches configuracionCaches) {
		return createCaches(configuracionCaches, Q70Constantes.CACHES_APLICACION_POR_DEFECTO);
	}
		
	/**
	 * Este método crea las caches pertenecientes a un determinado grupo
	 * pasándole la configuración de todas las caches.
	 * @param Q70BeanConfiguracionCaches configuracion de todas las caches
	 * @param String grupo al que pertenecen las caches a crear.
	 * @return Map HashMap con las diferentes caches pertenecientes a dicho grupo
	 */
	private Map createCaches(Q70BeanConfiguracionCaches configuracionCaches, String grupoCaches) {
		Map retornoCaches = new HashMap();
		
		Q70BeanConfiguracionCache configuracionCacheAux = null;
		Iterator it = configuracionCaches.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			if (e.getValue() instanceof Q70BeanConfiguracionCache) {
				configuracionCacheAux = (Q70BeanConfiguracionCache) e.getValue();
				if (grupoCaches.equals(configuracionCacheAux.getGrupoCache())) {
					retornoCaches.put(e.getKey(),createCache((String)e.getKey(), configuracionCacheAux));
				}
			}
		}
		return retornoCaches;
	}

	/**
	 * Método que recupera la configuración de todas las cachés por defecto.
	 * @param configuracionCachesAplicacion
	 * @return Q70BeanConfiguracionCaches configuracion caches por defecto
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getConfiguracionCachesPorDefecto(java.util.Map)
	 */
	public Q70BeanConfiguracionCaches getConfiguracionCachesPorDefecto(Map configuracionCachesAplicacion) {
		Q70BeanConfiguracionCaches configuracionCachesPorDefecto = new Q70BeanConfiguracionCaches();
		
		Q70BeanConfiguracionCache configuracionCacheAux = null;
		Iterator it = getConfiguracion().entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			if (e.getValue() instanceof Q70BeanConfiguracionCache) {
				configuracionCacheAux = (Q70BeanConfiguracionCache) e.getValue();
				if (Q70Constantes.CACHES_APLICACION_POR_DEFECTO.equals(configuracionCacheAux.getGrupoCache())) {
					if (configuracionCachesAplicacion.get(e.getKey()) == null) {
						configuracionCachesPorDefecto.putConfiguracionCache((String)e.getKey(), configuracionCacheAux);
					}
				}
			}
		}
		return configuracionCachesPorDefecto;
	}
	
	/**
	 * Método que añade una referencia de todas las caches por defecto de una
	 * aplicación. Este método es para que la clase Q70GestorCacheServidor
	 * guarde una referencia a dichas caches para hacer posible la
	 * reconfiguración de las caches por defecto en caliente.
	 * @param Q70GestorCacheInterface referencia al Q70GestorCacheAplicacion
	 * @param Map HashMap con las diferentes caches por defecto de la aplicacion
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#addCachesPorDefecto(es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheInterface, java.util.Map)
	 */
	public void addCachesPorDefecto(Q70GestorCacheInterface gestorCacheAplicacion, Map cachesPorDefectoAplicacion) {
		getLock().entradaZonaCritica();		
		try {
			this.getCachesPorDefecto().put(gestorCacheAplicacion, cachesPorDefectoAplicacion);
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Método que elimina una referencia de todas las caches por defecto de una
	 * aplicación. Este método es para que la clase Q70GestorCacheServidor
	 * elimine una referencia a dichas caches para hacer posible la
	 * reconfiguración de las caches por defecto en caliente.
	 * @param Q70GestorCacheInterface referencia al Q70GestorCacheAplicacion
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#removeCachesPorDefecto(es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheInterface)
	 */
	public void removeCachesPorDefecto(Q70GestorCacheInterface gestorCacheAplicacion) {
		getLock().entradaZonaCritica();
		try {
			cachesPorDefecto.remove(gestorCacheAplicacion);
		} catch (RuntimeException e) {
			throw e;
		} finally {
			getLock().salidaZonaCritica();
		}
	}
	
	/**
	 * Método que retorna una referencia de todas las caches por defecto de una
	 * aplicación. Este método es para que la clase Q70GestorCacheServidor
	 * retorne una referencia a dichas caches para hacer posible la
	 * reconfiguración de las caches por defecto en caliente.
	 * @param Q70GestorCacheInterface referencia al Q70GestorCacheAplicacion
	 * @return Map HashMap con las diferentes caches por defecto de la aplicacion
	 * @see es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheServidorInterface#getCachesPorDefecto(es.ejie.frmk.infraestructura.poolCache.Q70GestorCacheInterface)
	 */
	protected Map getCachesPorDefecto(Q70GestorCacheInterface gestorCacheAplicacion) {
		return (Map)cachesPorDefecto.get(gestorCacheAplicacion);
	}

	/**
	 * @return Returns the memoriaMax.
	 */
	protected long getMemoriaMax() {
		return memoriaMax;
	}

	/**
	 * @param memoriaMax The memoriaMax to set.
	 */
	protected void setMemoriaMax(long memoriaMax) {
		Q70GestorCacheBase.memoriaMax = memoriaMax;
	}

	/**
	 * @return Returns the tamanoMax.
	 */
	protected int getTamanoMax() {
		return tamanoMax;
	}

	/**
	 * @param tamanoMax The tamanoMax to set.
	 */
	protected void setTamanoMax(int tamanoMax) {
		Q70GestorCacheBase.tamanoMax = tamanoMax;
	}

	/**
	 * @return Returns the tIntervalo.
	 */
	protected long getTIntervalo() {
		return tIntervalo;
	}

	/**
	 * @param intervalo The tIntervalo to set.
	 */
	protected void setTIntervalo(long intervalo) {
		tIntervalo = intervalo;
	}

	/**
	 * @return Returns the caches.
	 */
	public Map getCaches() {
		// TODO Rehacer para dejar el método protected???
		return caches;
	}

	/**
	 * @param caches The caches to set.
	 */
	protected void setCaches(Map caches) {
		this.caches = caches;
	}

	/**
	 * @return Returns the cachesPorDefecto.
	 */
	protected Map getCachesPorDefecto() {
		return cachesPorDefecto;
	}

	/**
	 * @param cachesPorDefecto The cachesPorDefecto to set.
	 */
	protected void setCachesPorDefecto(Map cachesPorDefecto) {
		this.cachesPorDefecto = cachesPorDefecto;
	}
}