br.com.itw.commons.aop.OnSuccessAdvice.java Source code

Java tutorial

Introduction

Here is the source code for br.com.itw.commons.aop.OnSuccessAdvice.java

Source

/**
 *  Guick Generate class: https://github.com/wdavilaneto/guick
 *  Author: service-wdavilaneto@redhat.com
 *  This source is free under The Apache Software License, Version 2.0
 *  license url http://www.apache.org/licenses/LICENSE-2.0.txt
 */
package br.com.itw.commons.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

/**
 * Created by Igor Veloso
 * Date: 22/10/14
 * Time: 21:51
 * <p/>
 * Este aspecto intercepta o retorno qualquer mtodo anotado como @Okable.
 * O retorno deve ser do tipo HttpEntity. O cdigo de mensagem  obtido do messages.properties pelo Spring.
 * O aspecto retorna a mensagem de sucesso no header do HttpResponse assim como um ttulo da entidade sendo
 * manipulada. Caso necessite de um nome melhor tratado, basta incluir (no mesmo bundle), um nome customizado
 * com o seguinte cdigo: Okable.httpResponse.headers.title.'sua.propria.Entidade'=Qualquer nome
 * Alm disso, inclui um HttpStatus.OK no response
 */
@Aspect
public class OnSuccessAdvice {

    public static final String SUCESSO_TITLE = "Sucesso!";
    public static final String SUCESSO_MSG = "SucessoDefault";

    public static final String TITLE = "title";
    public static final String MESSAGE = "message";
    public static final String ON_SUCCESS = "OnSuccess.";
    public static final String ERRO_GET = "Um mtodo no pode aceitar requisies GET com outros tipos";
    public static final String ERRO_SEM_METODO_DEFINIDO = " necessrio definir um RequestMethod.method() em sua annotation";

    @Resource
    MessageSource messageSource;

    @Around("execution(public * br.com.itw.qopsearch.api.**.*.*(..)) && @annotation(requestMapping)")
    public HttpEntity onSuccess(ProceedingJoinPoint pjp, RequestMapping requestMapping) throws Throwable {

        int length = requestMapping.method().length;
        if (length == 0) {
            throw new IllegalArgumentException(ERRO_SEM_METODO_DEFINIDO);
        }

        boolean containsGet = Arrays.asList(requestMapping.method()).contains(RequestMethod.GET);
        if (containsGet && length > 1) {
            throw new IllegalArgumentException(ERRO_GET);
        }

        Object object = null;
        Object objectBody = null;
        HttpStatus httpStatus = HttpStatus.OK;

        String methodName = pjp.getSignature().getName();

        if (!containsGet && !methodName.startsWith("find") && !methodName.startsWith("search")) {

            object = pjp.proceed();

            HttpEntity httpEntity;
            ResponseEntity responseEntity;

            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            String prefixCode = ON_SUCCESS + pjp.getTarget().getClass().getSimpleName() + "." + methodName;

            String titleCode = prefixCode + "." + TITLE;
            String messageCode = prefixCode + "." + MESSAGE;

            if (!pjp.getSignature().toString().startsWith("void")) {

                if (object instanceof ResponseEntity) {
                    responseEntity = (ResponseEntity) object;
                    httpStatus = responseEntity.getStatusCode();
                    objectBody = responseEntity.getBody();
                } else if (object instanceof HttpEntity) {
                    httpEntity = (HttpEntity) object;

                    httpStatus = httpEntity == null ? HttpStatus.NO_CONTENT : HttpStatus.CREATED;
                    if (HttpStatus.CREATED.equals(httpStatus))
                        objectBody = httpEntity.getBody();
                }

                String title = messageSource.getMessage(titleCode, null, SUCESSO_TITLE, Locale.getDefault());
                headers.add(TITLE, title);

                String sucessoDefault = messageSource.getMessage(SUCESSO_MSG, null, Locale.getDefault());
                String message = messageSource.getMessage(messageCode, null, sucessoDefault, Locale.getDefault());
                headers.add(MESSAGE, message);

                return new ResponseEntity(objectBody, headers, httpStatus);
            } else {
                //Mtodos do tipo void, no tem como fazer nada, o desenvolvedor decidiu retornar 200
                return null;
            }

        }

        return httpGetEntity(pjp, objectBody, httpStatus);

    }

    /**
     * Para mtodos do tipo GET, eu verifico se o retorno  nulo ou vazio (no caso de lista)
     * retorna um status NOT_FOUND que pode ser tratado na tela
     *
     * @param pjp
     * @param objectBody
     * @param httpStatus
     * @return
     * @throws Throwable
     */
    private HttpEntity httpGetEntity(ProceedingJoinPoint pjp, Object objectBody, HttpStatus httpStatus)
            throws Throwable {
        HttpEntity returnObject;

        returnObject = (HttpEntity) pjp.proceed();
        boolean found = false;
        if (returnObject != null) {
            objectBody = returnObject.getBody();
            if (objectBody != null) {
                if (objectBody instanceof List) {
                    List objectList = (List) objectBody;
                    found = !objectList.isEmpty();
                } else if (objectBody instanceof Page) {
                    found = ((Page) objectBody).getTotalElements() != 0;
                } else {
                    found = true;
                }
            }
        }

        ResponseEntity responseEntity = null;
        if (returnObject instanceof ResponseEntity) {
            responseEntity = (ResponseEntity) returnObject;
            httpStatus = responseEntity.getStatusCode();
        }

        if (!found && responseEntity == null)
            httpStatus = HttpStatus.NOT_FOUND;
        return new ResponseEntity(objectBody, httpStatus);
    }
}