com.nec.harvest.controller.SonekihController.java Source code

Java tutorial

Introduction

Here is the source code for com.nec.harvest.controller.SonekihController.java

Source

/*
 * Copyright(C) 2014
 * NEC Corporation All rights reserved.
 * 
 * No permission to use, copy, modify and distribute this software
 * and its documentation for any purpose is granted.
 * This software is provided under applicable license agreement only.
 */
package com.nec.harvest.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.text.ParseException;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import com.nec.core.exception.ObjectNotFoundException;
import com.nec.harvest.bean.mapping.ProfitMonthlyBean;
import com.nec.harvest.constant.Constants;
import com.nec.harvest.exception.ServiceException;
import com.nec.harvest.http.HttpServletContentType;
import com.nec.harvest.menu.group.ProfitAndLossManagementProGroup;
import com.nec.harvest.model.Division;
import com.nec.harvest.model.Organization;
import com.nec.harvest.service.DivisionService;
import com.nec.harvest.service.OrganizationService;
import com.nec.harvest.service.ProfitMonthlyService;
import com.nec.harvest.stereotype.SessionAttribute;
import com.nec.harvest.util.DateFormatUtil;
import com.nec.harvest.util.DateFormatUtil.DateFormat;

/**
 * Provide all method to handle request from client
 * related to profit by shop of department management actions
 * 
 * @author huonghv
 */
@Controller
@RequestMapping(Constants.SONEKIH_PATH)
public class SonekihController extends ProfitAndLossManagementProGroup implements PageRenderer, TitleRenderer {

    private static final Logger logger = LoggerFactory.getLogger(SonekihController.class);

    private static final String DEFAULT_KBN_ID = "KAISOU";

    private final DivisionService divisionService;

    private final OrganizationService organizationService;

    private final ProfitMonthlyService profitMonthlyService;

    @Inject
    public SonekihController(DivisionService divisionService, OrganizationService organizationService,
            ProfitMonthlyService profitMonthlyService) {
        this.divisionService = divisionService;
        this.organizationService = organizationService;
        this.profitMonthlyService = profitMonthlyService;
    }

