/*
 * Q70DisplayMenuTag.java
 *
 * Created on February 14, 2001, 11:44 AM
 * author ssayles, mraible
 */
package es.ejie.frmk.presentacion.iu.taglib.html.menu;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;

import org.apache.struts.util.RequestUtils;

import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.presentacion.iu.taglib.base.Q70Constants;
import es.ejie.frmk.presentacion.iu.taglib.html.Q70BaseHandlerTag;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.base.Q70MenuComponent;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.base.Q70MenuRepository;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer.Q70MenuDisplayer;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer.Q70MessageResourcesMenuDisplayer;


/**
 * <p>The major behavior of this tag is to set the value for the usage in the
 * HTML hyperlink 'href' attribute. The value is determined by the following
 * attributes defined in menu-config.xml, in this prioritize order:
 * 'location', 'page', 'forward', 'action'.
 * <p>You can now define a 'forward' or  'action' attribute in the
 * &lt;Item&gt; element in your menu-config.xml. The 'action' attribute takes
 * the value of a Logical Struts Action name for which to look up the
 * context-relative URI. The resultant URI will carry the Context
 * Path (if any), Module Prefix (if any), Session ID (if any),
 * and Servlet Mapping (path mapping or extension mapping). Here is
 * an example:
 * <pre>
 * &lt;Menu name="indexMenuMore" title="More Examples"&gt;
 *   &lt;Item name="actionExample"  title="Example - 'action' attribute"
 *         <B>action="/menu/bullet"</B>/&gt;
 *   &lt;Item name="pageExample" title="Example - 'page' attribute"
 *         <B>page="/bulletmenu.jsp"</B>/&gt;
 * &lt;/Menu&gt;
 * </pre>
 * @version 1.0  Fecha: 14-feb-01
 */

public class Q70DisplayMenuTag extends Q70BaseHandlerTag {

	private static final String MENU_ITEMS_REPOSITORY_KEY =
			"es.ejie.frmk.presentacion.iu.taglib.html.menu.MENU_ITEMS_REPOSITORY";


	 // Instancia del log de trazas
	private static Q70Traza tr = Q70Traza.getSingleton();
	

    //Holds value of property name
    private String name;

    //Holds value of property target 
    private String target;

    //~ Constructors ===========================================================

    /** Creates new Q70DisplayMenuTag */
    public Q70DisplayMenuTag() {
    }

    //~ Methods ================================================================

    /** 
     * Getter for property name.
     * @return Value of property name.
     */
    public String getName() {
        return name;
    }

    /** 
     * Setter for property name.
     * @param name New value of property name.
     */
    public void setName(String name) {
		if (tr.isTraceActive())	
			tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Estableciendo nombre del menu a: " + name);        

        this.name = name;
    }

    /** 
     * Getter for property target.
     * @return Value of property target.
     */
    public String getTarget() {
        return target;
    }

    /** 
     * Setter for property target.
     * @param target New value of property target.
     */
    public void setTarget(String target) {
        this.target = target;
    }


	//----------------------------------------------------------------------------------- Tag Methods

    /**
     *@throws JspException 
     */
    public int doStartTag() throws JspException 
    {
	   	//Pintar el menu solo si por seguridad esta permitido.
	   	//Se hace una doble comprobacion con el gestor de seguridad para saber si pintarlo o no:
	   	//1.- Se chequea el valor de la propiedad secureId del tag en la jsp
	   	//2.- Se chequea el valor de la propiedad secureId del tag <menu> del fichero de configuracion de la O.P. (menu-config.xml)  
    	if (Q70Constants.MODE_NOTDISPLAYED	!= super.getDisplayMode())
    	{    	    	
	        Q70MenuDisplayer displayer =
	                (Q70MenuDisplayer) pageContext.getAttribute(Q70UseMenuDisplayerTag.DISPLAYER_KEY, PageContext.REQUEST_SCOPE);
	
	        if (displayer == null) 
	        {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "No se pudo obtener el tipo de menu.");
				} 	        	
				JspException e =
					new JspException("No se pudo obtener el tipo de menu.");
				RequestUtils.saveException(pageContext, e);
				throw e;				
	        }
	        
