com.jd.survey.web.statistics.StatisticsController.java Source code

Java tutorial

Introduction

Here is the source code for com.jd.survey.web.statistics.StatisticsController.java

Source

/*Copyright (C) 2014  JD Software, Inc.
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.jd.survey.web.statistics;

import java.awt.Color;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.PieSectionLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.Rotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.annotation.Secured;
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.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.jd.survey.domain.security.User;
import com.jd.survey.domain.settings.Question;
import com.jd.survey.domain.settings.QuestionOption;
import com.jd.survey.domain.settings.QuestionRowLabel;
import com.jd.survey.domain.settings.SurveyDefinition;
import com.jd.survey.domain.settings.SurveyDefinitionPage;
import com.jd.survey.domain.survey.QuestionStatistic;
import com.jd.survey.domain.survey.SurveyStatistic;
import com.jd.survey.service.security.SecurityService;
import com.jd.survey.service.security.UserService;
import com.jd.survey.service.settings.SurveySettingsService;
import com.jd.survey.service.survey.SurveyService;

@RequestMapping("/statistics")
@Controller
public class StatisticsController {
    private static final Log log = LogFactory.getLog(StatisticsController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private SurveyService surveyService;
    @Autowired
    private SurveySettingsService surveySettingsService;
    @Autowired
    private SecurityService securityService;
    @Autowired
    private MessageSource messageSource;

    private static final String DATE_FORMAT = "date_format";

    private static final String SURVEY_LABEL = "com.jd.survey.domain.settings.surveydefinition_label_short";
    private static final String TOTAL_LABEL = "com.jd.survey.domain.survey.surveystatistic.totalcount_label";
    private static final String COMPLETED_LABEL = "com.jd.survey.domain.survey.surveystatistic.submittedcount_label";
    private static final String OPTION_FREQUENCY_LABEL = "com.jd.survey.domain.survey.questionstatistic.frequency_label";
    private static final String NO_STATSTISTICS_MESSAGE = "statistics_not_applicable_message";
    private static final String PAGE_LABEL = "com.jd.survey.domain.survey.surveypage_label_short";
    private static final String OPTION_LABEL = "com.jd.survey.domain.settings.questionoption_label_short";
    private static final String MINIMUM_LABEL = "com.jd.survey.domain.survey.questionstatistic.min_label";
    private static final String MAXIMUM_LABEL = "com.jd.survey.domain.survey.questionstatistic.max_label";
    private static final String AVERAGE_LABEL = "com.jd.survey.domain.survey.questionstatistic.average_label";
    private static final String STANDARD_DEVIATION_LABEL = "com.jd.survey.domain.survey.questionstatistic.samplestandarddeviation_label";
    private static final String FALSE_LABEL = "false_message";
    private static final String TRUE_LABEL = "true_message";

    void populateModel(Model uiModel, Long surveyDefinitionId, Question question, User user, String... args) {
        try {
            //
            SurveyDefinition surveyDefinition = surveySettingsService.surveyDefinition_findById(surveyDefinitionId);
            //show all definition
            Set<SurveyDefinition> surveyDefinitions = surveySettingsService
                    .surveyDefinition_findAllCompletedInternal(user);
            //show total digits
            SurveyStatistic surveyStatistic = surveyService.surveyStatistic_get(surveyDefinitionId, args);

            Long recordCount = surveyStatistic.getSubmittedCount();

            uiModel.addAttribute("question", question);
            uiModel.addAttribute("questionId", question.getId());
            uiModel.addAttribute("surveyDefinition", surveyDefinition);
            uiModel.addAttribute("surveyDefinitions", surveyDefinitions);
            uiModel.addAttribute("surveyStatistic", surveyStatistic);
            uiModel.addAttribute("recordCount", recordCount);
            List<QuestionStatistic> lq = surveyService.questionStatistic_getStatistics(question, recordCount, args);
            uiModel.addAttribute("questionStatistics", lq);

            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("questionText", question.getQuestionText());
            jsonObject.addProperty("order", question.getOrder());
            jsonObject.addProperty("visible", question.getVisible());
            jsonObject.addProperty("required", question.getRequired());
            jsonObject.addProperty("code", question.getType().getCode());
            jsonObject.add("options", new JsonArray());
            if ("SR".equals(question.getType().getCode()) || "MC".equals(question.getType().getCode())) {
                SortedSet<QuestionOption> options = question.getOptions();
                for (QuestionOption row : options) {
                    JsonObject optionJsonOject = new JsonObject();
                    jsonObject.getAsJsonArray("options").add(optionJsonOject);
                    optionJsonOject.addProperty("text", row.getText());
                    optionJsonOject.addProperty("value", row.getValue());
                    optionJsonOject.addProperty("order", row.getOrder());
                    for (QuestionStatistic qs : lq) {
                        if (qs.getEntry().equals(row.getValue())) {
                            optionJsonOject.addProperty("frequency", qs.getFrequency());
                            break;
                        } else {
                            optionJsonOject.addProperty("frequency", 0);
                        }
                    }
                }
            }
            System.out.println(jsonObject.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }

    }

    /**
     * Shows a list of Survey Definitions 
     * @param surveyId
     * @param principal
     * @param uiModel
     * @param httpServletRequest
     * @return
     */
    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    @RequestMapping(produces = "text/html", method = RequestMethod.GET)
    public String listSurveys(Model uiModel, Principal principal) {
        try {

            User user = userService.user_findByLogin(principal.getName());
            Set<SurveyDefinition> surveyDefinitions = surveySettingsService
                    .surveyDefinition_findAllCompletedInternal(user);
            uiModel.addAttribute("surveyDefinitions", surveyDefinitions);
            return "statistics/statistics";
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    /**
     * Shows a list of Survey Entries for a Survey Definition, Supports Paging 
     * @param surveyId
     * @param principal
     * @param uiModel
     * @param httpServletRequest
     * @return
     */
    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    @RequestMapping(value = "/list", produces = "text/html", method = RequestMethod.GET)
    public String listSurveyEntries(@RequestParam(value = "sid", required = true) Long surveyDefinitionId,
            @RequestParam(value = "qid", required = false) Long questionId,
            @RequestParam(value = "shopId", required = false) String shopId, Model uiModel, Principal principal,
            HttpServletRequest httpServletRequest) {

        try {

            Question question;
            User user = userService.user_findByLogin(principal.getName());
            if (!securityService.userIsAuthorizedToManageSurvey(surveyDefinitionId, user)) {
                log.warn("Unauthorized access to url path " + httpServletRequest.getPathInfo()
                        + " attempted by user login:" + principal.getName() + "from IP:"
                        + httpServletRequest.getLocalAddr());
                return "accessDenied";
            }

            //get the first question
            if (questionId == null) {
                question = surveySettingsService.question_findByOrder(surveyDefinitionId, (short) 1, (short) 1);
            } else {
                question = surveySettingsService.question_findById(questionId);
            }
            if (StringUtils.isNotEmpty(shopId)) {
                populateModel(uiModel, surveyDefinitionId, question, user, shopId);
            } else {
                populateModel(uiModel, surveyDefinitionId, question, user);
            }

            Set<String> ls = surveyService.survey_findgetShops();
            uiModel.addAttribute("shops", ls);

            return "statistics/statistics";
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    /**
     * export the single Survey to a PDF 
     * @param surveyId
     * @param principal
     * @param uiModel
     * @param httpServletRequest
     * @return
     */
    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    @RequestMapping(value = "/pdf/{id}", produces = "text/html")
    public ModelAndView exportSurveyToPdf(@PathVariable("id") Long surveyDefinitionId, Principal principal,
            HttpServletRequest httpServletRequest, HttpServletResponse response) {

        try {

            User user = userService.user_findByLogin(principal.getName());
            if (!securityService.userIsAuthorizedToManageSurvey(surveyDefinitionId, user)) {
                log.warn("Unauthorized access to url path " + httpServletRequest.getPathInfo()
                        + " attempted by user login:" + principal.getName() + "from IP:"
                        + httpServletRequest.getLocalAddr());
                throw (new RuntimeException("Unauthorized access"));
            }
            ModelAndView modelAndView = new ModelAndView("statisticsPdf");

            Map<String, String> messages = new TreeMap<String, String>();

            messages.put("surveyLabel",
                    messageSource.getMessage(SURVEY_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("totalLabel",
                    messageSource.getMessage(TOTAL_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("completedLabel",
                    messageSource.getMessage(COMPLETED_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("optionFrequencyLabel",
                    messageSource.getMessage(OPTION_FREQUENCY_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("noStatstisticsMessage",
                    messageSource.getMessage(NO_STATSTISTICS_MESSAGE, null, LocaleContextHolder.getLocale()));

            messages.put("pageLabel", messageSource.getMessage(PAGE_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("optionLabel",
                    messageSource.getMessage(OPTION_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("minimumLabel",
                    messageSource.getMessage(MINIMUM_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("maximumLabel",
                    messageSource.getMessage(MAXIMUM_LABEL, null, LocaleContextHolder.getLocale()));

            messages.put("averageLabel",
                    messageSource.getMessage(AVERAGE_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("standardDeviationLabel",
                    messageSource.getMessage(STANDARD_DEVIATION_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("date_format",
                    messageSource.getMessage(DATE_FORMAT, null, LocaleContextHolder.getLocale()));
            messages.put("falseLabel",
                    messageSource.getMessage(FALSE_LABEL, null, LocaleContextHolder.getLocale()));
            messages.put("trueLabel", messageSource.getMessage(TRUE_LABEL, null, LocaleContextHolder.getLocale()));

            SurveyDefinition surveyDefinition = surveySettingsService.surveyDefinition_findById(surveyDefinitionId);
            SurveyStatistic surveyStatistic = surveyService.surveyStatistic_get(surveyDefinitionId);
            Long recordCount = surveyStatistic.getSubmittedCount();
            modelAndView.addObject("surveyDefinition", surveyDefinition);
            modelAndView.addObject("surveyStatistic", surveyStatistic);
            modelAndView.addObject("messages", messages);
            Map<String, List<QuestionStatistic>> allquestionStatistics = new TreeMap<String, List<QuestionStatistic>>();

            for (SurveyDefinitionPage page : surveyDefinition.getPages()) {
                for (Question question : page.getQuestions()) {
                    List<QuestionStatistic> questionStatistics = surveyService
                            .questionStatistic_getStatistics(question, recordCount);
                    allquestionStatistics.put("q" + question.getId().toString(), questionStatistics);
                }
            }
            modelAndView.addObject("allquestionStatistics", allquestionStatistics);
            return modelAndView;

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    /**
     * Controller that handles the chart generation for a question statistics
     * @param surveyDefinitionId
     * @param pageOrder
     * @param questionOrder
     * @param recordCount
     * @param response
     */
    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    @RequestMapping(value = "/chart/{surveyDefinitionId}/{questionId}")
    public void generatePieChart(@PathVariable("surveyDefinitionId") Long surveyDefinitionId,
            @PathVariable("questionId") Long questionId, HttpServletResponse response) {
        try {
            response.setContentType("image/png");
            long recordCount = surveyService.surveyStatistic_get(surveyDefinitionId).getSubmittedCount();
            PieDataset pieDataSet = createDataset(questionId, recordCount);
            JFreeChart chart = createChart(pieDataSet, "");
            ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, 340, 200);
            response.getOutputStream().close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    private PieDataset createDataset(Long questionId, Long recordCount) {
        try {
            String columnValue = "";
            Question question = surveySettingsService.question_findById(questionId);
            List<QuestionStatistic> questionStatistics = surveyService.questionStatistic_getStatistics(question,
                    recordCount);
            DefaultPieDataset defaultPieDataset = new DefaultPieDataset();
            for (QuestionStatistic questionStatistic : questionStatistics) {
                //double percentage = ((double)questionStatistic.getCount()/(double)recordCount) * 100;
                //percentage = Double.valueOf(new DecimalFormat("#.##").format(percentage));
                defaultPieDataset.setValue(questionStatistic.getEntry(), questionStatistic.getFrequency() * 100);
            }
            return defaultPieDataset;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    @Secured({ "ROLE_ADMIN", "ROLE_SURVEY_ADMIN" })
    private JFreeChart createChart(PieDataset pieDataset, String title) {
        try {
            JFreeChart chart = ChartFactory.createPieChart(title, pieDataset, false, true, false);

            chart.setBackgroundPaint(null);//this line necessary for transparency of background
            final ChartPanel chartPanel = new ChartPanel(chart);
            chartPanel.setOpaque(false); //this line necessary for transparency of background
            chartPanel.setBackground(new Color(0, 0, 0, 0)); //this line necessary for transparency of background

            PiePlot plot = (PiePlot) chart.getPlot();

            //Color[] colors = {new Color(170, 195, 217, 255),new Color(246, 140, 31, 255),new Color(204, 204, 204, 255),new Color(231, 238, 144, 255),new Color(51, 51, 51, 255),new Color(101, 125, 151, 255),new Color(0, 102, 255, 255)}; 
            //PieRenderer renderer = new PieRenderer(colors); 
            //renderer.setColor(plot, pieDataset);

            PieSectionLabelGenerator generator = new StandardPieSectionLabelGenerator("{0}:{1}%");
            plot.setLabelGenerator(generator);

            plot.setStartAngle(270);
            plot.setDirection(Rotation.CLOCKWISE);

            return chart;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw (new RuntimeException(e));
        }
    }

    /**
     * Not Used
     * @author Admin
     *
     */
    static class PieRenderer {
        private Color[] color;

        public PieRenderer(Color[] color) {
            this.color = color;
        }

        public void setColor(PiePlot plot, PieDataset dataset) {
            List<Comparable> keys = dataset.getKeys();
            int aInt;

            for (int i = 0; i < keys.size(); i++) {
                aInt = i % this.color.length;
                plot.setSectionPaint(keys.get(i), this.color[aInt]);
            }
        }
    }

}