    /** {@inheritDoc} */
    @Override
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo,
            final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering sonekih default page view...");
        }

        // 
        model.addAttribute(PROCESSING_MONTH, businessDay);

        try {
            // Get a list of divisions
            List<Division> divisions;
            try {
                divisions = divisionService.findByKbnId(DEFAULT_KBN_ID);
            } catch (IllegalArgumentException | ObjectNotFoundException ex) {
                logger.warn(ex.getMessage());

                // Set default is empty if there is no devision
                divisions = Collections.emptyList();
            }

            model.addAttribute("classifies", divisions);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
        }

        return getViewName();
    }

    /**
     * Calculate and load data
     * 
     * @param userOrgCode
     *            Organization code from session
     * @param businessDay
     *            Business day from session
     * @param proGNo
     *            Processing menu group
     * @param unitLevel
     *            Classify code of management
     * @param unitDept
     *            Department code of management
     * @param month
     *            Processing month
     * @param request
     *            HttpServletRequest object
     * @param response
     *            HttpServletResponse object
     * @param model
     *            Model interchange between client and server
     * @return View name logic
     */
    @RequestMapping(value = "load/{unitdept}/{deptCode}/{month}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo,
            @PathVariable String unitdept, @PathVariable String deptCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date month, final Model model) {
        logger.info("Loading profit monthly data");

        try {
            // 
            loadDepartmentData(unitdept, deptCode, month, businessDay, model);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
        }
        return getViewName();
    }

    @RequestMapping(value = "/{unitLevel}/{unitDept}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo,
            @PathVariable String unitLevel, @PathVariable String unitDept, final HttpServletRequest request,
            final Model model) {

        UriComponents uriComponents = UriComponentsBuilder
                .fromUriString(Constants.SONEKIH_PATH + "/{unitLevel}/{unitDept}/{month}").build();
        String businessMonth = DateFormatUtil.format(businessDay, DateFormat.DATE_WITHOUT_DAY);
        URI uri = uriComponents.expand(proGNo, unitLevel, unitDept, businessMonth).encode().toUri();
        return "redirect:" + uri.toString();
    }

    /**
     * Handling when user type on browser's address to take calculation totally
     * of all organizations that given department manage them
     * 
     * @param userOrgCode
     *            Organization code from session
     * @param businessDay
     *            Business day from session
     * @param proGNo
     *            Processing menu group
     * @param unitLevel
     *            Classify code of management
     * @param unitDept
     *            Department code of management
     * @param month
     *            Processing month
     * @param model
     *            Model interchange between client and server
     * @return Redirect url path
     */
    @RequestMapping(value = "/{unitLevel}/{unitDept}/{month}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo,
            @PathVariable String unitLevel, @PathVariable String unitDept, final HttpServletRequest request,
            @PathVariable String month, final Model model) {
        logger.info("Loading profit monthly data by full path [/sonekih/{unitLevel}/{unitDept}/{month}]");

        try {
            /* Get processing month */
            Date processMonth = monthStandard(month, businessDay);
            if (processMonth == null) {
                UriComponents uriComponents = UriComponentsBuilder
                        .fromUriString(Constants.SONEKIH_PATH + "/{unitLevel}/{unitDept}/{deptCode}/{month}")
                        .build();
                String businessMonth = DateFormatUtil.format(businessDay, DateFormat.DATE_WITHOUT_DAY);
                URI uri = uriComponents.expand(proGNo, unitLevel, unitDept, month, businessMonth).encode().toUri();

                return "redirect:" + uri.toString();
            }

            loadClassifies(unitLevel, model);
            loadDepartments(unitLevel, unitDept, model);
            loadDepartmentPage(request, proGNo, unitDept, "-1", model);
            loadDepartmentData(unitDept, unitDept, processMonth, businessDay, model);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
        }
        return getViewName();
    }

    /**
     * Handle when user type on browser's address
     * 
     * @param userOrgCode
     *            Organization code from session
     * @param businessDay
     *            Business day from session
     * @param proGNo
     *            Processing menu group
     * @param unitLevel
     *            Classify code of management
     * @param unitDept
     *            Department code of management
     * @param deptCode
     *            Department code detail
     * @param month
     *            Processing month
     * @param model
     *            Model interchange between client and server
     * @return Page view logic name
     */
    @RequestMapping(value = "/{unitLevel}/{unitDept}/{deptCode}/{month}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo,
            @PathVariable String unitLevel, @PathVariable String unitDept, @PathVariable String deptCode,
            final HttpServletRequest request, @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date month,
            final Model model) {
        logger.info(
                "Loading profit monthly data by full path [/sonekih/{unitLevel}/{unitDept}/{deptCode}/{month}]");

        try {
            loadClassifies(unitLevel, model);
            loadDepartments(unitLevel, unitDept, model);
            loadDepartmentPage(request, proGNo, unitDept, deptCode, model);
            loadDepartmentData(unitDept, deptCode, month, businessDay, model);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
        }
        return getViewName();
    }

    /**
     * Check string input is a date time type or not
     * 
     * @param month
     *            Data to check
     * @param businessMonth
     *            Business month get from session
     * @return Data in date type
     */
    private Date monthStandard(String month, Date businessMonth) {
        try {
            Date processMonth = DateFormatUtil.parse(month, DateFormat.DATE_WITHOUT_DAY);
            return processMonth;
        } catch (NullPointerException | IllegalArgumentException | ParseException ex) {
            logger.warn(ex.getMessage());
        }
        return null;
    }

    /**
     * Calculate and load given department data
     * 
     * @param selectedDepartment
     *            Given department
     * @param processingMonth
     *            The processing month
     * @param businessMonth
     *            Business month get from session
     * @param model
     *            Model interchange between client and server
     */
    private void loadDepartmentData(String unitDepartment, String selectedDepartment, Date processingMonth,
            Date businessMonth, Model model) {
        ProfitMonthlyBean profitMonthlyBean = profitMonthlyService
                .aggregateProfitMonthlyByDepartment(selectedDepartment, processingMonth, businessMonth);

        // 
        model.addAttribute(PROCESSING_MONTH, processingMonth);
        model.addAttribute("profitMonthly", profitMonthlyBean);

        /* Check next month */
        Date monthAvailable = null;
        try {
            monthAvailable = profitMonthlyService.checkAvailableByOrgCodeAndMothly(unitDepartment, processingMonth,
                    businessMonth, true);
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());
            //
            monthAvailable = null;
        }

        // Next monthly data
        model.addAttribute(NEXT_MONTH, monthAvailable);

        /* Check previous month */
        try {
            monthAvailable = profitMonthlyService.checkAvailableByOrgCodeAndMothly(unitDepartment, processingMonth,
                    businessMonth, false);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            //
            monthAvailable = null;
        }

        // Previous monthly data
        model.addAttribute(PREVIOUS_MONTH, monthAvailable);
    }

    /**
     * Load given department current page
     * 
     * @param request
     *            HttpServletRequest
     * @param processingGroup
     *            Current processing group menu
     * @param selectedDepartment
     *            Given department
     * @param model
     *            Model interchange between client and server
     */
    private void loadDepartmentPage(HttpServletRequest request, String processingGroup, String selectedDepartment,
            String processingDepartment, Model model) {
        if (StringUtils.isEmpty(processingGroup) || StringUtils.isEmpty(selectedDepartment)) {
            model.addAttribute("page", null);
            model.addAttribute("manualLoad", false);
        }

        UriComponents uriComponent = UriComponentsBuilder
                .fromUriString(
                        request.getContextPath() + "/{proNo}/pagination/paging/{orglevel}/{deptCode}/{index}")
                .build();
        URI uri = uriComponent.expand(processingGroup, selectedDepartment, processingDepartment, 0).encode()
                .toUri();

        try {
            HttpClient client = HttpClientBuilder.create().build();
            HttpHost host = new HttpHost(request.getServerName(), request.getLocalPort(), request.getScheme());
            HttpGet get = new HttpGet(uri);
            HttpResponse response = client.execute(host, get);

            // Get the content
            String htmlPage = read(response.getEntity().getContent());

            // 
            model.addAttribute("page", htmlPage);
            model.addAttribute("manualLoad", true);
            model.addAttribute("unitDept", selectedDepartment);
            model.addAttribute("deptCode", processingDepartment);
        } catch (IOException ex) {
            logger.error(ex.getMessage(), ex);
        }
    }

    /**
     * Get classify list
     * 
     * @param selectedClassify
     *            Current department classify
     * @param model
     *            Model interchange between client and server
     */
    private void loadClassifies(String selectedClassify, Model model) {
        List<Division> divisions;
        try {
            divisions = divisionService.findByKbnId(DEFAULT_KBN_ID);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            // Set default is empty if there is no division
            divisions = Collections.emptyList();
        }

        model.addAttribute("classifies", divisions);
        model.addAttribute("unitLevel", getDisplayClassfyName(divisions, selectedClassify));
    }

    /**
     * Get departments list
     * 
     * @param selectedClassify
     *            Department's classify
     * @param selectedDepartment
     *            Department is selected
     * @param model
     * 
     */
    private void loadDepartments(String selectedClassify, String selectedDepartment, Model model) {
        List<Organization> departments = null;
        try {
            // Get the list of organizations level 2
            departments = organizationService.findByKaisoBango(selectedClassify);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());
        }

        model.addAttribute("departments", departments);
        model.addAttribute("unitDeptName", getDisplayDepartmentName(departments, selectedDepartment));
    }

    /**
     * Get data from input stream into string type
     * 
     * @param in
     *            Input stream
     * @return Data from input stream in string type
     * @throws IOException
     *             When runtime exception
     */
    private String read(InputStream in) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader r = new BufferedReader(new InputStreamReader(in, HttpServletContentType.DEFAULT_ENCODING));
        for (String line = r.readLine(); line != null; line = r.readLine()) {
            sb.append(line);
        }
        in.close();
        return sb.toString();
    }

    /**
     * Get full display of classify to show on page
     * 
     * @param classifies
     *            List of classify
     * @param classify
     *            Classify code to get name
     * @return Name of classify in strings
     */
    private String getDisplayClassfyName(List<Division> classifies, String classify) {
        if (CollectionUtils.isNotEmpty(classifies) && StringUtils.isNotEmpty(classify)) {
            boolean result = false;
            for (int i = 0; i < classifies.size(); i++) {
                result = result || classifies.get(i).getKbnCode().equalsIgnoreCase(classify);
                Division division = classifies.get(i);
                if (division.getKbnCode().equalsIgnoreCase(classify)) {
                    return (classify + ": " + division.getKbnName());
                }
            }
            return null;
        }
        return null;
    }

    /**
     * Get full display of department to show on page
     * 
     * @param departments
     *            List of department
     * @param deptCode
     *            Department code to get name
     * @return Department name in string
     */
    private String getDisplayDepartmentName(List<Organization> departments, String deptCode) {
        if (CollectionUtils.isNotEmpty(departments) && StringUtils.isNotEmpty(deptCode)) {
            for (int i = 0; i < departments.size(); i++) {
                Organization department = departments.get(i);
                if (department.getStrCode().equalsIgnoreCase(deptCode)) {
                    return deptCode + ": " + department.getStrNameR();
                }
            }
            return null;
        }
        return null;
    }

    /** {@inheritDoc} */
    @Override
    public String getViewName() {
        return "sonekih/sonekih";
    }

    @Override
    public String getTitleName() {
        return "??";
    }
}