View Javadoc
1   package org.kuali.ole.deliver.service;
2   
3   import com.itextpdf.text.*;
4   import com.itextpdf.text.pdf.BaseFont;
5   import com.itextpdf.text.pdf.PdfPCell;
6   import com.itextpdf.text.pdf.PdfPTable;
7   import com.itextpdf.text.pdf.PdfWriter;
8   import org.apache.commons.lang3.StringUtils;
9   import org.apache.log4j.Logger;
10  import org.kuali.ole.OLEConstants;
11  import org.kuali.ole.OLEParameterConstants;
12  import org.kuali.ole.deliver.bo.OleCirculationDesk;
13  import org.kuali.ole.deliver.bo.OleLoanDocument;
14  import org.kuali.ole.deliver.bo.OlePatronDocument;
15  import org.kuali.ole.deliver.processor.LoanProcessor;
16  import org.kuali.ole.service.OlePatronHelperService;
17  import org.kuali.ole.service.OlePatronHelperServiceImpl;
18  import org.kuali.ole.sys.context.SpringContext;
19  import org.kuali.rice.core.api.config.property.ConfigContext;
20  import org.kuali.rice.core.api.util.RiceConstants;
21  import org.kuali.rice.kim.impl.identity.type.EntityTypeContactInfoBo;
22  import org.springframework.core.io.ClassPathResource;
23  import org.springframework.core.io.Resource;
24  
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.text.SimpleDateFormat;
28  import java.util.*;
29  import java.util.List;
30  
31  /**
32   * Created by premkb on 4/8/15.
33   */
34  public class NoticePDFContentFormatter {
35  
36      private static final Logger LOG = Logger.getLogger(NoticePDFContentFormatter.class);
37      private CircDeskLocationResolver circDeskLocationResolver;
38      private SimpleDateFormat simpleDateFormat;
39      private String urlProperty;
40      private ParameterValueResolver parameterResolverInstance;
41      private OlePatronHelperServiceImpl olePatronHelperService;
42  
43      public OlePatronHelperService getOlePatronHelperService(){
44          if(olePatronHelperService==null)
45              olePatronHelperService=new OlePatronHelperServiceImpl();
46          return olePatronHelperService;
47      }
48  
49      public void setOlePatronHelperService(OlePatronHelperServiceImpl olePatronHelperService) {
50          this.olePatronHelperService = olePatronHelperService;
51      }
52  
53      public void setUrlProperty(String urlProperty) {
54          this.urlProperty = urlProperty;
55      }
56  
57      public String generateOverDueNoticeContent(OleLoanDocument oleLoanDocument)
58              throws Exception {
59          Document document = new Document(PageSize.A4);
60          String fileName = createPDFFile(getParameterResolverInstance().getParameter(OLEConstants
61                  .APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEParameterConstants.OVERDUE_TITLE), oleLoanDocument.getItemId());
62          FileOutputStream fileOutputStream = new FileOutputStream(fileName);
63          PdfWriter.getInstance(document, fileOutputStream);
64          document.open();
65          String title = getParameterResolverInstance().getParameter(OLEConstants
66                  .APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEParameterConstants.OVERDUE_TITLE);
67          String body = getParameterResolverInstance().getParameter(OLEConstants
68                  .APPL_ID_OLE, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEConstants.OleDeliverRequest.OVERDUE_NOTICE_CONTENT);
69          addPdfHeader(document, title);
70          addPatronInfoToDocument(document, oleLoanDocument.getOlePatron(), title, body);
71          addOverdueNoticeInfoToDocument(oleLoanDocument, document);
72          addPdfFooter(document);
73          document.close();
74          return fileName;
75      }
76  
77      private void addPatronInfoToDocument(Document document, OlePatronDocument olePatronDocument, String title, String body)
78              throws
79              Exception {
80  
81          EntityTypeContactInfoBo entityTypeContactInfoBo = olePatronDocument.getEntity().getEntityTypeContactInfos().get(0);
82          Paragraph paraGraph = new Paragraph();
83          paraGraph.add(Chunk.NEWLINE);
84          document.add(paraGraph);
85          paraGraph = new Paragraph();
86          paraGraph.add(new Chunk("Patron information", getBoldFont()));
87          paraGraph.add(Chunk.NEWLINE);
88          paraGraph.add(Chunk.NEWLINE);
89          document.add(paraGraph);
90  
91          PdfPTable pdfTable = new PdfPTable(3);
92          pdfTable.setWidths(new int[]{20, 2, 30});
93  
94          pdfTable.addCell(getPdfPCellInJustified("Patron Name"));
95          pdfTable.addCell(getPdfPCellInLeft(":"));
96          pdfTable.addCell(getPdfPCellInJustified((olePatronDocument.getEntity().getNames().get(0).getFirstName() + " " + olePatronDocument.getEntity().getNames().get(0).getLastName())));
97  
98  
99          pdfTable.addCell(getPdfPCellInJustified("Address"));
100         pdfTable.addCell(getPdfPCellInLeft(":"));
101         pdfTable.addCell(getPdfPCellInJustified((getOlePatronHelperService().getPatronPreferredAddress(entityTypeContactInfoBo) != null ? getOlePatronHelperService().getPatronPreferredAddress(entityTypeContactInfoBo) : "")));
102 
103 
104         pdfTable.addCell(getPdfPCellInJustified("Email"));
105         pdfTable.addCell(getPdfPCellInLeft(":"));
106         pdfTable.addCell(getPdfPCellInJustified((getOlePatronHelperService().getPatronHomeEmailId(entityTypeContactInfoBo) != null ? getOlePatronHelperService().getPatronHomeEmailId(entityTypeContactInfoBo) : "")));
107 
108         pdfTable.addCell(getPdfPCellInJustified("Phone #"));
109         pdfTable.addCell(getPdfPCellInLeft(":"));
110         pdfTable.addCell(getPdfPCellInJustified((getOlePatronHelperService().getPatronHomePhoneNumber(entityTypeContactInfoBo) != null ? getOlePatronHelperService().getPatronHomePhoneNumber(entityTypeContactInfoBo) : "")));
111 
112         document.add(pdfTable);
113         paraGraph = new Paragraph();
114         paraGraph.add(Chunk.NEWLINE);
115         document.add(paraGraph);
116 
117 
118         getPdfTemplateBody(document, title, body);
119         paraGraph = new Paragraph();
120         paraGraph.add(new Chunk("Title/item information", getBoldFont()));
121         paraGraph.add(Chunk.NEWLINE);
122         paraGraph.add(Chunk.NEWLINE);
123         document.add(paraGraph);
124     }
125 
126     private void getPdfTemplateBody(Document document, String title, String body) throws Exception {
127         //Notice Type
128         Paragraph paraGraph = new Paragraph();
129         paraGraph.add(new Chunk(title, getBoldFont()));
130         paraGraph.setAlignment(Element.ALIGN_CENTER);
131         paraGraph.add(Chunk.NEWLINE);
132         paraGraph.add(Chunk.NEWLINE);
133         document.add(paraGraph);
134 
135 
136         //Notice-specific text
137         paraGraph = new Paragraph();
138         paraGraph.add(new Chunk(body, getBoldFont()));
139         paraGraph.setAlignment(Element.ALIGN_CENTER);
140         paraGraph.add(Chunk.NEWLINE);
141         paraGraph.add(Chunk.NEWLINE);
142         document.add(paraGraph);
143     }
144 
145     public void addPdfFooter(Document document) throws DocumentException {
146         String url = getURLProperty();
147         // String myAccountURL = loanProcessor.getParameter(OLEConstants.MY_ACCOUNT_URL);
148         String myAccountURL = url + OLEConstants.OLE_MY_ACCOUNT_URL_CHANNEL + url + OLEConstants.OLE_MY_ACCOUNT_URL;
149         if (myAccountURL != null && !myAccountURL.trim().isEmpty()) {
150             Font ver_15_normal = FontFactory.getFont("Times-Roman", 15, Font.BOLD, BaseColor.BLUE);
151             ver_15_normal.setColor(BaseColor.BLUE);
152             ver_15_normal.setStyle(Font.UNDERLINE);
153             Anchor anchor = new Anchor("MyAccount", ver_15_normal);
154             anchor.setReference(myAccountURL);
155             Paragraph paraGraph = new Paragraph();
156             paraGraph.add(anchor);
157             paraGraph.setFont(ver_15_normal);
158             paraGraph.setAlignment(Element.ALIGN_CENTER);
159             document.add(paraGraph);
160         }
161 
162     }
163 
164     private String getURLProperty() {
165         if (null == urlProperty) {
166             urlProperty = ConfigContext.getCurrentContextConfig().getProperty("ole.fs.url.base");
167         }
168         return urlProperty;
169     }
170 
171     public void addOverdueNoticeInfoToDocument(OleLoanDocument oleLoanDocument, Document document) throws DocumentException {
172         Paragraph paraGraph;
173         SimpleDateFormat sdf = getSimpleDateFormat();
174         PdfPTable pdfTable = new PdfPTable(3);
175         pdfTable.setWidths(new int[]{20, 2, 30});
176 
177         String circulationLocation = null;
178         String circulationReplyToEmail = null;
179         OleCirculationDesk oleCirculationDesk = getCircDeskLocationResolver().getCirculationDesk(oleLoanDocument.getItemLocation());
180         if (oleCirculationDesk != null) {
181             circulationLocation = oleCirculationDesk.getCirculationDeskPublicName();
182             if (StringUtils.isNotBlank(oleCirculationDesk.getReplyToEmail())) {
183                 circulationReplyToEmail = oleCirculationDesk.getReplyToEmail();
184             } else {
185                 circulationReplyToEmail = getParameterResolverInstance().getParameter(OLEConstants
186                         .APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEParameterConstants.NOTICE_FROM_MAIL);
187             }
188         } else {
189             circulationLocation = getParameterResolverInstance().getParameter(OLEConstants
190                     .APPL_ID_OLE, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEParameterConstants.DEFAULT_CIRCULATION_DESK);
191             circulationReplyToEmail = getParameterResolverInstance().getParameter(OLEConstants
192                     .APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT,OLEParameterConstants.NOTICE_FROM_MAIL);
193         }
194 
195         pdfTable.addCell(getPdfPCellInJustified("Circulation Location / Library Name"));
196         pdfTable.addCell(getPdfPCellInLeft(":"));
197         pdfTable.addCell(getPdfPCellInJustified(circulationLocation));
198 
199         pdfTable.addCell(getPdfPCellInJustified("Circulation Reply-To Email"));
200         pdfTable.addCell(getPdfPCellInLeft(":"));
201         pdfTable.addCell(getPdfPCellInJustified(circulationReplyToEmail));
202 
203         pdfTable.addCell(getPdfPCellInJustified("Title"));
204         pdfTable.addCell(getPdfPCellInLeft(":"));
205         pdfTable.addCell(getPdfPCellInJustified((oleLoanDocument.getTitle() == null ? "" : oleLoanDocument.getTitle())));
206 
207         pdfTable.addCell(getPdfPCellInJustified("Author"));
208         pdfTable.addCell(getPdfPCellInLeft(":"));
209         pdfTable.addCell(getPdfPCellInJustified((oleLoanDocument.getAuthor() == null ? "" : oleLoanDocument.getAuthor())));
210 
211         String volume = (String) oleLoanDocument.getEnumeration() != null && !oleLoanDocument.getEnumeration().equals("") ? oleLoanDocument.getEnumeration() : "";
212         String issue = new String(" ");
213         String copyNumber = (String) oleLoanDocument.getItemCopyNumber() != null && !oleLoanDocument.getItemCopyNumber().equals("") ? oleLoanDocument.getItemCopyNumber() : "";
214         String volumeNumber = volume + "/" + issue + "/" + copyNumber;
215 
216         pdfTable.addCell(getPdfPCellInJustified("Volume/Issue/Copy #"));
217         pdfTable.addCell(getPdfPCellInLeft(":"));
218         pdfTable.addCell(getPdfPCellInJustified((volumeNumber == null ? "" : volumeNumber)));
219 
220         pdfTable.addCell(getPdfPCellInJustified("Library shelving location "));
221         pdfTable.addCell(getPdfPCellInLeft(":"));
222         pdfTable.addCell(getPdfPCellInJustified((oleLoanDocument.getItemLocation() == null ? "" : oleLoanDocument.getItemLocation())));
223 
224         String callNumber = "";
225         if (oleLoanDocument.getItemCallNumber() != null && !oleLoanDocument.getItemCallNumber().equals("")) {
226             callNumber = (String) (oleLoanDocument.getItemCallNumber() != null && !oleLoanDocument.getItemCallNumber().equals("") ? oleLoanDocument.getItemCallNumber() : "");
227         }
228         pdfTable.addCell(getPdfPCellInJustified("Call # "));
229         pdfTable.addCell(getPdfPCellInLeft(":"));
230         pdfTable.addCell(getPdfPCellInJustified((callNumber == null ? "" : callNumber)));
231 
232         pdfTable.addCell(getPdfPCellInJustified("Item barcode"));
233         pdfTable.addCell(getPdfPCellInLeft(":"));
234         pdfTable.addCell(getPdfPCellInJustified((oleLoanDocument.getItemId() == null ? "" : oleLoanDocument.getItemId())));
235 
236         document.add(pdfTable);
237         paraGraph = new Paragraph();
238         paraGraph.add(Chunk.NEWLINE);
239         document.add(paraGraph);
240 
241         pdfTable = new PdfPTable(3);
242         pdfTable.setWidths(new int[]{20, 2, 30});
243 
244         pdfTable.addCell(getPdfPCellInJustified("Item was due"));
245         pdfTable.addCell(getPdfPCellInLeft(":"));
246         pdfTable.addCell(getPdfPCellInJustified((oleLoanDocument.getLoanDueDate() == null ? "" : (sdf.format(oleLoanDocument.getLoanDueDate()).toString()))));
247 
248         document.add(pdfTable);
249         paraGraph = new Paragraph();
250         paraGraph.add(Chunk.NEWLINE);
251         document.add(paraGraph);
252 
253     }
254 
255     private void addPdfHeader(Document document, String title) throws
256             Exception {
257         Paragraph paraGraph = new Paragraph();
258         paraGraph.setAlignment(Element.ALIGN_CENTER);
259         paraGraph.add(new Chunk(title, getBoldFont()));
260         paraGraph.add(Chunk.NEWLINE);
261         document.add(paraGraph);
262     }
263 
264     public Font getBoldFont() {
265         return FontFactory.getFont(FontFactory.TIMES_ROMAN, 15, Font.BOLD);
266     }
267 
268     private PdfPCell getPdfPCellInJustified(String chunk) {
269         if (null == chunk) {
270             chunk = "";
271         }
272         PdfPCell pdfPCell = new PdfPCell(new Paragraph(new Chunk(chunk, getFont(chunk))));
273         pdfPCell.setBorder(pdfPCell.NO_BORDER);
274         pdfPCell.setHorizontalAlignment(pdfPCell.ALIGN_JUSTIFIED);
275         return pdfPCell;
276     }
277 
278     private PdfPCell getPdfPCellInLeft(String chunk) {
279         PdfPCell pdfPCell = new PdfPCell(new Paragraph(new Chunk(chunk, getDefaultFont())));
280         pdfPCell.setBorder(pdfPCell.NO_BORDER);
281         pdfPCell.setHorizontalAlignment(pdfPCell.ALIGN_LEFT);
282         return pdfPCell;
283     }
284 
285     private PdfPCell getPdfPCellInCenter(String chunk) {
286         PdfPCell pdfPCell = new PdfPCell(new Paragraph(new Chunk(chunk, getDefaultFont())));
287         pdfPCell.setBorder(pdfPCell.NO_BORDER);
288         pdfPCell.setHorizontalAlignment(pdfPCell.ALIGN_LEFT);
289         return pdfPCell;
290     }
291 
292     private PdfPCell getPdfPCellInCenter(String chunk, Font font) {
293         PdfPCell pdfPCell = new PdfPCell(new Paragraph(new Chunk(chunk, font)));
294         pdfPCell.setBorder(pdfPCell.NO_BORDER);
295         pdfPCell.setHorizontalAlignment(pdfPCell.ALIGN_LEFT);
296         return pdfPCell;
297     }
298 
299     private PdfPCell getPdfPCellNewLine() {
300         PdfPCell pdfPCell = new PdfPCell(new Paragraph(Chunk.NEWLINE));
301         pdfPCell.setBorder(pdfPCell.NO_BORDER);
302         return pdfPCell;
303     }
304 
305     public Font getDefaultFont() {
306         com.itextpdf.text.Font font = FontFactory.getFont(getFontFilePath("org/kuali/ole/deliver/batch/fonts/ARIALUNI.TTF"), BaseFont.IDENTITY_H, 10);
307         return font;
308     }
309 
310     public String getFontFilePath(String classpathRelativePath) {
311         try {
312             Resource rsrc = new ClassPathResource(classpathRelativePath);
313             return rsrc.getFile().getAbsolutePath();
314         } catch (Exception e) {
315             LOG.error("Error : while accessing font file " + e);
316         }
317         return null;
318     }
319 
320     public Font getFont(String data) {
321         if (null != data) {
322             String myData = new String(data);
323             java.util.List<Character.UnicodeBlock> unicodeBlocks = new ArrayList<>();
324             if (StringUtils.isNotBlank(myData)) {
325                 unicodeBlocks = getListOfLanguage(myData);
326             }
327             if (unicodeBlocks.contains(Character.UnicodeBlock.ARABIC)) {
328                 Font font = FontFactory.getFont(getFontFilePath("org/kuali/ole/deliver/batch/fonts/arial.ttf"), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
329                 return font;
330             }
331         }
332         return getDefaultFont();
333     }
334 
335     private List<Character.UnicodeBlock> getListOfLanguage(String data) {
336         Set<Character.UnicodeBlock> languageSet = new HashSet<Character.UnicodeBlock>();
337         char[] valueArray = data.toCharArray();
338         for (int counter = 0; counter < valueArray.length; counter++) {
339             languageSet.add(Character.UnicodeBlock.of(valueArray[counter]));
340         }
341         return (new ArrayList<Character.UnicodeBlock>(languageSet));
342     }
343 
344     public String createPDFFile(String title, String itemId) throws Exception {
345         String pdfLocationSystemParam = getParameterResolverInstance().getParameter(OLEConstants
346                 .APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT, OLEParameterConstants.PDF_LOCATION);
347         if (LOG.isDebugEnabled()) {
348             LOG.debug("System Parameter for PDF_Location --> " + pdfLocationSystemParam);
349         }
350         if (pdfLocationSystemParam == null || pdfLocationSystemParam.trim().isEmpty()) {
351             pdfLocationSystemParam = ConfigContext.getCurrentContextConfig().getProperty("staging.directory") + "/";
352             if (LOG.isDebugEnabled()) {
353                 LOG.debug("System Parameter for PDF_Location staging dir--> " + pdfLocationSystemParam);
354             }
355         } else {
356             pdfLocationSystemParam = ConfigContext.getCurrentContextConfig().getProperty("homeDirectory") + "/" + pdfLocationSystemParam + "/";
357 
358         }
359         boolean locationExist = new File(pdfLocationSystemParam).exists();
360         boolean fileCreated = false;
361         if (LOG.isDebugEnabled()) {
362             LOG.debug("Is directory Exist ::" + locationExist);
363         }
364         try {
365             if (!locationExist) {
366                 fileCreated = new File(pdfLocationSystemParam).mkdirs();
367                 if (!fileCreated) {
368                     throw new RuntimeException("Unable to create directory :" + pdfLocationSystemParam);
369                 }
370             }
371         } catch (Exception e) {
372             LOG.error("Exception occurred while creating the directory : " + e.getMessage(), e);
373             throw e;
374         }
375 
376         if (title == null || title.trim().isEmpty()) {
377             title = OLEConstants.ITEM_TITLE;
378         }
379         title = title.replaceAll(" ", "_");
380 
381         if (itemId == null || itemId.trim().isEmpty()) {
382             itemId = OLEConstants.ITEM_ID;
383         }
384         String fileName = pdfLocationSystemParam + title + "_" + itemId + "_" + (new Date(System.currentTimeMillis())).toString().replaceAll(":", "_") + ".pdf";
385         String unModifiedFileName = fileName;
386         fileName = fileName.replace(" ", "_");
387         if (LOG.isDebugEnabled()) {
388             LOG.debug("File Created :" + title + "file name ::" + fileName + "::");
389         }
390         return unModifiedFileName;
391     }
392 
393     private SimpleDateFormat getSimpleDateFormat() {
394         if (null == simpleDateFormat) {
395             simpleDateFormat = new SimpleDateFormat(RiceConstants.SIMPLE_DATE_FORMAT_FOR_DATE + " " + RiceConstants.SIMPLE_DATE_FORMAT_FOR_TIME);
396         }
397         return simpleDateFormat;
398     }
399 
400     public void setSimpleDateFormat(SimpleDateFormat simpleDateFormat) {
401         this.simpleDateFormat = simpleDateFormat;
402     }
403 
404     private CircDeskLocationResolver getCircDeskLocationResolver() {
405         if (circDeskLocationResolver == null) {
406             circDeskLocationResolver = new CircDeskLocationResolver();
407         }
408         return circDeskLocationResolver;
409     }
410 
411     public void setCircDeskLocationResolver(CircDeskLocationResolver circDeskLocationResolver) {
412         this.circDeskLocationResolver = circDeskLocationResolver;
413     }
414 
415     private ParameterValueResolver getParameterResolverInstance() {
416         if (null == parameterResolverInstance) {
417             parameterResolverInstance = ParameterValueResolver.getInstance();
418         }
419         return parameterResolverInstance;
420     }
421 
422     public void setParameterResolverInstance(ParameterValueResolver parameterResolverInstance) {
423         this.parameterResolverInstance = parameterResolverInstance;
424     }
425 }