Java tutorial
/* * Copyright 2009 Davide Casciato, Sandra Reich, Johannes Wettinger * * This file is part of Resi. * * Resi is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Resi 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Resi. If not, see <http://www.gnu.org/licenses/>. */ package org.revager.export; import static org.revager.app.model.Data.translate; import java.awt.Color; import java.io.File; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.Duration; import org.revager.app.Application; import org.revager.app.AttendeeManagement; import org.revager.app.FindingManagement; import org.revager.app.ProtocolManagement; import org.revager.app.model.Data; import org.revager.app.model.schema.Aspect; import org.revager.app.model.schema.Attendee; import org.revager.app.model.schema.Finding; import org.revager.app.model.schema.Meeting; import org.revager.app.model.schema.Protocol; import org.revager.tools.PDFTools; import com.lowagie.text.Anchor; import com.lowagie.text.Chunk; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; /** * This class implements the basic functionality for exporting protocols. */ public abstract class ProtocolPDFExporter extends PDFExporter { /** * Reference to finding management. */ private FindingManagement findMgmt = Application.getInstance().getFindingMgmt(); /** * Reference to protocol management. */ private ProtocolManagement protMgmt = Application.getInstance().getProtocolMgmt(); /** * The attendee management. */ private AttendeeManagement attMgmt = Application.getInstance().getAttendeeMgmt(); /** * The date formatter for dates. */ protected DateFormat sdfDate = SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG); /** * The date formatter for times. */ protected DateFormat sdfTime = new SimpleDateFormat(translate("HH:mm")); /** * The cell background for tables. */ protected Color cellBackground = new Color(235, 235, 235); /** * The background color for the table titles. */ protected Color bgColorTitle = new Color(100, 100, 100); /** * The padding for table cells. */ protected float padding = PDFTools.cmToPt(0.2f); /** * The line leading for phrases. */ protected float leading = PDFTools.cmToPt(0.45f); /** * The vertical border width. */ protected float verticalBorderWidth = 1.2f; /** * The vertical border color. */ protected Color verticalBorderColor = Color.GRAY; /** * Helper method to get the title of the invitation. */ public static String getReviewTitle() { String title = Data.getInstance().getResiData().getReview().getName(); if (title.trim().equals("")) { title = translate("Review"); } return title; } /** * Instantiates a new protocol pdf exporter. * * @param filePath * the file path * @param headTitle * the head title * @param headLogoPath * the head logo path * @param footText * the foot text * * @throws ExportException * If an error occurs while instantiating the protocol pdf * exporter */ protected ProtocolPDFExporter(String filePath, String headTitle, String headLogoPath, String footText) throws ExportException { super(filePath, headTitle, headLogoPath, footText); } /** * Write the title page of the meeting protocol. * * @param meeting * the meeting * @param attachProdExtRefs * true, if the external reference of the product should be part * of the protocol * * @throws ExportException * If an error occurs while writing the title page */ protected void writeTitlePage(Meeting meeting, boolean attachProdExtRefs) throws ExportException { List<Meeting> meetings = new ArrayList<Meeting>(); meetings.add(meeting); writeTitlePage(meetings, attachProdExtRefs); } /** * Write the title page of the protocol. * * @param meetings * the meetings * @param attachProdExtRefs * true, if the external reference of the product should be part * of the protocol * * @throws ExportException * If an error occurs while writing the title page */ protected void writeTitlePage(List<Meeting> meetings, boolean attachProdExtRefs) throws ExportException { try { Font plainFont = new Font(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font plainFontSmall = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 8); Font boldFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 11); Font italicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font italicFontSmall = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 8); Font boldItalicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 11); Font boldItalicFontSmall = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 8); Font protocolFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 20); Font reviewFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 15); Font meetingFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 13); /* * Title of the protocol */ PdfPTable tableTitlePage = new PdfPTable(new float[] { 0.6f, 0.4f }); tableTitlePage.setWidthPercentage(100); tableTitlePage.setSplitRows(false); tableTitlePage.getDefaultCell().setBorder(0); tableTitlePage.getDefaultCell().setPadding(0); String protocolTitle = translate("Findings List of the Review"); if (meetings.size() == 1) { protocolTitle = translate("Findings List of the Review Meeting"); } PdfPCell cellProtocol = new PdfPCell(new Phrase(protocolTitle, protocolFontTitle)); cellProtocol.setHorizontalAlignment(Element.ALIGN_CENTER); cellProtocol.setColspan(2); cellProtocol.setBorderWidth(0); cellProtocol.setPaddingTop(PDFTools.cmToPt(0.4f)); cellProtocol.setPaddingBottom(PDFTools.cmToPt(0.2f)); tableTitlePage.addCell(cellProtocol); /* * Name of the review */ PdfPCell cellRevName = new PdfPCell( new Phrase(Application.getInstance().getReviewMgmt().getReviewName(), reviewFontTitle)); cellRevName.setHorizontalAlignment(Element.ALIGN_CENTER); cellRevName.setColspan(2); cellRevName.setBorderWidth(0); cellRevName.setPaddingBottom(PDFTools.cmToPt(1.6f)); tableTitlePage.addCell(cellRevName); /* * Review meeting date and location */ if (meetings.size() == 1) { sdfDate.setTimeZone(meetings.get(0).getProtocol().getDate().getTimeZone()); sdfTime.setTimeZone(meetings.get(0).getProtocol().getDate().getTimeZone()); String meetingDate = sdfDate.format(meetings.get(0).getProtocol().getDate().getTime()); String meetingTime = sdfTime.format(meetings.get(0).getProtocol().getStart().getTime()) + " - " + sdfTime.format(meetings.get(0).getProtocol().getEnd().getTime()) + " [" + meetings.get(0).getProtocol().getEnd().getTimeZone().getDisplayName() + "]"; Phrase phraseMeeting = new Phrase(meetingDate + " (" + meetingTime + ")", meetingFontTitle); PdfPCell cellMeeting = new PdfPCell(phraseMeeting); cellMeeting.setColspan(2); cellMeeting.setHorizontalAlignment(Element.ALIGN_CENTER); cellMeeting.setPadding(0); cellMeeting.setBorderWidth(0); tableTitlePage.addCell(cellMeeting); String location = meetings.get(0).getProtocol().getLocation(); if (location.trim().equals("")) { location = "--"; } cellMeeting = new PdfPCell(new Phrase(translate("Location") + ": " + location, meetingFontTitle)); cellMeeting.setColspan(2); cellMeeting.setHorizontalAlignment(Element.ALIGN_CENTER); cellMeeting.setPadding(0); cellMeeting.setBorderWidth(0); cellMeeting.setPaddingTop(PDFTools.cmToPt(0.15f)); cellMeeting.setPaddingBottom(PDFTools.cmToPt(1.9f)); tableTitlePage.addCell(cellMeeting); } /* * Review description and comments */ PdfPCell cellRevDesc = new PdfPCell(new Phrase(translate("Review Description:"), boldItalicFont)); cellRevDesc.setBorderWidth(0); cellRevDesc.setPadding(padding); tableTitlePage.addCell(cellRevDesc); cellRevDesc = new PdfPCell(new Phrase(translate("Review Comments"), boldFont)); cellRevDesc.setBorderWidth(0); cellRevDesc.setPadding(padding); cellRevDesc.setBackgroundColor(cellBackground); tableTitlePage.addCell(cellRevDesc); String revDesc = Application.getInstance().getReviewMgmt().getReviewDescription(); if (revDesc.trim().equals("")) { revDesc = "--"; } Phrase phrDesc = new Phrase(revDesc, plainFont); phrDesc.setLeading(leading); cellRevDesc = new PdfPCell(); cellRevDesc.addElement(phrDesc); cellRevDesc.setBorderWidth(0); cellRevDesc.setPadding(padding); cellRevDesc.setPaddingBottom(padding * 1.8f); tableTitlePage.addCell(cellRevDesc); String revComm = Application.getInstance().getReviewMgmt().getReviewComments(); if (revComm.trim().equals("")) { revComm = "--"; } Phrase phrComm = new Phrase(revComm, italicFont); phrComm.setLeading(leading); cellRevDesc = new PdfPCell(); cellRevDesc.addElement(phrComm); cellRevDesc.setBorderWidth(0); cellRevDesc.setPadding(padding); cellRevDesc.setPaddingBottom(padding * 1.8f); cellRevDesc.setBackgroundColor(cellBackground); tableTitlePage.addCell(cellRevDesc); tableTitlePage.addCell(createVerticalStrut(PDFTools.cmToPt(1.0f), 2)); /* * Product title */ PdfPTable tableProduct = new PdfPTable(new float[] { 0.07f, 0.93f }); tableProduct.setWidthPercentage(100); tableProduct.setSplitRows(false); tableProduct.getDefaultCell().setBorderWidth(0); tableProduct.getDefaultCell().setPadding(0); PdfPCell cellProdTitle = new PdfPCell(new Phrase(translate("Reviewed Product:"), boldItalicFont)); cellProdTitle.setColspan(2); cellProdTitle.setPadding(padding); cellProdTitle.setBorder(0); tableProduct.addCell(cellProdTitle); /* * List point used for lists */ Phrase phraseListPoint = new Phrase("", boldFont); phraseListPoint.setLeading(leading); PdfPCell cellListPoint = new PdfPCell(); cellListPoint.addElement(phraseListPoint); cellListPoint.setBorderWidth(0); cellListPoint.setPadding(padding); cellListPoint.setPaddingLeft(padding * 2); cellListPoint.setPaddingBottom(0); /* * Write name and version of the reviewed product */ String prodName = Data.getInstance().getResiData().getReview().getProduct().getName(); if (prodName.trim().equals("")) { prodName = "--"; } Phrase phrName = new Phrase(translate("Product Name") + ": " + prodName, plainFont); phrName.setLeading(leading); PdfPCell cellName = new PdfPCell(); cellName.addElement(phrName); cellName.setBorderWidth(0); cellName.setPadding(padding); cellName.setPaddingBottom(0); tableProduct.addCell(cellListPoint); tableProduct.addCell(cellName); String prodVersion = Data.getInstance().getResiData().getReview().getProduct().getVersion(); if (prodVersion.trim().equals("")) { prodVersion = "--"; } Phrase phrVersion = new Phrase(translate("Product Version") + ": " + prodVersion, plainFont); phrVersion.setLeading(leading); PdfPCell cellVersion = new PdfPCell(); cellVersion.addElement(phrVersion); cellVersion.setBorderWidth(0); cellVersion.setPadding(padding); cellVersion.setPaddingBottom(0); tableProduct.addCell(cellListPoint); tableProduct.addCell(cellVersion); if (Application.getInstance().getReviewMgmt().getNumberOfProdRefs() > 0) { /* * Table of product references */ PdfPCell cellRefTitle = new PdfPCell(new Phrase(translate("Product References:"), boldItalicFont)); cellRefTitle.setBorderWidth(0); cellRefTitle.setPadding(padding); cellRefTitle.setPaddingTop(padding * 4); cellRefTitle.setColspan(2); tableProduct.addCell(cellRefTitle); /* * Textual references */ for (String ref : Application.getInstance().getReviewMgmt().getProductReferences()) { Phrase phraseRef = new Phrase(ref, plainFont); phraseRef.setLeading(leading); PdfPCell cellRef = new PdfPCell(); cellRef.addElement(phraseRef); cellRef.setBorderWidth(0); cellRef.setPadding(padding); cellRef.setPaddingBottom(0); tableProduct.addCell(cellListPoint); tableProduct.addCell(cellRef); } /* * External file references */ for (File ref : Application.getInstance().getReviewMgmt().getExtProdReferences()) { Phrase phraseRef = new Phrase(); phraseRef.add(new Chunk(ref.getName(), plainFont)); phraseRef.add(new Chunk(" (" + translate("File Attachment") + ")", italicFont)); phraseRef.setFont(plainFont); phraseRef.setLeading(leading); PdfPCell cellRef = new PdfPCell(); cellRef.addElement(phraseRef); cellRef.setBorderWidth(0); cellRef.setPadding(padding); cellRef.setPaddingBottom(0); tableProduct.addCell(cellListPoint); if (attachProdExtRefs) { cellRef.setCellEvent(new PDFCellEventExtRef(pdfWriter, ref)); } tableProduct.addCell(cellRef); } } /* * Add the product table to the base table */ PdfPCell cellProduct = new PdfPCell(tableProduct); cellProduct.setBorder(0); cellProduct.setPadding(0); tableTitlePage.addCell(cellProduct); /* * List the meetings of this review */ PdfPCell cellInfos = new PdfPCell(); cellInfos.setBorder(0); cellInfos.setPadding(0); /* * meeting list title or meeting info title */ PdfPTable tableInfos = new PdfPTable(new float[] { 0.09f, 0.91f }); tableInfos.setWidthPercentage(100); tableInfos.setSplitRows(false); tableInfos.getDefaultCell().setBorderWidth(0); tableInfos.getDefaultCell().setPadding(0); String title = translate("Meeting Information:"); if (meetings.size() > 1) { title = translate("Findings Lists of the Review Meetings:"); } PdfPCell cellInfosTitle = new PdfPCell(new Phrase(title, boldFont)); cellInfosTitle.setColspan(2); cellInfosTitle.setPadding(padding); cellInfosTitle.setBorder(0); tableInfos.addCell(cellInfosTitle); if (meetings.size() > 1) { /* * list the meetings of this review (for review protocols) */ for (Meeting m : meetings) { Protocol protocol = m.getProtocol(); if (protocol != null) { String meetingDate = sdfDate.format(protocol.getDate().getTime()); String meetingTime = sdfTime.format(protocol.getStart().getTime()) + " - " + sdfTime.format(protocol.getEnd().getTime()) + " [" + protocol.getEnd().getTimeZone().getDisplayName() + "]"; String protLoc = protocol.getLocation(); if (protLoc.trim().equals("")) { protLoc = "--"; } Phrase phraseMeet = new Phrase( translate("Date") + ": " + meetingDate + "\n" + translate("Time") + ": " + meetingTime + "\n" + translate("Location") + ": " + protLoc, italicFont); Paragraph paraMeet = new Paragraph(); paraMeet.setLeading(leading); Anchor anchor = new Anchor(phraseMeet); anchor.setReference("#" + Long.toString( protocol.getDate().getTimeInMillis() + protocol.getStart().getTimeInMillis())); paraMeet.add(anchor); PdfPCell cellMeet = new PdfPCell(); cellMeet.addElement(paraMeet); cellMeet.setBorderWidth(0); cellMeet.setPadding(padding); tableInfos.addCell(cellListPoint); tableInfos.addCell(cellMeet); } } } else { Protocol prot = meetings.get(0).getProtocol(); Duration meetDur = DatatypeFactory.newInstance() .newDuration(prot.getEnd().getTimeInMillis() - prot.getStart().getTimeInMillis()); Phrase phraseMeetInfo = new Phrase( translate("Duration of the meeting") + ":\n" + meetDur.getHours() + " " + translate("Hour(s)") + ", " + meetDur.getMinutes() + " " + translate("Minute(s)"), italicFont); phraseMeetInfo.setLeading(leading); PdfPCell cellMeetInfo = new PdfPCell(); cellMeetInfo.addElement(phraseMeetInfo); cellMeetInfo.setBorderWidth(0); cellMeetInfo.setPadding(padding); tableInfos.addCell(cellListPoint); tableInfos.addCell(cellMeetInfo); /* * meeting number of findings */ phraseMeetInfo = new Phrase(translate("Number of findings") + ": " + prot.getFindings().size(), italicFont); phraseMeetInfo.setLeading(leading); cellMeetInfo = new PdfPCell(); cellMeetInfo.addElement(phraseMeetInfo); cellMeetInfo.setBorderWidth(0); cellMeetInfo.setPadding(padding); tableInfos.addCell(cellListPoint); tableInfos.addCell(cellMeetInfo); /* * meeting number of attendees */ phraseMeetInfo = new Phrase( translate("Number of attendees") + ": " + protMgmt.getAttendees(prot).size(), italicFont); phraseMeetInfo.setLeading(leading); cellMeetInfo = new PdfPCell(); cellMeetInfo.addElement(phraseMeetInfo); cellMeetInfo.setBorderWidth(0); cellMeetInfo.setPadding(padding); tableInfos.addCell(cellListPoint); tableInfos.addCell(cellMeetInfo); } cellInfos.addElement(tableInfos); cellInfos.setBackgroundColor(cellBackground); cellInfos.setPaddingBottom(padding); tableTitlePage.addCell(cellInfos); /* * Insert vertical strut */ tableTitlePage.addCell(createVerticalStrut(PDFTools.cmToPt(1.0f), 2)); /* * Write general impression and recommendation */ PdfPTable tableRevInfo = new PdfPTable(new float[] { 0.5f, 0.5f }); tableRevInfo.setWidthPercentage(100); tableRevInfo.setSplitRows(false); tableRevInfo.getDefaultCell().setBorderWidth(0); tableRevInfo.getDefaultCell().setPadding(0); /* * Insert vertical strut */ tableRevInfo.addCell(createVerticalStrut(PDFTools.cmToPt(0.5f), 2)); PdfPCell cellImpr = new PdfPCell( new Phrase(translate("General impressions of the product:"), boldFont)); cellImpr.setBorderWidth(0); cellImpr.setPadding(padding); cellImpr.setBorderColor(verticalBorderColor); cellImpr.setBorderWidthLeft(verticalBorderWidth); tableRevInfo.addCell(cellImpr); PdfPCell cellReco = new PdfPCell( new Phrase(translate("Final recommendation for the product:"), boldFont)); cellReco.setBorderWidth(0); cellReco.setPadding(padding); cellReco.setBorderColor(verticalBorderColor); cellReco.setBorderWidthLeft(verticalBorderWidth); tableRevInfo.addCell(cellReco); String impression = Application.getInstance().getReviewMgmt().getImpression(); if (impression.trim().equals("")) { impression = "--"; } Phrase phrImpr = new Phrase(impression, italicFont); phrImpr.setLeading(leading); cellImpr = new PdfPCell(); cellImpr.addElement(phrImpr); cellImpr.setBorderWidth(0); cellImpr.setPadding(padding); cellImpr.setPaddingBottom(padding * 1.8f); cellImpr.setBorderColor(verticalBorderColor); cellImpr.setBorderWidthLeft(verticalBorderWidth); tableRevInfo.addCell(cellImpr); String recommendation = Application.getInstance().getReviewMgmt().getRecommendation(); if (recommendation.trim().equals("")) { recommendation = "--"; } Phrase phrReco = new Phrase(recommendation, italicFont); phrReco.setLeading(leading); cellReco = new PdfPCell(); cellReco.addElement(phrReco); cellReco.setBorderWidth(0); cellReco.setPadding(padding); cellReco.setPaddingBottom(padding * 1.8f); cellReco.setBorderColor(verticalBorderColor); cellReco.setBorderWidthLeft(verticalBorderWidth); tableRevInfo.addCell(cellReco); /* * Add vertical strut */ tableRevInfo.addCell(createVerticalStrut(PDFTools.cmToPt(0.8f), 2)); /* * Write possible severities for this review */ String severities = ""; String separator = ""; for (String sev : Application.getInstance().getSeverityMgmt().getSeverities()) { severities = severities + separator + sev; separator = "; "; } Phrase phrSeverities = new Phrase(); phrSeverities.add(new Chunk( translate("The severities of the findings in this review (descending order of importance):"), italicFontSmall)); phrSeverities.add(new Chunk(" " + severities, boldItalicFontSmall)); phrSeverities.setLeading(leading); PdfPCell cellSevs = new PdfPCell(); cellSevs.setColspan(2); cellSevs.addElement(phrSeverities); cellSevs.setBorderWidth(0); cellSevs.setPadding(padding); tableRevInfo.addCell(cellSevs); /* * Short review statistics */ if (meetings.size() > 1) { Phrase phrRevStat = new Phrase(MessageFormat.format(translate( "This review consists of {0} attendees, {1} findings, {2} meetings and {3} aspects."), Application.getInstance().getReviewMgmt().getNumberOfAttendees(), Application.getInstance().getReviewMgmt().getNumberOfFindings(), Application.getInstance().getReviewMgmt().getNumberOfMeetings(), Application.getInstance().getReviewMgmt().getNumberOfAspects()), italicFontSmall); phrRevStat.setLeading(leading); PdfPCell cellRevStat = new PdfPCell(); cellRevStat.setColspan(2); cellRevStat.setHorizontalAlignment(Element.ALIGN_CENTER); cellRevStat.addElement(phrRevStat); cellRevStat.setBorderWidth(0); cellRevStat.setPadding(padding); cellRevStat.setPaddingTop(0); tableRevInfo.addCell(cellRevStat); } /* * Write the date of creation */ String creationDate = sdfDate.format(new Date().getTime()); Phrase phrCreationDate = new Phrase( translate("This finding has been created with RevAger on") + " " + creationDate, plainFontSmall); phrCreationDate.setLeading(leading); PdfPCell cellCrDate = new PdfPCell(); cellCrDate.setColspan(2); cellCrDate.setHorizontalAlignment(Element.ALIGN_CENTER); cellCrDate.addElement(phrCreationDate); cellCrDate.setBorderWidth(0); cellCrDate.setPadding(0); cellCrDate.setPaddingLeft(padding); cellCrDate.setPaddingRight(padding); tableRevInfo.addCell(cellCrDate); /* * Add content to the base table */ PdfPCell cellRevInfo = new PdfPCell(); cellRevInfo.setColspan(2); cellRevInfo.setBorder(0); cellRevInfo.setPadding(0); cellRevInfo.addElement(tableRevInfo); tableTitlePage.addCell(cellRevInfo); pdfDoc.add(tableTitlePage); } catch (Exception e) { /* * Not part of unit testing because this exception is only thrown if * an internal error occurs. */ throw new ExportException(translate("Cannot generate front page of the PDF document.")); } } /** * Writes the given meeting to the protocol. * * @param meeting * the meeting * @param attachExtRefs * true if the external references should be part of the protocol * @param showSignatureFields * true, if the signature fields should be part of the protocol * * @throws ExportException * If an error occurs while writing the meeting */ protected void writeMeeting(Meeting meeting, boolean attachExtRefs, boolean showSignatureFields) throws ExportException { Protocol protocol = meeting.getProtocol(); if (protocol != null) { try { Font plainFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font boldFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font italicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font boldItalicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font boldFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 17); Font italicFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 13); /* * Base table for the meeting properties */ PdfPTable tableMeeting = new PdfPTable(2); tableMeeting.setWidthPercentage(100); tableMeeting.setSplitRows(false); tableMeeting.getDefaultCell().setBorderWidth(0); tableMeeting.getDefaultCell().setPadding(0); /* * Write date, time and location of the meeting */ String meetingDate = sdfDate.format(protocol.getDate().getTime()); String meetingTime = sdfTime.format(protocol.getStart().getTime()) + " - " + sdfTime.format(protocol.getEnd().getTime()) + " [" + protocol.getEnd().getTimeZone().getDisplayName() + "]"; Anchor anchorTitle = new Anchor(translate("Review Meeting on") + " " + meetingDate, boldFontTitle); anchorTitle.setName(Long .toString(protocol.getDate().getTimeInMillis() + protocol.getStart().getTimeInMillis())); PdfPCell cellTitle = new PdfPCell(anchorTitle); cellTitle.setColspan(2); cellTitle.setHorizontalAlignment(Element.ALIGN_CENTER); cellTitle.setPadding(0); cellTitle.setBorderWidth(0); cellTitle.setPaddingTop(PDFTools.cmToPt(0.6f)); cellTitle.setPaddingBottom(padding * 2); tableMeeting.addCell(cellTitle); PdfPCell cellTime = new PdfPCell(new Phrase(meetingTime, italicFontTitle)); cellTime.setColspan(2); cellTime.setHorizontalAlignment(Element.ALIGN_CENTER); cellTime.setPadding(0); cellTime.setBorderWidth(0); cellTime.setPaddingBottom(padding * 2); tableMeeting.addCell(cellTime); String location = protocol.getLocation(); if (location.trim().equals("")) { location = "--"; } PdfPCell cellLocation = new PdfPCell( new Phrase(translate("Location") + ": " + location, italicFontTitle)); cellLocation.setColspan(2); cellLocation.setHorizontalAlignment(Element.ALIGN_CENTER); cellLocation.setPadding(0); cellLocation.setBorderWidth(0); cellLocation.setPaddingBottom(PDFTools.cmToPt(1.5f)); tableMeeting.addCell(cellLocation); /* * Compare with planned meeting */ PdfPCell cellPlanned; boolean plannedDateEqualsProtocolDate = meeting.getPlannedDate() .get(Calendar.DAY_OF_MONTH) == protocol.getDate().get(Calendar.DAY_OF_MONTH) && meeting.getPlannedDate().get(Calendar.MONTH) == protocol.getDate().get(Calendar.MONTH) && meeting.getPlannedDate().get(Calendar.YEAR) == protocol.getDate().get(Calendar.YEAR); boolean plannedStartEqualsProtocolStart = meeting.getPlannedStart().get(Calendar.HOUR) == protocol .getStart().get(Calendar.HOUR) && meeting.getPlannedStart().get(Calendar.MINUTE) == protocol.getStart() .get(Calendar.MINUTE) && meeting.getPlannedStart().get(Calendar.AM_PM) == protocol.getStart().get(Calendar.AM_PM); boolean plannedEndEqualsProtocolEnd = meeting.getPlannedEnd().get(Calendar.HOUR) == protocol .getEnd().get(Calendar.HOUR) && meeting.getPlannedEnd().get(Calendar.MINUTE) == protocol.getEnd().get(Calendar.MINUTE) && meeting.getPlannedEnd().get(Calendar.AM_PM) == protocol.getEnd().get(Calendar.AM_PM); boolean plannedLocationEqualsProtocolLocation = meeting.getPlannedLocation() .equals(protocol.getLocation()); if (plannedDateEqualsProtocolDate && plannedStartEqualsProtocolStart && plannedEndEqualsProtocolEnd && plannedLocationEqualsProtocolLocation) { cellPlanned = new PdfPCell( new Phrase(translate("The meeting took place as it has been planned."), plainFont)); } else { cellPlanned = new PdfPCell(); cellPlanned.addElement(new Phrase(translate( "The meeting didn't take place as it has been planned. The meeting was planned:"), plainFont)); /* * Planned date, time and location */ String plannedDate = sdfDate.format(meeting.getPlannedDate().getTime()); String plannedTime = sdfTime.format(meeting.getPlannedStart().getTime()) + " - " + sdfTime.format(meeting.getPlannedEnd().getTime()) + " [" + meeting.getPlannedEnd().getTimeZone().getDisplayName() + "]"; Phrase phrasePlanned = new Phrase(plannedDate + " (" + plannedTime + "); " + translate("Location") + ": " + meeting.getPlannedLocation(), italicFont); cellPlanned.addElement(phrasePlanned); } cellPlanned.setColspan(2); cellPlanned.setBorderWidth(0); cellPlanned.setPadding(padding); cellPlanned.setPaddingBottom(PDFTools.cmToPt(1.5f)); tableMeeting.addCell(cellPlanned); /* * Comments of the meeting and protocol */ Phrase phraseComments = new Phrase(translate("Comments on the Meeting:"), boldFont); PdfPCell cellComments = new PdfPCell(phraseComments); cellComments.setBorderWidth(0); cellComments.setPadding(padding); cellComments.setBorderColor(verticalBorderColor); cellComments.setBorderWidthLeft(verticalBorderWidth); tableMeeting.addCell(cellComments); phraseComments = new Phrase(translate("Comments on the Findings List:"), boldFont); cellComments = new PdfPCell(phraseComments); cellComments.setBorderWidth(0); cellComments.setPadding(padding); cellComments.setBorderColor(verticalBorderColor); cellComments.setBorderWidthLeft(verticalBorderWidth); tableMeeting.addCell(cellComments); String meetingComments = meeting.getComments(); if (meetingComments.trim().equals("")) { meetingComments = "--"; } phraseComments = new Phrase(meetingComments, italicFont); phraseComments.setLeading(leading); cellComments = new PdfPCell(); cellComments.addElement(phraseComments); cellComments.setBorderWidth(0); cellComments.setPadding(padding); cellComments.setPaddingBottom(padding * 1.8f); cellComments.setBorderColor(verticalBorderColor); cellComments.setBorderWidthLeft(verticalBorderWidth); tableMeeting.addCell(cellComments); String protocolComments = protocol.getComments(); if (protocolComments.trim().equals("")) { protocolComments = "--"; } phraseComments = new Phrase(protocolComments, italicFont); phraseComments.setLeading(leading); cellComments = new PdfPCell(); cellComments.addElement(phraseComments); cellComments.setBorderWidth(0); cellComments.setPadding(padding); cellComments.setPaddingBottom(padding * 1.8f); cellComments.setBorderColor(verticalBorderColor); cellComments.setBorderWidthLeft(verticalBorderWidth); tableMeeting.addCell(cellComments); /* * Strut cell */ tableMeeting.addCell(createVerticalStrut(PDFTools.cmToPt(1.3f), 2)); /* * Write attendees */ if (protMgmt.getAttendees(protocol).size() > 0) { PdfPCell cellAtt = new PdfPCell(new Phrase( translate("The following attendees participated") + " (" + protMgmt.getAttendees(protocol).size() + " " + translate("attendees") + "):", boldItalicFont)); cellAtt.setColspan(2); cellAtt.setPadding(0); cellAtt.setBorderWidth(0); cellAtt.setPadding(padding); cellAtt.setPaddingBottom(PDFTools.cmToPt(0.8f)); tableMeeting.addCell(cellAtt); } pdfDoc.add(tableMeeting); if (protMgmt.getAttendees(protocol).size() > 0) { writeAttendees(protocol, true, true, showSignatureFields); } /* * If there isn't any finding, finish the export here. */ if (findMgmt.getNumberOfFindings(protocol) == 0) { return; } else if (findMgmt.getNumberOfFindings(protocol) == 1) { Finding find = findMgmt.getFindings(protocol).get(0); if (find.getDescription().trim().equals("") && find.getExternalReferences().size() == 0 && find.getReferences().size() == 0 && find.getAspects().size() == 0) { return; } } /* * Write findings */ pdfDoc.newPage(); PdfPTable tableFindIntro = new PdfPTable(1); tableFindIntro.setWidthPercentage(100); Phrase phraseFindIntro = new Phrase( translate("The following findings were recorded by the participating reviewers") + " (" + findMgmt.getNumberOfFindings(protocol) + " " + translate("findings") + "): ", boldItalicFont); phraseFindIntro.setLeading(leading); PdfPCell cellFindIntro = new PdfPCell(); cellFindIntro.addElement(phraseFindIntro); cellFindIntro.setBorderWidth(0); cellFindIntro.setPadding(0); cellFindIntro.setPaddingBottom(PDFTools.cmToPt(0.1f)); tableFindIntro.addCell(cellFindIntro); pdfDoc.add(tableFindIntro); writeFindings(protocol, attachExtRefs); } catch (Exception e) { /* * Not part of unit testing because this exception is only * thrown if an internal error occurs. */ throw new ExportException(translate("Cannot put the selected review meeting in the PDF document.")); } } } /** * Writes the given attendees to the protocol. * * @param protocol * the protocol * @param showAttendeesAspects * true, if the aspects of the reviewers should be part of the * protocol * @param showAttendeesPrepTime * true, if the preparation time of the reviewers should be part * of the protocol * @param showSignatureFields * ture, if the signature fields should be part of the protocol * * @throws ExportException * If an error occurs while writing the attendees to the * protocol */ protected void writeAttendees(Protocol protocol, boolean showAttendeesAspects, boolean showAttendeesPrepTime, boolean showSignatureFields) throws ExportException { List<Attendee> atts; if (protocol != null) { atts = protMgmt.getAttendees(protocol); } else { atts = Application.getInstance().getAttendeeMgmt().getAttendees(); } /* * Sort the attendees by their role into different lists */ List<Attendee> reviewers = new ArrayList<Attendee>(); List<Attendee> moderators = new ArrayList<Attendee>(); List<Attendee> scribes = new ArrayList<Attendee>(); List<Attendee> authors = new ArrayList<Attendee>(); List<Attendee> customers = new ArrayList<Attendee>(); List<Attendee> others = new ArrayList<Attendee>(); for (Attendee att : atts) { switch (att.getRole()) { case AUTHOR: authors.add(att); break; case CUSTOMER: customers.add(att); break; case MODERATOR: moderators.add(att); break; case REVIEWER: reviewers.add(att); break; case SCRIBE: scribes.add(att); break; default: others.add(att); break; } } List<List<Attendee>> attendees = new ArrayList<List<Attendee>>(); attendees.add(moderators); attendees.add(scribes); attendees.add(authors); attendees.add(customers); attendees.add(reviewers); attendees.add(others); /* * Write attendees */ try { Font contactFont = new Font(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font nameFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font roleFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font aspectsFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 8); Font aspectsTitleFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 8); /* * Build base table for all attendees */ PdfPTable tableAttendees = new PdfPTable(1); tableAttendees.setWidthPercentage(100); tableAttendees.setSplitRows(false); tableAttendees.getDefaultCell().setBorderWidth(0); tableAttendees.getDefaultCell().setPadding(0); boolean grayBackground = true; for (List<Attendee> attList : attendees) { for (Attendee att : attList) { /* * Build table for one attendee */ PdfPTable tableAttendee = new PdfPTable(new float[] { 0.80f, 0.20f }); tableAttendee.setWidthPercentage(100); tableAttendee.getDefaultCell().setBorderWidth(0); tableAttendee.getDefaultCell().setPadding(0); PdfPCell cellAttendee = new PdfPCell(); cellAttendee.setPadding(0); cellAttendee.setBorder(0); /* * Name of the attendee */ PdfPCell cell = new PdfPCell(); cell.setBorderWidth(0); cell.setPadding(padding * 0.4f); cell.setPaddingBottom(padding * 1.5f); cell.addElement(new Phrase(att.getName(), nameFont)); cell.addElement(new Phrase(att.getContact(), contactFont)); Phrase phraseStrut = new Phrase(" "); phraseStrut.setLeading(leading * 0.6f); /* * Aspects of this attendee */ if (!attMgmt.getAspects(att).isEmpty() && showAttendeesAspects) { String separator = ""; cell.addElement(phraseStrut); cell.addElement(new Phrase(translate("Assigned aspects:") + " ", aspectsTitleFont)); Phrase phraseAspects = new Phrase(); phraseAspects.setLeading(leading); phraseAspects.setFont(aspectsFont); for (Aspect asp : attMgmt.getAspects(att)) { phraseAspects.add(new Chunk( separator + asp.getDirective() + " (" + asp.getCategory() + ")", aspectsFont)); separator = " "; } cell.addElement(phraseAspects); } /* * Preparation time of the attendee */ Duration prepTime; if (protocol != null) { prepTime = protMgmt.getAttendeePrepTime(att, protocol); } else { prepTime = null; } if (prepTime != null && showAttendeesPrepTime) { cell.addElement(phraseStrut); cell.addElement(new Phrase(translate("Preparation time:") + " ", aspectsTitleFont)); Phrase phrasePrepTime = new Phrase(); phrasePrepTime.setLeading(leading); phrasePrepTime.setFont(aspectsFont); String prep = ""; String separator = ""; if (prepTime.getDays() > 0) { prep = prep + prepTime.getDays() + " " + translate("Day(s)"); separator = ", "; } if (prepTime.getHours() > 0) { prep = prep + separator + prepTime.getHours() + " " + translate("Hour(s)"); separator = ", "; } if (prepTime.getMinutes() >= 0) { prep = prep + separator + prepTime.getMinutes() + " " + translate("Minute(s)"); separator = ", "; } phrasePrepTime.add(new Chunk(prep, aspectsFont)); cell.addElement(phrasePrepTime); } /* * Signature field for the attendee */ if (showSignatureFields) { cell.addElement(phraseStrut); cell.addElement(phraseStrut); cell.addElement(phraseStrut); cell.addElement(phraseStrut); cell.addElement(new Phrase("________________________________________", aspectsFont)); cell.addElement( new Phrase(translate("Date, Signature") + " (" + att.getName() + ")", aspectsFont)); } tableAttendee.addCell(cell); /* * role of the attendee */ cell = new PdfPCell(new Phrase(translate(att.getRole().toString()), roleFont)); cell.setBorderWidth(0); cell.setPadding(padding * 0.4f); cell.setPaddingTop(padding * 1.1f); cell.setHorizontalAlignment(Element.ALIGN_RIGHT); tableAttendee.addCell(cell); cellAttendee.addElement(tableAttendee); cellAttendee.setPadding(0); cellAttendee.setPaddingLeft(padding); cellAttendee.setPaddingRight(padding); if (grayBackground == true) { grayBackground = false; cellAttendee.setBackgroundColor(cellBackground); } else { grayBackground = true; } /* * Add attendee to the list */ tableAttendees.addCell(cellAttendee); } } PdfPCell cellBottomLine = new PdfPCell(); cellBottomLine.setPadding(0); cellBottomLine.setBorderWidth(0); cellBottomLine.setBorderWidthBottom(1); cellBottomLine.setBorderColor(cellBackground); tableAttendees.addCell(cellBottomLine); /* * Add the attendee base table to the document */ pdfDoc.add(tableAttendees); } catch (Exception e) { /* * Not part of unit testing because this exception is only thrown if * an internal error occurs. */ throw new ExportException(translate("Cannot put attendees into the PDF document.")); } } /** * Write the findings to the protocol. * * @param protocol * the protocol * @param attachExtRefs * true if the external references should be part of the protocol * * @throws ExportException * If an error occurs while writing the findings to the protocol */ protected void writeFindings(Protocol protocol, boolean attachExtRefs) throws ExportException { try { /* * Define fonts */ Font plainFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 9, Font.NORMAL, Color.WHITE); Font boldFontTitle = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 10, Font.NORMAL, Color.WHITE); Font plainFont = new Font(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font boldFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font italicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_OBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); Font boldItalicFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE, BaseFont.CP1252, BaseFont.EMBEDDED), 10); /* * Write findings */ PdfPTable tableBase = new PdfPTable(1); tableBase.setWidthPercentage(100); tableBase.setSplitRows(false); tableBase.getDefaultCell().setBorderWidth(0); tableBase.getDefaultCell().setPadding(0); for (Finding f : protocol.getFindings()) { tableBase.addCell(createVerticalStrut(PDFTools.cmToPt(0.7f), 1)); PdfPCell cellFinding = new PdfPCell(); cellFinding.setBorderColor(Color.GRAY); cellFinding.setBorderWidth(0.5f); PdfPTable tableTitle = new PdfPTable(3); tableTitle.setWidthPercentage(100); /* * Print title of the finding */ Phrase phraseTitle = new Phrase(translate("Finding") + " " + f.getId(), boldFontTitle); PdfPCell cellTitle = new PdfPCell(phraseTitle); cellTitle.setBackgroundColor(bgColorTitle); cellTitle.setBorderWidth(0); cellTitle.setPadding(padding); cellTitle.setPaddingBottom(padding * 1.5f); cellTitle.setHorizontalAlignment(Element.ALIGN_LEFT); tableTitle.addCell(cellTitle); /* * Print severity of the finding */ Phrase phraseSeverity = new Phrase(findMgmt.getLocalizedSeverity(f), plainFontTitle); PdfPCell cellSeverity = new PdfPCell(phraseSeverity); cellSeverity.setBackgroundColor(bgColorTitle); cellSeverity.setBorderWidth(0); cellSeverity.setPadding(padding); cellSeverity.setPaddingTop(padding * 1.1f); cellSeverity.setHorizontalAlignment(Element.ALIGN_CENTER); tableTitle.addCell(cellSeverity); /* * Print the meeting date and time of the finding */ String meetingDate = sdfDate.format(protocol.getDate().getTime()); PdfPCell cellMeeting = new PdfPCell(new Phrase(meetingDate, plainFontTitle)); cellMeeting.setBackgroundColor(bgColorTitle); cellMeeting.setBorderWidth(0); cellMeeting.setPadding(padding); cellMeeting.setPaddingTop(padding * 1.1f); cellMeeting.setHorizontalAlignment(Element.ALIGN_RIGHT); tableTitle.addCell(cellMeeting); /* * Description */ Phrase phraseDesc = new Phrase(f.getDescription(), plainFont); phraseDesc.setLeading(leading); PdfPCell cellDesc = new PdfPCell(); cellDesc.addElement(phraseDesc); cellDesc.setBorderWidth(0); cellDesc.setPadding(padding); cellDesc.setColspan(3); tableTitle.addCell(cellDesc); cellFinding.addElement(tableTitle); /* * List point used for lists */ Phrase phraseListPoint = new Phrase("", boldFont); phraseListPoint.setLeading(leading * 0.93f); PdfPCell cellListPoint = new PdfPCell(); cellListPoint.addElement(phraseListPoint); cellListPoint.setBorderWidth(0); cellListPoint.setPadding(padding); cellListPoint.setPaddingLeft(padding * 2); /* * Table of references */ if (f.getReferences().size() > 0 || (f.getExternalReferences().size() > 0 && attachExtRefs == true)) { PdfPTable tableRefs = new PdfPTable(new float[] { 0.04f, 0.96f }); tableRefs.setWidthPercentage(100); PdfPCell cellRefTitle = new PdfPCell(new Phrase(translate("References:"), boldItalicFont)); cellRefTitle.setBorderWidth(0); cellRefTitle.setPadding(padding); cellRefTitle.setPaddingTop(padding * 3); cellRefTitle.setPaddingBottom(0); cellRefTitle.setColspan(2); tableRefs.addCell(cellRefTitle); /* * Textual references */ for (String ref : f.getReferences()) { Phrase phraseRef = new Phrase(ref, plainFont); phraseRef.setLeading(leading); PdfPCell cellRef = new PdfPCell(); cellRef.addElement(phraseRef); cellRef.setBorderWidth(0); cellRef.setPadding(padding); tableRefs.addCell(cellListPoint); tableRefs.addCell(cellRef); } /* * External file references */ if (attachExtRefs == true) { for (File ref : findMgmt.getExtReferences(f)) { Phrase phraseRef = new Phrase(); phraseRef.add(new Chunk(ref.getName(), plainFont)); phraseRef.add(new Chunk(" (" + translate("File Attachment") + ")", italicFont)); phraseRef.setFont(plainFont); phraseRef.setLeading(leading); PdfPCell cellRef = new PdfPCell(); cellRef.addElement(phraseRef); cellRef.setBorderWidth(0); cellRef.setPadding(padding); tableRefs.addCell(cellListPoint); cellRef.setCellEvent(new PDFCellEventExtRef(pdfWriter, ref)); tableRefs.addCell(cellRef); } } cellFinding.addElement(tableRefs); } /* * Table of aspects */ if (f.getAspects().size() > 0) { PdfPTable tableAspects = new PdfPTable(new float[] { 0.04f, 0.96f }); tableAspects.setWidthPercentage(100); PdfPCell cellAspTitle = new PdfPCell(new Phrase(translate("Aspects:"), boldItalicFont)); cellAspTitle.setBorderWidth(0); cellAspTitle.setPadding(padding); cellAspTitle.setPaddingTop(padding * 3); cellAspTitle.setPaddingBottom(0); cellAspTitle.setColspan(2); tableAspects.addCell(cellAspTitle); for (String asp : f.getAspects()) { Phrase phraseAsp = new Phrase(asp, plainFont); phraseAsp.setLeading(leading); PdfPCell cellAsp = new PdfPCell(); cellAsp.addElement(phraseAsp); cellAsp.setBorderWidth(0); cellAsp.setPadding(padding); tableAspects.addCell(cellListPoint); tableAspects.addCell(cellAsp); } cellFinding.addElement(tableAspects); } /* * Vertical strut at the end of the table */ PdfPTable tableStrut = new PdfPTable(1); tableStrut.setWidthPercentage(100); tableStrut.addCell(createVerticalStrut(padding, 1)); cellFinding.addElement(tableStrut); tableBase.addCell(cellFinding); } pdfDoc.add(tableBase); } catch (Exception e) { /* * Not part of unit testing because this exception is only thrown if * an internal error occurs. */ throw new ExportException(translate("Cannot put findings into the PDF document.")); } } }