ControllerBase.java

// license-header java merge-point
// Generated by andromda-jsf cartridge (utils\ControllerBase.java.vsl) DO NOT EDIT!
package org.andromda.presentation.jsf;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.myfaces.trinidad.context.RequestContext;

/**
 * Base class for all controllers
 */
public abstract class ControllerBase
{
    /** org.andromda.cartridges.jsf.USE_CASE_FORMS */
    public static final String USE_CASE_FORMS_KEY="org.andromda.cartridges.jsf.USE_CASE_FORMS";
    /** org.andromda.cartridges.jsf.PAGE_VARIABLES */
    public static final String USE_CASE_PAGE_VARIABLES_KEY="org.andromda.cartridges.jsf.PAGE_VARIABLES";
    /** org.andromda.cartridges.jsf.USE_CASE_PARAMETERS */
    public static final String USE_CASE_PARAMETERS_KEY="org.andromda.cartridges.jsf.USE_CASE_PARAMETERS";
    /** form */
    public static final String FORM_KEY="form";

    /**
     * Returns the forms associated with this controller in the pageFlowScope.
     * @param pageFlowScope
     * @return Forms Map<String,Object>
     */
    @SuppressWarnings("unchecked")
    public static Map<String,Object> getForms( Map<String,Object> pageFlowScope)
    {
        Map<String,Object> result = (Map<String,Object>)pageFlowScope.get(USE_CASE_FORMS_KEY);
        if(result == null){
            result=new HashMap<String, Object>();
            pageFlowScope.put(USE_CASE_FORMS_KEY, result);
        }
        return result;
    }

    /**
     * Returns the forms associated with this controller.
     * @return ControllerBase.getForms(getPageFlowScope())
     */
    public Map<String,Object> getForms()
    {
        return ControllerBase.getForms(this.getPageFlowScope());
    }

    /**
     * @param formName
     * @return getProperty(formName)
     */
    public Object getForm(final String formName)
    {
        try
        {
            return PropertyUtils.getProperty(this, formName);
        } catch (Exception e)
        {
            return null;
        }
    }

    /**
     * Returns the page variables associated with this controller, in the pageFlowScope.
     * @param pageFlowScope
     * @return PageVariables
     */
    public static Map<String,Object> getPageVariables( Map<String,Object> pageFlowScope)
    {
        @SuppressWarnings("unchecked")
        Map<String,Object> result = (Map<String,Object>)pageFlowScope.get(USE_CASE_PAGE_VARIABLES_KEY);
        if(result == null){
            result = new HashMap<String, Object>();
            pageFlowScope.put(USE_CASE_PAGE_VARIABLES_KEY, result);
        }
        return result;
    }

    /**
     * Returns the page variables associated with this controller, in the pageFlowScope.
     * @return PageVariables
     */
    public Map<String,Object> getPageVariables()
    {
        return ControllerBase.getPageVariables(this.getPageFlowScope());
    }

    /**
     * Returns true if there is at least one use case parameter.
     * @return hasUseCaseParameters
     */
    @SuppressWarnings("unchecked")
    public boolean hasUseCaseParameters()
    {
        final Map<String, Object> pageFlowScope=this.getPageFlowScope();
        Map<String,Object> parameters = (Map<String,Object>)pageFlowScope.get(USE_CASE_PARAMETERS_KEY);
        return parameters != null && !parameters.isEmpty();
    }

    /**
     * Returns the use case parameters associated with this controller, in the current pageFlowScope.
     * @return useCaseParameters
     */
    @SuppressWarnings("unchecked")
    public Map<String,Object> getUseCaseParameters()
    {
        final Map<String, Object> pageFlowScope=this.getPageFlowScope();
        Map<String,Object> result = (Map<String,Object>)pageFlowScope.get(USE_CASE_PARAMETERS_KEY);
        if(result == null){
            result=new HashMap<String, Object>();
            pageFlowScope.put(USE_CASE_PARAMETERS_KEY, result);
        }
        return result;
    }

    /**
     * Removes all the forms and page variables from the current pageFlowScope.
     */
    protected void resetUseCaseFormsAndPageVariables()
    {
        final Map<String, Object> pageFlowScope=this.getPageFlowScope();
        pageFlowScope.remove(USE_CASE_FORMS_KEY);
        pageFlowScope.remove(USE_CASE_PAGE_VARIABLES_KEY);
    }

    /**
     * Removes all the forms and page variables from the current pageFlowScope.
     */
    protected void resetUseCaseParameters()
    {
        final Map<String, Object> pageFlowScope=this.getPageFlowScope();
        pageFlowScope.remove(USE_CASE_PARAMETERS_KEY);
    }

