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
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
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
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
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 }