package es.ejie.frmk.presentacion.operacion.paso;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.RedirectingActionForward;

import es.ejie.frmk.control.apilamiento.Q70GestorDeApilamiento;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.presentacion.base.Q70PasosOPMapping;
import es.ejie.frmk.presentacion.operacion.Q70OperacionDePresentacionException;


/**
 * Esta clase redirige el flujo hacia un paso de otra Operación de Presentación, involucrado en un apilamiento/desapilamiento remoto de contextos.
 * <p>
 * Se trata de una extensión de la clase <code>Q70ActionRemoto</code>, por lo que deberá sobrecargar el método
 * <code>process()</code> que implemente el mecanismo de redirección. 
 */

public class Q70ActionApilamientoRemoto extends Q70ActionRemoto {

	/**
	 * Constante que indica el componente al que pertenece la clase. Es
	 * necesario para el uso del log de trazas.
	 */
	private static final String COMPONENTE = "OPERACION_PRESENTACION";
	
	/**
	 * Instancia del log de trazas
	 */
	private static Q70Traza tr = Q70Traza.getSingleton();

	/**
	 * El método reencamina al paso remoto indicado, enviando como parámetro extra en la URL el identificador HASH del contexto de la OP apilada serializado en BBDD.
	 * <p>
	 * Para ello, recoge las propiedades esperadas de configuración del paso, las válida, recoge el HASH , lo concatena a la URL como un parámetro más, y devuelve 
	 * la redirección al paso remoto indicado.
	 * 
	 * @see es.ejie.frmk.presentacion.operacion.paso.Q70ActionRemoto#procces(es.ejie.frmk.presentacion.base.Q70PasosOPMapping, java.lang.String, javax.servlet.http.HttpServletRequest, org.apache.struts.action.ActionForm)
	 */
	protected RedirectingActionForward procces(Q70PasosOPMapping mapping, String pathRemoto, HttpServletRequest request, ActionForm form) throws Q70OperacionDePresentacionException
	{
		RedirectingActionForward retVal = null;
		
		try
		{
			//Validación para ver si la declaración del action es correcta
			if ((null==mapping.getCallOpRemota()) || !(mapping.getCallOpRemota().equalsIgnoreCase("init")))
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Falta la propiedad <set-property property='callOpRemota' value='init'/> en el fichero XML de configuración de la operación de presentación.");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"procces","Falta la propiedad <set-property property='callOpRemota' value='init'/> en el fichero XML de configuración de la operación de presentación.",null);
			}
			if ((null==mapping.getSubOpRetPath()) || (0==mapping.getSubOpRetPath().trim().length()))
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Falta la propiedad <set-property property='subOpRetOPath' value='URL'/> en el fichero XML de configuración de la operación de presentación.");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"procces", "Falta la propiedad <set-property property='subOpRetOPath' value='URL'/> en el fichero XML de configuración de la operación de presentación.",null);
			}
			
			//Pedimos al GestordeApilamiento el hash de la estructura de
			//dialogo generada para el apilamiento remoto.
			String hash = Q70GestorDeApilamiento.getSingleton().getStoredHash(request, mapping);
			if (null == hash)
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Error al recuperar el hash del GestorDeApilamiento.");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"procces","Error al recuperar el hash del GestorDeApilamiento.",null);
			}
			
			//Hacer una redireccion tipo RedirectingActionForward
			// a la url destino con el hash concatenado como parametro.
			String urlRemota = pathRemoto.indexOf("?") == -1 ? pathRemoto + "?" : pathRemoto + "&";
			urlRemota += Q70GestorDeApilamiento.getSingleton().getNombreParametroUrlRemota(mapping) + hash;
			
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Forward del Q70ActionApilamientoRemoto = "+urlRemota);
			}
			retVal = new RedirectingActionForward(urlRemota);
		}
		catch(Exception e)
		{
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Excepción recogida por Action de Operacion de Presentacion que invoca a una suboperación remota.");
			}
			throw new Q70OperacionDePresentacionException (this.getClass().toString(),"procces","Excepción recogida por Action de Operacion de Presentacion que invoca a una suboperación remota.",e);
		}
		
		return retVal; 
	}

}