    /**
     * Gets the current faces context.  This object is the point
     * from which to retrieve any request, session, etc information.
     *
     * @return the JSF faces context instance.
     */
    public FacesContext getContext()
    {
        return FacesContext.getCurrentInstance();
    }

    /**
     * A helper method that gets the current request from the faces
     * context.
     *
     * @return the current request instance.
     */
    protected HttpServletRequest getRequest()
    {
        return (HttpServletRequest)this.getContext().getExternalContext().getRequest();
    }

    /**
     * A helper method that gets the current reponse from the faces
     * context.
     *
     * @return the current response instance.
     */
    protected HttpServletResponse getResponse()
    {
        return (HttpServletResponse)this.getContext().getExternalContext().getResponse();
    }

    /**
     * A helper method that gets the current session from the faces
     * context.
     *
     * @param create If the create parameter is true, create (if necessary) and return a
     *        session instance associated with the current request. If the create
     *        parameter is false return any existing session instance associated with the
     *        current request, or return null if there is no such session.
     * @return the current session instance.
     */
    protected HttpSession getSession(final boolean create)
    {
        return (HttpSession)this.getContext().getExternalContext().getSession(create);
    }

    /**
     * Attempts to resolve the variable, given, the <code>name</code> of
     * the variable using the faces context variable resolver instance.
     * @param name
     * @return the resolved variable or null if not found.
     */
    protected Object resolveVariable(final String name)
    {
        final FacesContext context = this.getContext();
        return context != null ? context.getApplication().getVariableResolver().resolveVariable(context, name) : null;
    }

    /**
     * @param formKey
     * @param form
     * @param includeInSession
     */
    protected void setForm(final String formKey, final Object form, boolean includeInSession)
    {
        getForms().put(formKey,form);
        if (includeInSession)
        {
            this.setSessionAttribute(formKey, form);
        }
    }

    /**
     * Finds the root cause of the given <code>throwable</code> and
     * adds the message taken from that cause to the faces context messages.
     *
     * @param throwable the exception information to add.
     */
    protected final void addExceptionMessage(
        Throwable throwable)
    {
        String message = null;
        final Throwable rootCause = ExceptionUtils.getRootCause(throwable);
        if (rootCause != null)
        {
            message = rootCause.toString();
        }
        if (message == null || message.trim().length() == 0)
        {
            message = throwable.toString();
        }
        this.addErrorMessage(message);
    }

    /**
     * Adds the given error <code>message</code> to the current faces context.
     *
     * @param message the message to add.
     */
    protected void addErrorMessage(final String message)
    {
        this.addMessage(FacesMessage.SEVERITY_ERROR, message);
    }

    /**
     * Adds the given warning <code>message</code> to the current faces context.
     *
     * @param message the message to add.
     */
    protected void addWarningMessage(final String message)
    {
        this.addMessage(FacesMessage.SEVERITY_WARN, message);
    }

    /**
     * Adds the given info <code>message</code> to the current faces context.
     *
     * @param message the message to add.
     */
    protected void addInfoMessage(final String message)
    {
        this.addMessage(FacesMessage.SEVERITY_INFO, message);
    }

    /**
     * Adds the given fatal <code>message</code> to the current faces context.
     *
     * @param message the message to add.
     */
    protected void addFatalMessage(final String message)
    {
        this.addMessage(FacesMessage.SEVERITY_FATAL, message);
    }

    /**
     * Adds a message to the faces context (which will show up on your view when using the
     * lt;h:messages/gt; tag).
     *
     * @param severity the severity of the message
     * @param message the message to add.
     */
    protected void addMessage(final FacesMessage.Severity severity, final String message)
    {
        final FacesMessage facesMessage = new FacesMessage(severity, message, message);
        final Object form = this.resolveVariable(FORM_KEY);
        if (form != null)
        {
            try
            {
                final Method method = form.getClass().getMethod(
                    "addJsfMessages",
                    new Class[]{FacesMessage.class});
                method.invoke(form, new Object[]{facesMessage});
            }
            catch (final Exception exception)
            {
                throw new RuntimeException(exception);
            }
        }
    }

    /**
     * Sets the messages title to use on the next view.
     *
     * @param messagesTitle the title to use.
     */
    protected void setMessagesTitle(final String messagesTitle)
    {
        final Object form = this.resolveVariable(FORM_KEY);
        if (form != null)
        {
            try
            {
                final Method method = form.getClass().getMethod(
                    "setJsfMessagesTitle",
                    new Class[]{String.class});
                method.invoke(form, new Object[]{messagesTitle});
            }
            catch (final Exception exception)
            {
                throw new RuntimeException(exception);
            }
        }
    }

