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 }