pl.chilldev.facelets.taglib.spring.web.form.ErrorsTag.java Source code

Java tutorial

Introduction

Here is the source code for pl.chilldev.facelets.taglib.spring.web.form.ErrorsTag.java

Source

/**
 * This file is part of the ChillDev-Facelets.
 *
 * @license http://mit-license.org/ The MIT license
 * @copyright 2014  by Rafa Wrzeszcz - Wrzasq.pl.
 */

package pl.chilldev.facelets.taglib.spring.web.form;

import java.io.IOException;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;

import org.springframework.web.servlet.support.RequestContext;
import org.springframework.web.servlet.tags.RequestContextAwareTag;

/**
 * Binding errors wrapper.
 *
 * @version 0.0.1
 * @since 0.0.1
 */
public class ErrorsTag extends TagHandler {
    /**
     * `path=""` attribute name.
     */
    public static final String ATTRIBUTE_PATH = "path";

    /**
     * `var=""` attribute name.
     */
    public static final String ATTRIBUTE_VAR = "var";

    /**
     * Property path attribute.
     */
    protected TagAttribute path;

    /**
     * Variable name attribute.
     */
    protected TagAttribute var;

    /**
     * Initializes handler configuration.
     *
     * @param config Handler configuration.
     * @since 0.0.1
     */
    public ErrorsTag(TagConfig config) {
        super(config);

        this.path = this.getRequiredAttribute(ErrorsTag.ATTRIBUTE_PATH);
        this.var = this.getRequiredAttribute(ErrorsTag.ATTRIBUTE_VAR);
    }

    /**
     * {@inheritDoc}
     *
     * @since 0.0.1
     */
    @Override
    public void apply(FaceletContext context, UIComponent parent) throws IOException {
        RequestContext requestContext = this.getRequestContext(context);

        // unsupported execution context
        if (requestContext == null) {
            return;
        }

        List<String> errorMessages = new ArrayList<>();
        try {
            String beanName;
            String path = this.path.getValue(context);

            // split property path
            int position = path.indexOf('.');
            if (position == -1) {
                beanName = path;
                path = null;
            } else {
                beanName = path.substring(0, position);
                path = path.substring(position + 1);
            }

            Errors errors = requestContext.getErrors(beanName, false);

            // nothing was wrong
            if (errors == null) {
                return;
            }

            // find error objects
            List<? extends ObjectError> objectErrors;
            if (path != null) {
                if ("*".equals(path)) {
                    objectErrors = errors.getAllErrors();
                } else {
                    objectErrors = errors.getFieldErrors(path);
                }
            } else {
                objectErrors = errors.getGlobalErrors();
            }

            // build messages
            for (ObjectError error : objectErrors) {
                errorMessages.add(requestContext.getMessage(error, false));
            }
        } catch (IllegalStateException error) {
            return;
        }

        String var = this.var.getValue(context);
        Object value = context.getAttribute(var);

        try {
            // invoke tag content for every error message
            for (String message : errorMessages) {
                context.setAttribute(var, message);
                this.nextHandler.apply(context, parent);
            }
        } finally {
            // recover old values
            context.setAttribute(var, value);
        }
    }

    /**
     * Attempts to retrive current request context.
     *
     * @param faceletContext Current view context.
     * @return Request context.
     * @since 0.0.1
     */
    protected RequestContext getRequestContext(FaceletContext faceletContext) {
        // first check if there is a context stored in view
        Object context = faceletContext.getAttribute(RequestContextAwareTag.REQUEST_CONTEXT_PAGE_ATTRIBUTE);
        if (context instanceof RequestContext) {
            return (RequestContext) context;
        }

        // if not then create completely new one
        RequestContext requestContext = null;
        ExternalContext externalContext = faceletContext.getFacesContext().getExternalContext();

        Object request = externalContext.getRequest();
        Object response = externalContext.getResponse();
        context = externalContext.getContext();

        // check all types
        if (request instanceof HttpServletRequest && response instanceof HttpServletResponse
                && context instanceof ServletContext) {
            requestContext = new RequestContext((HttpServletRequest) request, (HttpServletResponse) response,
                    (ServletContext) context, null);
            faceletContext.setAttribute(RequestContextAwareTag.REQUEST_CONTEXT_PAGE_ATTRIBUTE, requestContext);
        }
        return requestContext;
    }
}