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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.presentacion.base.Q70Constantes;
import es.ejie.frmk.presentacion.operacion.Q70OperacionDePresentacionException;
import es.ejie.frmk.presentacion.sesiondatos.Q70ContextoEJIE;

/**
 * Esta clase implementa la funcionalidad de paso de Operación de Presentación cuando éste no necesita 
 * acceder a capa de negocio.
 * <p>
 * La clase <b>deberá ser extendida por la aplicación</b>, de tal modo que:
 * <UL>  
 * <li>sobrecargue un método abstracto (<code>processOP</code>) que permite tener acceso y posibilidad de manipulación de los contextos.</li>
 * <li>sobrecargue un método abstracto (<code>processForward</code>) para la decisión de encaminamiento posterior.</li>
 * </UL>
 * @version 1.0
 * Fecha: 09-ene-04
 */
public abstract class Q70ActionPasoOP extends Action {

	/**
	 * Constante que indica el componente al que pertenece dicha 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();

	/**
	 * Método que aporta funcionalidad común a todas los pasos de Operación de Presentación.
	 * <p>
	 * El método invoca métodos que serán implementados por los pasos que extiendan de esta clase.
	 * La funcionalidad que presenta el método es la siguiente:
	 * <UL>
	 * <li>Recupera los contextos</li>
	 * <li>Invoca método <code>processOP</code> aportado por el paso</li>
	 * <li>Invoca método <code>forwardOP</code> aportado por el paso</li>
	 * <li>Genera la estructura de errores y la deposita en la request</li>
	 * </UL>
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		ActionErrors errors = null;
		ActionForward forward = null;

		Q70ContextoEJIE contexto = null;
		
		try {
			errors = new ActionErrors();
			//Recuperamos el contexto
			contexto = (Q70ContextoEJIE)request.getSession().getAttribute(Q70Constantes.CONTEXT);
			
			processOP(contexto,errors,mapping,form,request,response);
			
			//Calculando el forward
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Llamando al método processForward de la clase Q70ActionPasoOP...");
			}
			forward = processForward(contexto,errors,mapping,form,request,response);
			
			if (tr.isTraceActive())
			{
				if(forward==null)
					tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Resultado del método processForward -> Forward: NULL");
				else
					tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Resultado del método processForward -> Forward: "+forward.getPath());
			}
			
			// If a message is required, save the specified key(s)
			// into the request for use by the <struts:errors> tag.
			if (!errors.isEmpty())
			{
				saveErrors(request, errors);
			}
			
			// Finish with
			return (forward);
		} catch (Exception e) {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Excepción en Action de Operacion de Presentacion");
			}
			throw new Q70OperacionDePresentacionException (this.getClass().toString(),"execute","Excepción recogida por Action de paso entre operaciones de presentación.",e);
		}
	}
	
	/**
	 * Este método debe ser implementado por las clases que extiendan de <code>Q70ActionPasoOP</code>.
	 * <p>
	 * Sirve para encapsular el tratamiento de presentación que necesite la aplicación. 
	 * Por ejemplo, obtener atributos de contextos, realizar cálculos y depositarlos sobre atributos
	 * del contexto.
	 * @param contexto Estructura de contexto genérica. 
	 * @param errores Lista de errores.
	 * @param mapping Configuración de los pasos de una operacion de presentacion.
	 * @param form Bean de Formulario de la página anterior.
	 * @param request Petición a atender
	 * @param response Respuesta a generar
	 * @throws Exception
	 */
	protected abstract void processOP(Q70ContextoEJIE contexto, ActionErrors errores, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception;
	
	/**
	 * Este método debe ser implementado por las clases que extiendan de <code>Q70ActionPasoOP</code>.
	 * <p>
	 * Sirve para encapsular la toma de decisión de enrutamiento hacia la siguiente paso de OP.
	 *  
	 * @param contexto Estructura de contexto genérica. 
	 * @param errores Lista de errores.
	 * @param mapping Configuración de los pasos de una operacion de presentacion.
	 * @param form Bean de Formulario de la página anterior.
	 * @param request Petición a atender
	 * @param response Respuesta a generar
	 * @throws Exception
	 */
	protected abstract ActionForward processForward(Q70ContextoEJIE contexto, ActionErrors errores, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
