001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.module.cam.report; 017 018 import java.io.File; 019 import java.io.FileOutputStream; 020 import java.text.SimpleDateFormat; 021 import java.util.Date; 022 import java.util.List; 023 024 import org.kuali.kfs.module.cam.CamsConstants; 025 import org.kuali.kfs.module.cam.CamsKeyConstants; 026 import org.kuali.kfs.sys.KFSConstants; 027 import org.kuali.kfs.sys.context.SpringContext; 028 import org.kuali.rice.kns.service.DateTimeService; 029 import org.kuali.rice.kns.service.KualiConfigurationService; 030 031 import com.lowagie.text.Cell; 032 import com.lowagie.text.Chunk; 033 import com.lowagie.text.Document; 034 import com.lowagie.text.DocumentException; 035 import com.lowagie.text.Element; 036 import com.lowagie.text.ExceptionConverter; 037 import com.lowagie.text.Font; 038 import com.lowagie.text.FontFactory; 039 import com.lowagie.text.Paragraph; 040 import com.lowagie.text.Phrase; 041 import com.lowagie.text.Rectangle; 042 import com.lowagie.text.Table; 043 import com.lowagie.text.pdf.PdfPCell; 044 import com.lowagie.text.pdf.PdfPTable; 045 import com.lowagie.text.pdf.PdfPageEventHelper; 046 import com.lowagie.text.pdf.PdfWriter; 047 048 public class DepreciationReport { 049 050 051 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DepreciationReport.class); 052 private int pageNumber = 0; 053 private int line = 0; 054 private int linesPerPage = 28; 055 private Document document; 056 private PdfWriter writer; 057 058 /** 059 * This method creates the report file and invokes the methods that write the data 060 * 061 * @param reportLog 062 * @param errorMsg 063 */ 064 public void generateReport(List<String[]> reportLog, String errorMsg, String sDepreciationDate) { 065 try { 066 DateTimeService dateTimeService = SpringContext.getBean(DateTimeService.class); 067 LOG.debug("createReport() started"); 068 this.document = new Document(); 069 070 String destinationDirectory = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.REPORTS_DIRECTORY_KEY); 071 072 SimpleDateFormat sdf = new SimpleDateFormat(CamsConstants.DateFormats.YEAR_MONTH_DAY_NO_DELIMITER + "_" + CamsConstants.DateFormats.MILITARY_TIME_NO_DELIMITER); 073 074 String filename = destinationDirectory + File.separator + "cam" + File.separator + CamsConstants.Report.FILE_PREFIX + "_" + CamsConstants.Depreciation.REPORT_FILE_NAME + "_" + sdf.format(dateTimeService.getCurrentDate()) + "." + CamsConstants.Report.REPORT_EXTENSION; 075 076 Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL); 077 078 PageHelper helper = new PageHelper(); 079 helper.runDate = dateTimeService.getCurrentDate(); 080 helper.headerFont = headerFont; 081 helper.title = CamsConstants.Depreciation.DEPRECIATION_REPORT_TITLE; 082 083 writer = PdfWriter.getInstance(this.document, new FileOutputStream(filename)); 084 writer.setPageEvent(helper); 085 086 this.document.open(); 087 088 // Generate body of document. 089 this.generateReportLogBody(reportLog); 090 this.generateReportErrorLog(errorMsg); 091 092 } 093 catch (Exception e) { 094 throw new RuntimeException("DepreciationReport.generateReport(List<String[]> reportLog, List<String> errorLog) - Error on report generation: " + e.getMessage()); 095 } 096 finally { 097 if ((this.document != null) && this.document.isOpen()) { 098 this.document.close(); 099 } 100 } 101 } 102 103 /** 104 * This method adds the log lines into the report 105 * 106 * @param reportLog 107 */ 108 private void generateReportLogBody(List<String[]> reportLog) { 109 try { 110 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL); 111 int columnwidths[]; 112 columnwidths = new int[] { 40, 15 }; 113 114 Table aTable = new Table(2, linesPerPage); 115 int rowsWritten = 0; 116 for (String[] columns : reportLog) { 117 if (pageNumber == 0 || line >= linesPerPage) { 118 if (pageNumber > 0) { 119 this.document.add(aTable); 120 } 121 int elementsLeft = reportLog.size() - rowsWritten; 122 int rowsNeeded = (elementsLeft >= linesPerPage ? linesPerPage : elementsLeft); 123 this.document.newPage(); 124 125 this.generateColumnHeaders(); 126 127 aTable = new Table(2, rowsNeeded); // 12 columns, 11 rows. 128 129 aTable.setAutoFillEmptyCells(true); 130 aTable.setPadding(3); 131 aTable.setWidths(columnwidths); 132 aTable.setWidth(100); 133 aTable.setBorder(Rectangle.NO_BORDER); 134 135 line = 0; 136 pageNumber++; 137 } 138 rowsWritten++; 139 140 Cell cell; 141 cell = new Cell(new Phrase(columns[0], font)); 142 cell.setHorizontalAlignment(Element.ALIGN_LEFT); 143 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 144 aTable.addCell(cell); 145 146 cell = new Cell(new Phrase(columns[1], font)); 147 cell.setHorizontalAlignment(Element.ALIGN_RIGHT); 148 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 149 aTable.addCell(cell); 150 line++; 151 } 152 this.document.add(aTable); 153 } 154 catch (DocumentException de) { 155 throw new RuntimeException("DepreciationReport.generateReportLogBody(List<String[]> reportLog) - error: " + de.getMessage()); 156 } 157 } 158 159 /** 160 * This method adds any error to the report 161 * 162 * @param errorMsg 163 */ 164 private void generateReportErrorLog(String errorMsg) { 165 try { 166 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL); 167 Paragraph p1 = new Paragraph(); 168 169 int rowsWritten = 0; 170 if (!errorMsg.equals("")) { 171 this.generateErrorColumnHeaders(); 172 173 p1 = new Paragraph(new Chunk(errorMsg, font)); 174 this.document.add(p1); 175 line++; 176 } 177 } 178 catch (Exception de) { 179 throw new RuntimeException("DepreciationReport.generateReportErrorLog(List<String> reportLog) - Report Generation Failed: " + de.getMessage()); 180 } 181 } 182 183 /** 184 * This method creates a report group for the error message on the report 185 * 186 * @throws DocumentException 187 */ 188 private void generateErrorColumnHeaders() throws DocumentException { 189 try { 190 int headerwidths[] = { 60 }; 191 192 Table aTable = new Table(1, 1); // 2 columns, 1 rows. 193 194 aTable.setAutoFillEmptyCells(true); 195 aTable.setPadding(3); 196 aTable.setWidths(headerwidths); 197 aTable.setWidth(100); 198 199 Cell cell; 200 201 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL); 202 203 cell = new Cell(new Phrase("Error(s)", font)); 204 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 205 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 206 cell.setGrayFill(0.9f); 207 aTable.addCell(cell); 208 209 this.document.add(aTable); 210 211 } 212 catch (Exception e) { 213 throw new RuntimeException("DepreciationReport.generateErrorColumnHeaders() - Error: " + e.getMessage()); 214 } 215 } 216 217 /** 218 * This method inserts the depreciation date on the report 219 * 220 * @param sDepreciationDate private void generateDepreciationDateLabel(String sDepreciationDate) { try { int headerwidths[] = { 221 * 100 }; Table aTable = new Table(1, 1); // 1 columns, 1 rows. aTable.setAutoFillEmptyCells(true); aTable.setPadding(3); 222 * aTable.setWidths(headerwidths); aTable.setWidth(100); aTable.setBorder(0); Cell cell; Font font = 223 * FontFactory.getFont(FontFactory.HELVETICA, 11, Font.NORMAL); cell = new Cell(new Phrase("Depreciation Date: 224 * "+sDepreciationDate, font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); 225 * cell.setVerticalAlignment(Element.ALIGN_CENTER); cell.setBorder(0); aTable.addCell(cell); this.document.add(aTable); } 226 * catch (Exception e) { throw new RuntimeException("DepreciationReport.generateDepreciationDateLabel() - Error: " + 227 * e.getMessage()); } } 228 */ 229 230 /** 231 * This method creates the headers for the report statistics 232 */ 233 private void generateColumnHeaders() { 234 try { 235 int headerwidths[] = { 40, 15 }; 236 237 Table aTable = new Table(2, 1); // 2 columns, 1 rows. 238 239 aTable.setAutoFillEmptyCells(true); 240 aTable.setPadding(3); 241 aTable.setWidths(headerwidths); 242 aTable.setWidth(100); 243 244 Cell cell; 245 246 Font font = FontFactory.getFont(FontFactory.HELVETICA, 9, Font.NORMAL); 247 248 cell = new Cell(new Phrase(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(CamsKeyConstants.Depreciation.MSG_REPORT_DEPRECIATION_HEADING1), font)); 249 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 250 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 251 cell.setGrayFill(0.9f); 252 aTable.addCell(cell); 253 254 cell = new Cell(new Phrase(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(CamsKeyConstants.Depreciation.MSG_REPORT_DEPRECIATION_HEADING2), font)); 255 cell.setHorizontalAlignment(Element.ALIGN_CENTER); 256 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); 257 cell.setGrayFill(0.9f); 258 aTable.addCell(cell); 259 this.document.add(aTable); 260 261 } 262 catch (Exception e) { 263 throw new RuntimeException("DepreciationReport.generateColumnHeaders() - Error: " + e.getMessage()); 264 } 265 } 266 267 268 /** 269 * An inner class to help set up the PDF that is written 270 */ 271 class PageHelper extends PdfPageEventHelper { 272 public Date runDate; 273 public Font headerFont; 274 public String title; 275 276 /** 277 * Writes the footer on the last page 278 * 279 * @see com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document) 280 */ 281 public void onEndPage(PdfWriter writer, Document document) { 282 try { 283 Font titleFont = FontFactory.getFont(FontFactory.HELVETICA, 12, Font.NORMAL); 284 Font font = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.NORMAL); 285 286 Rectangle page = document.getPageSize(); 287 PdfPTable head = new PdfPTable(3); 288 289 int[] widths = { 15, 70, 15 }; 290 head.setWidths(widths); 291 292 SimpleDateFormat sdf = new SimpleDateFormat(CamsConstants.DateFormats.MONTH_DAY_YEAR + " " + CamsConstants.DateFormats.MILITARY_TIME); 293 294 PdfPCell cell = new PdfPCell(new Phrase(sdf.format(runDate), font)); 295 cell.setBorder(Rectangle.NO_BORDER); 296 head.addCell(cell); 297 298 cell = new PdfPCell(new Phrase(title, titleFont)); 299 cell.setBorder(Rectangle.NO_BORDER); 300 cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); 301 head.addCell(cell); 302 303 cell = new PdfPCell(new Phrase("Page: " + new Integer(writer.getPageNumber()), font)); 304 cell.setBorder(Rectangle.NO_BORDER); 305 cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT); 306 head.addCell(cell); 307 308 head.setTotalWidth(page.width() - document.leftMargin() - document.rightMargin()); 309 head.writeSelectedRows(0, -1, document.leftMargin(), page.height() - document.topMargin() + head.getTotalHeight(), writer.getDirectContent()); 310 } 311 catch (Exception e) { 312 throw new ExceptionConverter(e); 313 } 314 } 315 } 316 }