    /**
     * Gets the maximum severity of the messages stored in the current form.
     *
     * @return the maximum message severity.
     */
    protected FacesMessage.Severity getMaximumMessageSeverity()
    {
        FacesMessage.Severity maximumSeverity = null;
        final Object form = this.resolveVariable(FORM_KEY);
        if (form != null)
        {
            try
            {
                final Method method = form.getClass().getMethod(
                    "getMaximumMessageSeverity",
                    (Class[])null);
                maximumSeverity = (FacesMessage.Severity)method.invoke(form, (Object[])null);
            }
            catch (final Exception exception)
            {
                throw new RuntimeException(exception);
            }
        }
        return maximumSeverity;
    }

    /**
     * Retrieves the current action form while making sure the form is of the given
     * <code>type</code>.  If the action form is found, but not of the given type, null will
     * be returned.
     *
     * @param type the type of form to retrieve.
     * @return the found form.
     */
    protected Object getCurrentActionForm(final Class<?> type)
    {
        Object form = this.getCurrentActionForm();
        if (!type.isInstance(form))
        {
            form = null;
        }
        return form;
    }

    /**
     * Retrieves the current action form instance.
     *
     * @return the current action form instance.
     */
    protected Object getCurrentActionForm()
    {
        return this.resolveVariable(FORM_KEY);
    }

    /**
     * The name of the request attribute that stores the attributes from the current action event.
     */
    protected static final String ACTION_EVENT_ATTRIBUTES = "actionEventAttributes";

    /**
     * This method just captures the event attributes and sets them into the request
     * so that we can retrieve in controller action operation and use to populate form.
     *
     * @param event the action event.
     */
    public void action(ActionEvent event)
    {
        this.setRequestAttribute(ACTION_EVENT_ATTRIBUTES, event.getComponent().getAttributes());
    }

    /**
     * @param name
     * @param object
     */
    protected void setRequestAttribute(final String name, final Object object)
    {
        this.getRequest().setAttribute(name, object);
    }

    /**
     * @param name
     * @return RequestAttribute
     */
    protected Object getRequestAttribute(final String name)
    {
        return this.getRequest().getAttribute(name);
    }

    /**
     * @param name
     * @param object
     */
    protected void setSessionAttribute(final String name, final Object object)
    {
        JsfUtils.setAttribute(this.getContext().getExternalContext().getSession(false), name, object);
    }

    /**
     * @param name
     * @return SessionAttribute
     */
    protected Object getSessionAttribute(final String name)
    {
        return JsfUtils.getAttribute(this.getContext().getExternalContext().getSession(false), name);
    }

    /**
     * Returns an FacesEvent parameter value, from its name
     *
     * @param parameterName the name of the parameter.
     * @param event the FacesEvent holding the parameter.
     * @return ParameterValue
     */
    protected Object getParameterValue(String parameterName, FacesEvent event)
    {
        for(Object uiObject : event.getComponent().getChildren()){
            if(uiObject instanceof UIParameter){
                final UIParameter param = (UIParameter)uiObject;
                if(param.getName().equals(parameterName)) {
                    return param.getValue();
                }
            }
        }
        return null;
    }

    /**
     * Sets the current action form instance.
     * @param form
     */
    protected void setCurrentActionForm(Object form)
    {
        this.setRequestAttribute(FORM_KEY, form);
        this.getPageFlowScope().put(FORM_KEY, form);
    }

    /**
     * Force the component to get its value from the backing bean before rendering
     *
     * @param uic the parent UIComponent.
     */
    protected void resetEditableComponentsValues(UIComponent uic)
    {
        if(uic instanceof EditableValueHolder)
        {
            final EditableValueHolder evh=(EditableValueHolder)uic;
            evh.setValue(null);
            evh.setSubmittedValue(null);
            evh.setLocalValueSet(false);
            evh.setValid(true);
        }
        for(Object component: uic.getChildren())
        {
            resetEditableComponentsValues((UIComponent)component);
        }
    }

    /**
     * Force all the editable components to get its values from the backing bean before rendering
     */
    protected void resetAllEditableComponentsValues()
    {
        resetEditableComponentsValues(this.getContext().getViewRoot());
    }

    /**
     * @return PageFlowScope Map<String,Object>
     */
    protected Map<String,Object> getPageFlowScope()
    {
        return RequestContext.getCurrentInstance().getPageFlowScope();
    }

    // controller-base merge-point
}