package model.manager.reports;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import model.manager.excel.conversion.exceptions.ReportException;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.apache.log4j.Logger;
import org.celllife.idart.database.hibernate.util.HibernateUtil;
import org.celllife.idart.database.hibernate.util.JDBCUtil;
import org.celllife.idart.misc.iDARTUtil;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.hibernate.Session;
import com.jasperassistant.designer.viewer.ViewerApp;
/**
* Abstract class with functionality for viewing a JasperReports. Extend this
* class for each report implementing the {@link #generateData()},
* {@link #getParameterMap()}, {@link #getReportFileName()}
*
* @author Simon Kelly
*
*/
public abstract class AbstractJasperReport implements iDARTReport {
protected static Logger log = Logger.getLogger(PepfarReport.class);
protected final Shell parent;
protected final Session hSession;
private JasperPrint jp;
public AbstractJasperReport(Shell parent) {
this.parent = parent;
this.hSession = HibernateUtil.getNewSession();
}
public Session getHSession() {
return hSession;
}
/**
* This method is called before the report is generated and can be used to
* generate CSV files etc.
*
* @throws ReportException
*/
protected abstract void generateData() throws ReportException;
/**
* @return the filename of the report (excluding the extension)
*/
protected abstract String getReportFileName();
/**
* @return the parameter map to pass to the report
* @throws ReportException
*/
protected abstract Map<String, Object> getParameterMap()
throws ReportException;
protected Object getDataSource() throws ReportException {
try {
return JDBCUtil.currentSession();
} catch (SQLException e) {
throw new ReportException("Error getting data source", e);
}
}
/**
* @return the path to where the iDART reports are kept
* (<idartroot>/Reports/)
*
* @throws ReportException
*/
protected String getReportPath() throws ReportException {
File path = new File("Reports" + java.io.File.separator);
try {
return path.getCanonicalPath();
} catch (IOException e) {
throw new ReportException("Error getting report path", e);
}
}
/**
* Give the input date this method returns a new date on the same day at
* 00:00:00
*
* @param theDate
* @return
*/
protected static Date getBeginningOfDay(Date theDate) {
return iDARTUtil.getBeginningOfDay(theDate);
}
/**
* Give the input date this method returns a new date on the same day at
* 23:59:59
*
* @param theDate
* @return
*/
protected static Date getEndOfDay(Date theDate) {
return iDARTUtil.getEndOfDay(theDate);
}
/*
* (non-Javadoc)
*
* @seemodel.manager.iDARTReport#fillReport(org.eclipse.core.runtime.
* IProgressMonitor)
*/
@Override
public void fillReport(IProgressMonitor monitor) throws ReportException {
try {
monitor.setTaskName("Getting report file");
String reportFileName = getReportFileName();
if (reportFileName == null || reportFileName.isEmpty())
throw new ReportException("Unable to find report file.");
FileInputStream fi = getJasperReportFromJRXMLorJASPER(reportFileName);
monitor.worked(5);
monitor.setTaskName("Generating report data");
generateData();
monitor.worked(45);
Object dataSource = getDataSource();
if (dataSource == null)
throw new ReportException("Unable to get report datasource.");
monitor.setTaskName("Getting report parameters");
Map<String, Object> parameters = getParameterMap();
monitor.worked(5);
if (parameters == null)
throw new ReportException("Null parameter map for report");
monitor.setTaskName("Generating report");
if (dataSource instanceof Connection) {
Connection connection = (Connection) dataSource;
jp = JasperFillManager.fillReport(fi, parameters, connection);
} else if (dataSource instanceof JRDataSource) {
JRDataSource jrDataSource = (JRDataSource) dataSource;
jp = JasperFillManager.fillReport(fi, parameters, jrDataSource);
}
monitor.worked(45);
} catch (JRException e) {
throw new ReportException("Error filling report", e);
}
}
/*
* (non-Javadoc)
*
* @see model.manager.iDARTReport#viewReport()
*/
@Override
public void viewReport() {
Runnable runner = new Runnable() {
@Override
public void run() {
if (jp != null) {
if (jp.getPages().size() > 0) {
ViewerApp viewer = new ViewerApp();
viewer.getReportViewer().setDocument(jp);
viewer.open();
} else {
MessageBox mNoPages = new MessageBox(parent,
SWT.ICON_ERROR | SWT.OK);
mNoPages.setText("Report Has No Pages");
mNoPages
.setMessage("The report you are trying to generate does not contain any data. \n\nPlease check the input values you have entered (such as dates) for this report, and try again.");
mNoPages.open();
}
}
}
};
Display.getCurrent().asyncExec(runner);
}
/**
* Returns the Fileinputstream for file.jasper From file.jrxml if
* file.jasper does not exist
*
* @param file
* String
* @return FileInputStream
*/
protected FileInputStream getJasperReportFromJRXMLorJASPER(String file) {
String path = "Reports" + java.io.File.separator + file;
FileInputStream result = null;
try {
FileInputStream jasper = new FileInputStream(path + ".jasper");
result = jasper;
} catch (FileNotFoundException fe) {
log.info(path + ".jasper not found, generating file from " + path
+ ".jrxml");
try {
FileInputStream jrxml = new FileInputStream(path + ".jrxml");
FileOutputStream jasperOut = new FileOutputStream(path
+ ".jasper");
JasperCompileManager.compileReportToStream(jrxml, jasperOut);
result = new FileInputStream(path + ".jasper");
} catch (FileNotFoundException e) {
log.error("\nTime of crash " + new Date() + " " + path
+ ".jrxml not found! Missing Report File");
} catch (JRException jre) {
log.error("\nTime of crash " + new Date()
+ " JasperReport Exception");
jre.printStackTrace();
}
}
return result;
}
/**
* Given a list of String[]'s this method will write them to a CSV file.
* Each String[] will be on a new line and each String in the array is
* separated by a comma.
*
* @param fileName
* @param fileContents
* @param escapeAllStrings
* if true wrap strings in inverted commas
* @return
*/
protected File createCSVFile(String fileName, List<String[]> fileContents,
boolean escapeAllStrings) {
File csvFile = null;
try {
// write to csv file
csvFile = new File("Reports" + java.io.File.separator + fileName);
FileWriter out = new FileWriter(csvFile);
// print the row strings
for (String[] theStringArr : fileContents) {
for (int i = 0; i < theStringArr.length; i++) {
if (theStringArr[i] != null) {
if (i != 0) {
out.write(",");
}
if (escapeAllStrings) {
out.write("\"" + theStringArr[i] + "\"");
} else {
out.write(theStringArr[i]);
}
} else {
out.write(",");
}
}
out.write(",\n");
}
out.close();
} catch (IOException e) {
log.error("Error writing csv report file: " + e.getMessage() + ":"
+ e.getStackTrace());
}
return csvFile;
}
}