jp.co.nemuzuka.core.controller.JsonController.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.nemuzuka.core.controller.JsonController.java

Source

/*
 * Copyright 2012 Kazumune Katagiri. (http://d.hatena.ne.jp/nemuzuka)
 *
 * 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 jp.co.nemuzuka.core.controller;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.logging.Level;

import jp.co.nemuzuka.core.annotation.TokenCheck;
import jp.co.nemuzuka.core.annotation.Validation;
import jp.co.nemuzuka.core.entity.JsonResult;
import jp.co.nemuzuka.exception.AlreadyExistKeyException;
import net.arnx.jsonic.JSON;

import org.apache.commons.lang.StringUtils;
import org.slim3.controller.Navigation;
import org.slim3.controller.validator.Validators;
import org.slim3.util.ApplicationMessage;

/**
 * JSON?????Controller.
 * @author kazumune
 */
public abstract class JsonController extends AbsController {

    /** token?. */
    private static final String TOKEN_ERR_KEY = "jp.co.nemuzuka.token.err";
    /** ??. */
    private static final String SEVERE_ERR_KEY = "jp.co.nemuzuka.severe.err";
    /** ???. */
    private static final String SETUP_ERROR = "jp.co.nemuzuka.setup.error";
    /** ???. */
    private static final String SESSION_TIMEOUT_ERROR = "jp.co.nemuzuka.session.timeout.error";

    /**
     * ?.
     * ?JSON?????????
     * @return JSON
     * @throws Exception 
     */
    abstract protected Object execute() throws Exception;

    /**
     * ?.
     * ?commit??ThreadLocal????
     * @see org.slim3.controller.Controller#run()
     */
    @Override
    protected Navigation run() throws Exception {

        //?????????????
        String setUpError = requestScope(SETUP_ERROR);
        if (StringUtils.isNotEmpty(setUpError)) {
            return null;
        }

        Object obj = null;
        try {
            obj = execute();
            if (obj == null) {
                throw new AssertionError("execute() must not be null.");
            }
            executeCommit();
        } catch (ConcurrentModificationException e) {
            //????????Json????
            super.tearDown();
            JsonResult result = new JsonResult();
            result.setStatus(JsonResult.VERSION_ERR);
            result.getErrorMsg().add(ApplicationMessage.get("errors.version"));
            obj = result;
        } catch (AlreadyExistKeyException e) {
            //?????????Json????
            super.tearDown();
            JsonResult result = new JsonResult();
            result.setStatus(JsonResult.DUPLICATE_ERR);
            result.getErrorMsg().add(ApplicationMessage.get("errors.duplicate"));
            obj = result;
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
            throw e;
        }
        return writeJsonObj(obj);
    }

    /**
     * ??.
     * ActionForm?
     * TokenCheck
     * validation
     * ?ThreadLocal?
     * ???
     * @see org.slim3.controller.Controller#setUp()
     */
    @SuppressWarnings("rawtypes")
    @Override
    protected Navigation setUp() {
        super.setUp();
        Class clazz = getClass();

        setUserService();

        //ActionForm?
        setActionForm(clazz);

        //Sesison???????
        boolean sessionCheck = executeSessionCheck(clazz);
        if (sessionCheck == false) {
            errors.put("message", ApplicationMessage.get("errors.session.timeout"));
            requestScope(SESSION_TIMEOUT_ERROR, "1");
            jsonError();
            return null;
        }

        //TokenCheck?ProjectAdmin?ProjectMember?????
        boolean status = executeTokenCheck(clazz);
        boolean projectAdmin = executeProjectAdminCheck(clazz);
        boolean projectMember = executeProjectMemberCheck(clazz);
        boolean systemManager = executeSystemManagerCheck(clazz);

        if (status && projectAdmin && projectMember && systemManager) {
            //validation?????
            status = executeValidation(clazz);
            if (status == false) {
                return null;
            }
            //???
            setTransaction();
        } else {
            requestScope(SETUP_ERROR, "1");
        }
        return null;
    }

    /**
     * ?.
     * @see org.slim3.controller.Controller#handleError(java.lang.Throwable)
     */
    @Override
    protected Navigation handleError(Throwable error) throws Throwable {
        logger.log(Level.SEVERE, error.getMessage(), error);
        errors.put("message", ApplicationMessage.get("errors.severe"));
        requestScope(SEVERE_ERR_KEY, "1");
        return jsonError();
    }

    /**
     * JSON???.
     * ??JSON?????
     * @param obj JSON
     * @return null
     * @throws IOException IO
     */
    protected Navigation writeJsonObj(Object obj) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.getWriter().write(JSON.encode(obj));
        response.flushBuffer();
        return null;
    }

    /**
     * JSON??????
     * ????JSON????
     * @return null
     */
    public Navigation jsonError() {
        JsonResult result = new JsonResult();
        for (Map.Entry<String, String> target : errors.entrySet()) {
            result.getErrorMsg().add(target.getValue());
        }
        String jsonError = requestScope(TOKEN_ERR_KEY);
        String severeError = requestScope(SEVERE_ERR_KEY);
        String sessionTimeOut = requestScope(SESSION_TIMEOUT_ERROR);

        if (StringUtils.isNotEmpty(jsonError)) {
            //Token
            result.setStatus(JsonResult.TOKEN_ERROR);
        } else if (StringUtils.isNotEmpty(severeError)) {
            //?
            result.setStatus(JsonResult.SEVERE_ERROR);
        } else if (StringUtils.isNotEmpty(sessionTimeOut)) {
            //Session
            result.setStatus(JsonResult.SESSION_TIMEOUT);
        } else {
            //?
            result.setStatus(JsonResult.STATUS_NG);
        }
        try {
            //???
            requestScope(SETUP_ERROR, "1");
            return writeJsonObj(result);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * JsonResult?.
     * ????JsonResult????
     * @param key Key
     * @param obj 
     * @return JsonResult
     */
    protected JsonResult createErrorMsg(String key, Object... obj) {
        JsonResult result = new JsonResult();
        result.setStatus(JsonResult.STATUS_NG);
        result.getErrorMsg().add(ApplicationMessage.get(key, obj));
        return result;
    }

    /**
     * validation.
     * ??@Validation??????????validate???
     * @param clazz 
     * @return ?? or validatation????true/????false
     */
    @SuppressWarnings({ "rawtypes" })
    private boolean executeValidation(Class clazz) {
        //execute?Validatetion?????
        Method target = null;
        try {
            target = getDeclaredMethod(clazz, "execute", (Class[]) null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        Validation validation = target.getAnnotation(Validation.class);
        if (validation != null) {

            Validators validators = (Validators) invoke(clazz, validation.method());

            //validate
            boolean bret = validators.validate();

            //???
            if (bret == false) {
                //input??????????
                invoke(getClass(), validation.input());
                return false;
            }
        }
        return true;
    }

    /**
     * token?.
     * ??@TokenCheck???????token????
     * ??????false????
     * @param clazz 
     * @return ?? or ???????true/????false
     */
    @SuppressWarnings({ "rawtypes" })
    private boolean executeTokenCheck(Class clazz) {
        //execute?TokenCheck?????
        Method target = null;
        try {
            target = getDeclaredMethod(clazz, "execute", (Class[]) null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        TokenCheck tokenCheck = target.getAnnotation(TokenCheck.class);
        if (tokenCheck != null) {

            if (isTokenCheck() == false) {
                //request???JSON???
                errors.put("message", ApplicationMessage.get("errors.token"));
                requestScope(TOKEN_ERR_KEY, "1");
                jsonError();
                return false;
            }
        }
        return true;
    }
}