JsfUtils.java

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.convert.Converter;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

/**
 * Utilities used within the JSF Cartridge
 *
 * @author Chad Brandon
 * @author Walter Mourao
 */
public class JsfUtils
{

    /**
     * Returns the current FacesContext
     *
     * @return the current FacesContext
     */
    public static FacesContext getFacesContext()
    {
        return FacesContext.getCurrentInstance();
    }
    
    /**
     * Returns the requestMap
     *
     * @return the requestMap
     */
    public static Map<String,Object> getRequestMap()
    {
        return getFacesContext().getExternalContext().getRequestMap();
    }
    
    /**
     * Returns the value in requestMap
     *
     * @ return the value in requestMap
     */
    public static Object getValueInRequestMap(String key)
    {
        return getRequestMap().get(key);
    }
    
    /**
     * Returns the the current flash scope.
     *
     * @return Map<String,Object>
     */
    public static Flash getFlash()
    {
        return getFacesContext().getExternalContext().getFlash();
    }
    
    /**
     * A helper method that gets the current request from the faces
     * context.
     *
     * @return the current request instance.
     */
    public static HttpServletRequest getRequest()
    {
        return (HttpServletRequest)getFacesContext().getExternalContext().getRequest();
    }

    /**
     * A helper method that gets the current reponse from the faces
     * context.
     *
     * @return the current response instance.
     */
    public static HttpServletResponse getResponse()
    {
        return (HttpServletResponse)getFacesContext().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.
     */
    public static HttpSession getSession(final boolean create)
    {
        return (HttpSession)getFacesContext().getExternalContext().getSession(create);
    }

    /**
     * A helper method that gets the current session from the faces
     * context.
     *
     * @return the current session instance.
     */
    public static HttpSession getSession()
    {
        return (HttpSession)getFacesContext().getExternalContext().getSession(false);
    }
    
    /**
     * 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.
     */
    public static Object resolveVariable(final String name)
    {
        return getFacesContext().getApplication().getELResolver().getValue(getFacesContext().getELContext(), null, (Object)name);
    }

    /**
     * Sets the value of a request attribute
     *
     * @param name the request attribute name
     * @param object the request attribute value
     */
    public static void setRequestAttribute(final String name, final Object object)
    {
        getRequest().setAttribute(name, object);
    }

    /**
     * Gets the value of a request attribute
     *
     * @param name the request attribute name
     * @return RequestAttribute
     */
    public static Object getRequestAttribute(final String name)
    {
        return getRequest().getAttribute(name);
    }

    /**
     * Sets the value of a session attribute
     *
     * @param name the session attribute name
     * @param object the session attribute value
     */
    public static void setSessionAttribute(final String name, final Object object)
    {
        getSession().setAttribute(name, object);
    }

    /**
     * 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.
     */
    public static 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();
        }
        addErrorMessage(message);
    }

    /**
     * Adds the given error <code>message</code> to the current faces context.
     *
     * @param clientId the component client id.
     * @param message the message to add.
     */
    public static void addErrorMessage(final String clientId, final String message)
    {
        addMessage(clientId,FacesMessage.SEVERITY_ERROR, message);
    }

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

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

    /**
     * Adds the given error <code>message</code> to the current faces context.
     *
     * @param clientId the component client id.
     * @param message the message to add.
     */
    public static void addWarningMessage(final String clientId, final String message)
    {
        addMessage(clientId,FacesMessage.SEVERITY_WARN, message);
    }

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

    /**
     * Adds the given fatal <code>message</code> to the current faces context.
     *
     * @param message the message to add.
     */
    public static void addFatalMessage(final String message)
    {
        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 clientId the clientId of the component
     * @param severity the severity of the message
     * @param message the message to add.
     */
    public static void addMessage(final String clientId, final FacesMessage.Severity severity, final String message)
    {
        getFacesContext().addMessage(clientId, new FacesMessage(severity, message, null));
    }

    /**
     * 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.
     */
    public static void addMessage(final FacesMessage.Severity severity, final String message)
    {
        addMessage(null, severity, message);
    }

    /**
     * Gets the value of a session attribute
     *
     * @param name the session attribute name
     * @return SessionAttribute
     */
    public static Object getSessionAttribute(final String name)
    {
        return getSession().getAttribute(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
     */
    public static 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;
    }

    /**
     * Force the component to get its value from the backing bean before rendering
     *
     * @param uic the parent UIComponent.
     */
    public static 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
     */
    public static void resetAllEditableComponentsValues()
    {
        final UIComponent viewRoot=getFacesContext().getViewRoot();
        if(viewRoot != null)
        {
            resetEditableComponentsValues(getFacesContext().getViewRoot());
        }
    }

    /**
     * Returns the converter identified by converterId
     *
     * @param converterId the id of the converter to be used
     * @return the Converter instance
     */
    public static Converter getConverter(
            final String converterId)
    {
        if(StringUtils.isEmpty(converterId))
        {
            return null;
        }
        final FacesContext facesContext=FacesContext.getCurrentInstance();
        return facesContext.getApplication().createConverter(converterId);
    }

    /**
     * Uses the converter identified by converterId to convert the value to a String.
     *
     * @param value the value to be converted
     * @param converterId the id of the converter to be used
     * @param componentId the id of the component being rendered
     * @return the String representation of the value.
     */
    public static String valueFromConverter(
            final Object value,
            final String converterId,
            final String componentId)
    {
        final FacesContext facesContext=FacesContext.getCurrentInstance();
        final Converter converter = facesContext.getApplication().createConverter(converterId);
        return converter.getAsString(facesContext,
                StringUtils.isEmpty(componentId)?null:facesContext.getViewRoot().findComponent(componentId),
                value);
    }

    /**
     * Uses the converter identified by converterId to convert the value to a String.
     *
     * @param value the value to be converted
     * @param converterId the id of the converter to be used
     * @param componentId the id of the component being rendered
     * @param escapeJavascript flag to escape javascript
     * @return the String representation of the value.
     */
    public static String valueFromConverter(
            final Object value,
            final String converterId,
            final String componentId,
            final Boolean escapeJavascript)
    {
        final String result = valueFromConverter(value,converterId,componentId);
        return escapeJavascript?StringEscapeUtils.escapeJavaScript(result):result;
    }    

    /**
     * Uses the converter identified by converterId to convert the value to a String.
     *
     * @param value the value to be converted
     * @param converterId the id of the converter to be used
     * @return the String representation of the value.
     */
    public static String valueFromConverter(
            final Object value,
            final String converterId)
    {
        final FacesContext facesContext=FacesContext.getCurrentInstance();
        final Converter converter = facesContext.getApplication().createConverter(converterId);
        return converter.getAsString(facesContext,null,value);
    }

    /**
     * Uses the converter identified by converterId to convert the value to a String.
     *
     * @param value the value to be converted
     * @param converterId the id of the converter to be used
     * @param escapeJavascript flag to escape javascript
     * @return the String representation of the value.
     */
    public static String valueFromConverter(
            final Object value,
            final String converterId,
            final Boolean escapeJavascript)
    {
        final String result = valueFromConverter(value,converterId);
        return escapeJavascript?StringEscapeUtils.escapeJavaScript(result):result;
    }    

    /**
     * Returns an ActionEvent parameter value, from its name
     *
     * @param parameterName the parameter name
     * @param event ActionEvent containing the parameter
     * @return the parameter value.
     */
    public static Object getParameterValue(String parameterName, ActionEvent event)
    {
        for(Object uiObject : event.getComponent().getChildren())
        {
            if(uiObject instanceof UIParameter)
            {
                final UIParameter param = (UIParameter)uiObject;
                if(param.getName().equals(parameterName))
                {
                    return param.getValue();
                }
            }
        }
        throw new RuntimeException("Parameter "+parameterName+" not found");
    }

    /**
     * Returns an array of SelectItem from the values/names of the enumeration
     *
     * @param prefix a String prefix to be used to load the name from the messages
     * @param enumClassName the enumeration class name
     * @return the array of SelectItem
     */
    @SuppressWarnings("rawtypes")
    public static SelectItem[] getEnumSelectItems(final String prefix, final String enumClassName)
    {
        try
        {
            final SelectItem[] result;
            final Class<?> enumClass=JsfUtils.class.getClassLoader().loadClass(enumClassName);
            if(enumClass.isEnum())
            {
                final Enum[] values=(Enum[])enumClass.getMethod("values", (Class<?>[])null).invoke(null, (Object[])null);
                result=new SelectItem[values.length];
                int i=0;
                for(final Enum value:values)
                {
                    result[i]=new SelectItem(value,Messages.get(prefix+value.name()));
                    i++;
                }
            }
            else
            {
                final List values=(List)enumClass.getMethod("values", (Class<?>[])null).invoke(null, (Object[])null);
                final int sz=values.size();
                final List names=(List)enumClass.getMethod("names", (Class<?>[])null).invoke(null, (Object[])null);
                result=new SelectItem[sz];
                for(int i=0; i<sz; i++)
                {
                    result[i]=new SelectItem(values.get(i),Messages.get(prefix+names.get(i)));
                }
            }

            return result;
        }
        catch (Exception e)
        {
            throw new RuntimeException(enumClassName+" is not an Andromda generated enumeration.",e);
        }
    }

    /**
     * Returns the messages.properties message of the enumeration value
     *
     * @param prefix a String prefix to be used to load the name from the messages
     * @param enumValue the value
     * @return the String from the messages.properties
     */
    @SuppressWarnings("rawtypes")
    public static String getEnumMessage(final String prefix, final Object enumValue)
    {
        if(enumValue == null)
        {
            return StringUtils.EMPTY;
        }
        final Class<?> enumClass=enumValue.getClass();
        if(enumClass.isEnum())
        {
            return Messages.get(prefix+((Enum)enumValue).name());
        }
        try
        {
            final List values=(List)enumClass.getMethod("values", (Class<?>[])null).invoke(null, (Object[])null);
            final int sz=values.size();
            final List names=(List)enumClass.getMethod("names", (Class<?>[])null).invoke(null, (Object[])null);
            for(int i=0; i<sz; i++)
            {
                if(values.get(i).equals(enumValue))
                {
                    return Messages.get(prefix+names.get(i));
                }
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException(enumValue.getClass().getCanonicalName()+" is not an Andromda generated enumeration.",e);
        }
        return null;
    }

    /**
     * Returns the array without the entries with zero (using to avoid the null to zero 
     * issue of EL)
     *
     * @param intArray an array filled with Integer
     * @return the array with the entries with zero and null removed
     */
    public static Integer[] removeZeros(Integer[] intArray)
    {
        if(intArray == null)
        {
            return null;
        }
        final Collection<Integer> result=new ArrayList<Integer>(intArray.length);
        for(Integer intValue: intArray)
        {
            if(intValue != null && intValue.intValue() != 0)
            {
                result.add(intValue);
            }
        }
        return result.toArray(new Integer[0]);
    }

    /**
     * Returns the array without the entries with zero (using to avoid the null to zero 
     * issue of EL)
     *
     * @param longArray an array filled with Integer
     * @return the array with the entries with zero and null removed
     */
    public static Long[] removeZeros(Long[] longArray)
    {
        if(longArray == null)
        {
            return null;
        }
        final Collection<Long> result=new ArrayList<Long>(longArray.length);
        for(Long longValue: longArray)
        {
            if(longValue != null && longValue.longValue() != 0)
            {
                result.add(longValue);
            }
        }
        return result.toArray(new Long[0]);
    }

    /**
     * Returns the current ViewRoot
     * @return the current Faces ViewRoot
     */
    public static UIViewRoot getViewRoot() {
        return FacesContext.getCurrentInstance().getViewRoot();
    }
    
    /**
     * Recursively locates a component in the view tree
     * @param id
     * @return
     */
    public static UIComponent findComponentInRoot(String scopedId) {
        return getViewRoot().findComponent(scopedId);
    }
    
}