Java tutorial
/* jBilling - The Enterprise Open Source Billing System Copyright (C) 2003-2011 Enterprise jBilling Software Ltd. and Emiliano Conde This file is part of jbilling. jbilling 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. jbilling 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 jbilling. If not, see <http://www.gnu.org/licenses/>. */ package com.sapienter.jbilling.server.invoice; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.List; import org.apache.log4j.Logger; import javax.sql.rowset.CachedRowSet; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PRAcroForm; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; import com.sapienter.jbilling.common.SessionInternalError; import com.sapienter.jbilling.common.Util; import com.sapienter.jbilling.server.process.db.PaperInvoiceBatchDTO; import com.sapienter.jbilling.server.invoice.db.InvoiceDTO; import com.sapienter.jbilling.server.notification.NotificationBL; import com.sapienter.jbilling.server.process.BillingProcessBL; import com.sapienter.jbilling.server.process.db.PaperInvoiceBatchDAS; import com.sapienter.jbilling.server.util.Constants; import com.sapienter.jbilling.server.util.PreferenceBL; import com.sapienter.jbilling.server.util.audit.EventLogger; /** * @author Emil */ public class PaperInvoiceBatchBL { private PaperInvoiceBatchDTO batch = null; private static final Logger LOG = Logger.getLogger(PaperInvoiceBatchBL.class); private EventLogger eLogger = null; private PaperInvoiceBatchDAS batchHome = null; public PaperInvoiceBatchBL(Integer batchId) { init(); set(batchId); } public PaperInvoiceBatchBL(PaperInvoiceBatchDTO batch) { init(); this.batch = batch; } public PaperInvoiceBatchBL() { init(); } private void init() { eLogger = EventLogger.getInstance(); batchHome = new PaperInvoiceBatchDAS(); } public PaperInvoiceBatchDTO getEntity() { return batch; } public void set(Integer id) { batch = batchHome.find(id); } /** * This method will create a record if there's none for the given * process id, otherwise it will return the existing one * @param processId * @return */ public PaperInvoiceBatchDTO createGet(Integer processId) { BillingProcessBL process = new BillingProcessBL(processId); batch = process.getEntity().getPaperInvoiceBatch(); if (batch == null) { PreferenceBL preference = new PreferenceBL(); preference.set(process.getEntity().getEntity().getId(), Constants.PREFERENCE_PAPER_SELF_DELIVERY); batch = batchHome.create(new Integer(0), preference.getEntity().getIntValue()); process.getEntity().setPaperInvoiceBatch(batch); } return batch; } /** * Will take all the files generated by the process and 'paste' them * into a big one, deleting the originals. * This then will facilitate the printing of a batch. */ public void compileInvoiceFilesForProcess(Integer entityId) throws DocumentException, IOException { String filePrefix = Util.getSysProp("base_dir") + "invoices/" + entityId + "-"; // now go through each of the invoices // first - sort them List invoices = new ArrayList(batch.getInvoices()); Collections.sort(invoices, new InvoiceEntityComparator()); Integer[] invoicesIds = new Integer[invoices.size()]; for (int f = 0; f < invoices.size(); f++) { InvoiceDTO invoice = (InvoiceDTO) invoices.get(f); invoicesIds[f] = invoice.getId(); } compileInvoiceFiles(filePrefix, new Integer(batch.getId()).toString(), entityId, invoicesIds); } /** * Takes a list of invoices and replaces the individual PDF files for one * single PDF in the destination directory. * @param destination * @param prefix * @param entityId * @param invoices * @throws PdfFormatException * @throws IOException */ public void compileInvoiceFiles(String destination, String prefix, Integer entityId, Integer[] invoices) throws DocumentException, IOException { String filePrefix = Util.getSysProp("base_dir") + "invoices/" + entityId + "-"; String outFile = destination + prefix + "-batch.pdf"; int pageOffset = 0; ArrayList master = new ArrayList(); Document document = null; PdfCopy writer = null; for (int f = 0; f < invoices.length; f++) { // we create a reader for a certain document PdfReader reader = new PdfReader(filePrefix + invoices[f] + "-invoice.pdf"); reader.consolidateNamedDestinations(); // we retrieve the total number of pages int numberOfPages = reader.getNumberOfPages(); List bookmarks = SimpleBookmark.getBookmark(reader); if (bookmarks != null) { if (pageOffset != 0) SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null); master.addAll(bookmarks); } pageOffset += numberOfPages; if (f == 0) { // step 1: creation of a document-object document = new Document(reader.getPageSizeWithRotation(1)); // step 2: we create a writer that listens to the document writer = new PdfCopy(document, new FileOutputStream(outFile)); // step 3: we open the document document.open(); } // step 4: we add content PdfImportedPage page; for (int i = 0; i < numberOfPages;) { ++i; page = writer.getImportedPage(reader, i); writer.addPage(page); } PRAcroForm form = reader.getAcroForm(); if (form != null) writer.copyAcroForm(reader); //release and delete writer.freeReader(reader); reader.close(); File file = new File(filePrefix + invoices[f] + "-invoice.pdf"); file.delete(); } if (!master.isEmpty()) writer.setOutlines(master); // step 5: we close the document if (document != null) { document.close(); } else { LOG.warn("document == null"); } LOG.debug("PDF batch file is ready " + outFile); } public void sendEmail() { Integer entityId = batch.getProcess().getEntity().getId(); PreferenceBL prefBL = new PreferenceBL(); prefBL.set(entityId, Constants.PREFERENCE_PAPER_SELF_DELIVERY); Boolean selfDelivery = new Boolean(prefBL.getInt() == 1); // If the entity doesn't want to delivery the invoices, then // sapienter has to. Entity 1 is always sapienter. Integer pritingEntity; if (!selfDelivery.booleanValue()) { pritingEntity = new Integer(1); } else { pritingEntity = entityId; } try { NotificationBL.sendSapienterEmail(pritingEntity, "invoice_batch", Util.getSysProp("base_dir") + "invoices/" + entityId + "-" + batch.getId() + "-batch.pdf", null); } catch (Exception e) { LOG.error("Could no send the email with the paper invoices " + "for entity " + entityId, e); } } public String generateFile(CachedRowSet cachedRowSet, Integer entityId, String realPath) throws SQLException, SessionInternalError, DocumentException, IOException { NotificationBL notif = new NotificationBL(); List invoices = new ArrayList(); int generated = 0; while (cachedRowSet.next()) { Integer invoiceId = new Integer(cachedRowSet.getInt(1)); InvoiceBL invoice = new InvoiceBL(invoiceId); LOG.debug("Generating paper invoice " + invoiceId); notif.generatePaperInvoiceAsFile(invoice.getEntity()); invoices.add(invoiceId); // no more than 1000 invoices at a time, please generated++; if (generated >= 1000) break; } if (generated > 0) { // merge all these files into a single one String hash = String.valueOf(System.currentTimeMillis()); Integer[] invoicesIds = new Integer[invoices.size()]; invoices.toArray(invoicesIds); compileInvoiceFiles(realPath.substring(0, realPath.indexOf("_FILE_NAME_")) + "/", entityId + "-" + hash, entityId, invoicesIds); return entityId + "-" + hash + "-batch.pdf"; } else { // there was no rows in that query ... return null; } } }