ch.ralscha.extdirectspring.bean.ExtDirectResponseBuilder.java Source code

Java tutorial

Introduction

Here is the source code for ch.ralscha.extdirectspring.bean.ExtDirectResponseBuilder.java

Source

/**
 * Copyright 2010-2016 Ralph Schaer <ralphschaer@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ch.ralscha.extdirectspring.bean;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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

import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.MessageSource;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import ch.ralscha.extdirectspring.controller.Configuration;
import ch.ralscha.extdirectspring.controller.RouterController;
import ch.ralscha.extdirectspring.util.ExtDirectSpringUtil;

/**
 * An utility class that helps building the response for a FORM_POST method. The response
 * is written directly into the {@link HttpServletResponse#getOutputStream()} with
 * {@link #buildAndWrite()}.
 */
public class ExtDirectResponseBuilder {

    private final ExtDirectResponse extDirectResponse;

    private final HttpServletRequest request;

    private final HttpServletResponse response;

    private final Map<String, Object> result;

    private Class<?> jsonView;

    /**
     * Creates a builder that builds and writes the response of a FORM_POST method. Sets
     * the successful flag to true, can be changed with the {@link #successful()} and
     * {@link #unsuccessful()} methods.
     *
     * @param request the current http servlet request object
     * @param response the current http servlet response object
     */
    public ExtDirectResponseBuilder(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;

        this.extDirectResponse = new ExtDirectResponse(request);
        this.result = new HashMap<String, Object>();
        successful();
        this.extDirectResponse.setResult(this.result);
    }

    /**
     * Creates a builder instance.
     *
     * @see #ExtDirectResponseBuilder(HttpServletRequest, HttpServletResponse)
     *
     * @param request the current http servlet request object
     * @param response the current http servlet response object
     *
     * @return the created builder instance
     */
    public static ExtDirectResponseBuilder create(HttpServletRequest request, HttpServletResponse response) {
        return new ExtDirectResponseBuilder(request, response);
    }

    /**
     * Creates an "exception" response. Calls {@link ExtDirectResponse#setType(String)}
     * with a value of "exception". Calls {@link ExtDirectResponse#setMessage(String)} and
     * {@link ExtDirectResponse#setWhere(String)} according to the {@link Configuration}.
     *
     * This is a method primarily used for implementations of
     * {@link HandlerExceptionResolver}.
     *
     * @param exception the exception that was thrown.
     * @return this instance
     */
    public ExtDirectResponseBuilder setException(Exception exception) {
        unsuccessful();

        WebApplicationContext ctx = RequestContextUtils.findWebApplicationContext(this.request);
        Configuration configuration;
        try {
            configuration = ctx.getBean(Configuration.class);
        } catch (NoSuchBeanDefinitionException e) {
            configuration = new Configuration();
        }

        this.extDirectResponse.setType("exception");
        this.extDirectResponse.setMessage(configuration.getMessage(exception));

        if (configuration.isSendStacktrace()) {
            this.extDirectResponse.setWhere(ExtDirectSpringUtil.getStackTrace(exception));
        } else {
            this.extDirectResponse.setWhere(null);
        }

        return this;
    }

    /**
     * Adds an "errors" property in the response if there are any errors in the
     * bindingResult. Sets the success flag to false if there are errors.
     *
     * @param bindingResult
     * @return this instance
     */
    public ExtDirectResponseBuilder addErrors(BindingResult bindingResult) {
        addErrors(null, null, bindingResult);
        return this;
    }

    /**
     * Adds an "errors" property in the response if there are any errors in the
     * bindingResult. Sets the success flag to false if there are errors.
     *
     * @param locale
     * @param messageSource
     * @param bindingResult
     * @return this instance
     */
    public ExtDirectResponseBuilder addErrors(Locale locale, MessageSource messageSource,
            final BindingResult bindingResult) {
        if (bindingResult != null && bindingResult.hasFieldErrors()) {
            Map<String, List<String>> errorMap = new HashMap<String, List<String>>();
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                String message = fieldError.getDefaultMessage();
                if (messageSource != null) {
                    Locale loc = locale != null ? locale : Locale.getDefault();
                    message = messageSource.getMessage(fieldError.getCode(), fieldError.getArguments(), loc);
                }
                List<String> fieldErrors = errorMap.get(fieldError.getField());

                if (fieldErrors == null) {
                    fieldErrors = new ArrayList<String>();
                    errorMap.put(fieldError.getField(), fieldErrors);
                }

                fieldErrors.add(message);
            }
            if (errorMap.isEmpty()) {
                addResultProperty("success", Boolean.TRUE);
            } else {
                addResultProperty("errors", errorMap);
                addResultProperty("success", Boolean.FALSE);
            }
        }
        return this;
    }

    /**
     * Add additional property to the response.
     *
     * @param key the key of the property
     * @param value the value of this property
     * @return this instance
     */
    public ExtDirectResponseBuilder addResultProperty(String key, Object value) {
        this.result.put(key, value);
        return this;
    }

    /**
     * Sets success flag to true.
     *
     * @return this instance
     */
    public ExtDirectResponseBuilder successful() {
        this.result.put("success", Boolean.TRUE);
        return this;
    }

    /**
     * Sets success flag to false.
     *
     * @return this instance
     */
    public ExtDirectResponseBuilder unsuccessful() {
        this.result.put("success", Boolean.FALSE);
        return this;
    }

    /**
     * Sets success flag to the provided parameter.
     *
     * @param flag the new success value
     * @return this instance
     */
    public ExtDirectResponseBuilder setSuccess(boolean flag) {
        this.result.put("success", flag);
        return this;
    }

    /**
     * Sets a specific JSON View (filter) that Jackson uses to serialize the response.
     *
     * @param jsonView
     */
    public void setJsonView(Class<?> jsonView) {
        this.jsonView = jsonView;
    }

    /**
     * Builds and writes the response into the OutputStream of {@link HttpServletResponse}
     * . This methods has to be called at the end of a FORM_POST method.
     */
    public void buildAndWrite() {

        try {
            RouterController routerController = RequestContextUtils.findWebApplicationContext(this.request)
                    .getBean(RouterController.class);

            routerController.writeJsonResponse(this.request, this.response, this.extDirectResponse, this.jsonView);

        } catch (IOException e) {
            LogFactory.getLog(getClass()).error("buildAndWrite", e);
            throw new RuntimeException(e);
        }

    }

}