ACS-9835-Improve code quality in alfresco-transform-core (#1116)

This commit is contained in:
Arindam Roy
2025-07-18 15:46:21 +05:30
committed by GitHub
parent ac477aea65
commit f075c0da9a
239 changed files with 8956 additions and 9395 deletions

View File

@@ -26,19 +26,20 @@
*/
package org.alfresco.transform.libreoffice;
import org.alfresco.transform.base.TransformEngine;
import org.alfresco.transform.base.probes.ProbeTransform;
import org.alfresco.transform.config.reader.TransformConfigResourceReader;
import org.alfresco.transform.config.TransformConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import static org.alfresco.transform.base.logging.StandardMessages.COMMUNITY_LICENCE;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_WORD;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.alfresco.transform.base.TransformEngine;
import org.alfresco.transform.base.probes.ProbeTransform;
import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transform.config.reader.TransformConfigResourceReader;
@Component
public class LibreOfficeTransformEngine implements TransformEngine
{
@@ -70,6 +71,6 @@ public class LibreOfficeTransformEngine implements TransformEngine
public ProbeTransform getProbeTransform()
{
return new ProbeTransform("probe.doc", MIMETYPE_WORD, MIMETYPE_PDF, Collections.emptyMap(),
9728, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20);
9728, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20);
}
}

View File

