1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.service.impl;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.text.MessageFormat;
25 import java.util.Arrays;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.Map;
29
30 import net.sf.jasperreports.engine.JRDataSource;
31 import net.sf.jasperreports.engine.JRException;
32 import net.sf.jasperreports.engine.JasperCompileManager;
33 import net.sf.jasperreports.engine.JasperRunManager;
34 import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
35
36 import org.apache.commons.lang.StringUtils;
37 import org.kuali.ole.sys.OLEConstants;
38 import org.kuali.ole.sys.OLEConstants.ReportGeneration;
39 import org.kuali.ole.sys.service.ReportGenerationService;
40 import org.kuali.rice.core.api.datetime.DateTimeService;
41 import org.springframework.core.io.ClassPathResource;
42 import org.springframework.ui.jasperreports.JasperReportsUtils;
43
44
45
46
47 public class ReportGenerationServiceImpl implements ReportGenerationService {
48 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ReportGenerationServiceImpl.class);
49
50 protected DateTimeService dateTimeService;
51
52 public final static String PARAMETER_NAME_SUBREPORT_DIR = ReportGeneration.PARAMETER_NAME_SUBREPORT_DIR;
53 public final static String PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME = ReportGeneration.PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME;
54
55 public final static String DESIGN_FILE_EXTENSION = ReportGeneration.DESIGN_FILE_EXTENSION;
56 public final static String JASPER_REPORT_EXTENSION = ReportGeneration.JASPER_REPORT_EXTENSION;
57 public final static String PDF_FILE_EXTENSION = ReportGeneration.PDF_FILE_EXTENSION;
58
59 public final static String SEPARATOR = "/";
60
61
62
63
64 public void generateReportToPdfFile(Map<String, Object> reportData, String template, String reportFileName) {
65 List<String> data = Arrays.asList(OLEConstants.EMPTY_STRING);
66 JRDataSource dataSource = new JRBeanCollectionDataSource(data);
67
68 generateReportToPdfFile(reportData, dataSource, template, reportFileName);
69 }
70
71
72
73
74
75
76
77 public void generateReportToPdfFile(Map<String, Object> reportData, Object dataSource, String template, String reportFileName) {
78 ClassPathResource resource = getReportTemplateClassPathResource(template);
79 if (resource == null || !resource.exists()) {
80 throw new IllegalArgumentException("Cannot find the template file: " + template);
81 }
82
83 try {
84 if (reportData != null && reportData.containsKey(PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME)) {
85 Map<String, String> subReports = (Map<String, String>) reportData.get(PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME);
86 String subReportDirectory = (String) reportData.get(PARAMETER_NAME_SUBREPORT_DIR);
87 compileSubReports(subReports, subReportDirectory);
88 }
89
90 String realTemplateNameWithoutExtension = removeTemplateExtension(resource);
91 String designTemplateName = realTemplateNameWithoutExtension.concat(DESIGN_FILE_EXTENSION);
92 String jasperReportName = realTemplateNameWithoutExtension.concat(JASPER_REPORT_EXTENSION);
93 compileReportTemplate(designTemplateName, jasperReportName);
94
95 JRDataSource jrDataSource = JasperReportsUtils.convertReportData(dataSource);
96
97 reportFileName = reportFileName + PDF_FILE_EXTENSION;
98 File reportDirectory = new File(StringUtils.substringBeforeLast(reportFileName, SEPARATOR));
99 if(!reportDirectory.exists()) {
100 reportDirectory.mkdir();
101 }
102
103 JasperRunManager.runReportToPdfFile(jasperReportName, reportFileName, reportData, jrDataSource);
104 }
105 catch (Exception e) {
106 LOG.error(e);
107 throw new RuntimeException("Fail to generate report.", e);
108 }
109 }
110
111
112
113
114
115 public void generateReportToOutputStream(Map<String, Object> reportData, Object dataSource, String template, ByteArrayOutputStream baos) {
116 ClassPathResource resource = getReportTemplateClassPathResource(template);
117 if (resource == null || !resource.exists()) {
118 throw new IllegalArgumentException("Cannot find the template file: " + template);
119 }
120
121 try {
122 if (reportData != null && reportData.containsKey(PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME)) {
123 Map<String, String> subReports = (Map<String, String>) reportData.get(PARAMETER_NAME_SUBREPORT_TEMPLATE_NAME);
124 String subReportDirectory = (String) reportData.get(PARAMETER_NAME_SUBREPORT_DIR);
125 compileSubReports(subReports, subReportDirectory);
126 }
127
128 String realTemplateNameWithoutExtension = removeTemplateExtension(resource);
129 String designTemplateName = realTemplateNameWithoutExtension.concat(DESIGN_FILE_EXTENSION);
130 String jasperReportName = realTemplateNameWithoutExtension.concat(JASPER_REPORT_EXTENSION);
131 compileReportTemplate(designTemplateName, jasperReportName);
132
133 JRDataSource jrDataSource = JasperReportsUtils.convertReportData(dataSource);
134
135 InputStream inputStream = new FileInputStream(jasperReportName);
136
137 JasperRunManager.runReportToPdfStream(inputStream, (OutputStream) baos, reportData, jrDataSource);
138 }
139 catch (Exception e) {
140 LOG.error(e);
141 throw new RuntimeException("Fail to generate report.", e);
142 }
143 }
144
145
146
147
148
149 public String buildFullFileName(Date runDate, String directory, String fileName, String extension) {
150 String runtimeStamp = dateTimeService.toDateTimeStringForFilename(runDate);
151 String fileNamePattern = "{0}" + SEPARATOR + "{1}_{2}{3}";
152
153 return MessageFormat.format(fileNamePattern, directory, fileName, runtimeStamp, extension);
154 }
155
156
157
158
159
160
161
162
163 protected ClassPathResource getReportTemplateClassPathResource(String reportTemplateName) {
164 if (reportTemplateName.endsWith(DESIGN_FILE_EXTENSION) || reportTemplateName.endsWith(JASPER_REPORT_EXTENSION)) {
165 return new ClassPathResource(reportTemplateName);
166 }
167
168 String jasperReport = reportTemplateName.concat(JASPER_REPORT_EXTENSION);
169 ClassPathResource resource = new ClassPathResource(jasperReport);
170 if (resource.exists()) {
171 return resource;
172 }
173
174 String designTemplate = reportTemplateName.concat(DESIGN_FILE_EXTENSION);
175 resource = new ClassPathResource(designTemplate);
176 return resource;
177 }
178
179
180
181
182
183
184
185 protected void compileReportTemplate(String designTemplate, String jasperReport) throws JRException {
186 File jasperFile = new File(jasperReport);
187 File designFile = new File(designTemplate);
188
189 if (!jasperFile.exists() && !designFile.exists()) {
190 throw new RuntimeException("Both the design template file and jasper report file don't exist: (" + designTemplate + ", " + jasperReport + ")");
191 }
192
193 if (!jasperFile.exists() && designFile.exists()) {
194 JasperCompileManager.compileReportToFile(designTemplate, jasperReport);
195 }
196 else if (jasperFile.exists() && designFile.exists()) {
197 if (jasperFile.lastModified() < designFile.lastModified()) {
198 JasperCompileManager.compileReportToFile(designTemplate, jasperReport);
199 }
200 }
201 }
202
203
204
205
206
207
208
209 protected void compileSubReports(Map<String, String> subReports, String subReportDirectory) throws Exception {
210 for (Map.Entry<String, String> entry: subReports.entrySet()) {
211 ClassPathResource resource = getReportTemplateClassPathResource(subReportDirectory + entry.getValue());
212 String realTemplateNameWithoutExtension = removeTemplateExtension(resource);
213
214 String designTemplateName = realTemplateNameWithoutExtension.concat(DESIGN_FILE_EXTENSION);
215 String jasperReportName = realTemplateNameWithoutExtension.concat(JASPER_REPORT_EXTENSION);
216
217 compileReportTemplate(designTemplateName, jasperReportName);
218 }
219 }
220
221
222
223
224
225
226
227 protected String removeTemplateExtension(ClassPathResource template) throws IOException {
228 String realTemplateName = template.getFile().getAbsolutePath();
229
230 int lastIndex = realTemplateName.lastIndexOf(".");
231 String realTemplateNameWithoutExtension = lastIndex > 0 ? realTemplateName.substring(0, lastIndex) : realTemplateName;
232
233 return realTemplateNameWithoutExtension;
234 }
235
236
237
238
239
240
241 public void setDateTimeService(DateTimeService dateTimeService) {
242 this.dateTimeService = dateTimeService;
243 }
244 }