mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-10-01 14:41:17 +00:00
Merge pull request #768 from Alfresco/feature/ATS-996-TIFF_to_PDF_-_invalid_output_format
ATS-996: TIFF to PDF - invalid output format
This commit is contained in:
@@ -64,6 +64,7 @@ public class AIOTikaTest extends TikaTest
|
|||||||
"page",
|
"page",
|
||||||
"pageLimit",
|
"pageLimit",
|
||||||
"pdfFormat",
|
"pdfFormat",
|
||||||
|
"pdfOrientation",
|
||||||
"resizeHeight",
|
"resizeHeight",
|
||||||
"resizePercentage",
|
"resizePercentage",
|
||||||
"resizeWidth",
|
"resizeWidth",
|
||||||
|
@@ -28,6 +28,7 @@ package org.alfresco.transform.misc.transformers;
|
|||||||
|
|
||||||
import static org.alfresco.transform.common.RequestParamMap.END_PAGE;
|
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.PDF_FORMAT;
|
||||||
|
import static org.alfresco.transform.common.RequestParamMap.PDF_ORIENTATION;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@@ -58,10 +59,11 @@ import org.springframework.stereotype.Component;
|
|||||||
* Converts image files into PDF files. Transformer uses PDF Box to perform conversions.
|
* 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.
|
* 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.
|
* 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:
|
* Transformer accepts bellow optional transform parameters:
|
||||||
* - startPage - page number of image (for multipage images) from which transformer should start conversion. Default: first page of the image.
|
* - startPage - page number of image (for multi-page 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.
|
* - endPage - page number of image (for multi-page 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.
|
* - pdfFormat - output PDF file format. Available formats: DEFAULT, A0, A1, A2, A3, A4, A5, A6, LETTER, LEGAL. Default: original image size.
|
||||||
|
* - pdfOrientation - output PDF file orientation. Available options: DEFAULT, PORTRAIT, LANDSCAPE. Default: original image orientation.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
||||||
@@ -73,8 +75,8 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
|||||||
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 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_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 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 String DEFAULT_PDF_FORMAT_STRING = "DEFAULT";
|
||||||
private static final PDRectangle DEFAULT_PDF_FORMAT = PDRectangle.A4;
|
private static final String DEFAULT_PDF_ORIENTATION_STRING = "DEFAULT";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformerName()
|
public String getTransformerName()
|
||||||
@@ -94,6 +96,7 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
|||||||
final Integer startPage = parseOptionIfPresent(transformOptions, START_PAGE, Integer.class).orElse(null);
|
final Integer startPage = parseOptionIfPresent(transformOptions, START_PAGE, Integer.class).orElse(null);
|
||||||
final Integer endPage = parseOptionIfPresent(transformOptions, END_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);
|
final String pdfFormat = parseOptionIfPresent(transformOptions, PDF_FORMAT, String.class).orElse(DEFAULT_PDF_FORMAT_STRING);
|
||||||
|
final String pdfOrientation = parseOptionIfPresent(transformOptions, PDF_ORIENTATION, String.class).orElse(DEFAULT_PDF_ORIENTATION_STRING);
|
||||||
verifyOptions(startPage, endPage);
|
verifyOptions(startPage, endPage);
|
||||||
|
|
||||||
final ImageReader imageReader = findImageReader(imageInputStream, imageFile.getName(), sourceMimetype);
|
final ImageReader imageReader = findImageReader(imageInputStream, imageFile.getName(), sourceMimetype);
|
||||||
@@ -108,7 +111,7 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scaleAndDrawImage(pdfDocument, imageReader.read(i), pdfFormat);
|
scaleAndDrawImage(pdfDocument, imageReader.read(i), pdfFormat, pdfOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
pdfDocument.save(pdfFile);
|
pdfDocument.save(pdfFile);
|
||||||
@@ -128,11 +131,12 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
|||||||
return imageReader;
|
return imageReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scaleAndDrawImage(final PDDocument pdfDocument, final BufferedImage bufferedImage, final String pdfFormat) throws IOException
|
private void scaleAndDrawImage(final PDDocument pdfDocument, final BufferedImage bufferedImage, final String pdfFormat, final String pdfOrientation)
|
||||||
|
throws IOException
|
||||||
{
|
{
|
||||||
final PDPage pdfPage = new PDPage(resolvePdfFormat(pdfFormat));
|
|
||||||
pdfDocument.addPage(pdfPage);
|
|
||||||
final PDImageXObject image = LosslessFactory.createFromImage(pdfDocument, bufferedImage);
|
final PDImageXObject image = LosslessFactory.createFromImage(pdfDocument, bufferedImage);
|
||||||
|
final PDPage pdfPage = new PDPage(resolvePdfFormat(pdfFormat, pdfOrientation, image.getWidth(), image.getHeight()));
|
||||||
|
pdfDocument.addPage(pdfPage);
|
||||||
try (PDPageContentStream pdfPageContent = new PDPageContentStream(pdfDocument, pdfPage))
|
try (PDPageContentStream pdfPageContent = new PDPageContentStream(pdfDocument, pdfPage))
|
||||||
{
|
{
|
||||||
final PDRectangle pageSize = pdfPage.getMediaBox();
|
final PDRectangle pageSize = pdfPage.getMediaBox();
|
||||||
@@ -146,31 +150,69 @@ public class ImageToPdfTransformer implements CustomTransformerFileAdaptor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PDRectangle resolvePdfFormat(final String pdfFormat)
|
private PDRectangle resolvePdfFormat(final String pdfFormat, final String pdfOrientation, final int defaultWidth, final int defaultHeight)
|
||||||
{
|
{
|
||||||
switch (pdfFormat.toUpperCase()) {
|
PDRectangle pdRectangle;
|
||||||
|
switch (pdfFormat.toUpperCase())
|
||||||
|
{
|
||||||
|
case "DEFAULT":
|
||||||
|
pdRectangle = new PDRectangle(defaultWidth, defaultHeight);
|
||||||
|
break;
|
||||||
case "A4":
|
case "A4":
|
||||||
return DEFAULT_PDF_FORMAT;
|
pdRectangle = PDRectangle.A4;
|
||||||
|
break;
|
||||||
case "LETTER":
|
case "LETTER":
|
||||||
return PDRectangle.LETTER;
|
pdRectangle = PDRectangle.LETTER;
|
||||||
|
break;
|
||||||
case "A0":
|
case "A0":
|
||||||
return PDRectangle.A0;
|
pdRectangle = PDRectangle.A0;
|
||||||
|
break;
|
||||||
case "A1":
|
case "A1":
|
||||||
return PDRectangle.A1;
|
pdRectangle = PDRectangle.A1;
|
||||||
|
break;
|
||||||
case "A2":
|
case "A2":
|
||||||
return PDRectangle.A2;
|
pdRectangle = PDRectangle.A2;
|
||||||
|
break;
|
||||||
case "A3":
|
case "A3":
|
||||||
return PDRectangle.A3;
|
pdRectangle = PDRectangle.A3;
|
||||||
|
break;
|
||||||
case "A5":
|
case "A5":
|
||||||
return PDRectangle.A5;
|
pdRectangle = PDRectangle.A5;
|
||||||
|
break;
|
||||||
case "A6":
|
case "A6":
|
||||||
return PDRectangle.A6;
|
pdRectangle = PDRectangle.A6;
|
||||||
|
break;
|
||||||
case "LEGAL":
|
case "LEGAL":
|
||||||
return PDRectangle.LEGAL;
|
pdRectangle = PDRectangle.LEGAL;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log.info("PDF format: '{}' not supported. Using default: '{}'", pdfFormat, DEFAULT_PDF_FORMAT_STRING);
|
log.warn("PDF format: '{}' not supported. Maintaining the default one.", pdfFormat);
|
||||||
return DEFAULT_PDF_FORMAT;
|
pdRectangle = new PDRectangle(defaultWidth, defaultHeight);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (pdfOrientation.toUpperCase())
|
||||||
|
{
|
||||||
|
case "DEFAULT":
|
||||||
|
break;
|
||||||
|
case "PORTRAIT":
|
||||||
|
if (pdRectangle.getWidth() > pdRectangle.getHeight())
|
||||||
|
{
|
||||||
|
pdRectangle = new PDRectangle(pdRectangle.getHeight(), pdRectangle.getWidth());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "LANDSCAPE":
|
||||||
|
if (pdRectangle.getHeight() > pdRectangle.getWidth())
|
||||||
|
{
|
||||||
|
pdRectangle = new PDRectangle(pdRectangle.getHeight(), pdRectangle.getWidth());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("PDF orientation: '{}' not supported. Maintaining the default one.", pdfOrientation);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdRectangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> Optional<T> parseOptionIfPresent(final Map<String, String> transformOptions, final String parameter, final Class<T> targetType)
|
private static <T> Optional<T> parseOptionIfPresent(final Map<String, String> transformOptions, final String parameter, final Class<T> targetType)
|
||||||
|
@@ -12,7 +12,8 @@
|
|||||||
"imageToPdfOptions": [
|
"imageToPdfOptions": [
|
||||||
{"value": {"name": "startPage"}},
|
{"value": {"name": "startPage"}},
|
||||||
{"value": {"name": "endPage"}},
|
{"value": {"name": "endPage"}},
|
||||||
{"value": {"name": "pdfFormat"}}
|
{"value": {"name": "pdfFormat"}},
|
||||||
|
{"value": {"name": "pdfOrientation"}}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"transformers": [
|
"transformers": [
|
||||||
|
@@ -33,18 +33,23 @@ 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.Mimetype.MIMETYPE_PDF;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.END_PAGE;
|
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.PDF_FORMAT;
|
||||||
|
import static org.alfresco.transform.common.RequestParamMap.PDF_ORIENTATION;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.mockito.BDDMockito.then;
|
import static org.mockito.BDDMockito.then;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -64,6 +69,8 @@ import org.mockito.MockitoAnnotations;
|
|||||||
class ImageToPdfTransformerTest
|
class ImageToPdfTransformerTest
|
||||||
{
|
{
|
||||||
private static final File sourceFile = loadFile("sample.gif");
|
private static final File sourceFile = loadFile("sample.gif");
|
||||||
|
private static final int sourceFileWidth;
|
||||||
|
private static final int sourceFileHeight;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private TransformManager transformManager;
|
private TransformManager transformManager;
|
||||||
@@ -108,16 +115,17 @@ class ImageToPdfTransformerTest
|
|||||||
TransformOptions.of(null, 0), // expected 1 page in target file
|
TransformOptions.of(null, 0), // expected 1 page in target file
|
||||||
TransformOptions.of(null, 1), // expected 2 pages in target file
|
TransformOptions.of(null, 1), // expected 2 pages in target file
|
||||||
TransformOptions.of(0, null), // expected all pages in target file
|
TransformOptions.of(0, null), // expected all pages in target file
|
||||||
TransformOptions.of(1, null), // expected 1 page in target file
|
TransformOptions.of(1, null), // expected all except first page in target file
|
||||||
TransformOptions.none() // expected all pages in target file
|
TransformOptions.none() // expected all pages in target file
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream<Arguments> transformSourcesAndOptions()
|
static Stream<Arguments> transformSourcesAndOptions()
|
||||||
{
|
{
|
||||||
|
ImageFile tiffImage = ImageFile.of("sample.tiff", MIMETYPE_IMAGE_TIFF, 6);
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
ArgumentsCartesianProduct.of(imageFiles(), defaultTransformOptions()),
|
ArgumentsCartesianProduct.of(imageFiles(), defaultTransformOptions()),
|
||||||
ArgumentsCartesianProduct.of(ImageFile.of("sample.tiff", MIMETYPE_IMAGE_TIFF, 6), tiffTransformOptions())
|
ArgumentsCartesianProduct.of(tiffImage, tiffTransformOptions())
|
||||||
).flatMap(Function.identity());
|
).flatMap(Function.identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,26 +194,65 @@ class ImageToPdfTransformerTest
|
|||||||
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions, sourceFile, targetFile, transformManager));
|
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions, sourceFile, targetFile, transformManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream<String> validPdfFormats()
|
/** Option and expected dimensions. */
|
||||||
|
static Stream<Arguments> validPdfFormats()
|
||||||
{
|
{
|
||||||
return Stream.of("A0", "a0", "A1", "A2", "A3", "A4", "A5", "A6", "a6", "LETTER", "letter", "LEGAL", "legal");
|
return Stream.of(
|
||||||
|
Arguments.of("DEFAULT", new PDRectangle(sourceFileWidth, sourceFileHeight)),
|
||||||
|
Arguments.of("default", new PDRectangle(sourceFileWidth, sourceFileHeight)),
|
||||||
|
Arguments.of("A0", PDRectangle.A0),
|
||||||
|
Arguments.of("a0", PDRectangle.A0),
|
||||||
|
Arguments.of("A1", PDRectangle.A1),
|
||||||
|
Arguments.of("A2", PDRectangle.A2),
|
||||||
|
Arguments.of("A3", PDRectangle.A3),
|
||||||
|
Arguments.of("A4", PDRectangle.A4),
|
||||||
|
Arguments.of("A5", PDRectangle.A5),
|
||||||
|
Arguments.of("A6", PDRectangle.A6),
|
||||||
|
Arguments.of("A6", PDRectangle.A6),
|
||||||
|
Arguments.of("LETTER", PDRectangle.LETTER),
|
||||||
|
Arguments.of("letter", PDRectangle.LETTER),
|
||||||
|
Arguments.of("LEGAL", PDRectangle.LEGAL),
|
||||||
|
Arguments.of("legal", PDRectangle.LEGAL)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Option and expected orientation. */
|
||||||
|
static Stream<Arguments> validPdfOrientations()
|
||||||
|
{
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of("DEFAULT", unchangedRectangle()),
|
||||||
|
Arguments.of("default", unchangedRectangle()),
|
||||||
|
Arguments.of("PORTRAIT", rectangleRotatedIf((width, height) -> width > height)),
|
||||||
|
Arguments.of("portrait", rectangleRotatedIf((width, height) -> width > height)),
|
||||||
|
Arguments.of("LANDSCAPE", rectangleRotatedIf((width, height) -> height > width)),
|
||||||
|
Arguments.of("landscape", rectangleRotatedIf((width, height) -> height > width))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<Arguments> validPdfFormatsAndOrientations()
|
||||||
|
{
|
||||||
|
return ArgumentsCartesianProduct.ofArguments(
|
||||||
|
validPdfFormats(),
|
||||||
|
validPdfOrientations()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("validPdfFormats")
|
@MethodSource("validPdfFormatsAndOrientations")
|
||||||
void testTransformImageToPDF_withVariousPdfFormats(String pdfFormat) throws Exception
|
void testTransformImageToPDF_withVariousPdfFormatsAndOrientations(String pdfFormat, PDRectangle expectedPdfFormat,
|
||||||
|
String pdfOrientation, BiFunction<Float, Float, PDRectangle> expectedPdfFormatRotator) throws Exception
|
||||||
{
|
{
|
||||||
TransformOptions transformOptions = TransformOptions.of(pdfFormat);
|
TransformOptions transformOptions = TransformOptions.of(pdfFormat, pdfOrientation);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager);
|
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager);
|
||||||
|
|
||||||
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
||||||
{
|
{
|
||||||
PDRectangle expectedPdfFormat = resolveExpectedPdfFormat(pdfFormat);
|
PDRectangle finalExpectedPdfFormat = expectedPdfFormatRotator.apply(expectedPdfFormat.getWidth(), expectedPdfFormat.getHeight());
|
||||||
assertNotNull(actualPdfDocument);
|
assertNotNull(actualPdfDocument);
|
||||||
assertEquals(expectedPdfFormat.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
|
assertEquals(finalExpectedPdfFormat.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
|
||||||
assertEquals(expectedPdfFormat.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
|
assertEquals(finalExpectedPdfFormat.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,37 +266,45 @@ class ImageToPdfTransformerTest
|
|||||||
|
|
||||||
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
||||||
{
|
{
|
||||||
|
BufferedImage actualImage = ImageIO.read(sourceFile);
|
||||||
assertNotNull(actualPdfDocument);
|
assertNotNull(actualPdfDocument);
|
||||||
assertEquals(PDRectangle.A4.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
|
assertEquals(actualImage.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
|
||||||
assertEquals(PDRectangle.A4.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
|
assertEquals(actualImage.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTransformImageToPDF_withInvalidPdfOrientationAndUsingDefaultOne() throws Exception
|
||||||
|
{
|
||||||
|
TransformOptions transformOptions = TransformOptions.of(null, "INVALID");
|
||||||
|
|
||||||
|
// when
|
||||||
|
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions.toMap(), sourceFile, targetFile, transformManager);
|
||||||
|
|
||||||
|
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
|
||||||
|
{
|
||||||
|
BufferedImage actualImage = ImageIO.read(sourceFile);
|
||||||
|
assertNotNull(actualPdfDocument);
|
||||||
|
assertEquals(actualImage.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
|
||||||
|
assertEquals(actualImage.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------- Helper methods and classes -----------------------------------------------
|
//----------------------------------------------- Helper methods and classes -----------------------------------------------
|
||||||
|
|
||||||
private static PDRectangle resolveExpectedPdfFormat(String pdfFormat)
|
private static BiFunction<Float, Float, PDRectangle> unchangedRectangle()
|
||||||
{
|
{
|
||||||
switch (pdfFormat.toUpperCase()) {
|
return rectangleRotatedIf(null);
|
||||||
case "LETTER":
|
}
|
||||||
return PDRectangle.LETTER;
|
|
||||||
case "LEGAL":
|
private static BiFunction<Float, Float, PDRectangle> rectangleRotatedIf(BiPredicate<Float, Float> predicate)
|
||||||
return PDRectangle.LEGAL;
|
{
|
||||||
case "A0":
|
if (predicate == null)
|
||||||
return PDRectangle.A0;
|
{
|
||||||
case "A1":
|
return PDRectangle::new;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (width, height) -> predicate.test(width, height)? new PDRectangle(height, width) : new PDRectangle(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File loadFile(String fileName)
|
private static File loadFile(String fileName)
|
||||||
@@ -302,12 +357,14 @@ class ImageToPdfTransformerTest
|
|||||||
Integer startPage;
|
Integer startPage;
|
||||||
Integer endPage;
|
Integer endPage;
|
||||||
String pdfFormat;
|
String pdfFormat;
|
||||||
|
String pdfOrientation;
|
||||||
|
|
||||||
private TransformOptions(Integer startPage, Integer endPage, String pdfFormat)
|
private TransformOptions(Integer startPage, Integer endPage, String pdfFormat, String pdfOrientation)
|
||||||
{
|
{
|
||||||
this.startPage = startPage;
|
this.startPage = startPage;
|
||||||
this.endPage = endPage;
|
this.endPage = endPage;
|
||||||
this.pdfFormat = pdfFormat;
|
this.pdfFormat = pdfFormat;
|
||||||
|
this.pdfOrientation = pdfOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> toMap()
|
public Map<String, String> toMap()
|
||||||
@@ -325,17 +382,26 @@ class ImageToPdfTransformerTest
|
|||||||
{
|
{
|
||||||
transformOptions.put(PDF_FORMAT, pdfFormat);
|
transformOptions.put(PDF_FORMAT, pdfFormat);
|
||||||
}
|
}
|
||||||
|
if (pdfOrientation != null)
|
||||||
|
{
|
||||||
|
transformOptions.put(PDF_ORIENTATION, pdfOrientation);
|
||||||
|
}
|
||||||
return transformOptions;
|
return transformOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TransformOptions of(Integer startPage, Integer endPage)
|
public static TransformOptions of(Integer startPage, Integer endPage)
|
||||||
{
|
{
|
||||||
return new TransformOptions(startPage, endPage, null);
|
return new TransformOptions(startPage, endPage, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TransformOptions of(String pdfFormat)
|
public static TransformOptions of(String pdfFormat)
|
||||||
{
|
{
|
||||||
return new TransformOptions(null, null, pdfFormat);
|
return new TransformOptions(null, null, pdfFormat, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TransformOptions of(String pdfFormat, String pdfOrientation)
|
||||||
|
{
|
||||||
|
return new TransformOptions(null, null, pdfFormat, pdfOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TransformOptions none()
|
public static TransformOptions none()
|
||||||
@@ -349,4 +415,17 @@ class ImageToPdfTransformerTest
|
|||||||
return "TransformOption{" + "startPage=" + startPage + ", endPage=" + endPage + '}';
|
return "TransformOption{" + "startPage=" + startPage + ", endPage=" + endPage + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BufferedImage image = ImageIO.read(sourceFile);
|
||||||
|
sourceFileWidth = image.getWidth();
|
||||||
|
sourceFileHeight = image.getHeight();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -27,6 +27,7 @@
|
|||||||
package org.alfresco.transform.misc.util;
|
package org.alfresco.transform.misc.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,7 +43,7 @@ import org.junit.jupiter.params.provider.Arguments;
|
|||||||
public class ArgumentsCartesianProduct
|
public class ArgumentsCartesianProduct
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Creates cartesian product of fixed argument and a stream of arguments.
|
* Creates arguments cartesian product of fixed object and a stream of objects.
|
||||||
* Example: a ✕ {x,y,z} = {a,x}, {a,y}, {a,z}
|
* Example: a ✕ {x,y,z} = {a,x}, {a,y}, {a,z}
|
||||||
*/
|
*/
|
||||||
public static Stream<Arguments> of(final Object fixedFirstArgument, final Stream<?> secondArguments)
|
public static Stream<Arguments> of(final Object fixedFirstArgument, final Stream<?> secondArguments)
|
||||||
@@ -51,7 +52,7 @@ public class ArgumentsCartesianProduct
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates cartesian product of a stream of arguments and fixed arguments.
|
* Creates arguments cartesian product of a stream of objects and fixed object.
|
||||||
* Example: {a,b,c} ✕ y ✕ z = {a,y,z}, {b,y,z}, {c,y,z}
|
* Example: {a,b,c} ✕ y ✕ z = {a,y,z}, {b,y,z}, {c,y,z}
|
||||||
*/
|
*/
|
||||||
public static Stream<Arguments> of(final Stream<?> firstArguments, final Object... otherFixedArguments)
|
public static Stream<Arguments> of(final Stream<?> firstArguments, final Object... otherFixedArguments)
|
||||||
@@ -60,7 +61,7 @@ public class ArgumentsCartesianProduct
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates cartesian product of two streams of arguments.
|
* Creates arguments cartesian product of two streams of objects.
|
||||||
* Example: {a,b} ✕ {y,z} = {a,y}, {a,z}, {b,y}, {b,z}
|
* Example: {a,b} ✕ {y,z} = {a,y}, {a,z}, {b,y}, {b,z}
|
||||||
*/
|
*/
|
||||||
public static Stream<Arguments> of(final Stream<?> firstArguments, final Stream<?> secondArguments)
|
public static Stream<Arguments> of(final Stream<?> firstArguments, final Stream<?> secondArguments)
|
||||||
@@ -69,7 +70,7 @@ public class ArgumentsCartesianProduct
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates cartesian product of multiple streams of arguments.
|
* Creates arguments cartesian product of multiple streams of objects.
|
||||||
* Example: {a,b} ✕ {k,l,m} ✕ ... ✕ {y,z} = {a,k,...,y}, {a,k,...,z}, {a,l,...,y}, ..., {b,m,...,z}
|
* Example: {a,b} ✕ {k,l,m} ✕ ... ✕ {y,z} = {a,k,...,y}, {a,k,...,z}, {a,l,...,y}, ..., {b,m,...,z}
|
||||||
*/
|
*/
|
||||||
public static Stream<Arguments> of(final Stream<?>... argumentsStreams)
|
public static Stream<Arguments> of(final Stream<?>... argumentsStreams)
|
||||||
@@ -77,6 +78,21 @@ public class ArgumentsCartesianProduct
|
|||||||
return cartesianProductOf(argumentsStreams).map(arguments -> Arguments.of(arguments.toArray()));
|
return cartesianProductOf(argumentsStreams).map(arguments -> Arguments.of(arguments.toArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates arguments 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}
|
||||||
|
*/
|
||||||
|
@SafeVarargs
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Stream<Arguments> ofArguments(final Stream<Arguments>... argumentsStreams)
|
||||||
|
{
|
||||||
|
return cartesianProductOf(argumentsStreams)
|
||||||
|
.map(argumentsStream -> (Stream<Arguments>) argumentsStream)
|
||||||
|
.map(argumentsStream -> Arguments.of(argumentsStream
|
||||||
|
.flatMap(arguments -> Arrays.stream(arguments.get()))
|
||||||
|
.toArray()));
|
||||||
|
}
|
||||||
|
|
||||||
private static Stream<Stream<?>> cartesianProductOf(final Stream<?>... streams)
|
private static Stream<Stream<?>> cartesianProductOf(final Stream<?>... streams)
|
||||||
{
|
{
|
||||||
if (streams == null)
|
if (streams == null)
|
||||||
|
@@ -65,6 +65,7 @@ public interface RequestParamMap
|
|||||||
String NOT_EXTRACT_BOOKMARKS_TEXT = "notExtractBookmarksText";
|
String NOT_EXTRACT_BOOKMARKS_TEXT = "notExtractBookmarksText";
|
||||||
String PAGE_LIMIT = "pageLimit";
|
String PAGE_LIMIT = "pageLimit";
|
||||||
String PDF_FORMAT = "pdfFormat";
|
String PDF_FORMAT = "pdfFormat";
|
||||||
|
String PDF_ORIENTATION = "pdfOrientation";
|
||||||
|
|
||||||
// Parameters interpreted by the TransformController
|
// Parameters interpreted by the TransformController
|
||||||
String DIRECT_ACCESS_URL = "directAccessUrl";
|
String DIRECT_ACCESS_URL = "directAccessUrl";
|
||||||
|
Reference in New Issue
Block a user