Java tutorial
/*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]); } } } }