@@ -33,7 +33,6 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
@@ -46,8 +45,7 @@ import org.slf4j.LoggerFactory;
///////// THIS FILE WAS A COPY OF THE CODE IN alfresco-repository /////////////
/**
* Makes use of the JodConverter library and an installed
* OpenOffice application to perform OpenOffice-driven conversions.
* Makes use of the JodConverter library and an installed OpenOffice application to perform OpenOffice-driven conversions.
*
* @author Neil McErlean
*/
@@ -68,7 +66,7 @@ public class JodConverterSharedInstance implements JodConverter
//
// Numeric parameters have to be handled as Strings, as that is what Spring gives us for missing values
// e.g. if jodconverter.maxTasksPerProcess is not specified in the properties file, the value
// "${jodconverter.maxTasksPerProcess}" will be injected.
// "${jodconverter.maxTasksPerProcess}" will be injected.
private Integer maxTasksPerProcess;
private String url;
@@ -163,7 +161,7 @@ public class JodConverterSharedInstance implements JodConverter
if (!tmp.isDirectory())
{
throw new RuntimeException(
"OpenOffice template profile directory " + templateProfileDir + " does not exist.");
"OpenOffice template profile directory " + templateProfileDir + " does not exist.");
}
this.templateProfileDir = tmp;
}
@@ -216,10 +214,10 @@ public class JodConverterSharedInstance implements JodConverter
// value in it.
// jodconverter.officeHome=/opt/libreoffice5.4/
// ooo.exe=/opt/libreoffice5.4/program/soffice.bin
// ooo.exe=/opt/libreoffice5.4/program/soffice.bin
// jodconverter.officeHome=C:/noscan/installs/521~1.1/LIBREO~1/App/libreoffice
// ooo.exe=C:/noscan/installs/COMMUN~1.0-E/LIBREO~1/App/libreoffice/program/soffice.exe
// ooo.exe=C:/noscan/installs/COMMUN~1.0-E/LIBREO~1/App/libreoffice/program/soffice.exe
File oooExe = new File(deprecatedOooExe);
File parent = oooExe.getParentFile();
@@ -238,11 +236,11 @@ public class JodConverterSharedInstance implements JodConverter
// So that Community systems <= Alfresco 6.0.1-ea keep working on upgrade, we may need to use the deprecated
// ooo.enabled setting if true rather than the jodconverter.enabled setting as oooDirect was replaced by
// jodconverter after this release.
// If ooo.enabled is true the JodConverter will be enabled.
// If ooo.enabled is false or unset the jodconverter.enabled value is used.
// Community set properties via alfresco-global.properties.
// Enterprise may do the same but may also reset jodconverter.enabled them via the Admin console.
// In the case of Enterprise it is very unlikely that ooo.enabled will be set to true.
// If ooo.enabled is true the JodConverter will be enabled.
// If ooo.enabled is false or unset the jodconverter.enabled value is used.
// Community set properties via alfresco-global.properties.
// Enterprise may do the same but may also reset jodconverter.enabled them via the Admin console.
// In the case of Enterprise it is very unlikely that ooo.enabled will be set to true.
private boolean isEnabled()
{
return (deprecatedOooEnabled != null && deprecatedOooEnabled) || (enabled != null && enabled);
@@ -254,8 +252,8 @@ public class JodConverterSharedInstance implements JodConverter
private int[] getPortNumbers()
{
return (enabled == null || !enabled) && deprecatedOooEnabled != null && deprecatedOooEnabled
? deprecatedOooPortNumbers
: portNumbers;
? deprecatedOooPortNumbers
: portNumbers;
}
private Long parseStringForLong(String string)
@@ -271,19 +269,17 @@ public class JodConverterSharedInstance implements JodConverter
return null;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.content.JodConverter#isAvailable()
*/
/* (non-Javadoc)
*
* @see org.alfresco.repo.content.JodConverter#isAvailable() */
public boolean isAvailable()
{
return isAvailable && (officeManager != null || (url != null && !url.isEmpty()));
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
/* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */
@PostConstruct
public void afterPropertiesSet()
{
@@ -295,7 +291,7 @@ public class JodConverterSharedInstance implements JodConverter
if (logger.isDebugEnabled())
{
logger.debug(
"JodConverter settings (null settings will be replaced by jodconverter defaults):");
"JodConverter settings (null settings will be replaced by jodconverter defaults):");
logger.debug(" officeHome = {}", officeHome);
logger.debug(" enabled = {}", isEnabled());
logger.debug(" portNumbers = {}", getString(portNumbers));
@@ -361,22 +357,23 @@ public class JodConverterSharedInstance implements JodConverter
catch (IllegalStateException e)
{
logger.error("Unable to pre-initialise JodConverter library. " +
"The following error is shown for informational purposes only.", e);
"The following error is shown for informational purposes only.", e);
return;
}
catch (OfficeException e)
{
logger.error("Unable to start JodConverter library. " +
"The following error is shown for informational purposes only.", e);
"The following error is shown for informational purposes only.", e);
// We need to let it continue (comment-out return statement) even if an error occurs. See MNT-13706 and associated issues.
//return;
// return;
}
catch (Exception e)
{
logger.error(
"Unexpected error in configuring or starting the JodConverter library." +
"The following error is shown for informational purposes only.", e);
"Unexpected error in configuring or starting the JodConverter library." +
"The following error is shown for informational purposes only.",
e);
return;
}
}
@@ -424,13 +421,13 @@ public class JodConverterSharedInstance implements JodConverter
}
private List<File> findSofficePrograms(File searchRoot, List<File> results,
int maxRecursionDepth)
int maxRecursionDepth)
{
return this.findSofficePrograms(searchRoot, results, 0, maxRecursionDepth);
}
private List<File> findSofficePrograms(File searchRoot, List<File> results,
int currentRecursionDepth, int maxRecursionDepth)
int currentRecursionDepth, int maxRecursionDepth)
{
if (currentRecursionDepth >= maxRecursionDepth)
{
@@ -461,7 +458,8 @@ public class JodConverterSharedInstance implements JodConverter
/**
* Logs some information on the specified file, including name and r/w/x permissions.
*
* @param f the file to log.
* @param f
* the file to log.
*/
private void logFileInfo(File f)
{
@@ -475,11 +473,11 @@ public class JodConverterSharedInstance implements JodConverter
if (f.exists() && f.canRead())
{
msg.append("(")
.append(f.isDirectory() ? "d" : "-")
.append(f.canRead() ? "r" : "-")
.append(f.canWrite() ? "w" : "-")
.append(f.canExecute() ? "x" : "-")
.append(")");
.append(f.isDirectory() ? "d" : "-")
.append(f.canRead() ? "r" : "-")
.append(f.canWrite() ? "w" : "-")
.append(f.canExecute() ? "x" : "-")
.append(")");
}
else
{
@@ -488,10 +486,9 @@ public class JodConverterSharedInstance implements JodConverter
logger.debug(msg.toString());
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
/* (non-Javadoc)
*
* @see org.springframework.beans.factory.DisposableBean#destroy() */
@PreDestroy
public void destroy()
{
@@ -510,8 +507,8 @@ public class JodConverterSharedInstance implements JodConverter
}
/* (non-Javadoc)
* @see org.alfresco.repo.content.JodConverterWorker#getOfficeManager()
*/
*
* @see org.alfresco.repo.content.JodConverterWorker#getOfficeManager() */
@Override
public OfficeManager getOfficeManager()
{

View File

@@ -26,6 +26,15 @@
*/
package org.alfresco.transform.libreoffice.transformers;
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
@@ -43,24 +52,16 @@ import org.artofsolving.jodconverter.office.OfficeContext;
import org.artofsolving.jodconverter.office.OfficeException;
import org.artofsolving.jodconverter.office.OfficeTask;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
/**
* @deprecated The JodConverterMetadataExtracter has not been in use since 6.0.1
*
* Extracts values from Open Office documents into the following:
* <pre>
* Extracts values from Open Office documents into the following:
*
* <pre>
* <b>author:</b> -- cm:author
* <b>title:</b> -- cm:title
* <b>description:</b> -- cm:description
* </pre>
* </pre>
*
* @author Neil McErlean
* @author adavis
@@ -68,10 +69,7 @@ import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
@Deprecated
public class LibreOfficeExtractMetadataTask implements OfficeTask
{
/*
* These keys are used by Alfresco to map properties into a content model and do need to
* have lower-case initial letters.
*/
/* These keys are used by Alfresco to map properties into a content model and do need to have lower-case initial letters. */
private static final String KEY_AUTHOR = "author";
private static final String KEY_TITLE = "title";
private static final String KEY_DESCRIPTION = "description";
@@ -192,7 +190,8 @@ public class LibreOfficeExtractMetadataTask implements OfficeTask
* OOo throws exceptions if we ask for properties that aren't there, so we'll tread carefully.
*
* @param propSet
* @param propertyName property name as used by the OOo API.
* @param propertyName
* property name as used by the OOo API.
* @throws UnknownPropertyException
* @throws WrappedTargetException
*/

View File

@@ -26,12 +26,17 @@
*/
package org.alfresco.transform.libreoffice.transformers;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import jakarta.annotation.PostConstruct;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.star.task.ErrorCodeIOException;
import org.alfresco.transform.base.TransformManager;
import org.alfresco.transform.base.executors.JavaExecutor;
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
import org.alfresco.transform.exceptions.TransformException;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -44,18 +49,13 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import org.alfresco.transform.base.TransformManager;
import org.alfresco.transform.base.executors.JavaExecutor;
import org.alfresco.transform.base.util.CustomTransformerFileAdaptor;
import org.alfresco.transform.exceptions.TransformException;
/**
* JavaExecutor implementation for running LibreOffice transformations. It loads the
* transformation logic in the same JVM (check the {@link JodConverter} implementation).
* JavaExecutor implementation for running LibreOffice transformations. It loads the transformation logic in the same JVM (check the {@link JodConverter} implementation).
*/
@Component
public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFileAdaptor
@@ -105,7 +105,7 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
{
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_TEMPLATE_PROFILE_DIR variable cannot be null");
}
if (isEnabled == null || isEnabled.isEmpty() || !(isEnabled.equalsIgnoreCase("true")|| isEnabled.equalsIgnoreCase("false")))
if (isEnabled == null || isEnabled.isEmpty() || !(isEnabled.equalsIgnoreCase("true") || isEnabled.equalsIgnoreCase("false")))
{
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_IS_ENABLED variable must be set to true/false");
}
@@ -131,7 +131,7 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
@Override
public void transform(String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
File sourceFile, File targetFile, TransformManager transformManager)
File sourceFile, File targetFile, TransformManager transformManager)
{
call(sourceFile, targetFile);
}
@@ -146,20 +146,21 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
catch (OfficeException e)
{
throw new TransformException(BAD_REQUEST,
"LibreOffice server conversion failed: \n" +
" from file: " + sourceFile + "\n" +
" to file: " + targetFile, e);
"LibreOffice server conversion failed: \n" +
" from file: " + sourceFile + "\n" +
" to file: " + targetFile,
e);
}
catch (Throwable throwable)
{
// Because of the known bug with empty Spreadsheets in JodConverter try to catch exception and produce empty pdf file
if (throwable.getCause() instanceof ErrorCodeIOException &&
((ErrorCodeIOException) throwable.getCause()).ErrCode == JODCONVERTER_TRANSFORMATION_ERROR_CODE)
((ErrorCodeIOException) throwable.getCause()).ErrCode == JODCONVERTER_TRANSFORMATION_ERROR_CODE)
{
logger.warn("Transformation failed: \n" +
"from file: " + sourceFile + "\n" +
"to file: " + targetFile +
"Source file " + sourceFile + " has no content");
"from file: " + sourceFile + "\n" +
"to file: " + targetFile +
"Source file " + sourceFile + " has no content");
produceEmptyPdfFile(targetFile);
}
else
@@ -182,8 +183,7 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
}
/**
* This method produces an empty PDF file at the specified File location.
* Apache's PDFBox is used to create the PDF file.
* This method produces an empty PDF file at the specified File location. Apache's PDFBox is used to create the PDF file.
*/
private static void produceEmptyPdfFile(File targetFile)
{
@@ -193,7 +193,7 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
PDPage pdfPage = new PDPage();
try (PDDocument pdfDoc = new PDDocument();
PDPageContentStream ignore = new PDPageContentStream(pdfDoc, pdfPage))
PDPageContentStream ignore = new PDPageContentStream(pdfDoc, pdfPage))
{
// Even though, we want an empty PDF, some libs (e.g. PDFRenderer) object to PDFs
// that have literally nothing in them. So we'll put a content stream in it.
@@ -209,13 +209,11 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
}
/**
* @deprecated The JodConverterMetadataExtracter has not been in use since 6.0.1.
* This code exists in case there are custom implementations, that need to be converted to T-Engines.
* It is simply a copy and paste from the content repository and has received limited testing.
* @deprecated The JodConverterMetadataExtracter has not been in use since 6.0.1. This code exists in case there are custom implementations, that need to be converted to T-Engines. It is simply a copy and paste from the content repository and has received limited testing.
*/
public void extractMetadata(String transformName, String sourceMimetype, String targetMimetype,
Map<String, String> transformOptions,
File sourceFile, File targetFile)
Map<String, String> transformOptions,
File sourceFile, File targetFile)
{
OfficeManager officeManager = jodconverter.getOfficeManager();
LibreOfficeExtractMetadataTask extractMetadataTask = new LibreOfficeExtractMetadataTask(sourceFile);
@@ -227,13 +225,14 @@ public class LibreOfficeTransformer implements JavaExecutor, CustomTransformerFi
{
throw new TransformException(BAD_REQUEST,
"LibreOffice metadata extract failed: \n" +
" from file: " + sourceFile, e);
" from file: " + sourceFile,
e);
}
Map<String, Serializable> metadata = extractMetadataTask.getMetadata();
if (logger.isDebugEnabled())
{
metadata.forEach((k,v) -> logger.debug(k+"="+v));
metadata.forEach((k, v) -> logger.debug(k + "=" + v));
}
writeMetadataIntoTargetFile(targetFile, metadata);

