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.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import es.ejie.frmk.infraestructura.internacionalizacion.Q70GestorMensajesi18n;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.listeners.base.Q70ListenerUtils;
import es.ejie.frmk.presentacion.base.Q70PasosOPMapping;
import es.ejie.frmk.presentacion.operacion.Q70OperacionDePresentacionException;

public class Q70ActionLookupDispatchOP extends Action {
	/**
	 * 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 obtiene el valor de un parametro de la request y devuelve un
	 * <code>ActionForward</code> hacia un paso identificado con el valor de
	 * dicho atributo.
	 * <p>
	 * Para ello recoge el valor <code>parameter</code> del fichero de
	 * configuración de la OP, acude a la <code>request</code> y consulta el
	 * valor del parametro identificado con el valor anterior. A continuación,
	 * mediante el Gestor de Mensajes e Internacionalización traduce los
	 * atributos <code>name</code> de los forwards definidos y devuelve el
	 * <code>ActionForward</code> cuya traducción coincida con el valor del
	 * parámetro consultado en la <code>request</code>.
	 * </p>
	 * 
	 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		ActionForward forward = null;
		String parameter = null;
		String parameterValue = null;
		String i18nKey = null;
		String idioma = null;
		String forwardName = null;
		
		try {
			// Identify the request parameter containing the method name
			parameter = mapping.getParameter();
			if (null == parameter) {
				if (tr.isTraceActive()) {
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR,
							"Q70ActionLookupDispatchOP: Falta el atributo parameter del Q70ActionLookupDispatchOP en el fichero de configuración de Struts correspondiente.");
				}
				throw new Q70OperacionDePresentacionException(this.getClass().toString(), "execute",
						"Falta el atributo parameter del Q70ActionLookupDispatchOP en el fichero de configuración de Struts correspondiente.", null);
			}
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Atributo 'parameter' para Q70ActionLookupDispatchOP= "+parameter);
			}
			
			// Identifica el ambito de mensajes e internacionalizacion para el ActionMapping 
			i18nKey = ((Q70PasosOPMapping)mapping).getI18nKey();
			if (null == i18nKey)
			{
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Falta ambito de mensajes e internacionalización del Q70ActionLookupDispatchOP. (property i18nKey)");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"execute","Falta ambito de mensajes e internacionalización del Q70ActionLookupDispatchOP. (property i18nKey)",null);					
			}
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Atributo 'i18nKey' para Q70ActionLookupDispatchOP= "+i18nKey);
			}
			
			// Identifica el valor del parametro de la request (lookup)
			parameterValue = request.getParameter(parameter);
			if (null == parameterValue) {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "El valor del parametro '"+parameter+"' de la request es Null.");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"execute","El valor del parametro '"+parameter+"' de la request es Null.",null);
			}
			if (tr.isTraceActive()) {
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "El valor del parametro '"+parameter+"' de la request es: " + parameterValue);
			}
			
			//Identifica el idioma actual
			idioma = Q70ListenerUtils.getLanguage(request);
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Idioma = " + idioma);
			}
			
			// Obtenemos todas las claves de los forwards (lookup).
			String[] forwardsKey = mapping.findForwards();
			boolean encontrado = false;
			String forwardValueAux = null;
			for (int i = 0; i < forwardsKey.length && !encontrado; i++) {
				// Obtenemos el valor de la clave del fichero de recursos según el idioma
				forwardValueAux = Q70GestorMensajesi18n.getSingleton().getMessage(i18nKey, forwardsKey[i], idioma);
				// Comparamos la descripción del forward con el valor del parámetro de la request.
				if (parameterValue.equalsIgnoreCase(forwardValueAux)) {
					forwardName = forwardsKey[i];
					encontrado = true;
				}
			}
			if (encontrado) {
				if (tr.isTraceActive()) {
					tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Nombre del forward encontrado para el parametro '" + parameterValue + "' = " + forwardName);
				}
			} else {
				if (tr.isTraceActive()) {
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "No se ha encontrado ningún forward para el parametro '" + parameterValue + "'. Revise las keys de los forward o de los literales.");
				}
				throw new Q70OperacionDePresentacionException (this.getClass().toString(),"execute","No se ha encontrado ningún forward para el parametro '" + parameterValue + "'",null);
			}
			// Realizamos el dispatch
			forward = mapping.findForward(forwardName);
			if (tr.isTraceActive()) {
				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Salida de lookupDispatch = " + forward.getPath());
			}
		} catch (Exception e) {
			throw new Q70OperacionDePresentacionException(this.getClass().toString(), "execute", "Excepción en Q70ActionLookupDispatchOP", e);
		}
		return forward;
	}
}
