Skip to content
Snippets Groups Projects
Select Git revision
  • master protected
  • dev default protected
2 results

PdfDocument.java

Blame
  • PdfDocument.java 7.14 KiB
    package NTNU.IDATT1002.utils;
    
    import NTNU.IDATT1002.models.Image;
    import NTNU.IDATT1002.models.ImageAlbum;
    import NTNU.IDATT1002.models.Metadata;
    import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.PdfWriter;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Date;
    
    
    /**
     * Class PdfDocument. Generates a pdf document displaying a given image album.
     *
     * @author Eirik Steira
     * @version 1.0 22.03.20
     */
    public class PdfDocument {
    
        /**
         * Height ratio satisfying a 16:9 ratio.
         */
        private final double HEIGHT_RATIO = 5.3;
    
        private ImageAlbum imageAlbum;
    
        private Document document;
    
        private String DESTINATION_FILE;
    
        private String defaultTitle = "Album";
    
        /**
         * Standard fonts.
         */
        private Font headerFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
                Font.BOLD);
        private Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16,
                Font.BOLD);
        private Font smallFont = new Font(Font.FontFamily.TIMES_ROMAN, 12);
    
        public PdfDocument(ImageAlbum imageAlbum, String DESTINATION_FILE) {
            this.imageAlbum = imageAlbum;
            this.DESTINATION_FILE = DESTINATION_FILE;
            this.document = new Document();
        }
    
        public File getPdfDocument() {
            return new File(DESTINATION_FILE);
        }
    
        /**
         * Create a new pdf document.
         */
        public void createPdfDocument() {
            try {
                generatePdfDocument();
            } catch (IOException | DocumentException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * Try to generate a pdf document.
         *
         * @throws IOException
         * @throws DocumentException
         */
        private void generatePdfDocument() throws IOException, DocumentException {
            PdfWriter.getInstance(document, new FileOutputStream(DESTINATION_FILE));
            document.open();
    
            addHeadlines();
            addContent();
    
            document.close();
        }
    
        /**
         * Add default headlines to the document, ie document title, ownership and date.
         *
         * @throws DocumentException
         */
        private void addHeadlines() throws DocumentException {
            Paragraph headline = new Paragraph();
    
            addEmptyLineTo(headline, 1);
    
            headline.add(new Paragraph(defaultTitle, headerFont));
            addEmptyLineTo(headline, 1);
    
            headline.add(new Paragraph(
                    "Generated by: " + imageAlbum.getUser().getUsername() + ", "
                            + new Date(),
                    smallFont));
            addEmptyLineTo(headline, 2);
    
            document.add(headline);
        }
    
        /**
         * Add main content to the document. This entails image album meta and all images.
         *
         * @throws DocumentException
         * @throws IOException
         */
        private void addContent() throws DocumentException, IOException {
            addImageAlbumMeta();
            addImagesContainer();
        }
    
        /**
         * Add image album meta to the document, such as title, user etc.
         *
         * @throws DocumentException
         */
        private void addImageAlbumMeta() throws DocumentException {
            Paragraph imageAlbumMeta = new Paragraph();
            String imageAlbumMetaContent = formatImageAlbumMeta();
            imageAlbumMeta.add(new Paragraph(
                    imageAlbumMetaContent,
                    smallFont));
    
            addEmptyLineTo(imageAlbumMeta, 1);
            document.add(imageAlbumMeta);
        }
    
        /**
         * Add container to contain images and a headline.
         *
         * @throws DocumentException
         * @throws IOException
         */
        private void addImagesContainer() throws DocumentException, IOException {
            Paragraph imagesContainer = new Paragraph();
    
            imagesContainer.add(new Paragraph("Images:", subFont));
            document.add(imagesContainer);
            addAllImages();
        }
    
        /**
         * Add all images in the album to the document.
         *
         * @throws IOException
         * @throws DocumentException
         */
        private void addAllImages() throws IOException, DocumentException {
            for (Image image : imageAlbum.getImages())
                addSingleImage(image);
        }
    
        /**
         * Add a single image to the document.
         *
         * @param image the image to add.
         * @throws IOException
         * @throws DocumentException
         */
        private void addSingleImage(Image image) throws IOException, DocumentException {
            com.itextpdf.text.Image displayImage = getImageFileFromBytes(image.getRawImage());
            scaleImage(displayImage);
    
            document.add(displayImage);
            addImageMetaData(image);
        }
    
        /**
         * Convert an array of bytes to {@link com.itextpdf.text.Image}.
         *
         * @param imageBytes the array of bytes to convert
         * @return the image to display
         * @throws IOException
         * @throws BadElementException
         */
        private com.itextpdf.text.Image getImageFileFromBytes(byte[] imageBytes)
                throws IOException, BadElementException {
            return com.itextpdf.text.Image.getInstance(imageBytes);
        }
    
        /**
         * Scale given {@link com.itextpdf.text.Image image} to stretch
         * half the width of the page, remaining a 16:9 ratio.
         *
         * @param image the image to scale
         */
        private void scaleImage(com.itextpdf.text.Image image) {
            float documentWidth = PageSize.A4.getWidth() - 2 * PageSize.A4.getBorder();
            float scaledHeight = (float) (documentWidth / 2 * HEIGHT_RATIO);
    
            image.scaleToFit(documentWidth / 2, scaledHeight);
        }
    
        /**
         * Add an images metadata to the document.
         *
         * @param image the image holding the metadata
         * @throws DocumentException
         */
        private void addImageMetaData(Image image) throws DocumentException {
            Metadata metadata = image.getMetadata();
            if (metadata != null)
                document.add(new Paragraph(metadata.toString()));
        }
    
        /**
         * Format the album meta.
         *
         * @return the formatted album
         */
        private String formatImageAlbumMeta() {
            return new StringBuilder()
                    .append("Title: ")
                    .append(imageAlbum.getTitle())
                    .append("\n")
                    .append("User: ")
                    .append(imageAlbum.getUser().getUsername())
                    .append("\n")
                    .append("Created at: ")
                    .append(imageAlbum.getCreatedAt())
                    .append("\n")
                    .append("Description: ")
                    .append(imageAlbum.getDescription())
                    .append("\n")
                    .append("Tags: ")
                    .append(formatTags())
                    .toString();
        }
    
        /**
         * Format the albums tags, separated by a comma.
         *
         * @return the formatted tags
         */
        private String formatTags() {
            StringBuilder tags = new StringBuilder();
            imageAlbum.getTags().forEach(tag -> tags.append(tag.getName()).append(", "));
    
            return tags.toString();
        }
    
        /**
         * Add an empty line to the document.
         *
         * @param paragraph the paragraph to insert an empty line into
         * @param number the number of empty lines desired
         */
        private void addEmptyLineTo(Paragraph paragraph, int number) {
            for (int i = 0; i < number; i++) {
                paragraph.add(new Paragraph(" "));
            }
        }
    
    }