org.ngrinder.home.controller.HomeController.java Source code

Java tutorial

Introduction

Here is the source code for org.ngrinder.home.controller.HomeController.java

Source

/* 
 * 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 org.ngrinder.home.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.lang.StringUtils;
import org.ngrinder.common.constant.ControllerConstants;
import org.ngrinder.common.controller.BaseController;
import org.ngrinder.common.util.ThreadUtils;
import org.ngrinder.home.model.PanelEntry;
import org.ngrinder.home.service.HomeService;
import org.ngrinder.infra.logger.CoreLogger;
import org.ngrinder.infra.schedule.ScheduledTaskService;
import org.ngrinder.model.Role;
import org.ngrinder.model.User;
import org.ngrinder.region.service.RegionService;
import org.ngrinder.script.handler.ScriptHandlerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.http.HttpEntity;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

import static org.ngrinder.common.util.ExceptionUtils.processException;
import static org.ngrinder.common.util.Preconditions.checkNotNull;

/**
 * Home index page controller.
 *
 * @author JunHo Yoon
 * @since 3.0
 */
@Controller
public class HomeController extends BaseController implements ControllerConstants {

    private static final Logger LOG = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    private HomeService homeService;

    @Autowired
    private RegionService regionService;

    @Autowired
    private ScriptHandlerFactory scriptHandlerFactory;

    private static final String TIMEZONE_ID_PREFIXES = "^(Africa|America|Asia|Atlantic|"
            + "Australia|Europe|Indian|Pacific)/.*";

    private List<TimeZone> timeZones = null;

    @Autowired
    private ScheduledTaskService scheduledTaskService;

    private static Gson rawObjectJsonSerializer = new GsonBuilder().setPrettyPrinting().create();

    /**
     * Initialize {@link HomeController}.
     */
    @PostConstruct
    public void init() {
        timeZones = new ArrayList<TimeZone>();
        final String[] timeZoneIds = TimeZone.getAvailableIDs();
        for (final String id : timeZoneIds) {
            if (id.matches(TIMEZONE_ID_PREFIXES) && !TimeZone.getTimeZone(id).getDisplayName().contains("GMT")) {
                timeZones.add(TimeZone.getTimeZone(id));
            }
        }
        Collections.sort(timeZones, new Comparator<TimeZone>() {
            public int compare(final TimeZone a, final TimeZone b) {
                return a.getID().compareTo(b.getID());
            }
        });
        scheduledTaskService.runAsync(new Runnable() {
            @Override
            public void run() {
                getLeftPanelEntries();
                getRightPanelEntries();
            }
        });
    }

    /**
     * Return nGrinder index page.
     *
     * @param user      user
     * @param exception exception if it's redirected from exception handler
     * @param region    region. where this access comes from. it's optional
     * @param model     model
     * @param response  response
     * @param request   request
     * @return "index" if already logged in. Otherwise "login".
     */
    @RequestMapping(value = { "/home", "/" })
    public String home(User user, @RequestParam(value = "exception", defaultValue = "") String exception,
            @RequestParam(value = "region", defaultValue = "") String region, ModelMap model,
            HttpServletResponse response, HttpServletRequest request) {
        try {
            Role role;
            try {
                recordReferrer(region);
                // set local language
                setLanguage(getCurrentUser().getUserLanguage(), response, request);
                setLoginPageDate(model);
                role = user.getRole();
            } catch (AuthenticationCredentialsNotFoundException e) {
                return "login";
            }
            setPanelEntries(model);
            model.addAttribute("handlers", scriptHandlerFactory.getVisibleHandlers());

            if (StringUtils.isNotBlank(exception)) {
                model.addAttribute("exception", exception);
            }
            if (role == Role.ADMIN || role == Role.SUPER_USER || role == Role.USER) {
                return "index";
            } else {
                LOG.info("Invalid user role:{}", role.getFullName());
                return "login";
            }
        } catch (Exception e) {
            // Make the home reliable...
            model.addAttribute("exception", e.getMessage());
            return "index";
        }
    }

    private void setPanelEntries(ModelMap model) {
        model.addAttribute("left_panel_entries", getLeftPanelEntries());
        model.addAttribute("right_panel_entries", getRightPanelEntries());
        model.addAttribute("ask_question_url",
                getConfig().getControllerProperties().getProperty(PROP_CONTROLLER_FRONT_PAGE_ASK_QUESTION_URL,
                        getMessages(PROP_CONTROLLER_FRONT_PAGE_ASK_QUESTION_URL)));
        model.addAttribute("see_more_question_url", getConfig().getControllerProperties().getProperty(
                PROP_CONTROLLER_FRONT_PAGE_QNA_MORE_URL, getMessages(PROP_CONTROLLER_FRONT_PAGE_QNA_MORE_URL)));
        model.addAttribute("see_more_resources_url",
                getConfig().getControllerProperties().getProperty(PROP_CONTROLLER_FRONT_PAGE_RESOURCES_MORE_URL));

    }

