empire-db-jakarta-faces/src/main/java/org/apache/empire/jakarta/app/WebApplication.java [66:464]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public abstract class WebApplication
{
    private static final Logger log                   = LoggerFactory.getLogger(WebApplication.class);
    
    private static final String REQUEST_CONNECTION_MAP = "requestConnectionMap";

    private static final String CONN_ROLLBACK_MANAGER = "connRollbackManager";
    
    public static String        APPLICATION_BEAN_NAME = "webApplication";

    protected TextResolver[]    textResolvers         = null;

    private String              webRoot               = null;
    
    private FacesImplementation facesImpl			  = null;
    
    private static WebApplication appInstance         = null;
    
    /**
     * Returns the one and only instance of the WebApplication (Singleton)
     * @param <T> the application type
     * @return the WebApplication instance
     */
    @SuppressWarnings("unchecked")
    public static <T extends WebApplication> T getInstance()
    {
        if (appInstance==null)
            log.warn("No WebApplication instance available. Please add a PostConstructApplicationEvent using WebAppStartupListener in your faces-config.xml to create the WebApplication object.");
        // return instance
        return (T)appInstance;
    }

    protected abstract void init(ServletContext servletContext);
    
    protected abstract DataSource getAppDataSource(DBDatabase db);

    protected WebApplication()
    {   // subscribe
        log.info("WebApplication {} created", getClass().getName());
        // Must be a singleton
        if (appInstance!=null) {
            throw new RuntimeException("An attempt was made to create second instance of WebApplication. WebApplication must be a Singleton!");
        }
        // set Instance
        appInstance = this;
    }

    /**
     * Init the Application
     * @param facesImpl the faces implementation
     * @param startupContext the startup context
     */
    public final void init(FacesImplementation facesImpl, FacesContext startupContext)
    {
        // Only call once!
        if (this.facesImpl!=null || this.webRoot!=null) 
        {   // already initialized
            log.warn("WARNING: WebApplication has already been initialized! Continuing without init...");
            return;
        }
        // set imppl
        this.facesImpl = facesImpl;
        // webRoot
        ServletContext servletContext = (ServletContext) startupContext.getExternalContext().getContext();
        webRoot = servletContext.getContextPath();
        servletContext.setAttribute("webRoot", webRoot);
        servletContext.setAttribute("app", this);
        // Init
        init(servletContext);
        // post init
        if (this.textResolvers==null)
        {   // text resolvers
            log.info("*** initTextResolvers() ***");
            initTextResolvers(startupContext.getApplication());
        }
        // Log info
        log.info("*** WebApplication initialization complete ***");
        log.info("JSF-Implementation is '{}'", facesImpl.getClass().getName());
        log.info("WebRoot is '{}'", webRoot);
    }

    public void destroy()
    {
    	// Override if needed
    }
    
    /* Context handling */
    
    /**
     * handle request cleanup
     * @param ctx the faces context
     */
    public void onRequestComplete(final FacesContext ctx)
    {
        releaseAllConnections(ctx);
    }

    /**
     * handle view not found
     * @param fc the faces context
     * @param req the request
     */
    public void onViewNotFound(final FacesContext fc, final HttpServletRequest req)
    {   // View not Found Error
        log.warn("No view found for request to '{}'. Use FacesUtils.redirectDirectly() to redirect to valid view.", req.getRequestURI());
        redirectDirectly(fc, StringUtils.EMPTY);
    }

    /**
     * handle view change
     * @param fc the faces context
     * @param viewId the view id
     */
    public void onChangeView(final FacesContext fc, String viewId)
    {   // allow custom view change logic

        // clear page resources
        Map<String, Object> sm = FacesUtils.getSessionMap(fc);
        if (sm!=null)
            sm.remove(FacesUtils.PAGE_RESOURCE_MAP_ATTRIBUTE);
    }

    /**
     * adds a Javascript call to the request 
     * @param fc the faces context
     * @param function the javascript command
     */
    public void addJavascriptCall(final FacesContext fc, String function)
    {
        throw new NotSupportedException(this, "addJavascriptCall");
    }

    /**
     * return the interface for Implementation specific features 
     * that are specific for Mojarra or MyFaces
     * @return the faces implementation
     */
    public FacesImplementation getFacesImplementation() 
    {
		return facesImpl;
	}
    
    /**
     * returns the web context path as returned from ServletContext.getContextPath()
     * @return the web root
     */
    public String getWebRoot()
    {
        return webRoot;
    }

    /**
     * returns the active locale for a given FacesContext
     * @param ctx the faces context
     * @return the context locale
     */
    public Locale getContextLocale(final FacesContext ctx)
    {
        UIViewRoot root;
        // Start out with the default locale
        Locale locale;
        Locale defaultLocale = Locale.getDefault();
        locale = defaultLocale;
        // See if this FacesContext has a ViewRoot
        if (null != (root = ctx.getViewRoot()))
        {
            // If so, ask it for its Locale
            if (null == (locale = root.getLocale()))
            {
                // If the ViewRoot has no Locale, fall back to the default.
                locale = defaultLocale;
            }
        }
        return locale;
    }

    public TextResolver getTextResolver(Locale locale)
    {
        // No text Resolvers provided
        if (textResolvers == null || textResolvers.length == 0)
        {
            throw new NotSupportedException(this, "getTextResolver");
        }
        // Lookup resolver for locale
        for (int i = 0; i < textResolvers.length; i++)
            if (locale.equals(textResolvers[i].getLocale()))
                return textResolvers[i];
        // locale not found: return default
        return textResolvers[0];
    }

    public TextResolver getTextResolver(FacesContext ctx)
    {
        return getTextResolver(getContextLocale(ctx));
    }

    /**
     * Returns a FacesMessage 
     * @param ctx the FacesContext
     * @param severity the message severity
     * @param msg the message or message key
     * @param params the message params
     * @return the FacesMessage or null to ignore
     */
    public FacesMessage getFacesMessage(FacesContext ctx, Severity severity, String msg, Object... params)
    {
        TextResolver resolver = getTextResolver(getContextLocale(ctx));
        msg = resolver.resolveText(msg);
        if (params.length>0)
        {   // translate params
            for (int i=0; i<params.length; i++)
                if (params[i] instanceof String)
                    params[i] = resolver.resolveText((String)params[i]);
                else if ((params[i] instanceof Integer) || (params[i] instanceof Long))
                    params[i] = String.valueOf(params[i]); // avoid group separator
            // format
            msg = MessageFormat.format(msg, params);
        }
        return new FacesMessage(severity, msg, null);
    }
    
    /**
     * Returns a FacesMessage for an Exception 
     * @param ctx the FacesContext
     * @param errorContext the error context (optional)
     * @param t the exception
     * @return the FacesMessage or null to ignore
     */
    public FacesMessage getFacesErrorMessage(FacesContext ctx, String errorContext, Throwable t)
    {
        // Wrap exception if necessary
        EmpireException e = (t instanceof EmpireException) ? ((EmpireException)t) : new InternalException(t); 
        // Get Message
        TextResolver tr = getTextResolver(ctx);
        String msg = tr.getExceptionMessage(e);
        String msgDetail = extractErrorMessageDetail(errorContext, t, 3);
        // create Faces Message
        return new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msgDetail);
    }
    
    protected String extractErrorMessageDetail(String errorContext, Throwable e, int stackTraceElements)
    {
        StringBuilder b = new StringBuilder();
        if (errorContext!=null)
        {   // Append context String
            b.append(errorContext);
            b.append(": ");
        }
        b.append(e.toString());
        b.append("\r\nat:");
        StackTraceElement[] stack = e.getStackTrace();
        int len = (stack.length>stackTraceElements) ? stackTraceElements : stack.length; 
        for (int i=0; i<len; i++)
        {
            b.append(stack[i].toString());
            b.append("\r\n");
        }
        return b.toString();
    }

    /**
     * checks if the current context contains an error
     * @param fc the FacesContext
     * @return true if the context has an error set or false otherwise
     */
    public boolean hasError(final FacesContext fc)
    {
        Iterator<FacesMessage> msgIterator = fc.getMessages();
        if (msgIterator != null)
        { // Check Messages
            while (msgIterator.hasNext())
            { // Check Severity
                Severity fms = msgIterator.next().getSeverity();
                if (fms == FacesMessage.SEVERITY_ERROR || fms == FacesMessage.SEVERITY_FATAL)
                    return true;
            }
        }
        return false;
    }
    
    /**
     * Redirects to another page or url
     * @param fc the FacesContext
     * @param url the target url
     */
    public void redirectDirectly(final FacesContext fc, String url)
    {
        try
        {   // check params
            if (fc==null)
                throw new InvalidArgumentException("fc", fc);
            if (fc.getResponseComplete())
                throw new InvalidOperationException("Unable to redirect. Response is already complete!");
            if (url==null)
                url = StringUtils.EMPTY; // redirect to root
            // Prepend Context-Path
            ExternalContext ec = fc.getExternalContext(); 
            String ctxPath = ec.getRequestContextPath();
            if (url.indexOf("://")>0)
            {   // Should not contain the context-path
                if (url.startsWith("http") && url.indexOf(ctxPath)>0)
                    log.warn("Redirect url \"{}\" contains protokoll and context-path. Please remove.", url);
                else
                    log.info("Redirecting to absolute url {}", url);
            }
            else if (!url.startsWith(ctxPath))
            {   // assemble url
                String sep = (url.length()>0 && url.charAt(0)!='/' ? "/" : null);
                url = StringUtils.concat(ctxPath, sep, url);
                // relative
                log.debug("Redirecting to relative url {}", url);
            }
            else
                log.warn("Redirect url \"{}\" already contains context-path. Please remove.", url);
            // redirectDirectly
            ec.redirect(url);
            fc.responseComplete();
        }
        catch (IOException e)
        {   // What can we do now?
            log.error("Failed to redirect to {}", url, e);
        }
    }
    
    /**
     * Handles an exeption, that could not be handled on the page level
     * The application should redirect to the error page.
     * @param context the faces context
     * @param source the page from which the exception originated
     * @param e the Exception to handle
     */
    public void handleException(FacesContext context, Page source, Throwable e)
    {
        // log source
        String origin = (source!=null ? source.getPageDefinition().getPageBeanName() : "[Unknown]");
        log.error("Fatal error of type {} from \"{}\": {}: {}", e.getClass().getName(), origin, e.getMessage());
        
        // check handled
        boolean handled = (context.getMaximumSeverity()==FacesMessage.SEVERITY_ERROR);

        // For page errors, give the ExceptionHandler a chance to handle
        if (!handled && source!=null)
        {
            // Queue event 
            ExceptionQueuedEventContext event = new ExceptionQueuedEventContext(context, e, null, context.getCurrentPhaseId());
            event.getAttributes().put (ExceptionQueuedEventContext.IN_BEFORE_PHASE_KEY, Boolean.TRUE);
            context.getApplication().publishEvent (context, ExceptionQueuedEvent.class, event);
            
            // Handle Exception
            context.getExceptionHandler().handle(); 
            if (context.getResponseComplete())
                return;
        }
        
        // Find message
        FacesMessage facesMsg = null;
        Iterator<FacesMessage> messages = context.getMessages();
        while (messages.hasNext())
        {
            FacesMessage msg = messages.next();
            if (msg.getSeverity()==FacesMessage.SEVERITY_ERROR)
            {   // found
                facesMsg = msg;
                break;
            }
        }
        if (facesMsg==null)
            facesMsg = getFacesErrorMessage(context, origin, e);
        // Set Session Message
        ExternalContext ec = context.getExternalContext();
        ec.getSessionMap().put(Page.SESSION_MESSAGE, facesMsg);

        // If parentPage is null then redirect to ContextPath (root)
        PageDefinition parentPage = (source!=null ? source.getParentPage() : null);
        String redirectUrl = (parentPage!=null ? parentPage.getOutcome().toString() : StringUtils.EMPTY);
        redirectDirectly(context, redirectUrl);
    }
    
    /**
     * returns true if a form input element has been partially submitted
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public boolean isPartialSubmit(final FacesContext fc)
    {
        // Override for your JSF component Framework. e.g. for IceFaces
        // Map<String,String> parameterMap = fc.getExternalContext().getRequestParameterMap();
        // return ObjectUtils.getBoolean(parameterMap.get("ice.submit.partial"));
        return false;
    }

    /**
     * returns the componentId for which a partial submit has been performed.
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public String getPartialSubmitComponentId(final FacesContext fc)
    {
        Map<String,String> parameterMap = fc.getExternalContext().getRequestParameterMap();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java [65:463]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public abstract class WebApplication
{
    private static final Logger log                   = LoggerFactory.getLogger(WebApplication.class);
    
    private static final String REQUEST_CONNECTION_MAP = "requestConnectionMap";

    private static final String CONN_ROLLBACK_MANAGER = "connRollbackManager";
    
    public static String        APPLICATION_BEAN_NAME = "webApplication";

    protected TextResolver[]    textResolvers         = null;

    private String              webRoot               = null;
    
    private FacesImplementation facesImpl			  = null;
    
    private static WebApplication appInstance         = null;
    
    /**
     * Returns the one and only instance of the WebApplication (Singleton)
     * @param <T> the application type
     * @return the WebApplication instance
     */
    @SuppressWarnings("unchecked")
    public static <T extends WebApplication> T getInstance()
    {
        if (appInstance==null)
            log.warn("No WebApplication instance available. Please add a PostConstructApplicationEvent using WebAppStartupListener in your faces-config.xml to create the WebApplication object.");
        // return instance
        return (T)appInstance;
    }

    protected abstract void init(ServletContext servletContext);
    
    protected abstract DataSource getAppDataSource(DBDatabase db);

    protected WebApplication()
    {   // subscribe
        log.info("WebApplication {} created", getClass().getName());
        // Must be a singleton
        if (appInstance!=null) {
            throw new RuntimeException("An attempt was made to create second instance of WebApplication. WebApplication must be a Singleton!");
        }
        // set Instance
        appInstance = this;
    }

    /**
     * Init the Application
     * @param facesImpl the faces implementation
     * @param startupContext the startup context
     */
    public final void init(FacesImplementation facesImpl, FacesContext startupContext)
    {
        // Only call once!
        if (this.facesImpl!=null || this.webRoot!=null) 
        {   // already initialized
            log.warn("WARNING: WebApplication has already been initialized! Continuing without init...");
            return;
        }
        // set imppl
        this.facesImpl = facesImpl;
        // webRoot
        ServletContext servletContext = (ServletContext) startupContext.getExternalContext().getContext();
        webRoot = servletContext.getContextPath();
        servletContext.setAttribute("webRoot", webRoot);
        servletContext.setAttribute("app", this);
        // Init
        init(servletContext);
        // post init
        if (this.textResolvers==null)
        {   // text resolvers
            log.info("*** initTextResolvers() ***");
            initTextResolvers(startupContext.getApplication());
        }
        // Log info
        log.info("*** WebApplication initialization complete ***");
        log.info("JSF-Implementation is '{}'", facesImpl.getClass().getName());
        log.info("WebRoot is '{}'", webRoot);
    }

    public void destroy()
    {
    	// Override if needed
    }
    
    /* Context handling */
    
    /**
     * handle request cleanup
     * @param ctx the faces context
     */
    public void onRequestComplete(final FacesContext ctx)
    {
        releaseAllConnections(ctx);
    }

    /**
     * handle view not found
     * @param fc the faces context
     * @param req the request
     */
    public void onViewNotFound(final FacesContext fc, final HttpServletRequest req)
    {   // View not Found Error
        log.warn("No view found for request to '{}'. Use FacesUtils.redirectDirectly() to redirect to valid view.", req.getRequestURI());
        redirectDirectly(fc, StringUtils.EMPTY);
    }

    /**
     * handle view change
     * @param fc the faces context
     * @param viewId the view id
     */
    public void onChangeView(final FacesContext fc, String viewId)
    {   // allow custom view change logic

        // clear page resources
        Map<String, Object> sm = FacesUtils.getSessionMap(fc);
        if (sm!=null)
            sm.remove(FacesUtils.PAGE_RESOURCE_MAP_ATTRIBUTE);
    }

    /**
     * adds a Javascript call to the request 
     * @param fc the faces context
     * @param function the javascript command
     */
    public void addJavascriptCall(final FacesContext fc, String function)
    {
        throw new NotSupportedException(this, "addJavascriptCall");
    }

    /**
     * return the interface for Implementation specific features 
     * that are specific for Mojarra or MyFaces
     * @return the faces implementation
     */
    public FacesImplementation getFacesImplementation() 
    {
		return facesImpl;
	}
    
    /**
     * returns the web context path as returned from ServletContext.getContextPath()
     * @return the web root
     */
    public String getWebRoot()
    {
        return webRoot;
    }

    /**
     * returns the active locale for a given FacesContext
     * @param ctx the faces context
     * @return the context locale
     */
    public Locale getContextLocale(final FacesContext ctx)
    {
        UIViewRoot root;
        // Start out with the default locale
        Locale locale;
        Locale defaultLocale = Locale.getDefault();
        locale = defaultLocale;
        // See if this FacesContext has a ViewRoot
        if (null != (root = ctx.getViewRoot()))
        {
            // If so, ask it for its Locale
            if (null == (locale = root.getLocale()))
            {
                // If the ViewRoot has no Locale, fall back to the default.
                locale = defaultLocale;
            }
        }
        return locale;
    }

    public TextResolver getTextResolver(Locale locale)
    {
        // No text Resolvers provided
        if (textResolvers == null || textResolvers.length == 0)
        {
            throw new NotSupportedException(this, "getTextResolver");
        }
        // Lookup resolver for locale
        for (int i = 0; i < textResolvers.length; i++)
            if (locale.equals(textResolvers[i].getLocale()))
                return textResolvers[i];
        // locale not found: return default
        return textResolvers[0];
    }

    public TextResolver getTextResolver(FacesContext ctx)
    {
        return getTextResolver(getContextLocale(ctx));
    }

    /**
     * Returns a FacesMessage 
     * @param ctx the FacesContext
     * @param severity the message severity
     * @param msg the message or message key
     * @param params the message params
     * @return the FacesMessage or null to ignore
     */
    public FacesMessage getFacesMessage(FacesContext ctx, Severity severity, String msg, Object... params)
    {
        TextResolver resolver = getTextResolver(getContextLocale(ctx));
        msg = resolver.resolveText(msg);
        if (params.length>0)
        {   // translate params
            for (int i=0; i<params.length; i++)
                if (params[i] instanceof String)
                    params[i] = resolver.resolveText((String)params[i]);
                else if ((params[i] instanceof Integer) || (params[i] instanceof Long))
                    params[i] = String.valueOf(params[i]); // avoid group separator
            // format
            msg = MessageFormat.format(msg, params);
        }
        return new FacesMessage(severity, msg, null);
    }
    
    /**
     * Returns a FacesMessage for an Exception 
     * @param ctx the FacesContext
     * @param errorContext the error context (optional)
     * @param t the exception
     * @return the FacesMessage or null to ignore
     */
    public FacesMessage getFacesErrorMessage(FacesContext ctx, String errorContext, Throwable t)
    {
        // Wrap exception if necessary
        EmpireException e = (t instanceof EmpireException) ? ((EmpireException)t) : new InternalException(t); 
        // Get Message
        TextResolver tr = getTextResolver(ctx);
        String msg = tr.getExceptionMessage(e);
        String msgDetail = extractErrorMessageDetail(errorContext, t, 3);
        // create Faces Message
        return new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msgDetail);
    }
    
    protected String extractErrorMessageDetail(String errorContext, Throwable e, int stackTraceElements)
    {
        StringBuilder b = new StringBuilder();
        if (errorContext!=null)
        {   // Append context String
            b.append(errorContext);
            b.append(": ");
        }
        b.append(e.toString());
        b.append("\r\nat:");
        StackTraceElement[] stack = e.getStackTrace();
        int len = (stack.length>stackTraceElements) ? stackTraceElements : stack.length; 
        for (int i=0; i<len; i++)
        {
            b.append(stack[i].toString());
            b.append("\r\n");
        }
        return b.toString();
    }

    /**
     * checks if the current context contains an error
     * @param fc the FacesContext
     * @return true if the context has an error set or false otherwise
     */
    public boolean hasError(final FacesContext fc)
    {
        Iterator<FacesMessage> msgIterator = fc.getMessages();
        if (msgIterator != null)
        { // Check Messages
            while (msgIterator.hasNext())
            { // Check Severity
                Severity fms = msgIterator.next().getSeverity();
                if (fms == FacesMessage.SEVERITY_ERROR || fms == FacesMessage.SEVERITY_FATAL)
                    return true;
            }
        }
        return false;
    }
    
    /**
     * Redirects to another page or url
     * @param fc the FacesContext
     * @param url the target url
     */
    public void redirectDirectly(final FacesContext fc, String url)
    {
        try
        {   // check params
            if (fc==null)
                throw new InvalidArgumentException("fc", fc);
            if (fc.getResponseComplete())
                throw new InvalidOperationException("Unable to redirect. Response is already complete!");
            if (url==null)
                url = StringUtils.EMPTY; // redirect to root
            // Prepend Context-Path
            ExternalContext ec = fc.getExternalContext(); 
            String ctxPath = ec.getRequestContextPath();
            if (url.indexOf("://")>0)
            {   // Should not contain the context-path
                if (url.startsWith("http") && url.indexOf(ctxPath)>0)
                    log.warn("Redirect url \"{}\" contains protokoll and context-path. Please remove.", url);
                else
                    log.info("Redirecting to absolute url {}", url);
            }
            else if (!url.startsWith(ctxPath))
            {   // assemble url
                String sep = (url.length()>0 && url.charAt(0)!='/' ? "/" : null);
                url = StringUtils.concat(ctxPath, sep, url);
                // relative
                log.debug("Redirecting to relative url {}", url);
            }
            else
                log.warn("Redirect url \"{}\" already contains context-path. Please remove.", url);
            // redirectDirectly
            ec.redirect(url);
            fc.responseComplete();
        }
        catch (IOException e)
        {   // What can we do now?
            log.error("Failed to redirect to {}", url, e);
        }
    }
    
    /**
     * Handles an exeption, that could not be handled on the page level
     * The application should redirect to the error page.
     * @param context the faces context
     * @param source the page from which the exception originated
     * @param e the Exception to handle
     */
    public void handleException(FacesContext context, Page source, Throwable e)
    {
        // log source
        String origin = (source!=null ? source.getPageDefinition().getPageBeanName() : "[Unknown]");
        log.error("Fatal error of type {} from \"{}\": {}: {}", e.getClass().getName(), origin, e.getMessage());
        
        // check handled
        boolean handled = (context.getMaximumSeverity()==FacesMessage.SEVERITY_ERROR);

        // For page errors, give the ExceptionHandler a chance to handle
        if (!handled && source!=null)
        {
            // Queue event 
            ExceptionQueuedEventContext event = new ExceptionQueuedEventContext(context, e, null, context.getCurrentPhaseId());
            event.getAttributes().put (ExceptionQueuedEventContext.IN_BEFORE_PHASE_KEY, Boolean.TRUE);
            context.getApplication().publishEvent (context, ExceptionQueuedEvent.class, event);
            
            // Handle Exception
            context.getExceptionHandler().handle(); 
            if (context.getResponseComplete())
                return;
        }
        
        // Find message
        FacesMessage facesMsg = null;
        Iterator<FacesMessage> messages = context.getMessages();
        while (messages.hasNext())
        {
            FacesMessage msg = messages.next();
            if (msg.getSeverity()==FacesMessage.SEVERITY_ERROR)
            {   // found
                facesMsg = msg;
                break;
            }
        }
        if (facesMsg==null)
            facesMsg = getFacesErrorMessage(context, origin, e);
        // Set Session Message
        ExternalContext ec = context.getExternalContext();
        ec.getSessionMap().put(Page.SESSION_MESSAGE, facesMsg);

        // If parentPage is null then redirect to ContextPath (root)
        PageDefinition parentPage = (source!=null ? source.getParentPage() : null);
        String redirectUrl = (parentPage!=null ? parentPage.getOutcome().toString() : StringUtils.EMPTY);
        redirectDirectly(context, redirectUrl);
    }
    
    /**
     * returns true if a form input element has been partially submitted
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public boolean isPartialSubmit(final FacesContext fc)
    {
        // Override for your JSF component Framework. e.g. for IceFaces
        // Map<String,String> parameterMap = fc.getExternalContext().getRequestParameterMap();
        // return ObjectUtils.getBoolean(parameterMap.get("ice.submit.partial"));
        return false;
    }

    /**
     * returns the componentId for which a partial submit has been performed.
     * @param fc the Faces Context
     * @return the componentId or null if no partial submit was been performed
     */
    public String getPartialSubmitComponentId(final FacesContext fc)
    {
        Map<String,String> parameterMap = fc.getExternalContext().getRequestParameterMap();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



