From d9dbd1eb380ad05f8ede735d43cc71fc7eb5b078 Mon Sep 17 00:00:00 2001 From: Dilantha Silva Date: Fri, 21 Jun 2019 13:05:51 +0200 Subject: [PATCH] ReportListController and RunReportFormController updated --- .../reporting/web/reports/CommandObject.java | 128 +++++++ .../web/reports/RunReportFormController.java | 325 +++++++----------- .../web/reports/RunReportListController.java | 24 +- .../resources/webModuleApplicationContext.xml | 15 - 4 files changed, 252 insertions(+), 240 deletions(-) create mode 100644 omod/src/main/java/org/openmrs/module/reporting/web/reports/CommandObject.java diff --git a/omod/src/main/java/org/openmrs/module/reporting/web/reports/CommandObject.java b/omod/src/main/java/org/openmrs/module/reporting/web/reports/CommandObject.java new file mode 100644 index 0000000000..b266089aae --- /dev/null +++ b/omod/src/main/java/org/openmrs/module/reporting/web/reports/CommandObject.java @@ -0,0 +1,128 @@ +package org.openmrs.module.reporting.web.reports; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.openmrs.api.context.Context; +import org.openmrs.module.reporting.cohort.definition.CohortDefinition; +import org.openmrs.module.reporting.evaluation.parameter.Mapped; +import org.openmrs.module.reporting.report.definition.ReportDefinition; +import org.openmrs.module.reporting.report.renderer.RenderingMode; +import org.openmrs.module.reporting.report.renderer.ReportRenderer; +import org.openmrs.util.OpenmrsUtil; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class CommandObject { + + private String existingRequestUuid; + private ReportDefinition reportDefinition; + private Mapped baseCohort; + private Map userEnteredParams; + private String selectedRenderer; // as RendererClass!Arg + private String schedule; + private Map expressions; + + private List renderingModes; + + private transient Log log = LogFactory.getLog(this.getClass()); + + public CommandObject() { + userEnteredParams = new LinkedHashMap(); + expressions = new HashMap(); + } + + @SuppressWarnings("unchecked") + public RenderingMode getSelectedMode() { + if (selectedRenderer != null) { + try { + String[] temp = selectedRenderer.split("!"); + Class rc = (Class) Context.loadClass(temp[0]); + String arg = (temp.length > 1 && StringUtils.hasText(temp[1])) ? temp[1] : null; + for (RenderingMode mode : renderingModes) { + if (mode.getRenderer().getClass().equals(rc) && OpenmrsUtil.nullSafeEquals(mode.getArgument(), arg)) { + return mode; + } + } + log.warn("Could not find requested rendering mode: " + selectedRenderer); + } + catch (Exception e) { + log.warn("Could not load requested renderer", e); + } + } + return null; + } + + public String getExistingRequestUuid() { + return existingRequestUuid; + } + + public void setExistingRequestUuid(String existingRequestUuid) { + this.existingRequestUuid = existingRequestUuid; + } + + public List getRenderingModes() { + return renderingModes; + } + + public void setRenderingModes(List rendereringModes) { + this.renderingModes = rendereringModes; + } + + public ReportDefinition getReportDefinition() { + return reportDefinition; + } + + public void setReportDefinition(ReportDefinition reportDefinition) { + this.reportDefinition = reportDefinition; + } + + public Mapped getBaseCohort() { + return baseCohort; + } + + public void setBaseCohort(Mapped baseCohort) { + this.baseCohort = baseCohort; + } + + public String getSelectedRenderer() { + return selectedRenderer; + } + + public void setSelectedRenderer(String selectedRenderer) { + this.selectedRenderer = selectedRenderer; + } + + public Map getUserEnteredParams() { + return userEnteredParams; + } + + public void setUserEnteredParams(Map userEnteredParams) { + this.userEnteredParams = userEnteredParams; + } + + public String getSchedule() { + return schedule; + } + + public void setSchedule(String schedule) { + this.schedule = schedule; + } + + /** + * @return the expressions + */ + public Map getExpressions() { + return expressions; + } + + /** + * @param expressions the expressions to set + */ + public void setExpressions(Map expressions) { + this.expressions = expressions; + } +} diff --git a/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportFormController.java b/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportFormController.java index 012b7a1d5c..8c26234647 100644 --- a/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportFormController.java +++ b/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportFormController.java @@ -3,7 +3,6 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. - * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ @@ -19,7 +18,6 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -41,16 +39,15 @@ import org.openmrs.module.reporting.report.service.ReportService; import org.openmrs.util.OpenmrsUtil; import org.quartz.CronExpression; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; -import org.springframework.validation.BindException; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; -import org.springframework.web.bind.ServletRequestDataBinder; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.mvc.BaseCommandController; -import org.springframework.web.servlet.mvc.SimpleFormController; -import org.springframework.web.servlet.view.RedirectView; +import org.springframework.validation.*; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; /** * This controller runs a report (which must be passed in with the reportId parameter) after @@ -59,23 +56,24 @@ * page redirects to the WebReportRenderer's specified URL. Otherwise the renderer writes to this * form's response. */ -public class RunReportFormController extends SimpleFormController implements Validator { + +/** + * This controller runs a report (which must be passed in with the reportId parameter) after + * allowing the user to enter parameters (if any) and to choose a ReportRenderer. If the chosen + * ReportRenderer is a WebReportRenderer, then the report data is placed in the session and this + * page redirects to the WebReportRenderer's specified URL. Otherwise the renderer writes to this + * form's response. + */ +@Controller +public class RunReportFormController implements Validator { private transient Log log = LogFactory.getLog(this.getClass()); - - /** - * @see BaseCommandController#initBinder(HttpServletRequest, ServletRequestDataBinder) - */ - protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { - super.initBinder(request, binder); - binder.registerCustomEditor(Mapped.class, new MappedEditor()); - } - + @SuppressWarnings("rawtypes") public boolean supports(Class c) { return c == CommandObject.class; } - + @Override public void validate(Object commandObject, Errors errors) { CommandObject command = (CommandObject) commandObject; @@ -90,20 +88,20 @@ public void validate(Object commandObject, Errors errors) { } } } - + for (Map.Entry e : command.getUserEnteredParams().entrySet()) { if (e.getValue() instanceof Iterable || e.getValue() instanceof Object[]) { Object iterable = e.getValue(); if (e.getValue() instanceof Object[]) { iterable = Arrays.asList((Object[]) e.getValue()); } - + boolean hasNull = true; - + for (Object value : (Iterable) iterable) { hasNull = !ObjectUtil.notNull(value); - } - + } + if (!hasNull) { requiredParams.remove(e.getKey()); } @@ -118,19 +116,19 @@ public void validate(Object commandObject, Errors errors) { String expression = command.getExpressions().get(parameterName); if (!EvaluationUtil.isExpression(expression)){ errors.rejectValue("expressions[" + parameterName + "]", - "reporting.Report.run.error.invalidParamExpression"); + "reporting.Report.run.error.invalidParamExpression"); } } else { errors.rejectValue("userEnteredParams[" + parameterName + "]", "error.required", - new Object[] { "This parameter" }, "{0} is required"); + new Object[] { "This parameter" }, "{0} is required"); } } } - + if (reportDefinition.getDataSetDefinitions() == null || reportDefinition.getDataSetDefinitions().size() == 0) { errors.reject("reporting.Report.run.error.definitionNotDeclared"); } - + if (ObjectUtil.notNull(command.getSchedule())) { if (!CronExpression.isValidExpression(command.getSchedule())) { errors.rejectValue("schedule", "reporting.Report.run.error.invalidCronExpression"); @@ -139,69 +137,52 @@ public void validate(Object commandObject, Errors errors) { } ValidationUtils.rejectIfEmpty(errors, "selectedRenderer", "reporting.Report.run.error.noRendererSelected"); } - - @Override - protected Object formBackingObject(HttpServletRequest request) throws Exception { + + + @InitBinder + private void initBinder(WebDataBinder binder) throws Exception { + binder.registerCustomEditor(Mapped.class, new MappedEditor()); + } + + @RequestMapping(value = "/module/reporting/run/runReport.form", method = RequestMethod.GET) + protected String initializeForm(HttpServletRequest request, ModelMap model) throws Exception { CommandObject command = new CommandObject(); - if (Context.isAuthenticated()) { - ReportDefinitionService rds = Context.getService(ReportDefinitionService.class); - ReportService reportService = Context.getService(ReportService.class); - if (StringUtils.hasText(request.getParameter("copyRequest"))) { - ReportRequest req = reportService.getReportRequestByUuid(request.getParameter("copyRequest")); - // avoid lazy init exceptions - command.setReportDefinition(rds.getDefinitionByUuid(req.getReportDefinition().getParameterizable().getUuid())); - for (Map.Entry param : req.getReportDefinition().getParameterMappings().entrySet()) { - Object value = param.getValue(); - if ( value != null && EvaluationUtil.isExpression( value.toString() ) ) { - command.getExpressions().put( param.getKey(), ( String ) value ); - value = ""; - } - command.getUserEnteredParams().put(param.getKey(), value ); - } - command.setSelectedRenderer(req.getRenderingMode().getDescriptor()); - } - else if (StringUtils.hasText(request.getParameter("requestUuid"))) { - String reqUuid = request.getParameter("requestUuid"); - ReportRequest rr = reportService.getReportRequestByUuid(reqUuid); - command.setExistingRequestUuid(reqUuid); - command.setReportDefinition(rr.getReportDefinition().getParameterizable()); - command.setUserEnteredParams(rr.getReportDefinition().getParameterMappings()); - command.setBaseCohort(rr.getBaseCohort()); - command.setSelectedRenderer(rr.getRenderingMode().getDescriptor()); - command.setSchedule(rr.getSchedule()); - } - else { - String uuid = request.getParameter("reportId"); - ReportDefinition reportDefinition = rds.getDefinitionByUuid(uuid); - command.setReportDefinition(reportDefinition); - for (Parameter p : reportDefinition.getParameters()) { - if (p.getDefaultValue() != null) { - command.getUserEnteredParams().put(p.getName(), p.getDefaultValue()); - } - } - } - command.setRenderingModes(reportService.getRenderingModes(command.getReportDefinition())); - } - return command; + + fillCommandObjectData(command, request); + + model.addAttribute("report", command); + addReferenceData(model, command); + return "/module/reporting/run/runReportForm"; } - - @Override - protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object commandObject, BindException errors) throws Exception { + + @RequestMapping(value = "/module/reporting/run/runReport.form", method = RequestMethod.POST) + protected String onSubmit(@ModelAttribute("report") CommandObject commandObject, BindingResult errors, + HttpServletRequest request) throws Exception { + CommandObject command = (CommandObject) commandObject; + fillCommandObjectData(command, request); + + validate(commandObject, errors); + + if (errors.hasErrors()) { + return "/module/reporting/run/runReportForm"; + } + ReportDefinition reportDefinition = command.getReportDefinition(); - + ReportService rs = Context.getService(ReportService.class); // Parse the input parameters into appropriate objects and fail validation if any are invalid Map params = new LinkedHashMap(); - if (reportDefinition.getParameters() != null && (command.getUserEnteredParams() != null || command.getExpressions() != null)) { + if (reportDefinition.getParameters() != null && (command.getUserEnteredParams() != null + || command.getExpressions() != null)) { for (Parameter parameter : reportDefinition.getParameters()) { Object value = null; String expression = null; - if (command.getExpressions() != null && ObjectUtil.notNull(command.getExpressions().get(parameter.getName()))) { + if (command.getExpressions() != null && ObjectUtil + .notNull(command.getExpressions().get(parameter.getName()))) { expression = command.getExpressions().get(parameter.getName()); - } - else { + } else { value = command.getUserEnteredParams().get(parameter.getName()); } if (ObjectUtil.notNull(value) || ObjectUtil.notNull(expression)) { @@ -219,7 +200,7 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse } } } - + // Ensure that the chosen renderer is valid for this report RenderingMode renderingMode = command.getSelectedMode(); if (!renderingMode.getRenderer().canRender(reportDefinition)) { @@ -227,161 +208,85 @@ protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse } if (errors.hasErrors()) { - return showForm(request, response, errors); + return "/module/reporting/run/runReportForm"; } - + ReportRequest rr = null; if (command.getExistingRequestUuid() != null) { rr = rs.getReportRequestByUuid(command.getExistingRequestUuid()); - } - else { + } else { rr = new ReportRequest(); } rr.setReportDefinition(new Mapped(reportDefinition, params)); rr.setBaseCohort(command.getBaseCohort()); - rr.setRenderingMode(command.getSelectedMode()); - rr.setPriority(Priority.NORMAL); - rr.setSchedule(command.getSchedule()); - + rr.setRenderingMode(command.getSelectedMode()); + rr.setPriority(Priority.NORMAL); + rr.setSchedule(command.getSchedule()); + // TODO: We might want to check here if this exact same report request is already queued and just re-direct if so - + rr = rs.queueReport(rr); rs.processNextQueuedReports(); - - return new ModelAndView(new RedirectView("../reports/reportHistoryOpen.form?uuid="+rr.getUuid())); + + return "redirect:/module/reporting/reports/reportHistoryOpen.form?uuid=" + rr.getUuid(); } - - /** - * @see org.springframework.web.servlet.mvc.SimpleFormController#referenceData(javax.servlet.http.HttpServletRequest) - */ - @Override - protected Map referenceData(HttpServletRequest request, Object commandObject, Errors errors) throws Exception { - CommandObject command = (CommandObject) commandObject; - Map map = new HashMap(); + + private void addReferenceData(ModelMap model, CommandObject command) + throws Exception { EvaluationContext ec = new EvaluationContext(); Set expSupportedTypes = new HashSet(); Set inputsToToggle = new HashSet(); for (Object value : ec.getContextValues().values()) { expSupportedTypes.add(value.getClass().getName()); } - map.put("expSupportedTypes", expSupportedTypes); + model.addAttribute("expSupportedTypes", expSupportedTypes); for (Map.Entry e : command.getUserEnteredParams().entrySet()) { if (StringUtils.hasText(command.getExpressions().get(e.getKey()))) { - inputsToToggle.add( e.getKey() ); + inputsToToggle.add(e.getKey()); } } - map.put( "inputsToToggle", inputsToToggle ); - return map; + model.addAttribute("inputsToToggle", inputsToToggle); } - - public class CommandObject { - - private String existingRequestUuid; - private ReportDefinition reportDefinition; - private Mapped baseCohort; - private Map userEnteredParams; - private String selectedRenderer; // as RendererClass!Arg - private String schedule; - private Map expressions; - - private List renderingModes; - - public CommandObject() { - userEnteredParams = new LinkedHashMap(); - expressions = new HashMap(); - } - - @SuppressWarnings("unchecked") - public RenderingMode getSelectedMode() { - if (selectedRenderer != null) { - try { - String[] temp = selectedRenderer.split("!"); - Class rc = (Class) Context.loadClass(temp[0]); - String arg = (temp.length > 1 && StringUtils.hasText(temp[1])) ? temp[1] : null; - for (RenderingMode mode : renderingModes) { - if (mode.getRenderer().getClass().equals(rc) && OpenmrsUtil.nullSafeEquals(mode.getArgument(), arg)) { - return mode; - } + + private void fillCommandObjectData(CommandObject command, HttpServletRequest request) { + if (Context.isAuthenticated()) { + ReportDefinitionService rds = Context.getService(ReportDefinitionService.class); + ReportService reportService = Context.getService(ReportService.class); + if (StringUtils.hasText(request.getParameter("copyRequest"))) { + ReportRequest req = reportService.getReportRequestByUuid(request.getParameter("copyRequest")); + // avoid lazy init exceptions + command.setReportDefinition( + rds.getDefinitionByUuid(req.getReportDefinition().getParameterizable().getUuid())); + for (Map.Entry param : req.getReportDefinition().getParameterMappings().entrySet()) { + Object value = param.getValue(); + if (value != null && EvaluationUtil.isExpression(value.toString())) { + command.getExpressions().put(param.getKey(), (String) value); + value = ""; } - log.warn("Could not find requested rendering mode: " + selectedRenderer); + command.getUserEnteredParams().put(param.getKey(), value); } - catch (Exception e) { - log.warn("Could not load requested renderer", e); + command.setSelectedRenderer(req.getRenderingMode().getDescriptor()); + } else if (StringUtils.hasText(request.getParameter("requestUuid"))) { + String reqUuid = request.getParameter("requestUuid"); + ReportRequest rr = reportService.getReportRequestByUuid(reqUuid); + command.setExistingRequestUuid(reqUuid); + command.setReportDefinition(rr.getReportDefinition().getParameterizable()); + command.setUserEnteredParams(rr.getReportDefinition().getParameterMappings()); + command.setBaseCohort(rr.getBaseCohort()); + command.setSelectedRenderer(rr.getRenderingMode().getDescriptor()); + command.setSchedule(rr.getSchedule()); + } else { + String uuid = request.getParameter("reportId"); + ReportDefinition reportDefinition = rds.getDefinitionByUuid(uuid); + command.setReportDefinition(reportDefinition); + for (Parameter p : reportDefinition.getParameters()) { + if (p.getDefaultValue() != null) { + command.getUserEnteredParams().put(p.getName(), p.getDefaultValue()); + } } } - return null; - } - - public String getExistingRequestUuid() { - return existingRequestUuid; - } - - public void setExistingRequestUuid(String existingRequestUuid) { - this.existingRequestUuid = existingRequestUuid; - } - - public List getRenderingModes() { - return renderingModes; - } - - public void setRenderingModes(List rendereringModes) { - this.renderingModes = rendereringModes; - } - - public ReportDefinition getReportDefinition() { - return reportDefinition; - } - - public void setReportDefinition(ReportDefinition reportDefinition) { - this.reportDefinition = reportDefinition; - } - - public Mapped getBaseCohort() { - return baseCohort; - } - - public void setBaseCohort(Mapped baseCohort) { - this.baseCohort = baseCohort; - } - - public String getSelectedRenderer() { - return selectedRenderer; - } - - public void setSelectedRenderer(String selectedRenderer) { - this.selectedRenderer = selectedRenderer; - } - - public Map getUserEnteredParams() { - return userEnteredParams; - } - - public void setUserEnteredParams(Map userEnteredParams) { - this.userEnteredParams = userEnteredParams; - } - - public String getSchedule() { - return schedule; - } - - public void setSchedule(String schedule) { - this.schedule = schedule; - } - - /** - * @return the expressions - */ - public Map getExpressions() { - return expressions; - } - - /** - * @param expressions the expressions to set - */ - public void setExpressions(Map expressions) { - this.expressions = expressions; + command.setRenderingModes(reportService.getRenderingModes(command.getReportDefinition())); } } - } diff --git a/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportListController.java b/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportListController.java index c9d1aaab7b..1682be9abc 100644 --- a/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportListController.java +++ b/omod/src/main/java/org/openmrs/module/reporting/web/reports/RunReportListController.java @@ -3,29 +3,23 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. - * * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS * graphic logo is a trademark of OpenMRS Inc. */ package org.openmrs.module.reporting.web.reports; -import javax.servlet.http.HttpServletRequest; - -import org.openmrs.api.context.Context; -import org.openmrs.module.reporting.report.definition.service.ReportDefinitionService; -import org.springframework.web.servlet.mvc.SimpleFormController; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; /** * */ -public class RunReportListController extends SimpleFormController { - - /** - * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest) - */ - @Override - protected Object formBackingObject(HttpServletRequest request) throws Exception { - return Context.getService(ReportDefinitionService.class).getAllDefinitions(false); +@Controller +public class RunReportListController { + + @RequestMapping("/module/reporting/run/runReport.list") + public Object initializeForm() { + return "/module/reporting/run/runReportList"; } - + } diff --git a/omod/src/main/resources/webModuleApplicationContext.xml b/omod/src/main/resources/webModuleApplicationContext.xml index acea8c95b8..1d9fc99776 100644 --- a/omod/src/main/resources/webModuleApplicationContext.xml +++ b/omod/src/main/resources/webModuleApplicationContext.xml @@ -42,8 +42,6 @@ runReportPortletController reportRequestPortletController reportListPortletController - runReportList - runReportForm @@ -65,18 +63,5 @@ - - reports - /module/reporting/run/runReportList - runReport.list - - - report - /module/reporting/run/runReportForm - runReport.list - - - -