    private List<PanelEntry> getRightPanelEntries() {
        if (getConfig().getControllerProperties().getPropertyBoolean(PROP_CONTROLLER_FRONT_PAGE_ENABLED)) {
            // Get nGrinder Resource RSS
            String rightPanelRssURL = getConfig().getControllerProperties()
                    .getProperty(PROP_CONTROLLER_FRONT_PAGE_RESOURCES_RSS);
            return homeService.getRightPanelEntries(rightPanelRssURL);
        }
        return Collections.emptyList();
    }

    private List<PanelEntry> getLeftPanelEntries() {
        if (getConfig().getControllerProperties().getPropertyBoolean(PROP_CONTROLLER_FRONT_PAGE_ENABLED)) {
            // Make the i18n applied QnA panel. Depending on the user language, show the different QnA panel.
            String leftPanelRssURLKey = getMessages(PROP_CONTROLLER_FRONT_PAGE_QNA_RSS);
            // Make admin configure the QnA panel.
            String leftPanelRssURL = getConfig().getControllerProperties()
                    .getProperty(PROP_CONTROLLER_FRONT_PAGE_QNA_RSS, leftPanelRssURLKey);
            return homeService.getLeftPanelEntries(leftPanelRssURL);
        }
        return Collections.emptyList();
    }

    private void recordReferrer(String region) {
        if (StringUtils.isNotEmpty(region)) {
            CoreLogger.LOGGER.info("Accessed to {}", region);
        }
    }

    /**
     * Return the health check message. If there is shutdown lock, it returns
     * 503. Otherwise it returns region lists.
     *
     * @param response response
     * @return region list
     */
    @RequestMapping("/check/healthcheck")
    public HttpEntity<String> healthCheck(HttpServletResponse response) {
        if (getConfig().hasShutdownLock()) {
            try {
                response.sendError(503, "nGrinder is about to down");
            } catch (IOException e) {
                LOG.error("While running healthCheck() in HomeController, the error occurs.");
                LOG.error("Details : ", e);
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("current", regionService.getCurrent());
        map.put("regions", regionService.getAll());
        return toJsonHttpEntity(map, rawObjectJsonSerializer);
    }

    /**
     * Return health check message with 1 sec delay. If there is shutdown lock,
     * it returns 503. Otherwise, it returns region lists.
     *
     * @param sleep    in milliseconds.
     * @param response response
     * @return region list
     */
    @ResponseBody
    @RequestMapping("/check/healthcheck_slow")
    public HttpEntity<String> healthCheckSlowly(@RequestParam(value = "delay", defaultValue = "1000") int sleep,
            HttpServletResponse response) {
        ThreadUtils.sleep(sleep);
        return healthCheck(response);
    }

    private void setLanguage(String lan, HttpServletResponse response, HttpServletRequest request) {
        LocaleResolver localeResolver = checkNotNull(RequestContextUtils.getLocaleResolver(request),
                "No LocaleResolver found!");
        LocaleEditor localeEditor = new LocaleEditor();
        String language = StringUtils.defaultIfBlank(lan,
                getConfig().getControllerProperties().getProperty(PROP_CONTROLLER_DEFAULT_LANG));
        localeEditor.setAsText(language);
        localeResolver.setLocale(request, response, (Locale) localeEditor.getValue());
    }

    /**
     * Return the login page.
     *
     * @param model model
     * @return "login" if not logged in. Otherwise, "/"
     */
    @RequestMapping(value = "/login")
    public String login(ModelMap model) {
        setLoginPageDate(model);
        model.addAttribute("signUpEnabled", getConfig().isSignUpEnabled());
        final String defaultLang = getConfig().getControllerProperties()
                .getProperty(ControllerConstants.PROP_CONTROLLER_DEFAULT_LANG);
        model.addAttribute("defaultLang", defaultLang);
        try {
            getCurrentUser();
        } catch (Exception e) {
            CoreLogger.LOGGER.info("Login Failure " + e.getMessage());
            return "login";
        }
        model.clear();
        return "redirect:/";
    }

    private void setLoginPageDate(ModelMap model) {
        TimeZone defaultTime = TimeZone.getDefault();
        model.addAttribute("timezones", timeZones);
        model.addAttribute("defaultTime", defaultTime.getID());
    }

    /**
     * Error redirection to 404.
     *
     * @return "redirect:/doError"
     */
    @RequestMapping(value = "/error_404")
    public String error404(ModelMap model) {
        model.clear();
        return "redirect:/doError?type=404";
    }

    /**
     * Error redirection as a second phase.
     *
     * @param user     user
     * @param model    model
     * @param response response
     * @param request  request
     * @return "index"
     */
    @RequestMapping(value = "/doError")
    public String second(User user, ModelMap model, HttpServletResponse response, HttpServletRequest request) {
        String parameter = request.getParameter("type");
        if ("404".equals(parameter)) {
            model.addAttribute("exception", processException("Requested URL does not exist"));
        }
        return home(user, null, null, model, response, request);
    }

}