/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright © 2013 VillageReach * * 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.  For additional information contact info@OpenLMIS.org.  */ package org.openlmis.reporting.service; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperReport; import org.openlmis.reporting.model.Template; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.view.jasperreports.*; import javax.servlet.http.HttpServletRequest; import javax.sql.DataSource; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Properties; import static java.io.File.createTempFile; import static net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN; import static org.apache.commons.io.FileUtils.writeByteArrayToFile; import static org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext; /** * Exposes the services for generating jasper report multi format view using a data source to fetch data. */ @Service public class JasperReportsViewFactory { @Autowired DataSource replicationDataSource; protected static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition"; private static final String PDF = "PDF"; private static final String XLS = "XLS"; private static final String HTML = "HTML"; private static final String CSV = "CSV"; public JasperReportsMultiFormatView getJasperReportsView(Template template) throws IOException, ClassNotFoundException, JRException { JasperReportsMultiFormatView jasperView = new JasperReportsMultiFormatView(); setExportParams(jasperView); setDataSourceAndURLAndApplicationContext(template, jasperView); return jasperView; } private void setExportParams(JasperReportsMultiFormatView jasperView) { Map<JRExporterParameter, Object> reportFormatMap = new HashMap<>(); reportFormatMap.put(IS_USING_IMAGES_TO_ALIGN, false); jasperView.setExporterParameters(reportFormatMap); } private void setDataSourceAndURLAndApplicationContext(Template template, JasperReportsMultiFormatView jasperView) throws IOException, ClassNotFoundException, JRException { WebApplicationContext ctx = getCurrentWebApplicationContext(); jasperView.setJdbcDataSource(replicationDataSource); jasperView.setUrl(getReportURLForReportData(template)); if (ctx != null) jasperView.setApplicationContext(ctx); } public String getReportURLForReportData(Template template) throws IOException, ClassNotFoundException, JRException { File tmpFile = createTempFile(template.getName() + "_temp", ".jasper"); ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(template.getData())); JasperReport jasperReport = (JasperReport) inputStream.readObject(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(jasperReport); writeByteArrayToFile(tmpFile, bos.toByteArray()); return tmpFile.toURI().toURL().toString(); } public AbstractJasperReportsSingleFormatView getJasperReportsView(HttpServletRequest httpServletRequest, DataSource dataSource, Template url, String format, String fileName) throws IOException, ClassNotFoundException, JRException { String viewFormat = format==null?"pdf":format; // set possible content headers Properties availableHeaders = new Properties(); availableHeaders.put("html", "inline; filename="+fileName+".html"); availableHeaders.put("csv", "inline; filename="+fileName+".csv"); availableHeaders.put("pdf", "inline; filename="+fileName+".pdf"); availableHeaders.put("xls", "inline; filename="+fileName+".xls"); // get jasperView class based on the format supplied // defaults to pdf AbstractJasperReportsSingleFormatView jasperView = null; switch (viewFormat.toUpperCase()) { case CSV: jasperView = new JasperReportsCsvView(); break; case XLS: jasperView = new JasperReportsXlsView(); break; case PDF: jasperView = new JasperReportsPdfView(); break; case HTML: jasperView = new JasperReportsHtmlView(); break; default: } // get appContext. required by the view WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext( httpServletRequest.getSession().getServletContext()); // set the appropriate content disposition header. Properties headers = new Properties(); headers.put(HEADER_CONTENT_DISPOSITION, availableHeaders.get(viewFormat)); // set the relevant jasperView properties if (jasperView != null) { jasperView.setJdbcDataSource(replicationDataSource); jasperView.setUrl(getReportURLForReportData(url)); jasperView.setApplicationContext(ctx); jasperView.setHeaders(headers); } // return view return jasperView; } }