			// Obtener el repositorio de menus
			Q70MenuRepository repository = getMenuRepository();
	
	        Q70MenuComponent menu = repository.getMenu(this.name);
	
	        if (menu != null) 
	        {
	            try 
	            {
	            	menu.setListaI18nKey(getListaI18nKey());
	            	
	            	//Asignar la propiedad i18nKey al menu.
					menu.setI18nKey(super.getI18nKey());
					
					//Asignar la propiedad secureId al menu:
	            	//si en el tag no se ha indicado, coger la de la definicion del menu.	            	
	            	if (null!=super.getSecureId())
						menu.setSecureId(super.getSecureId());	            	
	            		            	
	                // use the overridden target
	                if (target != null) {
	                    displayer.setTarget(this.target);
	                }
	                
	                if (displayer instanceof Q70MessageResourcesMenuDisplayer) 
	    			{				
	    				((Q70MessageResourcesMenuDisplayer) displayer).setListaI18nKey(getListaI18nKey());
	    			}
	                
	                displayer.display(menu,pageContext);    //Pasar aqui el pageContext           	
	                displayer.setTarget(null);	              
	                
	                pageContext.setAttribute(MENU_ITEMS_REPOSITORY_KEY, repository, PageContext.REQUEST_SCOPE );	                
	            } 
	            catch (Exception e) 
	            {
					// don't swallow the exception
	            	
					if (tr.isTraceActive())
					{
						tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70DisplayMenuTag: Throwable recogida en el menu de tipo '" + displayer.getClass() + "':" + e.getMessage());
					}       
					JspException e2 =
						new JspException("Q70DisplayMenuTag: Throwable recogida en el menu de tipo '" + displayer.getClass() + "':'" + e.getClass() + "':'" + e.getMessage() + "'",e);
					RequestUtils.saveException(pageContext, e2);
					throw e2;				
	            }
	        } 
	        else 
	        {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR,"No se ha definido menu de nombre:" + this.name);
				}
				JspException e =
					new JspException("No se ha definido menu de nombre:" + this.name);
				RequestUtils.saveException(pageContext, e);
				throw e;				
	        }

    	}
        return 0; //SKIP_BODY
    }
  
	/**
	 *
	 */
	public void release() {
		super.release();
		this.name = null;
		this.target = null;
	}

	/**
	  * Metodo para localizar el repositorio de menus.
	  * Primero lo busca en el contexto de pagina, por si algun menu anteriormente lo ha depositado.
	  * Si no existe, se busca a nivel de operacion de presentacion y de aplicacion. 
	  * Si tampoco existe, se lanza una excepcion.
	  **/    
	 private Q70MenuRepository getMenuRepository() 
		 throws JspException
	 {
    	
		 Q70MenuRepository menuRep = (Q70MenuRepository) pageContext.getAttribute(MENU_ITEMS_REPOSITORY_KEY, PageContext.REQUEST_SCOPE);
			
		 if (menuRep == null) 
		 {			
			//Obtener el nombre de la operacion de presentacion (o modulo).  
			String moduleName = RequestUtils.getModuleName((HttpServletRequest)pageContext.getRequest(),
															 pageContext.getSession().getServletContext());
			
			//Buscar el repositorio de menus a nivel de operacion de presentacion
			menuRep = (Q70MenuRepository) pageContext.getServletContext().
											 getAttribute(Q70MenuRepository.MENU_REPOSITORY_KEY + moduleName);
			if (null==menuRep) {
				JspException e =
					new JspException("Q70DisplayMenuTag: No se pudo obtener el repositorio de menus.");
				RequestUtils.saveException(pageContext, e);
				throw e;				
			}
			if (tr.isTraceActive()) {
				tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Obtenido Repositorio de menus del contexto de servlet.");
			} 				 
		 }
		 else
		 {
			 if (tr.isTraceActive()) {
				 tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Encontrado Repositorio de menus a nivel de pagina.");
			 } 				
		 }
		 return menuRep;
	 }
}
