View Javadoc
1   /*
2    * This software was designed and created by Jason Carroll.
3    * Copyright (c) 2002, 2003, 2004 Jason Carroll.
4    * The author can be reached at jcarroll@cowsultants.com
5    * ITracker website: http://www.cowsultants.com
6    * ITracker forums: http://www.cowsultants.com/phpBB/index.php
7    *
8    * This program is free software; you can redistribute it and/or modify
9    * it only under the terms of the GNU General Public License as published by
10   * the Free Software Foundation; either version 2 of the License, or
11   * (at your option) any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   */
18  
19  package org.itracker.web.actions.report;
20  
21  import net.sf.jasperreports.engine.*;
22  import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
23  import net.sf.jasperreports.engine.export.JRCsvExporter;
24  import net.sf.jasperreports.engine.export.JRHtmlExporter;
25  import net.sf.jasperreports.engine.export.JRPdfExporter;
26  import net.sf.jasperreports.engine.export.JRXlsExporter;
27  import org.apache.commons.beanutils.PropertyUtils;
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.log4j.Logger;
30  import org.apache.struts.action.*;
31  import org.itracker.ReportException;
32  import org.itracker.core.resources.ITrackerResourceBundle;
33  import org.itracker.core.resources.ITrackerResources;
34  import org.itracker.model.*;
35  import org.itracker.model.util.ReportUtilities;
36  import org.itracker.services.ConfigurationService;
37  import org.itracker.services.IssueService;
38  import org.itracker.services.ReportService;
39  import org.itracker.web.actions.base.ItrackerBaseAction;
40  import org.itracker.web.util.*;
41  
42  import javax.servlet.ServletException;
43  import javax.servlet.ServletOutputStream;
44  import javax.servlet.http.HttpServletRequest;
45  import javax.servlet.http.HttpServletResponse;
46  import javax.servlet.http.HttpSession;
47  import java.io.ByteArrayInputStream;
48  import java.io.File;
49  import java.io.IOException;
50  import java.text.SimpleDateFormat;
51  import java.util.*;
52  
53  
54  public class DisplayReportAction extends ItrackerBaseAction {
55      private static final Logger log = Logger.getLogger(DisplayReportAction.class);
56  
57      public DisplayReportAction() {
58      }
59  
60      public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
61          ActionMessages errors = new ActionMessages();
62  
63          try {
64              HttpSession session = request.getSession(false);
65              Locale userLocale = LoginUtilities.getCurrentLocale(request);
66  
67              List<Issue> reportingIssues = new ArrayList<Issue>();
68              String reportType = (String) PropertyUtils.getSimpleProperty(form, "type");
69              log.info("execute: report type was " + reportType);
70  
71              final Integer[] projectIds = (Integer[]) PropertyUtils.getSimpleProperty(form, "projectIds");
72              final IssueService issueService = ServletContextUtils.getItrackerServices().getIssueService();
73              final ConfigurationService configurationService = ServletContextUtils.getItrackerServices().getConfigurationService();
74              final ReportService reportService = ServletContextUtils.getItrackerServices().getReportService();
75  
76              if ("all".equalsIgnoreCase(reportType)) {
77                  // Export all of the issues in the system
78                  User currUser = (User) session.getAttribute(Constants.USER_KEY);
79                  if (!currUser.isSuperUser()) {
80                      errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.unauthorized"));
81                      throw new ReportException();
82                  }
83                  reportingIssues = issueService.getAllIssues();
84                  Collections.sort(reportingIssues, Issue.ID_COMPARATOR);
85              } else if ("project".equalsIgnoreCase(reportType)) {
86                  if (projectIds != null && projectIds.length > 0) {
87                      // This wasn't a regular search.  So instead, take all the selected projects and find all the
88                      // issues for them, check which ones the user can see, and then create a new array of issues
89                      List<Issue> reportDataList = new ArrayList<>();
90  
91                      List<Issue> issues;
92                     for (Integer projectId : projectIds) {
93                        issues = issueService.getIssuesByProjectId(projectId);
94                        for (Issue issue: issues) {
95                           if (LoginUtilities.canViewIssue(issue))
96                               reportDataList.add(issue);
97  
98                        }
99                     }
100                     reportingIssues = reportDataList;
101                     Collections.sort(reportingIssues, Issue.ID_COMPARATOR);
102 
103                 } else {
104                     throw new ReportException("", "itracker.web.error.projectrequired");
105                 }
106             } else {
107                 // This must be a regular search, look for a search query result.
108                 // must be loaded with current session (lazy loading)
109                 IssueSearchQuery isqm = (IssueSearchQuery) session.getAttribute(Constants.SEARCH_QUERY_KEY);
110                 for (Issue issue : isqm.getResults()) {
111                     reportingIssues.add(issueService.getIssue(issue.getId()));
112                 }
113             }
114 
115             log.debug("Report data contains " + reportingIssues.size() + " elements.");
116 
117             if (reportingIssues.isEmpty()) {
118                 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.noreportdata"));
119                 throw new ReportException();
120             }
121 
122             Integer reportId = (Integer) PropertyUtils.getSimpleProperty(form, "reportId");
123             String reportOutput = (String) PropertyUtils.getSimpleProperty(form, "reportOutput");
124             if (null == reportId) {
125                 log.debug("Invalid report id: " + reportId + " requested.");
126                 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.invalidreport"));
127             } else if (ReportUtilities.REPORT_EXPORT_XML == reportId.intValue()) {
128                 log.debug("Issue export requested.");
129 
130                 SystemConfiguration config = configurationService.getSystemConfiguration(ImportExportTags.EXPORT_LOCALE);
131 
132                 if (!ImportExportUtilities.exportIssues(reportingIssues, config, request, response)) {
133                     errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system"));
134                 } else {
135                    return null;
136                 }
137             } else if (reportId.intValue() > 0) {
138                 log.debug("Defined report (" + reportId + ") requested.");
139 
140                 Report reportModel = reportService.getReportDAO().findByPrimaryKey(reportId);
141 
142                 log.debug("Report " + reportModel + " found.");
143 
144                 Project project = null;
145                 log.debug("Processing report.");
146                 outputReport(reportingIssues, project, reportModel, userLocale, reportOutput, response);
147                 return null;
148 
149             }
150         } catch (ReportException re) {
151             log.debug("Error for report", re);
152             if (!StringUtils.isEmpty(re.getErrorKey())) {
153                 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(re.getErrorKey()));
154             } else {
155                 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.details", re.getMessage()));
156             }
157 
158         } catch (Exception e) {
159             log.warn("Error in report processing: " + e.getMessage(), e);
160             errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system"));
161             errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.details", e.getMessage()));
162         }
163 
164         if (!errors.isEmpty()) {
165             saveErrors(request, errors);
166         }
167 
168         return mapping.findForward("error");
169     }
170 
171 
172 
173 
174 
175     private static JasperPrint generateReport(Report report,
176                                        Map<String, Object> parameters, JRDataSource datasource)
177     throws ReportException{
178         try {
179 
180             JasperReport jasperReport = JasperCompileManager.compileReport(new ByteArrayInputStream(report.getFileData()));
181             JasperPrint jasperPrint = JasperFillManager.fillReport(
182                     jasperReport,
183                     parameters,
184                     datasource);
185 
186 
187             return jasperPrint;
188         } catch (JRException e) {
189             throw new ReportException(e);
190         }
191 
192     }
193 
194     /**
195      *
196      */
197     public static void outputReport(List<Issue> reportDataArray, Project project, Report report,
198                           Locale userLocale, String reportOutput,
199                           HttpServletResponse response) throws ReportException {
200 
201         try {
202             // hack, we have to find a more structured way to support
203             // various types of queries
204             final JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(
205                     reportDataArray);
206 
207             final Map<String, Object> parameters = new HashMap<String, Object>();
208             String reportTitle = report.getName();
209             if (project != null) {
210                 reportTitle += " - " + project.getName();
211                 if (report.getNameKey() != null) {
212                     reportTitle = ITrackerResources.getString(report.getNameKey(), project.getName());
213                 }
214             } else if (report.getNameKey() != null) {
215                 reportTitle = ITrackerResources.getString(report.getNameKey());
216             }
217             parameters.put("ReportTitle", reportTitle);
218             parameters.put("BaseDir", new File("."));
219             parameters.put("REPORT_LOCALE", userLocale);
220             parameters.put("REPORT_RESOURCE_BUNDLE", ITrackerResourceBundle.getBundle(userLocale));
221 
222             final JasperPrint jasperPrint = generateReport(report, parameters,
223                     beanCollectionDataSource);
224 
225 
226             final ServletOutputStream out = response.getOutputStream();
227             final JRExporter x;
228             if (ReportUtilities.REPORT_OUTPUT_PDF.equals(reportOutput)) {
229 
230                 response.setHeader("Content-Type", "application/pdf");
231                 response.setHeader("Content-Disposition", "attachment; filename=\"" + report.getName()
232                         + new SimpleDateFormat("-yyyy-MM-dd").format(new Date())
233                         + ".pdf\"");
234                 x = new JRPdfExporter();
235 
236             } else if (ReportUtilities.REPORT_OUTPUT_XLS.equals(reportOutput)) {
237                 response.setHeader("Content-Type", "application/xls");
238                 response.setHeader("Content-Disposition", "attachment; filename=\"" + report.getName()
239                            + new SimpleDateFormat("-yyyy-MM-dd").format(new Date())
240                            + ".xls\"");
241                 x = new JRXlsExporter();
242 
243             } else if (ReportUtilities.REPORT_OUTPUT_CSV.equals(reportOutput)) {
244 
245                 response.setHeader("Content-Type", "text/csv");
246                 response.setHeader("Content-Disposition", "attachment; filename=\"" + report.getName()
247                         + new SimpleDateFormat("-yyyy-MM-dd").format(new Date())
248                         + ".csv\"");
249                 x = new JRCsvExporter();
250 
251             } else if (ReportUtilities.REPORT_OUTPUT_HTML.equals(reportOutput)) {
252                 response.setHeader("Content-Type", "text/html");
253                 response.setHeader("Content-Disposition", "attachment; filename=\"" + report.getName()
254                         + new SimpleDateFormat("-yyyy-MM-dd").format(new Date())
255                         + ".html\"");
256                 x = new JRHtmlExporter();
257 
258             } else {
259                 log.error("Invalid report output format: " + reportOutput);
260                 throw new ReportException("Invalid report type.", "itracker.web.error.invalidreportoutput");
261             }
262             x.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
263             x.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
264 
265             x.exportReport();
266 
267             out.flush();
268             out.close();
269         } catch (JRException e) {
270             throw new ReportException(e);
271         } catch (IOException e) {
272             throw new ReportException(e);
273         }
274 
275     }
276 
277 }
278