ATS-996: TIFF to PDF - invalid output format

This commit is contained in:
Krystian Dabrowski 2023-03-28 17:06:45 +02:00
parent 8c59a96470
commit afadbaf8cb
2 changed files with 90 additions and 60 deletions

View File

@ -48,6 +48,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Stream;
@ -67,6 +69,8 @@ import org.mockito.MockitoAnnotations;
class ImageToPdfTransformerTest
{
private static final File sourceFile = loadFile("sample.gif");
private static final int sourceFileWidth;
private static final int sourceFileHeight;
@Mock
private TransformManager transformManager;
@ -190,17 +194,53 @@ class ImageToPdfTransformerTest
transformer.transform(MIMETYPE_IMAGE_TIFF, MIMETYPE_PDF, transformOptions, sourceFile, targetFile, transformManager));
}
/** Option and expected dimensions. */
static Stream<Arguments> validPdfFormats()
{
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.of(
Stream.of("default", "DEFAULT", "A0", "a0", "A1", "A2", "A3", "A4", "A5", "A6", "a6", "LETTER", "letter", "LEGAL", "legal"),
Stream.of("default", "DEFAULT", "portrait", "PORTRAIT", "landscape", "LANDSCAPE")
return ArgumentsCartesianProduct.ofArguments(
validPdfFormats(),
validPdfOrientations()
);
}
@ParameterizedTest
@MethodSource("validPdfFormatsAndOrientations")
void testTransformImageToPDF_withVariousPdfFormatsAndOrientations(String pdfFormat, String pdfOrientation) throws Exception
void testTransformImageToPDF_withVariousPdfFormatsAndOrientations(String pdfFormat, PDRectangle expectedPdfFormat,
String pdfOrientation, BiFunction<Float, Float, PDRectangle> expectedPdfFormatRotator) throws Exception
{
TransformOptions transformOptions = TransformOptions.of(pdfFormat, pdfOrientation);
@ -209,11 +249,10 @@ class ImageToPdfTransformerTest
try (PDDocument actualPdfDocument = PDDocument.load(targetFile))
{
BufferedImage actualImage = ImageIO.read(sourceFile);
PDRectangle expectedPdfFormat = resolveExpectedPdfFormat(pdfFormat, pdfOrientation, actualImage.getWidth(), actualImage.getHeight());
PDRectangle finalExpectedPdfFormat = expectedPdfFormatRotator.apply(expectedPdfFormat.getWidth(), expectedPdfFormat.getHeight());
assertNotNull(actualPdfDocument);
assertEquals(expectedPdfFormat.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
assertEquals(expectedPdfFormat.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
assertEquals(finalExpectedPdfFormat.getWidth(), actualPdfDocument.getPage(0).getMediaBox().getWidth());
assertEquals(finalExpectedPdfFormat.getHeight(), actualPdfDocument.getPage(0).getMediaBox().getHeight());
}
}
@ -253,57 +292,19 @@ class ImageToPdfTransformerTest
//----------------------------------------------- Helper methods and classes -----------------------------------------------
private static PDRectangle resolveExpectedPdfFormat(String pdfFormat, String pdfOrientation, int defaultWidth, int defaultHeight)
private static BiFunction<Float, Float, PDRectangle> unchangedRectangle()
{
PDRectangle pdRectangle;
switch (pdfFormat.toUpperCase()) {
case "LETTER":
pdRectangle = PDRectangle.LETTER;
break;
case "LEGAL":
pdRectangle = PDRectangle.LEGAL;
break;
case "A0":
pdRectangle = PDRectangle.A0;
break;
case "A1":
pdRectangle = PDRectangle.A1;
break;
case "A2":
pdRectangle = PDRectangle.A2;
break;
case "A3":
pdRectangle = PDRectangle.A3;
break;
case "A4":
pdRectangle = PDRectangle.A4;
break;
case "A5":
pdRectangle = PDRectangle.A5;
break;
case "A6":
pdRectangle = PDRectangle.A6;
break;
default:
pdRectangle = new PDRectangle(defaultWidth, defaultHeight);
return rectangleRotatedIf(null);
}
private static BiFunction<Float, Float, PDRectangle> rectangleRotatedIf(BiPredicate<Float, Float> predicate)
{
if (predicate == null)
{
return PDRectangle::new;
}
switch (pdfOrientation.toUpperCase()) {
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;
}
return pdRectangle;
return (width, height) -> predicate.test(width, height)? new PDRectangle(height, width) : new PDRectangle(width, height);
}
private static File loadFile(String fileName)
@ -414,4 +415,17 @@ class ImageToPdfTransformerTest
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);
}
}
}

View File

@ -27,6 +27,7 @@
package org.alfresco.transform.misc.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -42,7 +43,7 @@ import org.junit.jupiter.params.provider.Arguments;
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}
*/
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}
*/
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}
*/
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}
*/
public static Stream<Arguments> of(final Stream<?>... argumentsStreams)
@ -77,6 +78,21 @@ public class ArgumentsCartesianProduct
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)
{
if (streams == null)