From 5bd2430513d766a44a18785e6d29a396f2598b7a Mon Sep 17 00:00:00 2001 From: Krystian Dabrowski Date: Fri, 18 Nov 2022 17:49:20 +0100 Subject: [PATCH] ATS-995, MNT-23248: TIFF to PDF ImageMagick transform don't work - introducing new custom transformer-misc: ImageToPdf --- .../resources/imagemagick_engine_config.json | 3 +- .../transformers/ImageToPdfTransformer.java | 218 +++++++++++ .../main/resources/misc_engine_config.json | 14 + .../transform/misc/MiscTransformsIT.java | 36 +- .../ImageToPdfTransformerTest.java | 350 ++++++++++++++++++ .../misc/util/ArgumentsCartesianProduct.java | 101 +++++ engines/misc/src/test/resources/quick.gif | Bin 0 -> 6139 bytes engines/misc/src/test/resources/quick.jpg | Bin 0 -> 57586 bytes engines/misc/src/test/resources/quick.png | Bin 0 -> 6253 bytes engines/misc/src/test/resources/quick.tiff | Bin 0 -> 20746 bytes .../transform/common/RequestParamMap.java | 1 + 11 files changed, 710 insertions(+), 13 deletions(-) create mode 100644 engines/misc/src/main/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformer.java create mode 100644 engines/misc/src/test/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformerTest.java create mode 100644 engines/misc/src/test/java/org/alfresco/transform/misc/util/ArgumentsCartesianProduct.java create mode 100644 engines/misc/src/test/resources/quick.gif create mode 100644 engines/misc/src/test/resources/quick.jpg create mode 100644 engines/misc/src/test/resources/quick.png create mode 100644 engines/misc/src/test/resources/quick.tiff diff --git a/engines/imagemagick/src/main/resources/imagemagick_engine_config.json b/engines/imagemagick/src/main/resources/imagemagick_engine_config.json index add6f6a7..f7cdcc74 100644 --- a/engines/imagemagick/src/main/resources/imagemagick_engine_config.json +++ b/engines/imagemagick/src/main/resources/imagemagick_engine_config.json @@ -932,7 +932,7 @@ {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-raw-minolta" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-raw-nikon" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-raw-olympus" }, - {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-portable-bitmap" }, + {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-portable-bitmap" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-raw-pentax" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-portable-graymap" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-portable-anymap" }, @@ -950,7 +950,6 @@ {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-xbitmap" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-xpixmap" }, {"sourceMediaType": "image/tiff", "targetMediaType": "image/x-xwindowdump" }, - {"sourceMediaType": "image/tiff", "targetMediaType": "application/pdf" }, {"sourceMediaType": "image/x-raw-sigma", "targetMediaType": "image/x-raw-hasselblad" }, {"sourceMediaType": "image/x-raw-sigma", "targetMediaType": "image/x-raw-sony" }, diff --git a/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformer.java b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformer.java new file mode 100644 index 00000000..0afc5f02 --- /dev/null +++ b/engines/misc/src/main/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformer.java @@ -0,0 +1,218 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco 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 Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.misc.transformers; + +import static org.alfresco.transform.common.RequestParamMap.END_PAGE; +import static org.alfresco.transform.common.RequestParamMap.PDF_FORMAT; +import static org.alfresco.transform.common.RequestParamMap.START_PAGE; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import org.alfresco.transform.base.TransformManager; +import org.alfresco.transform.base.util.CustomTransformerFileAdaptor; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory; +import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * Converts image files into PDF files. Transformer uses PDF Box to perform conversions. + * During conversion image might be scaled down (keeping proportions) to match width or height of the PDF document. + * If the image is smaller than PDF page size, the image will be placed in the top left-hand side of the PDF document page. + * Transformer takes 3 optional transform options: + * - startPage - page number of image (for multipage images) from which transformer should start conversion. Default: first page of the image. + * - endPage - page number of image (for multipage images) up to which transformation should be performed. Default: last page of the image. + * - pdfFormat - output PDF file format. Available formats: A0, A1, A2, A3, A4, A5, A6, LETTER, LEGAL. Default: A4. + */ +@Component +public class ImageToPdfTransformer implements CustomTransformerFileAdaptor +{ + private static final Logger log = LoggerFactory.getLogger(ImageToPdfTransformer.class); + + private static final String NEGATIVE_START_PAGE_ERROR_MESSAGE = "Start page number cannot be a negative number."; + private static final String NEGATIVE_END_PAGE_ERROR_MESSAGE = "End page number cannot be a negative number."; + private static final String START_PAGE_GREATER_THAN_END_PAGE_ERROR_MESSAGE = "Start page number cannot be greater than end page."; + private static final String INVALID_OPTION_ERROR_MESSAGE = "Parameter '%s' is invalid: \"%s\" - it must be an integer."; + private static final String INVALID_IMAGE_ERROR_MESSAGE = "Image file (%s) format (%s) not supported by ImageIO."; + private static final String DEFAULT_PDF_FORMAT_STRING = "A4"; + private static final PDRectangle DEFAULT_PDF_FORMAT = PDRectangle.A4; + + @Override + public String getTransformerName() + { + return "imageToPdf"; + } + + @Override + public void transform( + String sourceMimetype, String targetMimetype, Map transformOptions, + File imageFile, File pdfFile, TransformManager transformManager + ) throws Exception { + try ( + ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFile); + PDDocument pdfDocument = new PDDocument() + ) { + final Integer startPage = parseOptionIfPresent(transformOptions, START_PAGE, Integer.class).orElse(null); + final Integer endPage = parseOptionIfPresent(transformOptions, END_PAGE, Integer.class).orElse(null); + final String pdfFormat = parseOptionIfPresent(transformOptions, PDF_FORMAT, String.class).orElse(DEFAULT_PDF_FORMAT_STRING); + verifyOptions(startPage, endPage); + + final ImageReader imageReader = findImageReader(imageInputStream, imageFile.getName(), sourceMimetype); + for (int i = 0; i < imageReader.getNumImages(true); i++) + { + if (startPage != null && i < startPage) + { + continue; + } + if (endPage != null && i > endPage) + { + break; + } + + scaleAndDrawImage(pdfDocument, imageReader.read(i), pdfFormat); + } + + pdfDocument.save(pdfFile); + } + } + + private ImageReader findImageReader(final ImageInputStream imageInputStream, final String imageName, final String mimetype) throws IOException + { + final Iterator imageReaders = ImageIO.getImageReaders(imageInputStream); + if (imageReaders == null || !imageReaders.hasNext()) + { + throw new IOException(String.format(INVALID_IMAGE_ERROR_MESSAGE, imageName, mimetype)); + } + final ImageReader imageReader = imageReaders.next(); + imageReader.setInput(imageInputStream); + + return imageReader; + } + + private void scaleAndDrawImage(final PDDocument pdfDocument, final BufferedImage bufferedImage, final String pdfFormat) throws IOException + { + final PDPage pdfPage = new PDPage(resolvePdfFormat(pdfFormat)); + pdfDocument.addPage(pdfPage); + final PDImageXObject image = LosslessFactory.createFromImage(pdfDocument, bufferedImage); + try (PDPageContentStream pdfPageContent = new PDPageContentStream(pdfDocument, pdfPage)) + { + final PDRectangle pageSize = pdfPage.getMediaBox(); + final float withRatio = pageSize.getWidth() / image.getWidth(); + final float heightRatio = pageSize.getHeight() / image.getHeight(); + final float ratio = Stream.of(withRatio, heightRatio, 1f).min(Comparator.naturalOrder()).get(); + // find image bottom + final float y = pageSize.getHeight() - image.getHeight() * ratio; + // drawing starts from bottom left corner + pdfPageContent.drawImage(image, 0, y, image.getWidth() * ratio, image.getHeight() * ratio); + } + } + + private PDRectangle resolvePdfFormat(final String pdfFormat) + { + switch (pdfFormat.toUpperCase()) { + case "A4": + return DEFAULT_PDF_FORMAT; + case "LETTER": + return PDRectangle.LETTER; + case "A0": + return PDRectangle.A0; + case "A1": + return PDRectangle.A1; + case "A2": + return PDRectangle.A2; + case "A3": + return PDRectangle.A3; + case "A5": + return PDRectangle.A5; + case "A6": + return PDRectangle.A6; + case "LEGAL": + return PDRectangle.LEGAL; + default: + log.info("PDF format: '{}' not supported. Using default: '{}'", pdfFormat, DEFAULT_PDF_FORMAT_STRING); + return DEFAULT_PDF_FORMAT; + } + } + + private static Optional parseOptionIfPresent(final Map transformOptions, final String parameter, final Class targetType) + { + if (transformOptions.containsKey(parameter)) + { + final String option = transformOptions.get(parameter); + if (targetType == Integer.class) + { + try + { + return Optional.of(targetType.cast(Integer.parseInt(option))); + } + catch (NumberFormatException e) + { + throw new IllegalArgumentException(String.format(INVALID_OPTION_ERROR_MESSAGE, parameter, option)); + } + } + else + { + return Optional.of(targetType.cast(option)); + } + } + + return Optional.empty(); + } + + private static void verifyOptions(final Integer startPage, final Integer endPage) + { + if (startPage != null && startPage < 0) + { + throw new IllegalArgumentException(NEGATIVE_START_PAGE_ERROR_MESSAGE); + } + + if (endPage != null && endPage < 0) + { + throw new IllegalArgumentException(NEGATIVE_END_PAGE_ERROR_MESSAGE); + } + + if (startPage != null && endPage != null && startPage > endPage) + { + throw new IllegalArgumentException(START_PAGE_GREATER_THAN_END_PAGE_ERROR_MESSAGE); + } + } +} diff --git a/engines/misc/src/main/resources/misc_engine_config.json b/engines/misc/src/main/resources/misc_engine_config.json index 41700f84..62c466c4 100644 --- a/engines/misc/src/main/resources/misc_engine_config.json +++ b/engines/misc/src/main/resources/misc_engine_config.json @@ -8,6 +8,11 @@ ], "metadataOptions": [ {"value": {"name": "extractMapping"}} + ], + "imageToPdfOptions": [ + {"value": {"name": "startPage"}}, + {"value": {"name": "endPage"}}, + {"value": {"name": "pdfFormat"}} ] }, "transformers": [ @@ -91,6 +96,15 @@ "transformOptions": [ "metadataOptions" ] + }, + { + "transformerName": "imageToPdf", + "supportedSourceAndTargetList": [ + {"sourceMediaType": "image/tiff", "targetMediaType": "application/pdf"} + ], + "transformOptions": [ + "imageToPdfOptions" + ] } ] } \ No newline at end of file diff --git a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTransformsIT.java b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTransformsIT.java index b6984c6c..577779e5 100644 --- a/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTransformsIT.java +++ b/engines/misc/src/test/java/org/alfresco/transform/misc/MiscTransformsIT.java @@ -26,21 +26,12 @@ */ package org.alfresco.transform.misc; -import org.alfresco.transform.base.clients.FileInfo; -import org.alfresco.transform.base.clients.SourceTarget; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.core.io.Resource; -import org.springframework.http.ResponseEntity; - -import java.util.Map; -import java.util.stream.Stream; - import static java.text.MessageFormat.format; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; -import static org.alfresco.transform.base.clients.HttpClient.sendTRequest; + import static org.alfresco.transform.base.clients.FileInfo.testFile; +import static org.alfresco.transform.base.clients.HttpClient.sendTRequest; import static org.alfresco.transform.common.Mimetype.MIMETYPE_DITA; import static org.alfresco.transform.common.Mimetype.MIMETYPE_EXCEL; import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML; @@ -67,9 +58,22 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN; import static org.alfresco.transform.common.Mimetype.MIMETYPE_WORD; import static org.alfresco.transform.common.Mimetype.MIMETYPE_XML; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; import static org.springframework.http.HttpStatus.OK; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; + +import org.alfresco.transform.base.clients.FileInfo; +import org.alfresco.transform.base.clients.SourceTarget; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; + /** * @author Cezar Leahu */ @@ -146,6 +150,8 @@ public class MiscTransformsIT SourceTarget.of("application/dita+xml", "application/pdf"), SourceTarget.of("text/xml", "application/pdf"), + SourceTarget.of(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF), + SourceTarget.of("message/rfc822", "text/plain") ); } @@ -164,9 +170,17 @@ public class MiscTransformsIT try { + // when final ResponseEntity response = sendTRequest(ENGINE_URL, sourceFile, sourceMimetype, targetMimetype, targetExtension); + assertEquals(OK, response.getStatusCode(), descriptor); + if (MIMETYPE_PDF.equals(targetMimetype)) + { + // verify if PDF isn't corrupted + final PDDocument pdfFile = PDDocument.load(Objects.requireNonNull(response.getBody()).getInputStream()); + assertNotNull(pdfFile); + } } catch (Exception e) { diff --git a/engines/misc/src/test/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformerTest.java b/engines/misc/src/test/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformerTest.java new file mode 100644 index 00000000..714c79f5 --- /dev/null +++ b/engines/misc/src/test/java/org/alfresco/transform/misc/transformers/ImageToPdfTransformerTest.java @@ -0,0 +1,350 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco 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 Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.misc.transformers; + +import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_GIF; +import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_JPEG; +import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_PNG; +import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_TIFF; +import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF; +import static org.alfresco.transform.common.RequestParamMap.END_PAGE; +import static org.alfresco.transform.common.RequestParamMap.PDF_FORMAT; +import static org.alfresco.transform.common.RequestParamMap.START_PAGE; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.then; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.alfresco.transform.base.TransformManager; +import org.alfresco.transform.misc.util.ArgumentsCartesianProduct; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +class ImageToPdfTransformerTest +{ + private static final File sourceFile = loadFile("quick.gif"); + + @Mock + private TransformManager transformManager; + + @InjectMocks + private ImageToPdfTransformer transformer; + + private File targetFile = null; + + @BeforeEach + void setUp() throws IOException + { + MockitoAnnotations.openMocks(this); + + targetFile = File.createTempFile("temp_target", ".pdf"); + } + + static Stream imageFiles() + { + return Stream.of( + ImageFile.of("quick.jpg", MIMETYPE_IMAGE_JPEG), + ImageFile.of("quick.gif", MIMETYPE_IMAGE_GIF), + ImageFile.of("quick.png", MIMETYPE_IMAGE_PNG) + ); + } + + static Stream defaultTransformOptions() + { + return Stream.of( + TransformOptions.none(), + TransformOptions.of(0, null), + TransformOptions.of(0, 0) + ); + } + + static Stream tiffTransformOptions() + { + return Stream.of( + TransformOptions.of(0, 0), + TransformOptions.of(0, 1), + TransformOptions.of(1, 1), + TransformOptions.of(null, 0), // expected 1 page in target file + TransformOptions.of(null, 1), // expected 2 pages in target file + TransformOptions.of(0, null), // expected all (2) pages in target file + TransformOptions.of(1, null), // expected 1 page in target file + TransformOptions.none() // expected all (2) pages in target file + ); + } + + static Stream transformSourcesAndOptions() + { + return Stream.of( + ArgumentsCartesianProduct.of(imageFiles(), defaultTransformOptions()), + ArgumentsCartesianProduct.of(ImageFile.of("quick.tiff", MIMETYPE_IMAGE_TIFF, 2), tiffTransformOptions()) + ).flatMap(Function.identity()); + } + + @ParameterizedTest + @MethodSource("transformSourcesAndOptions") + void testTransformImageToPdf(ImageFile imageFile, TransformOptions transformOptions) throws Exception + { + File sourceFile = loadFile(imageFile.fileName); + + // when + transformer.transform(imageFile.mimetype, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager); + + then(transformManager).shouldHaveNoInteractions(); + try (PDDocument actualPdfDocument = PDDocument.load(targetFile)) + { + int expectedNumberOfPages = calculateExpectedNumberOfPages(transformOptions, imageFile.firstPage(), imageFile.lastPage()); + assertNotNull(actualPdfDocument); + assertEquals(expectedNumberOfPages, actualPdfDocument.getNumberOfPages()); + } + } + + private static int calculateExpectedNumberOfPages(TransformOptions transformOptions, int firstPage, int lastPage) + { + int startPage = Optional.ofNullable(transformOptions.startPage).orElse(firstPage); + int endPage = Math.min(Optional.ofNullable(transformOptions.endPage).orElse(lastPage), lastPage); + return endPage - startPage + 1; + } + + static Stream improperTransformOptions() + { + return Stream.of( + TransformOptions.of(1, 0), + TransformOptions.of(-1, 0), + TransformOptions.of(0, -1) + ); + } + + @ParameterizedTest + @MethodSource("improperTransformOptions") + void testTransformTiffToPdf_withImproperOptions(TransformOptions transformOptions) + { + // when + assertThrows(IllegalArgumentException.class, () -> + transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager)); + } + + @Test + void testTransformTiffToPdf_withInvalidStartPageOption() + { + Map transformOptions = TransformOptions.none().toMap(); + transformOptions.put(START_PAGE, "a"); + + // when + assertThrows(IllegalArgumentException.class, () -> + transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions, sourceFile, targetFile, transformManager)); + } + + @Test + void testTransformTiffToPdf_withInvalidEndPageOption() + { + Map transformOptions = TransformOptions.none().toMap(); + transformOptions.put(END_PAGE, "z"); + + // when + assertThrows(IllegalArgumentException.class, () -> + transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions, sourceFile, targetFile, transformManager)); + } + + static Stream validPdfFormats() + { + return Stream.of("A0", "a0", "A1", "A2", "A3", "A4", "A5", "A6", "a6", "LETTER", "letter", "LEGAL", "legal"); + } + + @ParameterizedTest + @MethodSource("validPdfFormats") + void testTransformImageToPDF_withVariousPdfFormats(String pdfFormat) throws Exception + { + TransformOptions transformOptions = TransformOptions.of(pdfFormat); + + // when + transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager); + + try (PDDocument actualPdfDocument = PDDocument.load(targetFile)) + { + PDRectangle expectedPdfFormat = resolveExpectedPdfFormat(pdfFormat); + assertNotNull(actualPdfDocument); + assertEquals(expectedPdfFormat.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth()); + assertEquals(expectedPdfFormat.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight()); + } + } + + @Test + void testTransformImageToPDF_withInvalidPdfFormatAndUsingDefaultOne() throws Exception + { + TransformOptions transformOptions = TransformOptions.of("INVALID"); + + // when + transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager); + + try (PDDocument actualPdfDocument = PDDocument.load(targetFile)) + { + assertNotNull(actualPdfDocument); + assertEquals(PDRectangle.A4.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth()); + assertEquals(PDRectangle.A4.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight()); + } + } + + //----------------------------------------------- Helper methods and classes ----------------------------------------------- + + private static PDRectangle resolveExpectedPdfFormat(String pdfFormat) + { + switch (pdfFormat.toUpperCase()) { + case "LETTER": + return PDRectangle.LETTER; + case "LEGAL": + return PDRectangle.LEGAL; + case "A0": + return PDRectangle.A0; + case "A1": + return PDRectangle.A1; + case "A2": + return PDRectangle.A2; + case "A3": + return PDRectangle.A3; + case "A5": + return PDRectangle.A5; + case "A6": + return PDRectangle.A6; + case "A4": + default: + return PDRectangle.A4; + } + } + + private static File loadFile(String fileName) + { + return new File(Objects.requireNonNull(ImageToPdfTransformerTest.class.getClassLoader().getResource(fileName)).getFile()); + } + + private static class ImageFile + { + String fileName; + String mimetype; + int numberOfPages; + + private ImageFile(String fileName, String mimetype, int numberOfPages) + { + this.fileName = fileName; + this.mimetype = mimetype; + this.numberOfPages = numberOfPages; + } + + public static ImageFile of(String fileName, String mimetype, int numberOfPages) + { + return new ImageFile(fileName, mimetype, numberOfPages); + } + + public static ImageFile of(String fileName, String mimetype) + { + return of(fileName, mimetype, 1); + } + + public int firstPage() + { + return 0; + } + + public int lastPage() + { + return numberOfPages - 1; + } + + @Override + public String toString() + { + return "ImageFile{" + "fileName='" + fileName + '\'' + ", mimetype='" + mimetype + '\'' + '}'; + } + } + + private static class TransformOptions + { + Integer startPage; + Integer endPage; + String pdfFormat; + + private TransformOptions(Integer startPage, Integer endPage, String pdfFormat) + { + this.startPage = startPage; + this.endPage = endPage; + this.pdfFormat = pdfFormat; + } + + public Map toMap() + { + final Map transformOptions = new HashMap<>(); + if (startPage != null) + { + transformOptions.put(START_PAGE, startPage.toString()); + } + if (endPage != null) + { + transformOptions.put(END_PAGE, endPage.toString()); + } + if (pdfFormat != null) + { + transformOptions.put(PDF_FORMAT, pdfFormat); + } + return transformOptions; + } + + public static TransformOptions of(Integer startPage, Integer endPage) + { + return new TransformOptions(startPage, endPage, null); + } + + public static TransformOptions of(String pdfFormat) + { + return new TransformOptions(null, null, pdfFormat); + } + + public static TransformOptions none() + { + return TransformOptions.of(null); + } + + @Override + public String toString() + { + return "TransformOption{" + "startPage=" + startPage + ", endPage=" + endPage + '}'; + } + } +} \ No newline at end of file diff --git a/engines/misc/src/test/java/org/alfresco/transform/misc/util/ArgumentsCartesianProduct.java b/engines/misc/src/test/java/org/alfresco/transform/misc/util/ArgumentsCartesianProduct.java new file mode 100644 index 00000000..d08387a3 --- /dev/null +++ b/engines/misc/src/test/java/org/alfresco/transform/misc/util/ArgumentsCartesianProduct.java @@ -0,0 +1,101 @@ +/* + * #%L + * Alfresco Transform Core + * %% + * Copyright (C) 2005 - 2022 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco 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 Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ +package org.alfresco.transform.misc.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.params.provider.Arguments; + +/** + * Creates a cartesian product of arguments provided either in streams or as an objects. Result is a {@link Stream} of JUnit's {@link Arguments}. + */ +public class ArgumentsCartesianProduct +{ + /** + * Creates cartesian product of fixed argument and a stream of arguments. + * Example: a ✕ {x,y,z} = {a,x}, {a,y}, {a,z} + */ + public static Stream of(final Object fixedFirstArgument, final Stream secondArguments) + { + return secondArguments.map(secondArgument -> Arguments.of(fixedFirstArgument, secondArgument)); + } + + /** + * Creates cartesian product of a stream of arguments and fixed arguments. + * Example: {a,b,c} ✕ y ✕ z = {a,y,z}, {b,y,z}, {c,y,z} + */ + public static Stream of(final Stream firstArguments, final Object... otherFixedArguments) + { + return firstArguments.map(firstArgument -> Arguments.of(firstArgument, otherFixedArguments)); + } + + /** + * Creates cartesian product of two streams of arguments. + * Example: {a,b} ✕ {y,z} = {a,y}, {a,z}, {b,y}, {b,z} + */ + public static Stream of(final Stream firstArguments, final Stream secondArguments) + { + return cartesianProductOf(firstArguments, secondArguments).map(arguments -> Arguments.of(arguments.toArray())); + } + + /** + * Creates cartesian product of multiple streams of arguments. + * Example: {a,b} ✕ {k,l,m} ✕ ... ✕ {y,z} = {a,k,...,y}, {a,k,...,z}, {a,l,...,y}, ..., {b,m,...,z} + */ + public static Stream of(final Stream... argumentsStreams) + { + return cartesianProductOf(argumentsStreams).map(arguments -> Arguments.of(arguments.toArray())); + } + + private static Stream> cartesianProductOf(final Stream... streams) + { + if (streams == null) + { + return Stream.empty(); + } + + return Stream.of(streams) + .filter(Objects::nonNull) + .map(stream -> stream.map(Collections::singletonList)) + .reduce((result, nextElements) -> { + final List> nextElementsCopy = nextElements.collect(Collectors.toList()); + return result.flatMap(resultPortion -> nextElementsCopy.stream().map(nextElementsPortion -> { + final List extendedResultPortion = new ArrayList<>(); + extendedResultPortion.addAll(resultPortion); + extendedResultPortion.addAll(nextElementsPortion); + return extendedResultPortion; + })); + }).orElse(Stream.empty()) + .map(Collection::stream); + } +} diff --git a/engines/misc/src/test/resources/quick.gif b/engines/misc/src/test/resources/quick.gif new file mode 100644 index 0000000000000000000000000000000000000000..59f4989e2d4d4b29e9c8bfa3bdee2d0f0b97c7f5 GIT binary patch literal 6139 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 JuLA&T{{xRy7(4&~ literal 0 HcmV?d00001 diff --git a/engines/misc/src/test/resources/quick.jpg b/engines/misc/src/test/resources/quick.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1c1e377ad774ba42489e40ed19fb68463a86712d GIT binary patch literal 57586 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

)@ypm9G6& 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/vVtm3wR+5vsn$}yqK^EERr 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 literal 0 HcmV?d00001 diff --git a/engines/misc/src/test/resources/quick.tiff b/engines/misc/src/test/resources/quick.tiff new file mode 100644 index 0000000000000000000000000000000000000000..e8069e0925ee016b0da0f30cb5de690e65aa75c6 GIT binary patch literal 20746 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