package model.manager.exports.excel; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import model.manager.excel.conversion.exceptions.ReportException; import model.manager.excel.interfaces.GenerateExcelReportInterface; import model.manager.exports.DataExportFunctions; import model.nonPersistent.EntitySet; import org.apache.log4j.Logger; import org.celllife.idart.database.hibernate.util.HibernateUtil; import org.eclipse.core.runtime.IProgressMonitor; import org.hibernate.Session; public abstract class ExcelExporter { static Logger log = Logger.getLogger(ExcelExporter.class); static final int PAGE_SIZE = 100; protected Session session; protected HashMap<Integer, List<Integer>> patientPackageMap; private DataExportFunctions functions; private IProgressMonitor monitor; public ExcelExporter() { super(); } public void generate(ExcelReportObject report) throws ReportException { File file = new File(report.getPath()); FileOutputStream fos = null; try { fos = new FileOutputStream(file); } catch (FileNotFoundException e1) { throw new ReportException(e1); } functions = new DataExportFunctions(); session = HibernateUtil.getNewSession(); functions.setSession(session); setupFunctions(functions, report); EntitySet entitySet = getPatientSet(report); if (monitor != null){ monitor.beginTask("Generating report", entitySet.getSize()); } GenerateExcelReportInterface excelReport = getExcelReport(report); excelReport.writeTitle(); int extraColumns = getNumberOfExtraColumn(); excelReport.writeHeadings(extraColumns); int page = 0; int total = entitySet.size(); int pages = total / PAGE_SIZE; try { while (!isCancelled()) { // Set up list of patients if one wasn't passed into this method EntitySet pagedEntitySet = entitySet.getPage(page * PAGE_SIZE, PAGE_SIZE); if (pagedEntitySet.size() == 0) { break; } log.debug("Starting data export page " + page + " of " + pages); updateMonitorMessage("Processed " + page * PAGE_SIZE + " patients of " + total); try { exportPage(pagedEntitySet, functions, excelReport); } catch (Exception e) { throw new ReportException("Error running data export.", e); } finally { log.debug("Completed data export page " + page + " of " + pages); updateMonitorStatus(PAGE_SIZE); page++; pagedEntitySet = null; functions.clear(); log.debug("Clearing hibernate session"); session.clear(); // clear out the excess objects System.gc(); System.gc(); } } excelReport.writeFooter(); try { fos.write(excelReport.getReport()); } catch (IOException e) { throw new ReportException(e); } } catch (ReportException e) { throw e; } finally { try { fos.close(); } catch (IOException e) { log.error("Failed to close file stream.", e); } entitySet = null; report = null; session.close(); } } protected int getNumberOfExtraColumn() { return 0; } protected abstract GenerateExcelReportInterface getExcelReport(ExcelReportObject report); protected abstract void exportPage(EntitySet pagedEntitySet, DataExportFunctions functions, GenerateExcelReportInterface excelReport) throws Exception; protected void setupFunctions(DataExportFunctions functions, ExcelReportObject report) { functions.setAllPatients(false); functions.setExportStartDate(report.getStartDate()); functions.setExportEndDate(report.getEndDate()); } protected abstract EntitySet getPatientSet(ExcelReportObject report); private void updateMonitorStatus(int work) { if (monitor != null) { monitor.worked(work); } } private void updateMonitorMessage(String message) { if (monitor != null) { monitor.subTask(message); } } private boolean isCancelled() { if (monitor != null) return monitor.isCanceled(); return false; } public void setMonitor(IProgressMonitor monitor) { this.monitor = monitor; } }