View File

@@ -29,9 +29,11 @@ package org.alfresco.transform.libreoffice;
import org.alfresco.transform.base.LivenessReadinessProbeTest;
public class LibreOfficeLivenessReadinessProbeIT extends LivenessReadinessProbeTest {
public class LibreOfficeLivenessReadinessProbeIT extends LivenessReadinessProbeTest
{
@Override
protected ImagesForTests getImageForTest() {
protected ImagesForTests getImageForTest()
{
return new ImagesForTests("alfresco-libreoffice", "text/plain", "application/pdf", "original.txt");
}
}

View File

@@ -30,12 +30,11 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_WORDPROCES
import java.util.UUID;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.base.messaging.AbstractQueueIT;
import org.alfresco.transform.client.model.TransformRequest;
/**
* @author Lucian Tuca
* created on 15/01/2019
* @author Lucian Tuca created on 15/01/2019
*/
public class LibreOfficeQueueIT extends AbstractQueueIT
{
@@ -43,16 +42,16 @@ public class LibreOfficeQueueIT extends AbstractQueueIT
protected TransformRequest buildRequest()
{
return TransformRequest
.builder()
.withRequestId(UUID.randomUUID().toString())
.withSourceMediaType(MIMETYPE_OPENXML_WORDPROCESSING)
.withTargetMediaType(MIMETYPE_OPENXML_WORDPROCESSING)
.withTargetExtension("doc")
.withSchema(1)
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
.builder()
.withRequestId(UUID.randomUUID().toString())
.withSourceMediaType(MIMETYPE_OPENXML_WORDPROCESSING)
.withTargetMediaType(MIMETYPE_OPENXML_WORDPROCESSING)
.withTargetExtension("doc")
.withSchema(1)
.withClientData("ACS")
.withSourceReference(UUID.randomUUID().toString())
.withSourceSize(32L)
.withInternalContextForTransformEngineTests()
.build();
}
}

View File

@@ -26,11 +26,6 @@
*/
package org.alfresco.transform.libreoffice;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION;
import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -48,20 +43,18 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.util.StringUtils.getFilenameExtension;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION;
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.UUID;
import org.alfresco.transform.base.registry.CustomTransformers;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.base.executors.RuntimeExec.ExecutionResult;
import org.alfresco.transform.base.model.FileRefEntity;
import org.alfresco.transform.base.model.FileRefResponse;
import org.artofsolving.jodconverter.office.OfficeException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -79,6 +72,15 @@ import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.alfresco.transform.base.AbstractBaseTest;
import org.alfresco.transform.base.executors.RuntimeExec.ExecutionResult;
import org.alfresco.transform.base.model.FileRefEntity;
import org.alfresco.transform.base.model.FileRefResponse;
import org.alfresco.transform.base.registry.CustomTransformers;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
/**
* Test LibreOffice with mocked external command.
*/
@@ -122,13 +124,12 @@ public class LibreOfficeTest extends AbstractBaseTest
// This is because LibreOffice used JodConverter rather than a RuntimeExec
sourceFileBytes = Files.readAllBytes(
getTestFile("quick." + sourceExtension, true).toPath());
getTestFile("quick." + sourceExtension, true).toPath());
expectedTargetFileBytes = Files.readAllBytes(
getTestFile("quick." + targetExtension, true).toPath());
getTestFile("quick." + targetExtension, true).toPath());
sourceFile = new MockMultipartFile("file", "quick." + sourceExtension, sourceMimetype, sourceFileBytes);
doAnswer(invocation ->
{
doAnswer(invocation -> {
File sourceFile = invocation.getArgument(0);
File targetFile = invocation.getArgument(1);
String actualTargetExtension = getFilenameExtension(targetFile.getAbsolutePath());
@@ -164,8 +165,8 @@ public class LibreOfficeTest extends AbstractBaseTest
protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params)
{
final MockHttpServletRequestBuilder builder = super.mockMvcRequest(url, sourceFile, params)
.param("targetMimetype", targetMimetype)
.param("sourceMimetype", sourceMimetype);
.param("targetMimetype", targetMimetype)
.param("sourceMimetype", sourceMimetype);
return builder;
}
@@ -175,15 +176,15 @@ public class LibreOfficeTest extends AbstractBaseTest
doThrow(OfficeException.class).when(spyLibreOfficeTransformer).convert(any(), any());
mockMvc
.perform(MockMvcRequestBuilders
.multipart(ENDPOINT_TRANSFORM)
.file(sourceFile)
.param(TARGET_EXTENSION, "xxx")
.param(SOURCE_MIMETYPE,sourceMimetype)
.param(TARGET_MIMETYPE,targetMimetype))
.andExpect(status().is(400))
.andExpect(status().reason(
containsString("LibreOffice server conversion failed:")));
.perform(MockMvcRequestBuilders
.multipart(ENDPOINT_TRANSFORM)
.file(sourceFile)
.param(TARGET_EXTENSION, "xxx")
.param(SOURCE_MIMETYPE, sourceMimetype)
.param(TARGET_MIMETYPE, targetMimetype))
.andExpect(status().is(400))
.andExpect(status().reason(
containsString("LibreOffice server conversion failed:")));
}
@Override
@@ -209,11 +210,11 @@ public class LibreOfficeTest extends AbstractBaseTest
HttpHeaders headers = new HttpHeaders();
headers.set(CONTENT_DISPOSITION, "attachment; filename=quick." + sourceExtension);
ResponseEntity<Resource> response = new ResponseEntity<>(new FileSystemResource(
sourceFile), headers, OK);
sourceFile), headers, OK);
when(sharedFileStoreClient.retrieveFile(sourceFileRef)).thenReturn(response);
when(sharedFileStoreClient.saveFile(any()))
.thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef)));
.thenReturn(new FileRefResponse(new FileRefEntity(targetFileRef)));
when(mockExecutionResult.getExitValue()).thenReturn(0);
// Update the Transformation Request with any specific params before sending it
@@ -222,16 +223,16 @@ public class LibreOfficeTest extends AbstractBaseTest
// Serialize and call the transformer
String tr = objectMapper.writeValueAsString(transformRequest);
String transformationReplyAsString = mockMvc
.perform(MockMvcRequestBuilders
.post(ENDPOINT_TRANSFORM)
.header(ACCEPT, APPLICATION_JSON_VALUE)
.header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.content(tr))
.andExpect(status().is(CREATED.value()))
.andReturn().getResponse().getContentAsString();
.perform(MockMvcRequestBuilders
.post(ENDPOINT_TRANSFORM)
.header(ACCEPT, APPLICATION_JSON_VALUE)
.header(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.content(tr))
.andExpect(status().is(CREATED.value()))
.andReturn().getResponse().getContentAsString();
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString,
TransformReply.class);
TransformReply.class);
// Assert the reply
assertEquals(transformRequest.getRequestId(), transformReply.getRequestId());
@@ -242,42 +243,42 @@ public class LibreOfficeTest extends AbstractBaseTest
@Test
public void testOverridingExecutorPaths()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(execPath, System.getProperty("LIBREOFFICE_HOME"));
}
@Test
public void testOverridingExecutorMaxTasksPerProcess()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(maxTasksPerProcess, System.getProperty("LIBREOFFICE_MAX_TASKS_PER_PROCESS"));
}
@Test
public void testOverridingExecutorTimeout()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(timeout, System.getProperty("LIBREOFFICE_TIMEOUT"));
}
@Test
public void testOverridingExecutorPortNumbers()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(portNumbers, System.getProperty("LIBREOFFICE_PORT_NUMBERS"));
}
@Test
public void testOverridingExecutorTemplateProfileDir()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(templateProfileDir, System.getProperty("LIBREOFFICE_TEMPLATE_PROFILE_DIR"));
}
@Test
public void testOverridingExecutorIsEnabled()
{
//System test property value can be modified in the pom.xml
// System test property value can be modified in the pom.xml
assertEquals(isEnabled, System.getProperty("LIBREOFFICE_IS_ENABLED"));
}
@@ -285,33 +286,33 @@ public class LibreOfficeTest extends AbstractBaseTest
public void testInvalidExecutorMaxTasksPerProcess()
{
testInvalidValue("maxTasksPerProcess", "INVALID",
"LibreOfficeTransformer LIBREOFFICE_MAX_TASKS_PER_PROCESS must have a numeric value");
"LibreOfficeTransformer LIBREOFFICE_MAX_TASKS_PER_PROCESS must have a numeric value");
}
@Test
public void testInvalidExecutorTimeout()
{
testInvalidValue("timeout", "INVALID",
"LibreOfficeTransformer LIBREOFFICE_TIMEOUT must have a numeric value");
"LibreOfficeTransformer LIBREOFFICE_TIMEOUT must have a numeric value");
}
@Test
public void testInvalidExecutorPortNumbers()
{
testInvalidValue("portNumbers", null,
"LibreOfficeTransformer LIBREOFFICE_PORT_NUMBERS variable cannot be null or empty");
"LibreOfficeTransformer LIBREOFFICE_PORT_NUMBERS variable cannot be null or empty");
}
@Test
public void testInvalidExecutorIsEnabled()
{
testInvalidValue("isEnabled", "INVALID",
"LibreOfficeTransformer LIBREOFFICE_IS_ENABLED variable must be set to true/false");
"LibreOfficeTransformer LIBREOFFICE_IS_ENABLED variable must be set to true/false");
}
private void testInvalidValue(String fieldName, String invalidValue, String expectedErrorMessage)
{
String validValue = (String)ReflectionTestUtils.getField(libreOfficeTransformer, fieldName);
String validValue = (String) ReflectionTestUtils.getField(libreOfficeTransformer, fieldName);
String errorMessage = "";
try
{

View File

@@ -29,8 +29,14 @@ package org.alfresco.transform.libreoffice;
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.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.springframework.http.HttpStatus.OK;
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;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_SVG;
@@ -39,39 +45,33 @@ import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENDOCUMENT_PRESE
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENDOCUMENT_SPREADSHEET;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENDOCUMENT_TEXT;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_PRESENTATION;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_SPREADSHEET;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_WORDPROCESSING;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PPT;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_RTF;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STC;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STI;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STW;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_SXC;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_SXI;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_CSV;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TSV;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_VISIO;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_VISIO_2013;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_WORD;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_WORDPERFECT;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_XML;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_DITA;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_SXI;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_SXC;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STW;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STI;
import static org.alfresco.transform.common.Mimetype.MIMETYPE_STC;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.springframework.http.HttpStatus.OK;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableSet;
import org.alfresco.transform.base.clients.FileInfo;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -80,6 +80,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.alfresco.transform.base.clients.FileInfo;
/**
* @author Cezar Leahu
*/
@@ -88,112 +90,105 @@ public class LibreOfficeTransformationIT
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformationIT.class);
private static final String ENGINE_URL = "http://localhost:8090";
private static final Set<FileInfo> spreadsheetTargets = ImmutableSet.of(
testFile(MIMETYPE_TEXT_CSV, "csv",null),
testFile(MIMETYPE_HTML,"html",null),
testFile(MIMETYPE_OPENDOCUMENT_SPREADSHEET,"ods",null),
testFile(MIMETYPE_PDF,"pdf",null),
testFile(MIMETYPE_TSV,"tsv",null),
testFile(MIMETYPE_EXCEL,"xls",null)
);
testFile(MIMETYPE_TEXT_CSV, "csv", null),
testFile(MIMETYPE_HTML, "html", null),
testFile(MIMETYPE_OPENDOCUMENT_SPREADSHEET, "ods", null),
testFile(MIMETYPE_PDF, "pdf", null),
testFile(MIMETYPE_TSV, "tsv", null),
testFile(MIMETYPE_EXCEL, "xls", null));
private static final Set<FileInfo> documentsTargets = ImmutableSet.of(
testFile(MIMETYPE_WORD,"doc",null),
testFile(MIMETYPE_HTML,"html",null),
testFile(MIMETYPE_OPENDOCUMENT_TEXT,"odt",null),
testFile(MIMETYPE_PDF,"pdf",null),
testFile(MIMETYPE_RTF,"rtf",null)
);
testFile(MIMETYPE_WORD, "doc", null),
testFile(MIMETYPE_HTML, "html", null),
testFile(MIMETYPE_OPENDOCUMENT_TEXT, "odt", null),
testFile(MIMETYPE_PDF, "pdf", null),
testFile(MIMETYPE_RTF, "rtf", null));
private static final Set<FileInfo> graphicTargets = ImmutableSet.of(
testFile(MIMETYPE_PDF,"pdf",null),
testFile(MIMETYPE_IMAGE_SVG,"svg",null)
);
testFile(MIMETYPE_PDF, "pdf", null),
testFile(MIMETYPE_IMAGE_SVG, "svg", null));
private static final Set<FileInfo> presentationTargets = ImmutableSet.of(
testFile(MIMETYPE_HTML,"html",null),
testFile(MIMETYPE_OPENDOCUMENT_PRESENTATION,"odp",null),
testFile(MIMETYPE_PPT,"ppt",null),
testFile(MIMETYPE_PDF,"pdf",null)
);
testFile(MIMETYPE_HTML, "html", null),
testFile(MIMETYPE_OPENDOCUMENT_PRESENTATION, "odp", null),
testFile(MIMETYPE_PPT, "ppt", null),
testFile(MIMETYPE_PDF, "pdf", null));
private static final Set<FileInfo> pdfTarget = ImmutableSet.of(
testFile(MIMETYPE_PDF,"pdf",null)
);
testFile(MIMETYPE_PDF, "pdf", null));
private static final Set<FileInfo> txtTarget = ImmutableSet.of(
testFile(MIMETYPE_TEXT_PLAIN,"txt",null)
);
testFile(MIMETYPE_TEXT_PLAIN, "txt", null));
private static final Map<String, FileInfo> TEST_FILES = Stream.of(
testFile(MIMETYPE_WORD ,"doc" ,"quick.doc"),
testFile(MIMETYPE_OPENXML_WORDPROCESSING ,"docx" ,"quick.docx"),
testFile(MIMETYPE_OPENDOCUMENT_GRAPHICS ,"odg" ,"quick.odg"),
testFile(MIMETYPE_OPENDOCUMENT_PRESENTATION ,"odp" ,"quick.odp"),
testFile(MIMETYPE_OPENDOCUMENT_SPREADSHEET ,"ods" ,"quick.ods"),
testFile(MIMETYPE_OPENDOCUMENT_TEXT ,"odt" ,"quick.odt"),
testFile(MIMETYPE_PPT ,"ppt" ,"quick.ppt"),
testFile(MIMETYPE_OPENXML_PRESENTATION ,"pptx" ,"quick.pptx"),
testFile(MIMETYPE_VISIO ,"vdx" ,"quick.vdx"),
testFile(MIMETYPE_VISIO_2013 ,"vsd" ,"quick.vsd"),
testFile(MIMETYPE_WORDPERFECT ,"wpd" ,"quick.wpd"),
testFile(MIMETYPE_EXCEL ,"xls" ,"quick.xls" ),
testFile(MIMETYPE_OPENXML_SPREADSHEET ,"xlsx" ,"quick.xlsx"),
testFile(MIMETYPE_TEXT_CSV ,"csv" ,"people.csv"),
testFile(MIMETYPE_RTF ,"rtf" ,"sample.rtf"),
testFile(MIMETYPE_HTML ,"html" ,"quick.html"),
testFile(MIMETYPE_XML ,"xml" ,"quick.xml"),
testFile(MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO ,"xltm" ,"quick.xltm"),
testFile(MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW ,"ppsx" ,"quick.ppsx"),
testFile(MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO ,"ppsm" ,"quick.ppsm"),
testFile(MIMETYPE_DITA ,"dita" ,"quick.dita"),
testFile(MIMETYPE_TEXT_PLAIN ,"txt" ,"quick.txt"),
testFile(MIMETYPE_STC ,"stc" ,"quick.stc"),
testFile(MIMETYPE_STI ,"sti" ,"quick.sti"),
testFile(MIMETYPE_STW ,"stw" ,"quick.stw"),
testFile(MIMETYPE_SXC ,"sxc" ,"quick.sxc"),
testFile(MIMETYPE_SXI ,"sxi" ,"quick.sxi"),
testFile(MIMETYPE_TSV ,"tsv" ,"sample.tsv")
).collect(toMap(FileInfo::getPath, identity()));
testFile(MIMETYPE_WORD, "doc", "quick.doc"),
testFile(MIMETYPE_OPENXML_WORDPROCESSING, "docx", "quick.docx"),
testFile(MIMETYPE_OPENDOCUMENT_GRAPHICS, "odg", "quick.odg"),
testFile(MIMETYPE_OPENDOCUMENT_PRESENTATION, "odp", "quick.odp"),
testFile(MIMETYPE_OPENDOCUMENT_SPREADSHEET, "ods", "quick.ods"),
testFile(MIMETYPE_OPENDOCUMENT_TEXT, "odt", "quick.odt"),
testFile(MIMETYPE_PPT, "ppt", "quick.ppt"),
testFile(MIMETYPE_OPENXML_PRESENTATION, "pptx", "quick.pptx"),
testFile(MIMETYPE_VISIO, "vdx", "quick.vdx"),
testFile(MIMETYPE_VISIO_2013, "vsd", "quick.vsd"),
testFile(MIMETYPE_WORDPERFECT, "wpd", "quick.wpd"),
testFile(MIMETYPE_EXCEL, "xls", "quick.xls"),
testFile(MIMETYPE_OPENXML_SPREADSHEET, "xlsx", "quick.xlsx"),
testFile(MIMETYPE_TEXT_CSV, "csv", "people.csv"),
testFile(MIMETYPE_RTF, "rtf", "sample.rtf"),
testFile(MIMETYPE_HTML, "html", "quick.html"),
testFile(MIMETYPE_XML, "xml", "quick.xml"),
testFile(MIMETYPE_OPENXML_SPREADSHEET_TEMPLATE_MACRO, "xltm", "quick.xltm"),
testFile(MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW, "ppsx", "quick.ppsx"),
testFile(MIMETYPE_OPENXML_PRESENTATION_SLIDESHOW_MACRO, "ppsm", "quick.ppsm"),
testFile(MIMETYPE_DITA, "dita", "quick.dita"),
testFile(MIMETYPE_TEXT_PLAIN, "txt", "quick.txt"),
testFile(MIMETYPE_STC, "stc", "quick.stc"),
testFile(MIMETYPE_STI, "sti", "quick.sti"),
testFile(MIMETYPE_STW, "stw", "quick.stw"),
testFile(MIMETYPE_SXC, "sxc", "quick.sxc"),
testFile(MIMETYPE_SXI, "sxi", "quick.sxi"),
testFile(MIMETYPE_TSV, "tsv", "sample.tsv")).collect(toMap(FileInfo::getPath, identity()));
public static Stream<Pair<FileInfo, FileInfo>> engineTransformations()
{
return Stream
.of(
allTargets("quick.doc", documentsTargets),
allTargets("quick.docx", documentsTargets),
allTargets("quick.html", documentsTargets),
allTargets("quick.odt", documentsTargets),
allTargets("quick.wpd", documentsTargets),
allTargets("quick.txt", documentsTargets),
allTargets("sample.rtf", documentsTargets),
.of(
allTargets("quick.doc", documentsTargets),
allTargets("quick.docx", documentsTargets),
allTargets("quick.html", documentsTargets),
allTargets("quick.odt", documentsTargets),
allTargets("quick.wpd", documentsTargets),
allTargets("quick.txt", documentsTargets),
allTargets("sample.rtf", documentsTargets),
allTargets("quick.odp", presentationTargets),
allTargets("quick.ppt", presentationTargets),
allTargets("quick.pptx", presentationTargets),
allTargets("quick.odp", presentationTargets),
allTargets("quick.ppt", presentationTargets),
allTargets("quick.pptx", presentationTargets),
allTargets("quick.odg", graphicTargets),
allTargets("quick.vdx", graphicTargets),
allTargets("quick.vsd", graphicTargets),
allTargets("quick.odg", graphicTargets),
allTargets("quick.vdx", graphicTargets),
allTargets("quick.vsd", graphicTargets),
allTargets("quick.ods", spreadsheetTargets),
allTargets("quick.xls", spreadsheetTargets),
allTargets("quick.xlsx", spreadsheetTargets),
allTargets("people.csv", spreadsheetTargets),
allTargets("sample.tsv", spreadsheetTargets),
allTargets("quick.ods", spreadsheetTargets),
allTargets("quick.xls", spreadsheetTargets),
allTargets("quick.xlsx", spreadsheetTargets),
allTargets("people.csv", spreadsheetTargets),
allTargets("sample.tsv", spreadsheetTargets),
allTargets("quick.xml", pdfTarget),
allTargets("quick.xltm", pdfTarget),
allTargets("quick.dita", pdfTarget),
allTargets("quick.ppsm", pdfTarget),
allTargets("quick.ppsx", pdfTarget),
allTargets("quick.stc", pdfTarget),
allTargets("quick.sti", pdfTarget),
allTargets("quick.stw", pdfTarget),
allTargets("quick.sxc", pdfTarget),
allTargets("quick.sxi", pdfTarget)
allTargets("quick.xml", pdfTarget),
allTargets("quick.xltm", pdfTarget),
allTargets("quick.dita", pdfTarget),
allTargets("quick.ppsm", pdfTarget),
allTargets("quick.ppsx", pdfTarget),
allTargets("quick.stc", pdfTarget),
allTargets("quick.sti", pdfTarget),
allTargets("quick.stw", pdfTarget),
allTargets("quick.sxc", pdfTarget),
allTargets("quick.sxi", pdfTarget)
)
.flatMap(identity());
.flatMap(identity());
}
@ParameterizedTest
@@ -205,11 +200,11 @@ public class LibreOfficeTransformationIT
final String sourceMimetype = entry.getLeft().getMimeType();
final String targetMimetype = entry.getRight().getMimeType();
final String descriptor = format("Transform ({0}, {1} -> {2}, {3})",
sourceFile, sourceMimetype, targetMimetype, targetExtension);
sourceFile, sourceMimetype, targetMimetype, targetExtension);
try
{
final ResponseEntity<Resource> response = sendTRequest(ENGINE_URL, sourceFile, sourceMimetype,
targetMimetype, targetExtension);
targetMimetype, targetExtension);
assertEquals(OK, response.getStatusCode(), descriptor);
}
catch (Exception e)
@@ -219,14 +214,14 @@ public class LibreOfficeTransformationIT
}
private static Stream<Pair<FileInfo, FileInfo>> allTargets(final String sourceFile,
final Set<FileInfo> mimetypes)
final Set<FileInfo> mimetypes)
{
return mimetypes
.stream()
//Filter out duplicate mimetypes. eg. We do not want "Transform (quick.doc, application/msword -> application/msword, doc)" as these are not contained in the engine_config
.filter(type -> !type.getMimeType().equals(TEST_FILES.get(sourceFile).getMimeType()))
// Edge case: Transform (quick.ods, application/vnd.oasis.opendocument.spreadsheet -> text/csv, csv) not in engine_config
.filter(type -> !(TEST_FILES.get(sourceFile).getMimeType().equals(MIMETYPE_OPENDOCUMENT_SPREADSHEET) && type.getMimeType().equals(MIMETYPE_TEXT_CSV)))
.map(k -> Pair.of(TEST_FILES.get(sourceFile), k));
.stream()
// Filter out duplicate mimetypes. eg. We do not want "Transform (quick.doc, application/msword -> application/msword, doc)" as these are not contained in the engine_config
.filter(type -> !type.getMimeType().equals(TEST_FILES.get(sourceFile).getMimeType()))
// Edge case: Transform (quick.ods, application/vnd.oasis.opendocument.spreadsheet -> text/csv, csv) not in engine_config
.filter(type -> !(TEST_FILES.get(sourceFile).getMimeType().equals(MIMETYPE_OPENDOCUMENT_SPREADSHEET) && type.getMimeType().equals(MIMETYPE_TEXT_CSV)))
.map(k -> Pair.of(TEST_FILES.get(sourceFile), k));
}
}