mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
REPO-4319 Local Transformers (#313)
Creation of local transformers that don't depend on any of the legacy transformer code deprecated in ACS 6.1. The previous local transformers are now referred to as legacy transformers. The localTransformClient and localTransformServiceRegistry now are switches between these two classes of transform.
This commit is contained in:
@@ -59,6 +59,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
@Deprecated
|
||||
public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
{
|
||||
/* Error messages */
|
||||
|
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Abstract supper class for local transformer using flat transform options.
|
||||
*/
|
||||
public abstract class AbstractLocalTransformer implements LocalTransformer
|
||||
{
|
||||
protected static final Log log = LogFactory.getLog(LocalTransformer.class);
|
||||
|
||||
protected final String name;
|
||||
protected final MimetypeService mimetypeService;
|
||||
protected final TransformerDebug transformerDebug;
|
||||
|
||||
private final LocalTransformServiceRegistry localTransformServiceRegistry;
|
||||
private final boolean strictMimeTypeCheck;
|
||||
private final Map<String, Set<String>> strictMimetypeExceptions;
|
||||
private final boolean retryTransformOnDifferentMimeType;
|
||||
private final static ThreadLocal<Integer> depth = ThreadLocal.withInitial(()->0);
|
||||
|
||||
AbstractLocalTransformer(String name, TransformerDebug transformerDebug,
|
||||
MimetypeService mimetypeService, boolean strictMimeTypeCheck,
|
||||
Map<String, Set<String>> strictMimetypeExceptions, boolean retryTransformOnDifferentMimeType,
|
||||
LocalTransformServiceRegistry localTransformServiceRegistry)
|
||||
{
|
||||
this.name = name;
|
||||
this.transformerDebug = transformerDebug;
|
||||
this.mimetypeService = mimetypeService;
|
||||
this.strictMimeTypeCheck = strictMimeTypeCheck;
|
||||
this.strictMimetypeExceptions = strictMimetypeExceptions;
|
||||
this.retryTransformOnDifferentMimeType = retryTransformOnDifferentMimeType;
|
||||
this.localTransformServiceRegistry = localTransformServiceRegistry;
|
||||
}
|
||||
|
||||
public abstract boolean isAvailable();
|
||||
|
||||
protected abstract void transformImpl(ContentReader reader,
|
||||
ContentWriter writer, Map<String, String> transformOptions,
|
||||
String sourceMimetype, String targetMimetype,
|
||||
String sourceExtension, String targetExtension,
|
||||
String targetEncoding, String renditionName, NodeRef sourceNodeRef)
|
||||
throws Exception;
|
||||
|
||||
@Override
|
||||
public void transform(ContentReader reader, ContentWriter writer, Map<String, String> transformOptions,
|
||||
String renditionName, NodeRef sourceNodeRef)
|
||||
throws Exception
|
||||
{
|
||||
if (isAvailable())
|
||||
{
|
||||
String sourceMimetype = reader.getMimetype();
|
||||
String targetMimetype = writer.getMimetype();
|
||||
String targetEncoding = writer.getEncoding();
|
||||
|
||||
String sourceExtension = mimetypeService.getExtension(sourceMimetype);
|
||||
String targetExtension = mimetypeService.getExtension(targetMimetype);
|
||||
if (sourceExtension == null || targetExtension == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unknown extensions for mimetypes: \n" +
|
||||
" source mimetype: " + sourceMimetype + "\n" +
|
||||
" source extension: " + sourceExtension + "\n" +
|
||||
" target mimetype: " + targetMimetype + "\n" +
|
||||
" target extension: " + targetExtension + "\n" +
|
||||
" target encoding: " + targetEncoding);
|
||||
}
|
||||
|
||||
transformWithDebug(reader, writer, transformOptions, renditionName, sourceNodeRef, sourceMimetype,
|
||||
targetMimetype, targetEncoding, sourceExtension, targetExtension);
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Local transformation completed: \n" +
|
||||
" source: " + reader + "\n" +
|
||||
" target: " + writer + "\n" +
|
||||
" options: " + transformOptions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Local transformer not available: \n" +
|
||||
" source: " + reader + "\n" +
|
||||
" target: " + writer + "\n" +
|
||||
" options: " + transformOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private void transformWithDebug(ContentReader reader, ContentWriter writer, Map<String, String> transformOptions,
|
||||
String renditionName, NodeRef sourceNodeRef, String sourceMimetype, String targetMimetype,
|
||||
String targetEncoding, String sourceExtension, String targetExtension) throws Exception
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
depth.set(depth.get()+1);
|
||||
|
||||
if (transformerDebug.isEnabled())
|
||||
{
|
||||
transformerDebug.pushTransform(name, reader.getContentUrl(), sourceMimetype,
|
||||
targetMimetype, reader.getSize(), renditionName, sourceNodeRef);
|
||||
}
|
||||
|
||||
strictMimetypeCheck(reader, sourceNodeRef, sourceMimetype);
|
||||
transformImpl(reader, writer, transformOptions, sourceMimetype,
|
||||
targetMimetype, sourceExtension, targetExtension, targetEncoding, renditionName, sourceNodeRef);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
retryWithDifferentMimetype(reader, writer, targetMimetype, transformOptions, renditionName, sourceNodeRef, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
transformerDebug.popTransform();
|
||||
depth.set(depth.get()-1);
|
||||
}
|
||||
}
|
||||
|
||||
private void strictMimetypeCheck(ContentReader reader, NodeRef sourceNodeRef, String declaredMimetype)
|
||||
throws UnsupportedTransformationException
|
||||
{
|
||||
if (mimetypeService != null && strictMimeTypeCheck && depth.get() == 1)
|
||||
{
|
||||
String detectedMimetype = mimetypeService.getMimetypeIfNotMatches(reader.getReader());
|
||||
|
||||
if (!strictMimetypeCheck(declaredMimetype, detectedMimetype))
|
||||
{
|
||||
Set<String> allowedMimetypes = strictMimetypeExceptions.get(declaredMimetype);
|
||||
if (allowedMimetypes != null && allowedMimetypes.contains(detectedMimetype))
|
||||
{
|
||||
String fileName = transformerDebug.getFileName(sourceNodeRef, true, 0);
|
||||
String readerSourceMimetype = reader.getMimetype();
|
||||
String message = "Transformation of ("+fileName+
|
||||
") has not taken place because the declared mimetype ("+
|
||||
readerSourceMimetype+") does not match the detected mimetype ("+
|
||||
detectedMimetype+").";
|
||||
log.warn(message);
|
||||
throw new UnsupportedTransformationException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When strict mimetype checking is performed before a transformation, this method is called.
|
||||
* There are a few issues with the Tika mimetype detection. As a result we still allow some
|
||||
* transformations to take place even if there is a discrepancy between the detected and
|
||||
* declared mimetypes.
|
||||
* @param declaredMimetype the mimetype on the source node
|
||||
* @param detectedMimetype returned by Tika having looked at the content.
|
||||
* @return true if the transformation should take place. This includes the case where the
|
||||
* detectedMimetype is null (returned by Tika when the mimetypes are the same), or
|
||||
* the supplied pair of mimetypes have been added to the
|
||||
* {@code}transformer.strict.mimetype.check.whitelist{@code}.
|
||||
*/
|
||||
private boolean strictMimetypeCheck(String declaredMimetype, String detectedMimetype)
|
||||
{
|
||||
if (detectedMimetype == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> detectedMimetypes = strictMimetypeExceptions.get(declaredMimetype);
|
||||
return detectedMimetypes != null && detectedMimetypes.contains(detectedMimetype);
|
||||
}
|
||||
|
||||
private void retryWithDifferentMimetype(ContentReader reader, ContentWriter writer, String targetMimetype,
|
||||
Map<String, String> transformOptions, String renditionName,
|
||||
NodeRef sourceNodeRef, Throwable e) throws Exception
|
||||
{
|
||||
if (mimetypeService != null && localTransformServiceRegistry != null)
|
||||
{
|
||||
String differentType = mimetypeService.getMimetypeIfNotMatches(reader.getReader());
|
||||
if (differentType == null)
|
||||
{
|
||||
transformerDebug.debug(" Failed", e);
|
||||
throw new ContentIOException("Content conversion failed: \n" +
|
||||
" reader: " + reader + "\n" +
|
||||
" writer: " + writer + "\n" +
|
||||
" options: " + transformOptions,
|
||||
e);
|
||||
}
|
||||
else
|
||||
{
|
||||
transformerDebug.debug(" Failed: Mime type was '" + differentType + "'", e);
|
||||
String claimedMimetype = reader.getMimetype();
|
||||
|
||||
if (retryTransformOnDifferentMimeType)
|
||||
{
|
||||
reader = reader.getReader();
|
||||
reader.setMimetype(differentType);
|
||||
long sourceSizeInBytes = reader.getSize();
|
||||
|
||||
LocalTransformer localTransformer = localTransformServiceRegistry.getLocalTransformer(
|
||||
transformOptions, renditionName, differentType, targetMimetype, sourceSizeInBytes);
|
||||
if (localTransformer == null)
|
||||
{
|
||||
transformerDebug.debug(" Failed", e);
|
||||
throw new ContentIOException("Content conversion failed: \n" +
|
||||
" reader: " + reader + "\n" +
|
||||
" writer: " + writer + "\n" +
|
||||
" options: " + transformOptions + "\n" +
|
||||
" claimed mime type: " + claimedMimetype + "\n" +
|
||||
" detected mime type: " + differentType + "\n" +
|
||||
" transformer not found" + "\n",
|
||||
e
|
||||
);
|
||||
}
|
||||
localTransformer.transform(reader, writer, transformOptions, renditionName, sourceNodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ContentIOException("Content conversion failed: \n" +
|
||||
" reader: " + reader + "\n" +
|
||||
" writer: " + writer + "\n" +
|
||||
" options: " + transformOptions + "\n" +
|
||||
" claimed mime type: " + claimedMimetype + "\n" +
|
||||
" detected mime type: " + differentType,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -42,10 +42,17 @@ import org.apache.commons.logging.Log;
|
||||
@Deprecated
|
||||
public abstract class AbstractRemoteContentTransformer extends AbstractContentTransformer2
|
||||
{
|
||||
private boolean enabled = true;
|
||||
|
||||
private RemoteTransformerClient remoteTransformerClient;
|
||||
|
||||
private boolean available = false;
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optional remote transformer client which will be used in preference to a local command if available.
|
||||
*
|
||||
@@ -74,6 +81,8 @@ public abstract class AbstractRemoteContentTransformer extends AbstractContentTr
|
||||
}
|
||||
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
// check availability
|
||||
if (remoteTransformerClientConfigured())
|
||||
@@ -88,12 +97,12 @@ public abstract class AbstractRemoteContentTransformer extends AbstractContentTr
|
||||
{
|
||||
String versionString = msg;
|
||||
setAvailable(true);
|
||||
logger.info("Using remote " + getName() + ": " + versionString);
|
||||
logger.info("Using legacy local " + getName() + ": " + versionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAvailable(false);
|
||||
String message = "Remote " + getName() + " is not available for transformations. " + msg;
|
||||
String message = "Legacy local " + getName() + " is not available for transformations. " + msg;
|
||||
if (isAvailable == null)
|
||||
{
|
||||
logger.debug(message);
|
||||
@@ -117,6 +126,7 @@ public abstract class AbstractRemoteContentTransformer extends AbstractContentTr
|
||||
available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAvailable()
|
||||
{
|
||||
|
@@ -197,7 +197,7 @@ public class ContentTransformerRegistry
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
transformerDebug.debug("Local legacy transformers are " + (enabled ? "enabled" : "disabled"));
|
||||
transformerDebug.debug("Legacy transforms are " + (enabled ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
// Get the list of transformers
|
||||
|
@@ -48,8 +48,15 @@ public class JodContentTransformer extends OOoContentTransformerHelper implement
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(JodContentTransformer.class);
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private JodConverter jodconverter;
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setJodConverter(JodConverter jodc)
|
||||
{
|
||||
this.jodconverter = jodc;
|
||||
@@ -82,6 +89,8 @@ public class JodContentTransformer extends OOoContentTransformerHelper implement
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
super.afterPropertiesSet();
|
||||
if (remoteTransformerClientConfigured())
|
||||
@@ -91,11 +100,11 @@ public class JodContentTransformer extends OOoContentTransformerHelper implement
|
||||
if (isAvailable != null && isAvailable)
|
||||
{
|
||||
String versionString = result.getSecond().trim();
|
||||
logger.info("Using remote JodCoverter: "+versionString);
|
||||
logger.info("Using legacy local JodCoverter: " + versionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
String message = "Remote JodConverter is not available for transformations. " + result.getSecond();
|
||||
String message = "Legacy local JodConverter is not available for transformations. " + result.getSecond();
|
||||
if (isAvailable == null)
|
||||
{
|
||||
logger.debug(message);
|
||||
@@ -107,6 +116,7 @@ public class JodContentTransformer extends OOoContentTransformerHelper implement
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(File tempFromFile, DocumentFormat sourceFormat, File tempToFile,
|
||||
|
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Transformer that passes a document through a pipeline of transformations to arrive at an target mimetype.
|
||||
*
|
||||
* Instances are automatically created for transformers identified by alfresco/transform json files and returned from
|
||||
* T-Engines which are themselves identified by global properties the match the pattern localTransformer.<name>.url.
|
||||
* The transforms take place in a separate process (typically a Docker container).
|
||||
*/
|
||||
public class LocalPipelineTransformer extends AbstractLocalTransformer
|
||||
{
|
||||
private final List<IntermediateTransformer> transformers = new ArrayList<>();
|
||||
|
||||
private class IntermediateTransformer
|
||||
{
|
||||
LocalTransformer intermediateTransformer;
|
||||
String targetMimetype;
|
||||
}
|
||||
|
||||
public LocalPipelineTransformer(String name, TransformerDebug transformerDebug,
|
||||
MimetypeService mimetypeService, boolean strictMimeTypeCheck,
|
||||
Map<String, Set<String>> strictMimetypeExceptions,
|
||||
boolean retryTransformOnDifferentMimeType,
|
||||
LocalTransformServiceRegistry localTransformServiceRegistry)
|
||||
{
|
||||
super(name, transformerDebug, mimetypeService, strictMimeTypeCheck, strictMimetypeExceptions,
|
||||
retryTransformOnDifferentMimeType, localTransformServiceRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addIntermediateTransformer(LocalTransformer intermediateTransformer, String targetMimetype)
|
||||
{
|
||||
IntermediateTransformer transformer = new IntermediateTransformer();
|
||||
transformer.intermediateTransformer = intermediateTransformer;
|
||||
transformer.targetMimetype = targetMimetype;
|
||||
transformers.add(transformer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transformImpl(ContentReader reader,
|
||||
ContentWriter writer, Map<String, String> transformOptions,
|
||||
String sourceMimetype, String targetMimetype,
|
||||
String sourceExtension, String targetExtension,
|
||||
String targetEncoding, String renditionName, NodeRef sourceNodeRef) throws Exception
|
||||
{
|
||||
ContentReader currentReader = reader;
|
||||
int lastI = transformers.size() - 1;
|
||||
for (int i = 0; i <= lastI; i++)
|
||||
{
|
||||
IntermediateTransformer transformer = transformers.get(i);
|
||||
|
||||
ContentWriter currentWriter;
|
||||
if (i == lastI)
|
||||
{
|
||||
currentWriter = writer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// make a temp file writer with the correct extension
|
||||
String sourceExt = mimetypeService.getExtension(currentReader.getMimetype());
|
||||
String targetExt = mimetypeService.getExtension(transformer.targetMimetype);
|
||||
File tempFile = TempFileProvider.createTempFile(
|
||||
"LocalPipelineTransformer_intermediate_" + sourceExt + "_",
|
||||
"." + targetExt);
|
||||
currentWriter = new FileContentWriter(tempFile);
|
||||
currentWriter.setMimetype(transformer.targetMimetype);
|
||||
}
|
||||
|
||||
transformer.intermediateTransformer.transform(currentReader, currentWriter, transformOptions, renditionName, sourceNodeRef);
|
||||
|
||||
// Clear the sourceNodeRef after the first transformation to avoid later transformers thinking the
|
||||
// intermediate file is the original node.
|
||||
if (i == 0)
|
||||
{
|
||||
sourceNodeRef = null;
|
||||
}
|
||||
|
||||
// Pass the output to the next transformer
|
||||
if (i < lastI)
|
||||
{
|
||||
currentReader = currentWriter.getReader();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,398 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistryImpl;
|
||||
import org.alfresco.transform.client.model.config.TransformStep;
|
||||
import org.alfresco.transform.client.model.config.Transformer;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Implements {@link TransformServiceRegistry} providing a mechanism of validating if a local transformation
|
||||
* (based on {@link LocalTransformer} request is supported. It also extends this interface to provide a
|
||||
* {@link #transform} method.
|
||||
* @author adavis
|
||||
*/
|
||||
public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl implements InitializingBean
|
||||
{
|
||||
private static final Log log = LogFactory.getLog(LocalTransformer.class);
|
||||
|
||||
private static final String LOCAL_TRANSFORMER = "localTransformer.";
|
||||
private static final String URL = ".url";
|
||||
static final String STRICT_MIMETYPE_CHECK_WHITELIST_MIMETYPES = "transformer.strict.mimetype.check.whitelist.mimetypes";
|
||||
|
||||
private String pipelineConfigFolder;
|
||||
private boolean enabled = true;
|
||||
private boolean firstTime = true;
|
||||
private Properties properties;
|
||||
private MimetypeService mimetypeService;
|
||||
private TransformerDebug transformerDebug;
|
||||
private boolean strictMimeTypeCheck;
|
||||
private Map<String, Set<String>> strictMimetypeExceptions;
|
||||
private boolean retryTransformOnDifferentMimeType;
|
||||
|
||||
private Map<String, LocalTransformer> transformers = new HashMap<>();
|
||||
|
||||
public void setPipelineConfigFolder(String pipelineConfigFolder)
|
||||
{
|
||||
this.pipelineConfigFolder = pipelineConfigFolder;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
firstTime = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Alfresco global properties.
|
||||
*/
|
||||
public void setProperties(Properties properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setMimetypeService(MimetypeService mimetypeService)
|
||||
{
|
||||
this.mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
public void setTransformerDebug(TransformerDebug transformerDebug)
|
||||
{
|
||||
this.transformerDebug = transformerDebug;
|
||||
}
|
||||
|
||||
public void setStrictMimeTypeCheck(boolean strictMimeTypeCheck)
|
||||
{
|
||||
this.strictMimeTypeCheck = strictMimeTypeCheck;
|
||||
}
|
||||
|
||||
public void setRetryTransformOnDifferentMimeType(boolean retryTransformOnDifferentMimeType)
|
||||
{
|
||||
this.retryTransformOnDifferentMimeType = retryTransformOnDifferentMimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "mimetypeService", mimetypeService);
|
||||
PropertyCheck.mandatory(this, "pipelineConfigFolder", pipelineConfigFolder);
|
||||
PropertyCheck.mandatory(this, "properties", properties);
|
||||
PropertyCheck.mandatory(this, "transformerDebug", transformerDebug);
|
||||
super.afterPropertiesSet();
|
||||
transformers.clear();
|
||||
|
||||
strictMimetypeExceptions = getStrictMimetypeExceptions();
|
||||
|
||||
// TODO read json from the T-Engines. Need to find urls to these by looking for a-g.p or system props that match "localTransformer.*.url"
|
||||
// Do before reading local files, so the files can override T-Engine values.
|
||||
List<String> urls = getTEngineUrls();
|
||||
|
||||
// Reads files alfresco/transformers from resource path
|
||||
register(pipelineConfigFolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Transformer transformer)
|
||||
{
|
||||
super.register(transformer);
|
||||
|
||||
try
|
||||
{
|
||||
String name = transformer.getTransformerName();
|
||||
|
||||
if (name == null || transformers.get(name) != null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local transformer names must exist and be unique (" + name + ").");
|
||||
}
|
||||
|
||||
List<TransformStep> transformerPipeline = transformer.getTransformerPipeline();
|
||||
LocalTransformer localTransformer;
|
||||
if (transformerPipeline == null)
|
||||
{
|
||||
String baseUrl = getBaseUrl(name);
|
||||
int startupRetryPeriodSeconds = getStartupRetryPeriodSeconds(name);
|
||||
localTransformer = new LocalTransformerImpl(name, transformerDebug, mimetypeService,
|
||||
strictMimeTypeCheck, strictMimetypeExceptions, retryTransformOnDifferentMimeType,
|
||||
this, baseUrl, startupRetryPeriodSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
int transformerCount = transformerPipeline.size();
|
||||
if (transformerCount <= 1)
|
||||
{
|
||||
throw new IllegalArgumentException("Local pipeline transformer " + name +
|
||||
" must have more than one intermediate transformer defined.");
|
||||
}
|
||||
|
||||
localTransformer = new LocalPipelineTransformer(name, transformerDebug, mimetypeService,
|
||||
strictMimeTypeCheck, strictMimetypeExceptions, retryTransformOnDifferentMimeType,
|
||||
this);
|
||||
for (int i=0; i < transformerCount; i++)
|
||||
{
|
||||
TransformStep intermediateTransformerStep = transformerPipeline.get(i);
|
||||
String intermediateTransformerName = intermediateTransformerStep.getTransformerName();
|
||||
if (name == null || transformers.get(name) != null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local pipeline transformer " + name +
|
||||
" did not specified an intermediate transformer name.");
|
||||
}
|
||||
|
||||
LocalTransformer intermediateTransformer = transformers.get(intermediateTransformerName);
|
||||
if (intermediateTransformer == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local pipeline transformer " + name +
|
||||
" specified an intermediate transformer (" +
|
||||
intermediateTransformerName + " that has not previously been defined.");
|
||||
}
|
||||
|
||||
String targetMimetype = intermediateTransformerStep.getTargetMediaType();
|
||||
if (i == transformerCount-1)
|
||||
{
|
||||
if (targetMimetype != null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local pipeline transformer " + name +
|
||||
" must not specify targetExt for the final intermediate transformer, " +
|
||||
"as this is defined via the supportedSourceAndTargetList.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetMimetype == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local pipeline transformer " + name +
|
||||
" must specify targetExt for all intermediate transformers except for the final one.");
|
||||
}
|
||||
}
|
||||
((LocalPipelineTransformer)localTransformer).addIntermediateTransformer(intermediateTransformer, targetMimetype);
|
||||
}
|
||||
}
|
||||
transformers.put(name, localTransformer);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
String msg = e.getMessage();
|
||||
getLog().error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Log getLog()
|
||||
{
|
||||
return log;
|
||||
}
|
||||
|
||||
private List<String> getTEngineUrls()
|
||||
{
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Object o : getKeySet())
|
||||
{
|
||||
if (o instanceof String)
|
||||
{
|
||||
String key = (String)o;
|
||||
if (key.startsWith(LOCAL_TRANSFORMER) && key.endsWith(URL))
|
||||
{
|
||||
Object url = getProperty(key, null);
|
||||
if (url instanceof String)
|
||||
{
|
||||
String urlStr = ((String)url).trim();
|
||||
if (!urlStr.isEmpty())
|
||||
{
|
||||
urls.add((String) url);
|
||||
getLog().debug("T-Engine "+key+"="+url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
private String getBaseUrl(String name)
|
||||
{
|
||||
String baseUrlName = LOCAL_TRANSFORMER + name + URL;
|
||||
String baseUrl = getProperty(baseUrlName, null);
|
||||
if (baseUrl == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Local transformer property " + baseUrlName + " was not set");
|
||||
}
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
private int getStartupRetryPeriodSeconds(String name)
|
||||
{
|
||||
String startupRetryPeriodSecondsName = LOCAL_TRANSFORMER + name + ".startupRetryPeriodSeconds";
|
||||
String property = getProperty(startupRetryPeriodSecondsName, "60");
|
||||
int startupRetryPeriodSeconds;
|
||||
try
|
||||
{
|
||||
startupRetryPeriodSeconds = Integer.parseInt(property);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Local transformer property " + startupRetryPeriodSecondsName +
|
||||
" should be an integer");
|
||||
}
|
||||
return startupRetryPeriodSeconds;
|
||||
}
|
||||
|
||||
private Map<String, Set<String>> getStrictMimetypeExceptions()
|
||||
{
|
||||
Map<String, Set<String>> strictMimetypeExceptions = new HashMap<>();
|
||||
|
||||
String whitelist = getProperty(STRICT_MIMETYPE_CHECK_WHITELIST_MIMETYPES, "").trim();
|
||||
if (!whitelist.isEmpty())
|
||||
{
|
||||
String[] mimetypes = whitelist.split(";");
|
||||
|
||||
if (mimetypes.length % 2 != 0)
|
||||
{
|
||||
getLog().error(STRICT_MIMETYPE_CHECK_WHITELIST_MIMETYPES+" should have an even number of mimetypes as a ; separated list.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Set<String> detectedMimetypes = null;
|
||||
for (String mimetype: mimetypes)
|
||||
{
|
||||
mimetype = mimetype.trim();
|
||||
if (mimetype.isEmpty())
|
||||
{
|
||||
getLog().error(STRICT_MIMETYPE_CHECK_WHITELIST_MIMETYPES+" contains a blank mimetype.");
|
||||
// Still okay to use it in the map though, but it will be ignored.
|
||||
}
|
||||
|
||||
if (detectedMimetypes == null)
|
||||
{
|
||||
detectedMimetypes = strictMimetypeExceptions.get(mimetype);
|
||||
if (detectedMimetypes == null)
|
||||
{
|
||||
detectedMimetypes = new HashSet<>();
|
||||
strictMimetypeExceptions.put(mimetype, detectedMimetypes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
detectedMimetypes.add(mimetype);
|
||||
detectedMimetypes = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return strictMimetypeExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the set of property keys and System keys.
|
||||
*/
|
||||
private Set<String> getKeySet()
|
||||
{
|
||||
Set<Object> systemKeys = System.getProperties().keySet();
|
||||
Set<Object> alfrescoGlobalKeys = this.properties.keySet();
|
||||
Set<String> keys = new HashSet<>(systemKeys.size()+alfrescoGlobalKeys.size());
|
||||
addStrings(keys, systemKeys);
|
||||
addStrings(keys, alfrescoGlobalKeys);
|
||||
return keys;
|
||||
}
|
||||
|
||||
private void addStrings(Set<String> setOfStrings, Set<Object> objects)
|
||||
{
|
||||
objects.forEach(object->{
|
||||
if (object instanceof String)
|
||||
{
|
||||
setOfStrings.add((String)object);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property from an alfresco global property but falls back to a System property with the same name to
|
||||
* allow dynamic creation of transformers without having to have an AMP to add the alfresco global property.
|
||||
*/
|
||||
private String getProperty(String name, String defaultValue)
|
||||
{
|
||||
String value = properties.getProperty(name);
|
||||
if (value == null || value.isEmpty())
|
||||
{
|
||||
value = System.getProperty(name);
|
||||
if (value != null && value.isEmpty())
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxSize(String sourceMimetype, String targetMimetype, Map<String, String> options, String renditionName)
|
||||
{
|
||||
// This message is not logged if placed in afterPropertiesSet
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
transformerDebug.debug("Local transforms are " + (enabled ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
return enabled
|
||||
? super.getMaxSize(sourceMimetype, targetMimetype, options, renditionName)
|
||||
: 0;
|
||||
}
|
||||
|
||||
public void transform(ContentReader reader, ContentWriter writer, Map<String, String> actualOptions,
|
||||
String renditionName, NodeRef sourceNodeRef) throws Exception
|
||||
{
|
||||
|
||||
String sourceMimetype = reader.getMimetype();
|
||||
String targetMimetype = writer.getMimetype();
|
||||
long sourceSizeInBytes = reader.getSize();
|
||||
LocalTransformer localTransformer = getLocalTransformer(actualOptions, renditionName, sourceMimetype, targetMimetype, sourceSizeInBytes);
|
||||
localTransformer.transform(reader, writer, actualOptions, renditionName, sourceNodeRef);
|
||||
}
|
||||
|
||||
public LocalTransformer getLocalTransformer(Map<String, String> actualOptions, String renditionName,
|
||||
String sourceMimetype, String targetMimetype, long sourceSizeInBytes)
|
||||
{
|
||||
String name = getTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, renditionName);
|
||||
return transformers.get(name);
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface of a local transformer using flat transform options.
|
||||
*/
|
||||
public interface LocalTransformer
|
||||
{
|
||||
void transform(ContentReader reader, ContentWriter writer, Map<String, String> transformOptions,
|
||||
String renditionName, NodeRef sourceNodeRef)
|
||||
throws Exception;
|
||||
}
|
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.repo.rendition2.RenditionDefinition2;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A local transformer using flat transform options.
|
||||
*
|
||||
* Instances are automatically created for transformers identified by alfresco/transform json files and returned from
|
||||
* T-Engines which are themselves identified by global properties or system properties the match the pattern
|
||||
* localTransformer.<name>.url. The transforms take place in a separate process (typically a Docker container).
|
||||
*/
|
||||
public class LocalTransformerImpl extends AbstractLocalTransformer
|
||||
{
|
||||
private RemoteTransformerClient remoteTransformerClient;
|
||||
|
||||
private boolean available = false;
|
||||
|
||||
public LocalTransformerImpl(String name, TransformerDebug transformerDebug,
|
||||
MimetypeService mimetypeService, boolean strictMimeTypeCheck,
|
||||
Map<String, Set<String>> strictMimetypeExceptions,
|
||||
boolean retryTransformOnDifferentMimeType,
|
||||
LocalTransformServiceRegistry localTransformServiceRegistry, String baseUrl,
|
||||
int startupRetryPeriodSeconds)
|
||||
{
|
||||
super(name, transformerDebug, mimetypeService, strictMimeTypeCheck, strictMimetypeExceptions,
|
||||
retryTransformOnDifferentMimeType, localTransformServiceRegistry);
|
||||
remoteTransformerClient = new RemoteTransformerClient(name, baseUrl);
|
||||
remoteTransformerClient.setStartupRetryPeriodSeconds(startupRetryPeriodSeconds);
|
||||
|
||||
checkAvailability();
|
||||
}
|
||||
|
||||
private boolean remoteTransformerClientConfigured()
|
||||
{
|
||||
return remoteTransformerClient.getBaseUrl() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable()
|
||||
{
|
||||
if (remoteTransformerClientConfigured() && !remoteTransformerClient.isAvailable())
|
||||
{
|
||||
checkAvailability();
|
||||
}
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
private void setAvailable(boolean available)
|
||||
{
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
private void checkAvailability()
|
||||
{
|
||||
// check availability
|
||||
if (remoteTransformerClientConfigured())
|
||||
{
|
||||
try
|
||||
{
|
||||
Pair<Boolean, String> result = remoteTransformerClient.check(log);
|
||||
Boolean isAvailable = result.getFirst();
|
||||
String msg = result.getSecond() == null ? "" : result.getSecond();
|
||||
if (isAvailable != null && isAvailable)
|
||||
{
|
||||
setAvailable(true);
|
||||
log.info("Using local transformer " + name + ": " + msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAvailable(false);
|
||||
String message = "Local transformer " + name + " is not available. " + msg;
|
||||
if (isAvailable == null)
|
||||
{
|
||||
log.debug(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
setAvailable(false);
|
||||
log.error("Local transformer " + name + " is not available: " + (e.getMessage() != null ? e.getMessage() : ""));
|
||||
log.debug(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setAvailable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transformImpl(ContentReader reader,
|
||||
ContentWriter writer, Map<String, String> transformOptions,
|
||||
String sourceMimetype, String targetMimetype,
|
||||
String sourceExtension, String targetExtension,
|
||||
String targetEncoding, String renditionName, NodeRef sourceNodeRef) throws Exception
|
||||
{
|
||||
// Build an array of option names and values and extract the timeout.
|
||||
long timeoutMs = 0;
|
||||
int nonOptions = transformOptions.containsKey(RenditionDefinition2.TIMEOUT) ? 1 : 0;
|
||||
int size = (transformOptions.size() - nonOptions) * 2;
|
||||
String[] args = new String[size];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> option : transformOptions.entrySet())
|
||||
{
|
||||
String name = option.getKey();
|
||||
String value = option.getValue();
|
||||
if (RenditionDefinition2.TIMEOUT.equals(name))
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
timeoutMs = Long.parseLong(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args[i++] = name;
|
||||
args[i++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
remoteTransformerClient.request(reader, writer, sourceMimetype, sourceExtension, targetExtension,
|
||||
timeoutMs, log, args);
|
||||
}
|
||||
}
|
@@ -53,10 +53,7 @@ import java.util.StringJoiner;
|
||||
* saved in a ContentWriter. In the event of an error an Exception is thrown.
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public class RemoteTransformerClient
|
||||
{
|
||||
private final String name;
|
||||
@@ -137,7 +134,7 @@ public class RemoteTransformerClient
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Remote "+name+' '+sourceExtension+' '+targetExtension+' '+url+' '+args);
|
||||
logger.debug(name+' '+sourceExtension+' '+targetExtension+' '+url+' '+args);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -149,7 +146,7 @@ public class RemoteTransformerClient
|
||||
StatusLine statusLine = response.getStatusLine();
|
||||
if (statusLine == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote "+name+" returned no status " + url + ' ' + args);
|
||||
throw new AlfrescoRuntimeException(name+" returned no status " + url + ' ' + args);
|
||||
}
|
||||
HttpEntity resEntity = response.getEntity();
|
||||
if (resEntity != null)
|
||||
@@ -164,7 +161,7 @@ public class RemoteTransformerClient
|
||||
long responseContentLength = resEntity.getContentLength();
|
||||
Header responseContentEncoding = resEntity.getContentEncoding();
|
||||
Header responseContentType = resEntity.getContentType();
|
||||
logger.debug("Remote " + name + ' ' + sourceExtension + ' ' + targetExtension +
|
||||
logger.debug(name + ' ' + sourceExtension + ' ' + targetExtension +
|
||||
" returned. length=" + responseContentLength +
|
||||
" type=" + responseContentType +
|
||||
" encoding=" + responseContentEncoding);
|
||||
@@ -175,13 +172,13 @@ public class RemoteTransformerClient
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " failed to read the returned content", e);
|
||||
throw new AlfrescoRuntimeException(name + " failed to read the returned content", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String message = getErrorMessage(resEntity);
|
||||
String msg = ("Remote " + name + " returned a " + statusCode + " status " + message +
|
||||
String msg = (name + " returned a " + statusCode + " status " + message +
|
||||
' ' + url + ' ' + args).trim();
|
||||
if (statusCode == 401)
|
||||
{
|
||||
@@ -199,7 +196,7 @@ public class RemoteTransformerClient
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " did not return an entity " + url);
|
||||
throw new AlfrescoRuntimeException(name + " did not return an entity " + url);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
@@ -207,12 +204,12 @@ public class RemoteTransformerClient
|
||||
// In the case of transform requests, unlike version checks, it is only the failure to connect that
|
||||
// forces a wait before trying again.
|
||||
connectionFailed();
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " failed to connect or to read the response", e);
|
||||
throw new AlfrescoRuntimeException(name + " failed to connect or to read the response", e);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " failed to create an HttpClient", e);
|
||||
throw new AlfrescoRuntimeException(name + " failed to create an HttpClient", e);
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
@@ -235,7 +232,7 @@ public class RemoteTransformerClient
|
||||
{
|
||||
if (!isTimeToCheckAvailability())
|
||||
{
|
||||
logger.debug("Remote "+name+' '+" too early to check availability");
|
||||
logger.debug(name+' '+" too early to check availability");
|
||||
Pair<Boolean, String> result = getCheckResult();
|
||||
return result;
|
||||
}
|
||||
@@ -245,7 +242,7 @@ public class RemoteTransformerClient
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Remote "+name+' '+" check" +url);
|
||||
logger.debug(name+' '+" check" +url);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -257,7 +254,7 @@ public class RemoteTransformerClient
|
||||
StatusLine statusLine = response.getStatusLine();
|
||||
if (statusLine == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote "+name+" check returned no status " + url);
|
||||
throw new AlfrescoRuntimeException(name+" check returned no status " + url);
|
||||
}
|
||||
HttpEntity resEntity = response.getEntity();
|
||||
if (resEntity != null)
|
||||
@@ -274,7 +271,7 @@ public class RemoteTransformerClient
|
||||
long responseContentLength = resEntity.getContentLength();
|
||||
Header responseContentType = resEntity.getContentType();
|
||||
Header responseContentEncoding = resEntity.getContentEncoding();
|
||||
logger.debug("Remote " + name +
|
||||
logger.debug(name +
|
||||
" check returned. length=" + responseContentLength +
|
||||
" type=" + responseContentType +
|
||||
" encoding=" + responseContentEncoding+
|
||||
@@ -289,28 +286,28 @@ public class RemoteTransformerClient
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " check failed to read the returned content", e);
|
||||
throw new AlfrescoRuntimeException(name + " check failed to read the returned content", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
String message = getErrorMessage(resEntity);
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " check returned a " + statusCode + " status " + message + ' ' + url);
|
||||
throw new AlfrescoRuntimeException(name + " check returned a " + statusCode + " status " + message + ' ' + url);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " check did not return an entity " + url);
|
||||
throw new AlfrescoRuntimeException(name + " check did not return an entity " + url);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " check failed to connect or to read the response", e);
|
||||
throw new AlfrescoRuntimeException(name + " check failed to connect or to read the response", e);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Remote " + name + " check failed to create an HttpClient", e);
|
||||
throw new AlfrescoRuntimeException(name + " check failed to create an HttpClient", e);
|
||||
}
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
|
@@ -25,8 +25,37 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.repo.rendition2.RenditionDefinition2;
|
||||
import org.alfresco.repo.rendition2.RenditionDefinition2Impl;
|
||||
import org.alfresco.repo.rendition2.RenditionDefinitionRegistry2Impl;
|
||||
import org.alfresco.repo.rendition2.TransformClient;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.LogTee;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
@@ -34,8 +63,11 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
@@ -43,24 +75,7 @@ import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
import org.alfresco.util.LogTee;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import static org.alfresco.repo.rendition2.RenditionService2Impl.SOURCE_HAS_NO_CONTENT;
|
||||
|
||||
/**
|
||||
* Debugs transformers selection and activity.<p>
|
||||
@@ -79,21 +94,26 @@ import org.apache.commons.logging.LogFactory;
|
||||
* transformers) and {@link #popAvailable} are called.<p>
|
||||
*
|
||||
* @author Alan Davis
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
public class TransformerDebug
|
||||
public class TransformerDebug implements ApplicationContextAware
|
||||
{
|
||||
private static final String FINISHED_IN = "Finished in ";
|
||||
private static final String NO_TRANSFORMERS = "No transformers";
|
||||
|
||||
private final Log logger;
|
||||
private final Log info;
|
||||
private Log info;
|
||||
private Log logger;
|
||||
private NodeService nodeService;
|
||||
private MimetypeService mimetypeService;
|
||||
private ContentTransformerRegistry transformerRegistry;
|
||||
private TransformerConfig transformerConfig;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
private ContentService contentService;
|
||||
private TransformClient transformClient;
|
||||
private Repository repositoryHelper;
|
||||
private TransactionService transactionService;
|
||||
private RenditionDefinitionRegistry2Impl renditionDefinitionRegistry2;
|
||||
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
private enum Call
|
||||
{
|
||||
AVAILABLE,
|
||||
@@ -101,8 +121,6 @@ public class TransformerDebug
|
||||
AVAILABLE_AND_TRANSFORM
|
||||
};
|
||||
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
private static class ThreadInfo
|
||||
{
|
||||
private static final ThreadLocal<ThreadInfo> threadInfo = new ThreadLocal<ThreadInfo>()
|
||||
@@ -153,8 +171,6 @@ public class TransformerDebug
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
private static class Frame
|
||||
{
|
||||
private static final AtomicInteger uniqueId = new AtomicInteger(0);
|
||||
@@ -163,7 +179,8 @@ public class TransformerDebug
|
||||
private final String fromUrl;
|
||||
private final String sourceMimetype;
|
||||
private final String targetMimetype;
|
||||
private final TransformationOptions options;
|
||||
private final NodeRef sourceNodeRef;
|
||||
private final String renditionName;
|
||||
private final boolean origDebugOutput;
|
||||
private long start;
|
||||
|
||||
@@ -176,7 +193,7 @@ public class TransformerDebug
|
||||
private String transformerName;
|
||||
|
||||
private Frame(Frame parent, String transformerName, String fromUrl, String sourceMimetype, String targetMimetype,
|
||||
long sourceSize, TransformationOptions options, Call pushCall, boolean origDebugOutput)
|
||||
long sourceSize, String renditionName, NodeRef sourceNodeRef, Call pushCall, boolean origDebugOutput)
|
||||
{
|
||||
this.id = -1;
|
||||
this.parent = parent;
|
||||
@@ -185,7 +202,8 @@ public class TransformerDebug
|
||||
this.sourceMimetype = sourceMimetype;
|
||||
this.targetMimetype = targetMimetype;
|
||||
this.sourceSize = sourceSize;
|
||||
this.options = options;
|
||||
this.renditionName = renditionName;
|
||||
this.sourceNodeRef = sourceNodeRef;
|
||||
this.callType = pushCall;
|
||||
this.origDebugOutput = origDebugOutput;
|
||||
start = System.currentTimeMillis();
|
||||
@@ -232,7 +250,6 @@ public class TransformerDebug
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
private class UnavailableTransformer implements Comparable<UnavailableTransformer>
|
||||
{
|
||||
private final String name;
|
||||
@@ -283,26 +300,49 @@ public class TransformerDebug
|
||||
}
|
||||
}
|
||||
|
||||
private final NodeService nodeService;
|
||||
private final MimetypeService mimetypeService;
|
||||
private final ContentTransformerRegistry transformerRegistry;
|
||||
private final TransformerConfig transformerConfig;
|
||||
private ContentService contentService;
|
||||
public void setTransformerLog(Log transformerLog)
|
||||
{
|
||||
info = new LogTee(LogFactory.getLog(TransformerLog.class), transformerLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public TransformerDebug(NodeService nodeService, MimetypeService mimetypeService,
|
||||
ContentTransformerRegistry transformerRegistry, TransformerConfig transformerConfig,
|
||||
Log transformerLog, Log transformerDebugLog)
|
||||
public void setTransformerDebugLog(Log transformerDebugLog)
|
||||
{
|
||||
logger = new LogTee(LogFactory.getLog(TransformerDebug.class), transformerDebugLog);
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
this.mimetypeService = mimetypeService;
|
||||
this.transformerRegistry = transformerRegistry;
|
||||
this.transformerConfig = transformerConfig;
|
||||
}
|
||||
|
||||
logger = new LogTee(LogFactory.getLog(TransformerDebug.class), transformerDebugLog);
|
||||
info = new LogTee(LogFactory.getLog(TransformerLog.class), transformerLog);
|
||||
public void setMimetypeService(MimetypeService mimetypeService)
|
||||
{
|
||||
this.mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
public void setTransformerRegistry(ContentTransformerRegistry transformerRegistry)
|
||||
{
|
||||
this.transformerRegistry = transformerRegistry;
|
||||
}
|
||||
|
||||
public void setTransformerConfig(TransformerConfig transformerConfig)
|
||||
{
|
||||
this.transformerConfig = transformerConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
private ContentService getContentService()
|
||||
{
|
||||
if (contentService == null)
|
||||
{
|
||||
contentService = (ContentService) applicationContext.getBean("contentService");
|
||||
}
|
||||
return contentService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
@@ -310,37 +350,135 @@ public class TransformerDebug
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called prior to working out what transformers are available.
|
||||
*/
|
||||
private TransformClient getTransformClient()
|
||||
{
|
||||
if (transformClient == null)
|
||||
{
|
||||
transformClient = (TransformClient) applicationContext.getBean("transformClient");
|
||||
}
|
||||
return transformClient;
|
||||
}
|
||||
|
||||
public void setTransformClient(TransformClient transformClient)
|
||||
{
|
||||
this.transformClient = transformClient;
|
||||
}
|
||||
|
||||
public Repository getRepositoryHelper()
|
||||
{
|
||||
if (repositoryHelper == null)
|
||||
{
|
||||
repositoryHelper = (Repository) applicationContext.getBean("repositoryHelper");
|
||||
}
|
||||
return repositoryHelper;
|
||||
}
|
||||
|
||||
public void setRepositoryHelper(Repository repositoryHelper)
|
||||
{
|
||||
this.repositoryHelper = repositoryHelper;
|
||||
}
|
||||
|
||||
public TransactionService getTransactionService()
|
||||
{
|
||||
if (transactionService == null)
|
||||
{
|
||||
transactionService = (TransactionService) applicationContext.getBean("transactionService");
|
||||
}
|
||||
return transactionService;
|
||||
}
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public RenditionDefinitionRegistry2Impl getRenditionDefinitionRegistry2Impl()
|
||||
{
|
||||
if (renditionDefinitionRegistry2 == null)
|
||||
{
|
||||
renditionDefinitionRegistry2 = (RenditionDefinitionRegistry2Impl) applicationContext.getBean("renditionDefinitionRegistry2");
|
||||
}
|
||||
return renditionDefinitionRegistry2;
|
||||
}
|
||||
|
||||
public void setRenditionDefinitionRegistry2(RenditionDefinitionRegistry2Impl renditionDefinitionRegistry2)
|
||||
{
|
||||
this.renditionDefinitionRegistry2 = renditionDefinitionRegistry2;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "transformerLog", info);
|
||||
PropertyCheck.mandatory(this, "transformerDebugLog", logger);
|
||||
PropertyCheck.mandatory(this, "nodeService", nodeService);
|
||||
PropertyCheck.mandatory(this, "mimetypeService", mimetypeService);
|
||||
PropertyCheck.mandatory(this, "transformerRegistry", transformerRegistry);
|
||||
PropertyCheck.mandatory(this, "transformerConfig", transformerConfig);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void pushAvailable(String fromUrl, String sourceMimetype, String targetMimetype,
|
||||
TransformationOptions options)
|
||||
{
|
||||
String renditionName = options == null ? null : options.getUse();
|
||||
NodeRef sourceNodeRef = options == null ? null : options.getSourceNodeRef();
|
||||
pushAvailable(fromUrl, sourceMimetype, targetMimetype, renditionName, sourceNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called prior to working out what transformers are available.
|
||||
*/
|
||||
@Deprecated
|
||||
public void pushAvailable(String fromUrl, String sourceMimetype, String targetMimetype,
|
||||
String renditionName, NodeRef sourceNodeRef)
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
push(null, fromUrl, sourceMimetype, targetMimetype, -1, options, Call.AVAILABLE);
|
||||
push(null, fromUrl, sourceMimetype, targetMimetype, -1, renditionName,
|
||||
sourceNodeRef, Call.AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a transformer has been ignored because of a blacklist entry.
|
||||
*/
|
||||
@Deprecated
|
||||
public void blacklistTransform(ContentTransformer transformer, String sourceMimetype,
|
||||
String targetMimetype, TransformationOptions options)
|
||||
{
|
||||
log("Blacklist "+getName(transformer)+" "+getMimetypeExt(sourceMimetype)+getMimetypeExt(targetMimetype));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void pushTransform(ContentTransformer transformer, String fromUrl, String sourceMimetype,
|
||||
String targetMimetype, long sourceSize, TransformationOptions options)
|
||||
{
|
||||
String renditionName = options == null ? null : options.getUse();
|
||||
NodeRef sourceNodeRef = options == null ? null : options.getSourceNodeRef();
|
||||
pushTransform(transformer, fromUrl, sourceMimetype, targetMimetype, sourceSize, renditionName, sourceNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called prior to performing a transform.
|
||||
*/
|
||||
@Deprecated
|
||||
public void pushTransform(ContentTransformer transformer, String fromUrl, String sourceMimetype,
|
||||
String targetMimetype, long sourceSize, TransformationOptions options)
|
||||
String targetMimetype, long sourceSize, String renditionName, NodeRef sourceNodeRef)
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
push(getName(transformer), fromUrl, sourceMimetype, targetMimetype, sourceSize,
|
||||
options, Call.TRANSFORM);
|
||||
renditionName, sourceNodeRef, Call.TRANSFORM);
|
||||
}
|
||||
}
|
||||
|
||||
public void pushTransform(String transformerName, String fromUrl, String sourceMimetype,
|
||||
String targetMimetype, long sourceSize, String renditionName, NodeRef sourceNodeRef)
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
push(transformerName, fromUrl, sourceMimetype, targetMimetype, sourceSize,
|
||||
renditionName, sourceNodeRef, Call.TRANSFORM);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,13 +491,14 @@ public class TransformerDebug
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
push(null, null, null, null, -1, null, Call.AVAILABLE);
|
||||
push(null, null, null, null, -1, null, null, Call.AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called prior to calling a nested isTransformable.
|
||||
*/
|
||||
@Deprecated
|
||||
public void pushIsTransformableSize(ContentTransformer transformer)
|
||||
{
|
||||
if (isEnabled())
|
||||
@@ -369,7 +508,7 @@ public class TransformerDebug
|
||||
}
|
||||
|
||||
private void push(String transformerName, String fromUrl, String sourceMimetype, String targetMimetype,
|
||||
long sourceSize, TransformationOptions options, Call callType)
|
||||
long sourceSize, String renditionName, NodeRef sourceNodeRef, Call callType)
|
||||
{
|
||||
Deque<Frame> ourStack = ThreadInfo.getStack();
|
||||
Frame frame = ourStack.peek();
|
||||
@@ -383,13 +522,14 @@ public class TransformerDebug
|
||||
|
||||
// Create a new frame. Logging level is set to trace if the file size is 0
|
||||
boolean origDebugOutput = ThreadInfo.setDebugOutput(ThreadInfo.getDebugOutput() && sourceSize != 0);
|
||||
frame = new Frame(frame, transformerName, fromUrl, sourceMimetype, targetMimetype, sourceSize, options, callType, origDebugOutput);
|
||||
frame = new Frame(frame, transformerName, fromUrl, sourceMimetype, targetMimetype, sourceSize, renditionName,
|
||||
sourceNodeRef, callType, origDebugOutput);
|
||||
ourStack.push(frame);
|
||||
|
||||
if (callType == Call.TRANSFORM)
|
||||
{
|
||||
// Log the basic info about this transformation
|
||||
logBasicDetails(frame, sourceSize, options.getUse(), transformerName, (ourStack.size() == 1));
|
||||
logBasicDetails(frame, sourceSize, renditionName, transformerName, (ourStack.size() == 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,6 +537,7 @@ public class TransformerDebug
|
||||
* Called to identify a transformer that cannot be used during working out
|
||||
* available transformers.
|
||||
*/
|
||||
@Deprecated
|
||||
public void unavailableTransformer(ContentTransformer transformer, String sourceMimetype, String targetMimetype, long maxSourceSizeKBytes)
|
||||
{
|
||||
if (isEnabled())
|
||||
@@ -421,11 +562,21 @@ public class TransformerDebug
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void availableTransformers(List<ContentTransformer> transformers, long sourceSize,
|
||||
TransformationOptions options, String calledFrom)
|
||||
{
|
||||
String renditionName = options == null ? null : options.getUse();
|
||||
NodeRef sourceNodeRef = options == null ? null : options.getSourceNodeRef();
|
||||
availableTransformers(transformers, sourceSize, renditionName, sourceNodeRef, calledFrom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called once all available transformers have been identified.
|
||||
*/
|
||||
@Deprecated
|
||||
public void availableTransformers(List<ContentTransformer> transformers, long sourceSize,
|
||||
TransformationOptions options, String calledFrom)
|
||||
String renditionName, NodeRef sourceNodeRef, String calledFrom)
|
||||
{
|
||||
if (isEnabled())
|
||||
{
|
||||
@@ -447,7 +598,7 @@ public class TransformerDebug
|
||||
frame.setSourceSize(sourceSize);
|
||||
|
||||
// Log the basic info about this transformation
|
||||
logBasicDetails(frame, sourceSize, options.getUse(),
|
||||
logBasicDetails(frame, sourceSize, renditionName,
|
||||
calledFrom + ((transformers.size() == 0) ? " NO transformers" : ""), firstLevel);
|
||||
|
||||
// Report available and unavailable transformers
|
||||
@@ -457,7 +608,11 @@ public class TransformerDebug
|
||||
{
|
||||
String name = getName(trans);
|
||||
int padName = longestNameLength - name.length() + 1;
|
||||
long maxSourceSizeKBytes = trans.getMaxSourceSizeKBytes(frame.sourceMimetype, frame.targetMimetype, frame.options);
|
||||
// TODO replace with call to RenditionService2 or leave as a deprecated method using ContentService.
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setUse(frame.renditionName);
|
||||
options.setSourceNodeRef(frame.sourceNodeRef);
|
||||
long maxSourceSizeKBytes = trans.getMaxSourceSizeKBytes(frame.sourceMimetype, frame.targetMimetype, options);
|
||||
String size = maxSourceSizeKBytes > 0 ? "< "+fileSize(maxSourceSizeKBytes*1024) : "";
|
||||
int padSize = 10 - size.length();
|
||||
String priority = gePriority(trans, frame.sourceMimetype, frame.targetMimetype);
|
||||
@@ -491,11 +646,13 @@ public class TransformerDebug
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void inactiveTransformer(ContentTransformer transformer)
|
||||
{
|
||||
log(getName(transformer)+' '+ms(transformer.getTransformationTime(null, null))+" INACTIVE");
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void activeTransformer(int mimetypePairCount, ContentTransformer transformer, String sourceMimetype,
|
||||
String targetMimetype, long maxSourceSizeKBytes, boolean firstMimetypePair)
|
||||
{
|
||||
@@ -511,6 +668,7 @@ public class TransformerDebug
|
||||
(maxSourceSizeKBytes == 0 ? " disabled" : ""));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void activeTransformer(String sourceMimetype, String targetMimetype,
|
||||
int transformerCount, ContentTransformer transformer, long maxSourceSizeKBytes,
|
||||
boolean firstTransformer)
|
||||
@@ -548,7 +706,7 @@ public class TransformerDebug
|
||||
return longestNameLength;
|
||||
}
|
||||
|
||||
private void logBasicDetails(Frame frame, long sourceSize, String use, String message, boolean firstLevel)
|
||||
private void logBasicDetails(Frame frame, long sourceSize, String renditionName, String message, boolean firstLevel)
|
||||
{
|
||||
// Log the source URL, but there is no point if the parent has logged it
|
||||
if (frame.fromUrl != null && (firstLevel || frame.id != 1))
|
||||
@@ -557,14 +715,14 @@ public class TransformerDebug
|
||||
}
|
||||
log(frame.sourceMimetype+' '+frame.targetMimetype, false);
|
||||
|
||||
String fileName = getFileName(frame.options, firstLevel, sourceSize);
|
||||
String fileName = getFileName(frame.sourceNodeRef, firstLevel, sourceSize);
|
||||
log(getMimetypeExt(frame.sourceMimetype)+getMimetypeExt(frame.targetMimetype) +
|
||||
((fileName != null) ? fileName+' ' : "")+
|
||||
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") +
|
||||
(firstLevel && use != null ? "-- "+use+" -- " : "") + message);
|
||||
(firstLevel && renditionName != null ? "-- "+renditionName+" -- " : "") + message);
|
||||
if (firstLevel)
|
||||
{
|
||||
String nodeRef = getNodeRef(frame.options, firstLevel, sourceSize);
|
||||
String nodeRef = getNodeRef(frame.sourceNodeRef, firstLevel, sourceSize);
|
||||
if (!nodeRef.isEmpty())
|
||||
{
|
||||
log(nodeRef);
|
||||
@@ -659,7 +817,7 @@ public class TransformerDebug
|
||||
boolean firstLevel = size == 1;
|
||||
String sourceExt = getMimetypeExt(frame.sourceMimetype);
|
||||
String targetExt = getMimetypeExt(frame.targetMimetype);
|
||||
String fileName = getFileName(frame.options, firstLevel, frame.sourceSize);
|
||||
String fileName = getFileName(frame.sourceNodeRef, firstLevel, frame.sourceSize);
|
||||
long sourceSize = frame.getSourceSize();
|
||||
String transformerName = frame.getTransformerName();
|
||||
String level = null;
|
||||
@@ -893,9 +1051,11 @@ public class TransformerDebug
|
||||
* @param toString indicates that a String value should be returned in addition to any debug.
|
||||
* @param format42 indicates the old 4.1.4 format should be used which did not order the transformers
|
||||
* and only included top level transformers.
|
||||
* @param use to which the transformation will be put (such as "Index", "Preview", null).
|
||||
* @param renditionName to which the transformation will be put (such as "Index", "Preview", null).
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
public String transformationsByTransformer(String transformerName, boolean toString, boolean format42, String use)
|
||||
@Deprecated
|
||||
public String transformationsByTransformer(String transformerName, boolean toString, boolean format42, String renditionName)
|
||||
{
|
||||
// Do not generate this type of debug if already generating other debug to a StringBuilder
|
||||
// (for example a test transform).
|
||||
@@ -915,7 +1075,7 @@ public class TransformerDebug
|
||||
: mimetypeService.getMimetypes();
|
||||
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setUse(use);
|
||||
options.setUse(renditionName);
|
||||
StringBuilder sb = null;
|
||||
try
|
||||
{
|
||||
@@ -977,10 +1137,12 @@ public class TransformerDebug
|
||||
* level transformers.
|
||||
* @param onlyNonDeterministic if true only report transformations where there is more than
|
||||
* one transformer available with the same priority.
|
||||
* @param use to which the transformation will be put (such as "Index", "Preview", null).
|
||||
* @param renditionName to which the transformation will be put (such as "Index", "Preview", null).
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public String transformationsByExtension(String sourceExtension, String targetExtension, boolean toString,
|
||||
boolean format42, boolean onlyNonDeterministic, String use)
|
||||
boolean format42, boolean onlyNonDeterministic, String renditionName)
|
||||
{
|
||||
// Do not generate this type of debug if already generating other debug to a StringBuilder
|
||||
// (for example a test transform).
|
||||
@@ -1000,7 +1162,7 @@ public class TransformerDebug
|
||||
: mimetypeService.getMimetypes();
|
||||
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setUse(use);
|
||||
options.setUse(renditionName);
|
||||
StringBuilder sb = null;
|
||||
try
|
||||
{
|
||||
@@ -1248,24 +1410,30 @@ public class TransformerDebug
|
||||
return !transformerRegistry.getTransformers().contains(transformer);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getFileName(TransformationOptions options, boolean firstLevel, long sourceSize)
|
||||
{
|
||||
return getFileNameOrNodeRef(options, firstLevel, sourceSize, true);
|
||||
NodeRef sourceNodeRef = options == null ? null : options.getSourceNodeRef();
|
||||
return getFileName(sourceNodeRef, firstLevel, sourceSize);
|
||||
}
|
||||
|
||||
private String getNodeRef(TransformationOptions options, boolean firstLevel, long sourceSize)
|
||||
public String getFileName(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize)
|
||||
{
|
||||
return getFileNameOrNodeRef(options, firstLevel, sourceSize, false);
|
||||
return getFileNameOrNodeRef(sourceNodeRef, firstLevel, sourceSize, true);
|
||||
}
|
||||
|
||||
private String getFileNameOrNodeRef(TransformationOptions options, boolean firstLevel, long sourceSize, boolean getName)
|
||||
private String getNodeRef(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize)
|
||||
{
|
||||
return getFileNameOrNodeRef(sourceNodeRef, firstLevel, sourceSize, false);
|
||||
}
|
||||
|
||||
private String getFileNameOrNodeRef(NodeRef sourceNodeRef, boolean firstLevel, long sourceSize, boolean getName)
|
||||
{
|
||||
String result = getName ? null : "";
|
||||
if (options != null)
|
||||
if (sourceNodeRef != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
NodeRef sourceNodeRef = options.getSourceNodeRef();
|
||||
result = getName
|
||||
? (String)nodeService.getProperty(sourceNodeRef, ContentModel.PROP_NAME)
|
||||
: sourceNodeRef.toString()+" ";
|
||||
@@ -1368,7 +1536,9 @@ public class TransformerDebug
|
||||
* @param transformerName to restrict the collection to one entry
|
||||
* @return a new Collection of sorted transformers
|
||||
* @throws IllegalArgumentException if transformerName is not found.
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public Collection<ContentTransformer> sortTransformersByName(String transformerName)
|
||||
{
|
||||
Collection<ContentTransformer> transformers = (transformerName != null)
|
||||
@@ -1389,13 +1559,14 @@ public class TransformerDebug
|
||||
* Debugs a request to the Transform Service
|
||||
*/
|
||||
public int debugTransformServiceRequest(String sourceMimetype, long sourceSize, NodeRef sourceNodeRef,
|
||||
int contentHashcode, String fileName, String targetMimetype, String use)
|
||||
int contentHashcode, String fileName, String targetMimetype,
|
||||
String renditionName)
|
||||
{
|
||||
pushMisc();
|
||||
debug(getMimetypeExt(sourceMimetype)+getMimetypeExt(targetMimetype) +
|
||||
((fileName != null) ? fileName+' ' : "")+
|
||||
((sourceSize >= 0) ? fileSize(sourceSize)+' ' : "") +
|
||||
(use != null ? "-- "+use+" -- " : "") + " RenditionService2");
|
||||
(renditionName != null ? "-- "+renditionName+" -- " : "") + " RenditionService2");
|
||||
debug(sourceNodeRef.toString() + ' ' +contentHashcode);
|
||||
debug(" **a) [01] TransformService");
|
||||
return pop(Call.AVAILABLE, true, false);
|
||||
@@ -1426,35 +1597,19 @@ public class TransformerDebug
|
||||
pop(Call.AVAILABLE, suppressFinish, true);
|
||||
}
|
||||
|
||||
public String testTransform(String sourceExtension, String targetExtension, String use)
|
||||
public String testTransform(String sourceExtension, String targetExtension, String renditionName)
|
||||
{
|
||||
return new TestTransform()
|
||||
{
|
||||
protected void transform(ContentReader reader, ContentWriter writer, TransformationOptions options)
|
||||
{
|
||||
contentService.transform(reader, writer, options);
|
||||
}
|
||||
}.run(sourceExtension, targetExtension, use);
|
||||
return new TestTransform().run(sourceExtension, targetExtension, renditionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public String testTransform(final String transformerName, String sourceExtension,
|
||||
String targetExtension, String use)
|
||||
String targetExtension, String renditionName)
|
||||
{
|
||||
final ContentTransformer transformer = transformerRegistry.getTransformer(transformerName);
|
||||
return new TestTransform()
|
||||
{
|
||||
protected String isTransformable(String sourceMimetype, long sourceSize, String targetMimetype, TransformationOptions options)
|
||||
{
|
||||
return transformer.isTransformable(sourceMimetype, sourceSize, targetMimetype, options)
|
||||
? null
|
||||
: transformerName+" does not support this transformation.";
|
||||
}
|
||||
|
||||
protected void transform(ContentReader reader, ContentWriter writer, TransformationOptions options)
|
||||
{
|
||||
transformer.transform(reader, writer, options);
|
||||
}
|
||||
}.run(sourceExtension, targetExtension, use);
|
||||
return "The testTransform operation for a specific transformer is no longer supported.";
|
||||
}
|
||||
|
||||
public String[] getTestFileExtensionsAndMimetypes()
|
||||
@@ -1499,68 +1654,58 @@ public class TransformerDebug
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
private abstract class TestTransform
|
||||
private class TestTransform
|
||||
{
|
||||
String run(String sourceExtension, String targetExtension, String use)
|
||||
protected LinkedList<NodeRef> nodesToDeleteAfterTest = new LinkedList<NodeRef>();
|
||||
|
||||
String run(String sourceExtension, String targetExtension, String renditionName)
|
||||
{
|
||||
String debug;
|
||||
RenditionDefinitionRegistry2Impl renditionDefinitionRegistry2 = getRenditionDefinitionRegistry2Impl();
|
||||
|
||||
String targetMimetype = getMimetype(targetExtension, false);
|
||||
String sourceMimetype = getMimetype(sourceExtension, true);
|
||||
URL sourceURL = loadQuickTestFile(sourceExtension);
|
||||
if (sourceURL == null)
|
||||
{
|
||||
throw new IllegalArgumentException("There is no test file with a "+sourceExtension+" extension.");
|
||||
}
|
||||
|
||||
// This URL may point to a file on the filesystem or to an entry in a jar.
|
||||
// To use the transform method below, we need the content to be accessible from a ContentReader.
|
||||
// This is possible for a File but not a (non-file) URL.
|
||||
//
|
||||
// Therefore, we'll always copy the URL content to a temporary local file.
|
||||
final File sourceFile = TempFileProvider.createTempFile(TransformerDebug.class.getSimpleName() + "-tmp-", "");
|
||||
|
||||
try { FileUtils.copyURLToFile(sourceURL, sourceFile); }
|
||||
catch (IOException shouldNeverHappen)
|
||||
{
|
||||
// The sourceURL should always be readable as we're reading data that Alfresco is distributing.
|
||||
// But just in case...
|
||||
throw new IllegalArgumentException("Cannot read content of test file with a " +
|
||||
sourceExtension + " extension.", shouldNeverHappen);
|
||||
}
|
||||
|
||||
ContentReader reader = new FileContentReader(sourceFile);
|
||||
reader.setMimetype(sourceMimetype);
|
||||
File tempFile = TempFileProvider.createTempFile(
|
||||
"TestTransform_" + sourceExtension + "_", "." + targetExtension);
|
||||
ContentWriter writer = new FileContentWriter(tempFile);
|
||||
writer.setMimetype(targetMimetype);
|
||||
|
||||
long sourceSize = reader.getSize();
|
||||
TransformationOptions options = new TransformationOptions();
|
||||
options.setUse(use);
|
||||
|
||||
debug = isTransformable(sourceMimetype, sourceSize, targetMimetype, options);
|
||||
if (debug == null)
|
||||
{
|
||||
String testRenditionName = "testTransform"+System.currentTimeMillis();
|
||||
NodeRef sourceNodeRef = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try
|
||||
{
|
||||
setStringBuilder(sb);
|
||||
transform(reader, writer, options);
|
||||
}
|
||||
catch (AlfrescoRuntimeException e)
|
||||
RenditionDefinition2 renditionDefinition = new RenditionDefinition2Impl(testRenditionName, targetMimetype,
|
||||
Collections.emptyMap(), renditionDefinitionRegistry2);
|
||||
|
||||
sourceNodeRef = createSourceNode(sourceExtension, sourceMimetype);
|
||||
ContentData contentData = (ContentData) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_CONTENT);
|
||||
if (contentData != null)
|
||||
{
|
||||
sb.append(e.getMessage());
|
||||
String contentUrl = contentData.getContentUrl();
|
||||
if (contentUrl != null)
|
||||
{
|
||||
long size = contentData.getSize();
|
||||
int sourceContentHashCode = SOURCE_HAS_NO_CONTENT;
|
||||
String contentString = contentData.getContentUrl()+contentData.getMimetype();
|
||||
if (contentString != null)
|
||||
{
|
||||
sourceContentHashCode = contentString.hashCode();
|
||||
}
|
||||
|
||||
TransformClient transformClient = getTransformClient();
|
||||
transformClient.checkSupported(sourceNodeRef, renditionDefinition, sourceMimetype, size, contentUrl);
|
||||
transformClient.transform(sourceNodeRef, renditionDefinition, "testTransform", sourceContentHashCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
setStringBuilder(null);
|
||||
renditionDefinitionRegistry2.unregister(testRenditionName);
|
||||
deleteSourceNode(sourceNodeRef);
|
||||
}
|
||||
debug = sb.toString();
|
||||
}
|
||||
return debug;
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String getMimetype(String extension, boolean isSource)
|
||||
@@ -1581,11 +1726,57 @@ public class TransformerDebug
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
protected String isTransformable(String sourceMimetype, long sourceSize, String targetMimetype, TransformationOptions options)
|
||||
public NodeRef createSourceNode(String extension, String sourceMimetype)
|
||||
{
|
||||
return null;
|
||||
// Create a content node which will serve as test data for our transformations.
|
||||
RetryingTransactionHelper.RetryingTransactionCallback<NodeRef> makeNodeCallback = new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>()
|
||||
{
|
||||
public NodeRef execute() throws Throwable
|
||||
{
|
||||
// Create a source node loaded with a quick file.
|
||||
URL url = loadQuickTestFile(extension);
|
||||
URI uri = url.toURI();
|
||||
File sourceFile = new File(uri);
|
||||
|
||||
final NodeRef companyHome = getRepositoryHelper().getCompanyHome();
|
||||
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||
String localName = "TestTransform." + extension;
|
||||
props.put(ContentModel.PROP_NAME, localName);
|
||||
NodeRef node = nodeService.createNode(
|
||||
companyHome,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, localName),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
props).getChildRef();
|
||||
|
||||
ContentWriter writer = getContentService().getWriter(node, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(sourceMimetype);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.putContent(sourceFile);
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
NodeRef contentNodeRef = getTransactionService().getRetryingTransactionHelper().doInTransaction(makeNodeCallback);
|
||||
this.nodesToDeleteAfterTest.add(contentNodeRef);
|
||||
return contentNodeRef;
|
||||
}
|
||||
|
||||
protected abstract void transform(ContentReader reader, ContentWriter writer, TransformationOptions options);
|
||||
public void deleteSourceNode(NodeRef sourceNodeRef)
|
||||
{
|
||||
if (sourceNodeRef != null)
|
||||
{
|
||||
getTransactionService().getRetryingTransactionHelper().doInTransaction(
|
||||
(RetryingTransactionHelper.RetryingTransactionCallback<Void>) () ->
|
||||
{
|
||||
if (nodeService.exists(sourceNodeRef))
|
||||
{
|
||||
nodeService.deleteNode(sourceNodeRef);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -30,16 +30,12 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
|
||||
/**
|
||||
* Exception indicates that a transformer is unable to transform a requested
|
||||
* transformation. Normally the transformer is a component of a complex (compound) transformer
|
||||
* and has been asked to transform a file that is too large (see transformation limits) as the
|
||||
* transformation. Normally the transformer is a component of a pipeline transformer
|
||||
* and has been asked to transform a file that is too large as the
|
||||
* size of the intermediate file is unknown at the start.
|
||||
*
|
||||
* @author Alan Davis
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
@AlfrescoPublicApi
|
||||
public class UnsupportedTransformationException extends AlfrescoRuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 9039331287661301086L;
|
||||
|
@@ -81,6 +81,8 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
/** the system command executer */
|
||||
private RuntimeExec executer;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
/** the check command executer */
|
||||
private RuntimeExec checkCommand;
|
||||
|
||||
@@ -116,6 +118,11 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
this.executer = executer;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the command that must be executed in order to retrieve version information from the converting executable
|
||||
* and thus test that the executable itself is present.
|
||||
@@ -145,6 +152,8 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
if (!remoteTransformerClientConfigured() && executer == null)
|
||||
{
|
||||
@@ -180,13 +189,13 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
{
|
||||
setAvailable(true);
|
||||
versionString = result.getSecond().trim();
|
||||
logger.info("Using remote ImageMagick: "+versionString);
|
||||
logger.info("Using legacy local ImageMagick: " + versionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAvailable(false);
|
||||
versionString = "unknown";
|
||||
String message = "Remote ImageMagick is not available for transformations. " + result.getSecond();
|
||||
String message = "Leacy remote ImageMagick is not available for transformations. " + result.getSecond();
|
||||
if (isAvailable == null)
|
||||
{
|
||||
logger.debug(message);
|
||||
@@ -198,6 +207,7 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the image content from the source file to the target file
|
||||
|
@@ -77,6 +77,8 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
|
||||
/** the system command executer */
|
||||
private RuntimeExec executer;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
/** the check command executer */
|
||||
private RuntimeExec checkCommand;
|
||||
|
||||
@@ -110,6 +112,11 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
|
||||
this.executer = executer;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optional remote transformer client which will be used in preference to a local command if available.
|
||||
*
|
||||
@@ -140,6 +147,8 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
PropertyCheck.mandatory(this, "executer", executer);
|
||||
PropertyCheck.mandatory(this, "isAvailable", checkCommand);
|
||||
@@ -154,12 +163,12 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
|
||||
{
|
||||
versionString = result.getSecond();
|
||||
setAvailable(true);
|
||||
logger.info("Using remote Alfresco PDF Renderer: "+versionString);
|
||||
logger.info("Using legacy local Alfresco PDF Renderer: " + versionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAvailable(false);
|
||||
String message = "Remote Alfresco PDF Renderer is not available for transformations. " + result.getSecond();
|
||||
String message = "Legacy local Alfresco PDF Renderer is not available for transformations. " + result.getSecond();
|
||||
if (isAvailable == null)
|
||||
{
|
||||
logger.debug(message);
|
||||
@@ -178,6 +187,7 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
|
||||
logger.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns true if the transformer is functioning otherwise false
|
||||
|
@@ -37,6 +37,7 @@ import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
@@ -52,9 +53,9 @@ import java.util.concurrent.Executors;
|
||||
* @author adavis
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyLocalTransformClient extends AbstractTransformClient implements TransformClient
|
||||
public class LegacyTransformClient implements TransformClient, InitializingBean
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(LegacyLocalTransformClient.class);
|
||||
private static Log logger = LogFactory.getLog(LegacyTransformClient.class);
|
||||
|
||||
private TransactionService transactionService;
|
||||
|
||||
@@ -94,7 +95,7 @@ public class LegacyLocalTransformClient extends AbstractTransformClient implemen
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
super.afterPropertiesSet();
|
||||
PropertyCheck.mandatory(this, "transactionService", transactionService);
|
||||
PropertyCheck.mandatory(this, "contentService", contentService);
|
||||
PropertyCheck.mandatory(this, "renditionService2", renditionService2);
|
||||
PropertyCheck.mandatory(this, "converter", converter);
|
||||
@@ -144,7 +145,7 @@ public class LegacyLocalTransformClient extends AbstractTransformClient implemen
|
||||
TransformationOptions transformationOptions = converter.getTransformationOptions(renditionName, options);
|
||||
transformationOptions.setSourceNodeRef(sourceNodeRef);
|
||||
|
||||
ContentReader reader = LegacyLocalTransformClient.this.contentService.getReader(sourceNodeRef, ContentModel.PROP_CONTENT);
|
||||
ContentReader reader = LegacyTransformClient.this.contentService.getReader(sourceNodeRef, ContentModel.PROP_CONTENT);
|
||||
if (null == reader || !reader.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("The supplied sourceNodeRef "+sourceNodeRef+" has no content.");
|
@@ -41,7 +41,7 @@ import java.util.Map;
|
||||
* @author adavis
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyLocalTransformServiceRegistry extends AbstractTransformServiceRegistry implements InitializingBean
|
||||
public class LegacyTransformServiceRegistry extends AbstractTransformServiceRegistry implements InitializingBean
|
||||
{
|
||||
private ContentService contentService;
|
||||
private TransformationOptionsConverter converter;
|
||||
@@ -85,15 +85,22 @@ public class LegacyLocalTransformServiceRegistry extends AbstractTransformServic
|
||||
if (firstTime)
|
||||
{
|
||||
firstTime = false;
|
||||
transformerDebug.debug("Local legacy transformers are " + (enabled ? "enabled" : "disabled"));
|
||||
transformerDebug.debug("Legacy transforms are " + (enabled ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
long maxSize = 0;
|
||||
if (enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
TransformationOptions transformationOptions = converter.getTransformationOptions(renditionName, options);
|
||||
maxSize = contentService.getMaxSourceSizeBytes(sourceMimetype, targetMimetype, transformationOptions);
|
||||
}
|
||||
catch (IllegalArgumentException ignore)
|
||||
{
|
||||
// Typically if the mimetype is invalid.
|
||||
}
|
||||
}
|
||||
return maxSize;
|
||||
}
|
||||
}
|
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.transform.LocalTransformer;
|
||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Requests rendition transforms take place using transforms available on the local machine (based on
|
||||
* {@link LocalTransformer}. The transform and consumption of the
|
||||
* resulting content is linked into a single operation that will take place at some point in the future on the local
|
||||
* machine.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public class LocalTransformClient implements TransformClient, InitializingBean
|
||||
{
|
||||
private static Log logger = LogFactory.getLog(LocalTransformClient.class);
|
||||
|
||||
private LocalTransformServiceRegistry localTransformServiceRegistry;
|
||||
private TransactionService transactionService;
|
||||
private ContentService contentService;
|
||||
private RenditionService2Impl renditionService2;
|
||||
|
||||
private ExecutorService executorService;
|
||||
|
||||
public void setLocalTransformServiceRegistry(LocalTransformServiceRegistry localTransformServiceRegistry)
|
||||
{
|
||||
this.localTransformServiceRegistry = localTransformServiceRegistry;
|
||||
}
|
||||
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
public void setRenditionService2(RenditionService2Impl renditionService2)
|
||||
{
|
||||
this.renditionService2 = renditionService2;
|
||||
}
|
||||
|
||||
public void setExecutorService(ExecutorService executorService)
|
||||
{
|
||||
this.executorService = executorService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "localTransformServiceRegistry", localTransformServiceRegistry);
|
||||
PropertyCheck.mandatory(this, "transactionService", transactionService);
|
||||
PropertyCheck.mandatory(this, "contentService", contentService);
|
||||
PropertyCheck.mandatory(this, "renditionService2", renditionService2);
|
||||
if (executorService == null)
|
||||
{
|
||||
executorService = Executors.newCachedThreadPool();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSupported(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String sourceMimetype, long size, String contentUrl)
|
||||
{
|
||||
String targetMimetype = renditionDefinition.getTargetMimetype();
|
||||
String renditionName = renditionDefinition.getRenditionName();
|
||||
|
||||
Map<String, String> options = renditionDefinition.getTransformOptions();
|
||||
if (!localTransformServiceRegistry.isSupported(sourceMimetype, size, targetMimetype, options, renditionName))
|
||||
{
|
||||
String message = "Unsupported rendition " + renditionName + " from " + sourceMimetype + " size: " + size;
|
||||
logger.debug(message);
|
||||
throw new UnsupportedOperationException(message);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Rendition of " + renditionName + " from " + sourceMimetype + " will use local transforms");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentHashCode)
|
||||
{
|
||||
executorService.submit(() ->
|
||||
{
|
||||
AuthenticationUtil.runAs((AuthenticationUtil.RunAsWork<Void>) () ->
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
String targetMimetype = renditionDefinition.getTargetMimetype();
|
||||
String renditionName = renditionDefinition.getRenditionName();
|
||||
Map<String, String> options = renditionDefinition.getTransformOptions();
|
||||
|
||||
ContentReader reader = contentService.getReader(sourceNodeRef, ContentModel.PROP_CONTENT);
|
||||
if (null == reader || !reader.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("The supplied sourceNodeRef "+sourceNodeRef+" has no content.");
|
||||
}
|
||||
|
||||
ContentWriter writer = contentService.getTempWriter();
|
||||
writer.setMimetype(targetMimetype);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Local transform requested for rendition of " + renditionDefinition.getRenditionName());
|
||||
}
|
||||
localTransformServiceRegistry.transform(reader, writer, options, renditionName, sourceNodeRef);
|
||||
|
||||
InputStream inputStream = writer.getReader().getContentInputStream();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Local transform to be consumed for rendition of " + renditionDefinition.getRenditionName());
|
||||
}
|
||||
renditionService2.consume(sourceNodeRef, inputStream, renditionDefinition, sourceContentHashCode);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Local transform consumed for rendition of " + renditionDefinition.getRenditionName());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
String renditionName = renditionDefinition.getRenditionName();
|
||||
logger.error("Rendition of "+renditionName+" failed", e);
|
||||
}
|
||||
renditionService2.failure(sourceNodeRef, renditionDefinition, sourceContentHashCode);
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}), user);
|
||||
});
|
||||
}
|
||||
}
|
@@ -49,16 +49,18 @@ public class RenditionDefinitionRegistry2Impl implements RenditionDefinitionRegi
|
||||
public void setTransformServiceRegistry(TransformServiceRegistry transformServiceRegistry)
|
||||
{
|
||||
this.transformServiceRegistry = transformServiceRegistry;
|
||||
renditionsFor.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a {@link RenditionDefinition2} by name.
|
||||
* @param renditionName to be returned
|
||||
* @return the {@link RenditionDefinition2} or null if not registered.
|
||||
* @deprecated use {@link #getRenditionDefinition(String)}
|
||||
*/
|
||||
public RenditionDefinition2 getDefinition(String renditionName)
|
||||
{
|
||||
return renditionDefinitions.get(renditionName);
|
||||
return getRenditionDefinition(renditionName);
|
||||
}
|
||||
|
||||
public void register(RenditionDefinition2 renditionDefinition)
|
||||
|
@@ -38,7 +38,7 @@ public class SwitchingTransformClient implements TransformClient
|
||||
{
|
||||
private final TransformClient primary;
|
||||
private final TransformClient secondary;
|
||||
private ThreadLocal<Boolean> usePrimary = new ThreadLocal<>();
|
||||
private ThreadLocal<Boolean> usePrimary = ThreadLocal.withInitial(()->Boolean.FALSE);
|
||||
|
||||
public SwitchingTransformClient(TransformClient primary, TransformClient secondary)
|
||||
{
|
||||
|
@@ -166,6 +166,7 @@ public class ThumbnailRegistry implements ApplicationContextAware, ApplicationLi
|
||||
public void setTransformServiceRegistry(TransformServiceRegistry transformServiceRegistry)
|
||||
{
|
||||
this.transformServiceRegistry = transformServiceRegistry;
|
||||
mimetypeMap.clear();
|
||||
}
|
||||
|
||||
public void setRenditionDefinitionRegistry2(RenditionDefinitionRegistry2 renditionDefinitionRegistry2)
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -26,10 +26,21 @@
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
/**
|
||||
* Helper class to be supplied by the client to map file extensions to mimetypes, so the json description of what
|
||||
* is supported by the Transform Service includes file extensions rather than mmetypes, so is more readable.
|
||||
* Abstract implementation of TransformOption.
|
||||
*/
|
||||
public interface ExtensionMap
|
||||
public abstract class AbstractTransformOption implements TransformOption
|
||||
{
|
||||
String toMimetype(String extension);
|
||||
private boolean required;
|
||||
|
||||
@Override
|
||||
public boolean isRequired()
|
||||
{
|
||||
return required;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequired(boolean required)
|
||||
{
|
||||
this.required = required;
|
||||
}
|
||||
}
|
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
/**
|
||||
* This class recreates the json format used in ACS 6.1 where we just had an array of transformers and each
|
||||
* transformer has a list of transform options. The idea of this code is that it replaces the references with the
|
||||
* actual transform options that have been separated out into their own section.<p>
|
||||
*
|
||||
* The T-Router and T-Engines return the format with the transform option separated into their own section. Pipeline
|
||||
* definitions used by the LocalTransformServiceRegistry may use transform reference options defined in the json
|
||||
* returned by T-Engines. with the actual definitions from the transform options
|
||||
* reference section. It also combines multiple json sources into a single jsonNode structure that can be parsed as
|
||||
* before.
|
||||
*/
|
||||
public class JsonConverter
|
||||
{
|
||||
public static final String NAME = "name";
|
||||
private final Log log;
|
||||
|
||||
private static final String TRANSFORM_OPTIONS = "transformOptions";
|
||||
private static final String GROUP = "group";
|
||||
private static final String TRANSFORMERS = "transformers";
|
||||
|
||||
private Map<String, ArrayNode> allTransformOptions = new HashMap<>();
|
||||
private List<ObjectNode> allTransforms = new ArrayList<>();
|
||||
private ObjectMapper jsonObjectMapper = new ObjectMapper();
|
||||
|
||||
JsonConverter(Log log)
|
||||
{
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
void addJsonSource(String path) throws IOException
|
||||
{
|
||||
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||
if (jarFile.isFile())
|
||||
{
|
||||
JarFile jar = new JarFile(jarFile);
|
||||
Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
|
||||
String prefix = path + "/";
|
||||
List<String> names = new ArrayList<>();
|
||||
while (entries.hasMoreElements())
|
||||
{
|
||||
final String name = entries.nextElement().getName();
|
||||
if (name.startsWith(prefix) && name.length() > prefix.length())
|
||||
{
|
||||
names.add(name);
|
||||
}
|
||||
}
|
||||
Collections.sort(names);
|
||||
for (String name : names)
|
||||
{
|
||||
log.debug("Reading resource "+name);
|
||||
addJsonSource(new InputStreamReader(getResourceAsStream(name)));
|
||||
}
|
||||
|
||||
jar.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
URL url = getClass().getClassLoader().getResource(path);
|
||||
if (url != null)
|
||||
{
|
||||
File root = new File(url.getPath());
|
||||
if (root.isDirectory())
|
||||
{
|
||||
File[] files = root.listFiles();
|
||||
Arrays.sort(files, (file1, file2) -> file1.getName().compareTo(file2.getName()));
|
||||
for (File file: files)
|
||||
{
|
||||
log.debug("Reading dir file "+file.getPath());
|
||||
addJsonSource(new FileReader(file));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Reading file "+root.getPath());
|
||||
addJsonSource(new FileReader(root));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getResourceAsStream(String resource)
|
||||
{
|
||||
final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
|
||||
return in == null ? getClass().getResourceAsStream(resource) : in;
|
||||
}
|
||||
|
||||
private void addJsonSource(Reader reader) throws IOException
|
||||
{
|
||||
JsonNode jsonNode = jsonObjectMapper.readValue(reader, new TypeReference<JsonNode>() {});
|
||||
|
||||
JsonNode transformOptions = jsonNode.get(TRANSFORM_OPTIONS);
|
||||
if (transformOptions != null && transformOptions.isObject())
|
||||
{
|
||||
Iterator<Map.Entry<String, JsonNode>> iterator = transformOptions.fields();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Map.Entry<String, JsonNode> entry = iterator.next();
|
||||
|
||||
JsonNode options = entry.getValue();
|
||||
if (options.isArray())
|
||||
{
|
||||
String optionsName = entry.getKey();
|
||||
allTransformOptions.put(optionsName, (ArrayNode)options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JsonNode transformers = jsonNode.get(TRANSFORMERS);
|
||||
if (transformers != null && transformers.isArray())
|
||||
{
|
||||
for (JsonNode transformer : transformers)
|
||||
{
|
||||
if (transformer.isObject())
|
||||
{
|
||||
allTransforms.add((ObjectNode)transformer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Transformer> getTransformers() throws IOException
|
||||
{
|
||||
List<Transformer> transformers = new ArrayList<>();
|
||||
|
||||
// After all json input has been loaded build the output with the options in place.
|
||||
ArrayNode transformersNode = jsonObjectMapper.createArrayNode();
|
||||
for (ObjectNode transform : allTransforms)
|
||||
{
|
||||
try
|
||||
{
|
||||
ArrayNode transformOptions = (ArrayNode) transform.get(TRANSFORM_OPTIONS);
|
||||
if (transformOptions != null)
|
||||
{
|
||||
|
||||
ArrayNode options;
|
||||
int size = transformOptions.size();
|
||||
if (size == 1)
|
||||
{
|
||||
// If there is a single transform option reference, we can just use it.
|
||||
int i = 0;
|
||||
options = getTransformOptions(transformOptions, i, transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there are many transform option references (typically in a pipeline), then each element
|
||||
// has a group for each set of transform options.
|
||||
options = jsonObjectMapper.createArrayNode();
|
||||
for (int i = size - 1; i >= 0; i--)
|
||||
{
|
||||
JsonNode referencedTransformOptions = getTransformOptions(transformOptions, i, transform);
|
||||
if (referencedTransformOptions != null)
|
||||
{
|
||||
ObjectNode element = jsonObjectMapper.createObjectNode();
|
||||
options.add(element);
|
||||
|
||||
ObjectNode group = jsonObjectMapper.createObjectNode();
|
||||
group.set(TRANSFORM_OPTIONS, referencedTransformOptions);
|
||||
element.set(GROUP, group);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options == null || options.size() == 0)
|
||||
{
|
||||
transform.remove(TRANSFORM_OPTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.set(TRANSFORM_OPTIONS, options);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Transformer transformer = jsonObjectMapper.convertValue(transform, Transformer.class);
|
||||
transformers.add(transformer);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
log.error("Invalid transformer "+getTransformName(transform)+" "+e.getMessage());
|
||||
}
|
||||
transformersNode.add(transform);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
String transformString = jsonObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(transform);
|
||||
log.error(e.getMessage()+"\n"+ transformString);
|
||||
}
|
||||
}
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
private ArrayNode getTransformOptions(ArrayNode transformOptions, int i, ObjectNode transform)
|
||||
{
|
||||
ArrayNode options = null;
|
||||
JsonNode optionName = transformOptions.get(i);
|
||||
if (optionName.isTextual())
|
||||
{
|
||||
String name = optionName.asText();
|
||||
options = allTransformOptions.get(name);
|
||||
if (options == null)
|
||||
{
|
||||
String message = "Reference to \"transformOptions\": \"" + name + "\" not found. Transformer " +
|
||||
getTransformName(transform) + " ignored.";
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private String getTransformName(ObjectNode transform)
|
||||
{
|
||||
String name = "Unknown";
|
||||
JsonNode nameNode = transform.get(NAME);
|
||||
if (nameNode.isTextual())
|
||||
{
|
||||
name = '"'+nameNode.asText()+'"';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -31,29 +31,36 @@ package org.alfresco.transform.client.model.config;
|
||||
*/
|
||||
public class SupportedSourceAndTarget
|
||||
{
|
||||
private String sourceExt;
|
||||
private String sourceMediaType;
|
||||
private long maxSourceSizeBytes = -1;
|
||||
private String targetExt;
|
||||
private String targetMediaType;
|
||||
private int priority = 50;
|
||||
|
||||
public SupportedSourceAndTarget()
|
||||
{
|
||||
}
|
||||
|
||||
public SupportedSourceAndTarget(String sourceExt, String targetExt, long maxSourceSizeBytes)
|
||||
public SupportedSourceAndTarget(String sourceMediaType, String targetMediaType, long maxSourceSizeBytes)
|
||||
{
|
||||
setSourceExt(sourceExt);
|
||||
this(sourceMediaType, targetMediaType, maxSourceSizeBytes, 50);
|
||||
}
|
||||
|
||||
public SupportedSourceAndTarget(String sourceMediaType, String targetMediaType, long maxSourceSizeBytes, int priority)
|
||||
{
|
||||
setSourceMediaType(sourceMediaType);
|
||||
setMaxSourceSizeBytes(maxSourceSizeBytes);
|
||||
setTargetExt(targetExt);
|
||||
setTargetMediaType(targetMediaType);
|
||||
setPriority(priority);
|
||||
}
|
||||
|
||||
public String getSourceExt()
|
||||
public String getSourceMediaType()
|
||||
{
|
||||
return sourceExt;
|
||||
return sourceMediaType;
|
||||
}
|
||||
|
||||
public void setSourceExt(String sourceExt)
|
||||
public void setSourceMediaType(String sourceMediaType)
|
||||
{
|
||||
this.sourceExt = sourceExt;
|
||||
this.sourceMediaType = sourceMediaType;
|
||||
}
|
||||
|
||||
public long getMaxSourceSizeBytes()
|
||||
@@ -66,13 +73,23 @@ public class SupportedSourceAndTarget
|
||||
this.maxSourceSizeBytes = maxSourceSizeBytes;
|
||||
}
|
||||
|
||||
public String getTargetExt()
|
||||
public String getTargetMediaType()
|
||||
{
|
||||
return targetExt;
|
||||
return targetMediaType;
|
||||
}
|
||||
|
||||
public void setTargetExt(String targetExt)
|
||||
public void setTargetMediaType(String targetMediaType)
|
||||
{
|
||||
this.targetExt = targetExt;
|
||||
this.targetMediaType = targetMediaType;
|
||||
}
|
||||
|
||||
public int getPriority()
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void setPriority(int priority)
|
||||
{
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
|
@@ -30,11 +30,12 @@ import java.util.List;
|
||||
/**
|
||||
* Represents a group of one or more options. If the group is optional, child options that are marked as required are
|
||||
* only required if any child in the group is supplied by the client. If the group is required, child options are
|
||||
* optional or required based on their own setting alone. The top
|
||||
* optional or required based on their own setting alone.
|
||||
*
|
||||
* In a pipeline transformation, a group of options
|
||||
*/
|
||||
public class TransformOptionGroup implements TransformOption
|
||||
public class TransformOptionGroup extends AbstractTransformOption
|
||||
{
|
||||
private boolean required;
|
||||
List<TransformOption> transformOptions;
|
||||
|
||||
public TransformOptionGroup()
|
||||
@@ -47,18 +48,6 @@ public class TransformOptionGroup implements TransformOption
|
||||
setTransformOptions(transformOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequired()
|
||||
{
|
||||
return required;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequired(boolean required)
|
||||
{
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
public List<TransformOption> getTransformOptions()
|
||||
{
|
||||
return transformOptions;
|
||||
|
@@ -28,9 +28,8 @@ package org.alfresco.transform.client.model.config;
|
||||
/**
|
||||
* Represents a single transformation option.
|
||||
*/
|
||||
public class TransformOptionValue implements TransformOption
|
||||
public class TransformOptionValue extends AbstractTransformOption
|
||||
{
|
||||
private boolean required;
|
||||
private String name;
|
||||
|
||||
public TransformOptionValue()
|
||||
@@ -43,18 +42,6 @@ public class TransformOptionValue implements TransformOption
|
||||
setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequired()
|
||||
{
|
||||
return required;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequired(boolean required)
|
||||
{
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
|
@@ -27,6 +27,7 @@ package org.alfresco.transform.client.model.config;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -44,38 +45,36 @@ import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT;
|
||||
/**
|
||||
* Used by clients to work out if a transformation is supported by the Transform Service.
|
||||
*/
|
||||
public class TransformServiceRegistryImpl implements TransformServiceRegistry, InitializingBean
|
||||
public abstract class TransformServiceRegistryImpl implements TransformServiceRegistry, InitializingBean
|
||||
{
|
||||
class SupportedTransform
|
||||
{
|
||||
TransformOptionGroup transformOptions;
|
||||
private long maxSourceSizeBytes;
|
||||
long maxSourceSizeBytes;
|
||||
private String name;
|
||||
private int priority;
|
||||
|
||||
public SupportedTransform(List<TransformOption> transformOptions, long maxSourceSizeBytes)
|
||||
public SupportedTransform(String name, List<TransformOption> transformOptions, long maxSourceSizeBytes, int priority)
|
||||
{
|
||||
// Logically the top level TransformOptionGroup is required, so that child options are optional or required
|
||||
// based on their own setting.
|
||||
this.transformOptions = new TransformOptionGroup(true, transformOptions);
|
||||
this.maxSourceSizeBytes = maxSourceSizeBytes;
|
||||
this.name = name;
|
||||
this.priority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectMapper jsonObjectMapper;
|
||||
private ExtensionMap extensionMap;
|
||||
|
||||
ConcurrentMap<String, ConcurrentMap<String, List<SupportedTransform>>> transformers = new ConcurrentHashMap<>();
|
||||
ConcurrentMap<String, ConcurrentMap<String, Long>> cachedMaxSizes = new ConcurrentHashMap<>();
|
||||
ConcurrentMap<String, ConcurrentMap<String, List<SupportedTransform>>> cachedSupportedTransformList = new ConcurrentHashMap<>();
|
||||
|
||||
public void setJsonObjectMapper(ObjectMapper jsonObjectMapper)
|
||||
{
|
||||
this.jsonObjectMapper = jsonObjectMapper;
|
||||
}
|
||||
|
||||
public void setExtensionMap(ExtensionMap extensionMap)
|
||||
{
|
||||
this.extensionMap = extensionMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
@@ -83,30 +82,21 @@ public class TransformServiceRegistryImpl implements TransformServiceRegistry, I
|
||||
{
|
||||
throw new IllegalStateException("jsonObjectMapper has not been set");
|
||||
}
|
||||
if (extensionMap == null)
|
||||
{
|
||||
throw new IllegalStateException("extensionMap has not been set");
|
||||
}
|
||||
cachedSupportedTransformList.clear();
|
||||
transformers.clear();
|
||||
}
|
||||
|
||||
private String toMimetype(String ext)
|
||||
{
|
||||
String mimetype = extensionMap.toMimetype(ext);
|
||||
if (mimetype == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The mimetype for the file extension "+ext+" cannot be looked up by: "+
|
||||
extensionMap.getClass().getName());
|
||||
}
|
||||
return mimetype;
|
||||
}
|
||||
protected abstract Log getLog();
|
||||
|
||||
public void register(Transformer transformer)
|
||||
public void register(String path) throws IOException
|
||||
{
|
||||
transformer.getSupportedSourceAndTargetList().forEach(
|
||||
e -> transformers.computeIfAbsent(toMimetype(e.getSourceExt()),
|
||||
k -> new ConcurrentHashMap<>()).computeIfAbsent(toMimetype(e.getTargetExt()),
|
||||
k -> new ArrayList<>()).add(
|
||||
new SupportedTransform(transformer.getTransformOptions(), e.getMaxSourceSizeBytes())));
|
||||
JsonConverter jsonConverter = new JsonConverter(getLog());
|
||||
jsonConverter.addJsonSource(path);
|
||||
List<Transformer> transformers = jsonConverter.getTransformers();
|
||||
for (Transformer transformer : transformers)
|
||||
{
|
||||
register(transformer);
|
||||
}
|
||||
}
|
||||
|
||||
public void register(Reader reader) throws IOException
|
||||
@@ -115,31 +105,78 @@ public class TransformServiceRegistryImpl implements TransformServiceRegistry, I
|
||||
transformers.forEach(t -> register(t));
|
||||
}
|
||||
|
||||
public void register(Transformer transformer)
|
||||
{
|
||||
transformer.getSupportedSourceAndTargetList().forEach(
|
||||
e -> transformers.computeIfAbsent(e.getSourceMediaType(),
|
||||
k -> new ConcurrentHashMap<>()).computeIfAbsent(e.getTargetMediaType(),
|
||||
k -> new ArrayList<>()).add(
|
||||
new SupportedTransform(transformer.getTransformerName(),
|
||||
transformer.getTransformOptions(), e.getMaxSourceSizeBytes(), e.getPriority())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
||||
Map<String, String> actualOptions, String transformName)
|
||||
Map<String, String> actualOptions, String renditionName)
|
||||
{
|
||||
long maxSize = getMaxSize(sourceMimetype, targetMimetype, actualOptions, transformName);
|
||||
long maxSize = getMaxSize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
||||
return maxSize != 0 && (maxSize == -1L || maxSize >= sourceSizeInBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Works out the name of the transformer (might not map to an actual transformer) that will be used to transform
|
||||
* content of a given source mimetype and size into a target mimetype given a list of actual transform option names
|
||||
* and values (Strings) plus the data contained in the {@Transform} objects registered with this class.
|
||||
* @param sourceMimetype the mimetype of the source content
|
||||
* @param sourceSizeInBytes the size in bytes of the source content. Ignored if negative.
|
||||
* @param targetMimetype the mimetype of the target
|
||||
* @param actualOptions the actual name value pairs available that could be passed to the Transform Service.
|
||||
* @param renditionName (optional) name for the set of options and target mimetype. If supplied is used to cache
|
||||
* results to avoid having to work out if a given transformation is supported a second time.
|
||||
* The sourceMimetype and sourceSizeInBytes may still change. In the case of ACS this is the
|
||||
* rendition name.
|
||||
*/
|
||||
protected String getTransformerName(String sourceMimetype, long sourceSizeInBytes, String targetMimetype, Map<String, String> actualOptions, String renditionName)
|
||||
{
|
||||
List<SupportedTransform> supportedTransforms = getTransformListBySize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
||||
for (SupportedTransform supportedTransform : supportedTransforms)
|
||||
{
|
||||
if (supportedTransform.maxSourceSizeBytes == -1 || supportedTransform.maxSourceSizeBytes >= sourceSizeInBytes)
|
||||
{
|
||||
return supportedTransform.name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxSize(String sourceMimetype, String targetMimetype,
|
||||
Map<String, String> actualOptions, String transformName)
|
||||
Map<String, String> actualOptions, String renditionName)
|
||||
{
|
||||
List<SupportedTransform> supportedTransforms = getTransformListBySize(sourceMimetype, targetMimetype, actualOptions, renditionName);
|
||||
return supportedTransforms.isEmpty() ? 0 : supportedTransforms.get(supportedTransforms.size()-1).maxSourceSizeBytes;
|
||||
}
|
||||
|
||||
// Returns transformers in increasing supported size order, where lower priority transformers for the same size have
|
||||
// been discarded.
|
||||
private List<SupportedTransform> getTransformListBySize(String sourceMimetype, String targetMimetype,
|
||||
Map<String, String> actualOptions, String renditionName)
|
||||
{
|
||||
if (actualOptions == null)
|
||||
{
|
||||
actualOptions = Collections.EMPTY_MAP;
|
||||
}
|
||||
if (transformName != null && transformName.trim().isEmpty())
|
||||
if (renditionName != null && renditionName.trim().isEmpty())
|
||||
{
|
||||
transformName = null;
|
||||
renditionName = null;
|
||||
}
|
||||
|
||||
Long maxSize = transformName == null ? null : cachedMaxSizes.computeIfAbsent(transformName, k -> new ConcurrentHashMap<>()).get(sourceMimetype);
|
||||
if (maxSize != null)
|
||||
List<SupportedTransform> transformListBySize = renditionName == null ? null
|
||||
: cachedSupportedTransformList.computeIfAbsent(renditionName, k -> new ConcurrentHashMap<>()).get(sourceMimetype);
|
||||
if (transformListBySize != null)
|
||||
{
|
||||
return maxSize.longValue();
|
||||
return transformListBySize;
|
||||
}
|
||||
|
||||
// Remove the "timeout" property from the actualOptions as it is not used to select a transformer.
|
||||
@@ -149,7 +186,7 @@ public class TransformServiceRegistryImpl implements TransformServiceRegistry, I
|
||||
actualOptions.remove(TIMEOUT);
|
||||
}
|
||||
|
||||
long calculatedMaxSize = 0;
|
||||
transformListBySize = new ArrayList<>();
|
||||
ConcurrentMap<String, List<SupportedTransform>> targetMap = transformers.get(sourceMimetype);
|
||||
if (targetMap != null)
|
||||
{
|
||||
@@ -163,24 +200,66 @@ public class TransformServiceRegistryImpl implements TransformServiceRegistry, I
|
||||
addToPossibleTransformOptions(possibleTransformOptions, transformOptions, true, actualOptions);
|
||||
if (isSupported(possibleTransformOptions, actualOptions))
|
||||
{
|
||||
if (supportedTransform.maxSourceSizeBytes < 0)
|
||||
addToSupportedTransformList(transformListBySize, supportedTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (renditionName != null)
|
||||
{
|
||||
calculatedMaxSize = -1;
|
||||
break;
|
||||
cachedSupportedTransformList.get(renditionName).put(sourceMimetype, transformListBySize);
|
||||
}
|
||||
|
||||
calculatedMaxSize = Math.max(calculatedMaxSize, supportedTransform.maxSourceSizeBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return transformListBySize;
|
||||
}
|
||||
|
||||
if (transformName != null)
|
||||
// Add newTransform to the transformListBySize in increasing size order and discards lower priority (numerically
|
||||
// higher) transforms with a smaller or equal size.
|
||||
private void addToSupportedTransformList(List<SupportedTransform> transformListBySize, SupportedTransform newTransform)
|
||||
{
|
||||
cachedMaxSizes.get(transformName).put(sourceMimetype, calculatedMaxSize);
|
||||
for (int i=0; i < transformListBySize.size(); i++)
|
||||
{
|
||||
SupportedTransform existingTransform = transformListBySize.get(i);
|
||||
int added = -1;
|
||||
int compare = compare(newTransform.maxSourceSizeBytes, existingTransform.maxSourceSizeBytes);
|
||||
if (compare < 0)
|
||||
{
|
||||
transformListBySize.add(i, newTransform);
|
||||
added = i;
|
||||
}
|
||||
else if (compare == 0)
|
||||
{
|
||||
if (newTransform.priority < existingTransform.priority)
|
||||
{
|
||||
transformListBySize.set(i, newTransform);
|
||||
added = i;
|
||||
}
|
||||
}
|
||||
if (added == i)
|
||||
{
|
||||
for (i--; i >= 0; i--)
|
||||
{
|
||||
existingTransform = transformListBySize.get(i);
|
||||
if (newTransform.priority <= existingTransform.priority)
|
||||
{
|
||||
transformListBySize.remove(i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
transformListBySize.add(newTransform);
|
||||
}
|
||||
|
||||
return calculatedMaxSize;
|
||||
// compare where -1 is unlimited.
|
||||
private int compare(long a, long b)
|
||||
{
|
||||
return a == -1
|
||||
? b == -1 ? 0 : 1
|
||||
: b == -1 ? -1
|
||||
: a == b ? 0
|
||||
: a > b ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
/**
|
||||
* Represents a single transform step in a transform pipeline. The last step in the pipeline does not specify the
|
||||
* target type as that is based on the supported types and what has been requested.
|
||||
*/
|
||||
public class TransformStep
|
||||
{
|
||||
private String transformerName;
|
||||
private String targetMediaType;
|
||||
|
||||
public TransformStep()
|
||||
{
|
||||
}
|
||||
|
||||
public TransformStep(String transformerName, String targetMediaType)
|
||||
{
|
||||
setTransformerName(transformerName);
|
||||
setTargetMediaType(targetMediaType);
|
||||
}
|
||||
|
||||
public String getTransformerName()
|
||||
{
|
||||
return transformerName;
|
||||
}
|
||||
|
||||
public void setTransformerName(String transformerName)
|
||||
{
|
||||
this.transformerName = transformerName;
|
||||
}
|
||||
|
||||
public String getTargetMediaType()
|
||||
{
|
||||
return targetMediaType;
|
||||
}
|
||||
|
||||
public void setTargetMediaType(String targetMediaType)
|
||||
{
|
||||
this.targetMediaType = targetMediaType;
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -26,28 +26,34 @@
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
|
||||
/**
|
||||
* Represents a set of transformations supported by the Transform Service that share the same transform options. Each
|
||||
* may be an actual transformer or the amalgamation of multiple transformers. It is possible that more than one
|
||||
* transformer may able to perform a transformation from one mimetype to another. The actual selection of transformer
|
||||
* is up to the Transform Service to decide. Clients may use {@link TransformServiceRegistry#isSupported} to decide
|
||||
* Represents a set of transformations supported by the Transform Service or Local Transform Service Registry that
|
||||
* share the same transform options. Each may be an actual transformer or a pipeline of multiple transformers. It is
|
||||
* possible that more than one transformer may able to perform a transformation from one mimetype to another. The actual
|
||||
* selection of transformer is up to the Transform Service or Local Transform Service Registry to decide. Clients may
|
||||
* use {@link TransformServiceRegistry#isSupported(String, long, String, java.util.Map, String)} to decide
|
||||
* if they should send a request to the Transform Service. As a result clients have a simple generic view of
|
||||
* transformations which allows new transformations to be added without the need change client data structures other
|
||||
* transformations which allows new transformations to be added without the need to change client data structures other
|
||||
* than to define new name value pairs. For this to work the Transform Service defines unique names for each option.
|
||||
* <ul>
|
||||
* <lI>name - is unique. The client should infer nothing from the name as it is simply a label.</lI>
|
||||
* <li>version - of the transformer. The client should infer nothing from the value and should only use it
|
||||
* in messages. There should only be one version supplied to the client for each name.</li>
|
||||
* <li>transformerName - is optional but if supplied should be unique. The client should infer nothing from the name
|
||||
* as it is simply a label, but the Local Transform Service Registry will use the name in pipelines.</lI>
|
||||
* <li>transformOptions - a grouping of individual transformer transformOptions. The group may be optional and may
|
||||
* contain nested transformOptions.</li>
|
||||
* </ul>
|
||||
* For local transforms, this structure is extended when defining a pipeline transform.
|
||||
* <ul>
|
||||
* <li>transformerPipeline - an array of pairs of transformer name and target extension for each transformer in the
|
||||
* pipeline. The last one should not have an extension as that is defined by the request and should be in the
|
||||
* supported list.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class Transformer
|
||||
{
|
||||
private String name;
|
||||
private String version;
|
||||
private String transformerName;
|
||||
private List<TransformStep> transformerPipeline;
|
||||
private List<TransformOption> transformOptions;
|
||||
private List<SupportedSourceAndTarget> supportedSourceAndTargetList;
|
||||
|
||||
@@ -55,32 +61,37 @@ public class Transformer
|
||||
{
|
||||
}
|
||||
|
||||
public Transformer(String name, String version, List<TransformOption> transformOptions, List<SupportedSourceAndTarget> supportedSourceAndTargetList)
|
||||
public Transformer(String transformerName, List<TransformOption> transformOptions, List<SupportedSourceAndTarget> supportedSourceAndTargetList)
|
||||
{
|
||||
setName(name);
|
||||
setVersion(version);
|
||||
setTransformerName(transformerName);
|
||||
setTransformOptions(transformOptions);
|
||||
setSupportedSourceAndTargetList(supportedSourceAndTargetList);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
public Transformer(String transformerName, List<TransformStep> transformerPipeline, List<TransformOption> transformOptions, List<SupportedSourceAndTarget> supportedSourceAndTargetList)
|
||||
{
|
||||
return name;
|
||||
this(transformerName, transformOptions, supportedSourceAndTargetList);
|
||||
setTransformerPipeline(transformerPipeline);
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
public String getTransformerName()
|
||||
{
|
||||
this.name = name;
|
||||
return transformerName;
|
||||
}
|
||||
|
||||
public String getVersion()
|
||||
public void setTransformerName(String transformerName)
|
||||
{
|
||||
return version;
|
||||
this.transformerName = transformerName;
|
||||
}
|
||||
|
||||
public void setVersion(String version)
|
||||
public List<TransformStep> getTransformerPipeline()
|
||||
{
|
||||
this.version = version;
|
||||
return transformerPipeline;
|
||||
}
|
||||
|
||||
public void setTransformerPipeline(List<TransformStep> transformerPipeline)
|
||||
{
|
||||
this.transformerPipeline = transformerPipeline;
|
||||
}
|
||||
|
||||
public List<TransformOption> getTransformOptions()
|
||||
|
@@ -328,33 +328,18 @@
|
||||
<constructor-arg>
|
||||
<ref bean="transformerSelector"/>
|
||||
</constructor-arg>
|
||||
<property name="enabled" value="${local.transform.service.enabled}" />
|
||||
<property name="enabled" value="${legacy.transform.service.enabled}" />
|
||||
<property name="transformerDebug" ref="transformerDebug" />
|
||||
</bean>
|
||||
|
||||
<!-- Transformation Debug -->
|
||||
<bean id="transformerDebug" class="org.alfresco.repo.content.transform.TransformerDebug">
|
||||
<constructor-arg>
|
||||
<ref bean="nodeService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<ref bean="mimetypeService"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<ref bean="contentTransformerRegistry"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<ref bean="transformerConfig"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<ref bean="transformerLog" />
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<ref bean="transformerDebugLog" />
|
||||
</constructor-arg>
|
||||
<property name="contentService">
|
||||
<ref bean="contentService" />
|
||||
</property>
|
||||
<property name="nodeService" ref="nodeService" />
|
||||
<property name="mimetypeService" ref="mimetypeService" />
|
||||
<property name="transformerRegistry" ref="contentTransformerRegistry" />
|
||||
<property name="transformerConfig" ref="transformerConfig" />
|
||||
<property name="transformerLog" ref="transformerLog" />
|
||||
<property name="transformerDebugLog" ref="transformerDebugLog" />
|
||||
</bean>
|
||||
|
||||
<!-- Import the transformer configuration from the transformers subsystem -->
|
||||
@@ -489,6 +474,7 @@
|
||||
class="org.alfresco.repo.content.transform.TikaPoweredContentTransformer"
|
||||
abstract="true"
|
||||
parent="baseContentTransformer">
|
||||
<property name="enabled" value="${legacy.transform.service.enabled}" />
|
||||
<property name="remoteTransformerClient">
|
||||
<ref bean="tikaRemoteTransformerClient" />
|
||||
</property>
|
||||
|
@@ -71,9 +71,20 @@
|
||||
<!-- Replaced in the enterprise edition -->
|
||||
<bean id="transformClient" parent="localTransformClient"/>
|
||||
|
||||
<bean id="localTransformClient" class="org.alfresco.repo.rendition2.LegacyLocalTransformClient">
|
||||
<bean id="localTransformClient" class="org.alfresco.repo.rendition2.SwitchingTransformClient">
|
||||
<constructor-arg name="primary" ref="localTransformClientImpl" />
|
||||
<constructor-arg name="secondary" ref="legacyTransformClient" />
|
||||
</bean>
|
||||
|
||||
<bean id="localTransformClientImpl" class="org.alfresco.repo.rendition2.LocalTransformClient">
|
||||
<property name="localTransformServiceRegistry" ref="localTransformServiceRegistryImpl" />
|
||||
<property name="transactionService" ref="transactionService" />
|
||||
<property name="contentService" ref="contentService" />
|
||||
<property name="renditionService2" ref="renditionService2" />
|
||||
</bean>
|
||||
|
||||
<bean id="legacyTransformClient" class="org.alfresco.repo.rendition2.LegacyTransformClient">
|
||||
<property name="transactionService" ref="transactionService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="renditionService2" ref="renditionService2" />
|
||||
<property name="converter" ref="transformOptionsConverter" />
|
||||
@@ -91,10 +102,28 @@
|
||||
<!-- Replaced in the enterprise edition -->
|
||||
<bean id="transformServiceRegistry" parent="localTransformServiceRegistry"/>
|
||||
|
||||
<bean id="localTransformServiceRegistry" class="org.alfresco.repo.rendition2.LegacyLocalTransformServiceRegistry" >
|
||||
<bean id="localTransformServiceRegistry" class="org.alfresco.repo.rendition2.SwitchingTransformServiceRegistry">
|
||||
<constructor-arg name="primary" ref="localTransformServiceRegistryImpl" />
|
||||
<constructor-arg name="secondary" ref="legacyTransformServiceRegistry" />
|
||||
</bean>
|
||||
|
||||
<bean id="localTransformServiceRegistryImpl" class="org.alfresco.repo.content.transform.LocalTransformServiceRegistry" >
|
||||
<property name="jsonObjectMapper" ref="localTransformServiceRegistryJsonObjectMapper" />
|
||||
<property name="pipelineConfigFolder" value="alfresco/transformers" />
|
||||
<property name="enabled" value="${local.transform.service.enabled}" />
|
||||
<property name="properties" ref="global-properties" />
|
||||
<property name="transformerDebug" ref="transformerDebug" />
|
||||
<property name="mimetypeService" ref="MimetypeService" />
|
||||
<property name="strictMimeTypeCheck" value="${transformer.strict.mimetype.check}"/>
|
||||
<property name="retryTransformOnDifferentMimeType" value="${content.transformer.retryOn.different.mimetype}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="localTransformServiceRegistryJsonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
|
||||
|
||||
<bean id="legacyTransformServiceRegistry" class="org.alfresco.repo.rendition2.LegacyTransformServiceRegistry" >
|
||||
<property name="contentService" ref="contentService" />
|
||||
<property name="converter" ref="transformOptionsConverter" />
|
||||
<property name="enabled" value="${local.transform.service.enabled}" />
|
||||
<property name="enabled" value="${legacy.transform.service.enabled}" />
|
||||
<property name="transformerDebug" ref="transformerDebug" />
|
||||
</bean>
|
||||
|
||||
|
@@ -562,7 +562,7 @@ img.root=./ImageMagick
|
||||
img.dyn=${img.root}/lib
|
||||
img.exe=${img.root}/bin/convert
|
||||
|
||||
# Remote server (or docker container) url used to service imagemagick requests.
|
||||
# Legacy imageMagick transformer url to T-Engine to service transform requests via http. Disabled by default.
|
||||
img.url=
|
||||
|
||||
# When img.url is set, this value indicates the amount of time to wait after a connection failure
|
||||
@@ -611,13 +611,26 @@ system.thumbnail.redeployStaticDefsOnStartup=true
|
||||
# The default timeout for metadata mapping extracters
|
||||
content.metadataExtracter.default.timeoutMs=20000
|
||||
|
||||
# Remote server (or docker container) url used to service tika requests.
|
||||
# Legacy tika transformer url to T-Engines to service transform requests via http. Disabled by default.
|
||||
tika.url=
|
||||
|
||||
# When tika.url is set, this value indicates the amount of time to wait after a connection failure
|
||||
# When the legacy tika transformer .url is set, this value indicates the amount of time to wait after a connection failure
|
||||
# before retrying the connection to allow a docker container to (re)start.
|
||||
tika.startupRetryPeriodSeconds=60
|
||||
|
||||
# Local transformer urls to T-engines to service transform requests via http. Enabled by default.
|
||||
localTransformer.pdfrenderer.url=http://localhost:8090/
|
||||
localTransformer.imagemagick.url=http://localhost:8091/
|
||||
localTransformer.libreoffice.url=http://localhost:8092/
|
||||
localTransformer.tika.url=http://localhost:8093/
|
||||
|
||||
# When a local transformer .url is set, this value indicates the amount of time to wait after a connection failure
|
||||
# before retrying the connection to allow a docker container to (re)start.
|
||||
localTransformer.pdfrenderer.startupRetryPeriodSeconds=60
|
||||
localTransformer.imagemagick.startupRetryPeriodSeconds=60
|
||||
localTransformer.libreoffice.startupRetryPeriodSeconds=60
|
||||
localTransformer.tika.startupRetryPeriodSeconds=60
|
||||
|
||||
#
|
||||
content.metadataExtracter.pdf.maxDocumentSizeMB=10
|
||||
content.metadataExtracter.pdf.maxConcurrentExtractionsCount=5
|
||||
@@ -1065,6 +1078,9 @@ system.cronJob.startDelayMilliseconds=60000
|
||||
# Used to disable transforms locally.
|
||||
local.transform.service.enabled=true
|
||||
|
||||
# Used to disable transforms that extend AbstractContentTransformer2
|
||||
legacy.transform.service.enabled=true
|
||||
|
||||
#
|
||||
# Check that the declared mimetype (of the Node) is the same as the derived
|
||||
# mimetype of the content (via Tika) before a transformation takes place.
|
||||
@@ -1074,13 +1090,15 @@ local.transform.service.enabled=true
|
||||
#
|
||||
# There are a few issues with the Tika mimetype detection. So that transformations
|
||||
# still take place where the detected mimetype is not the same as the declared mimetype,
|
||||
# another property (transformer.strict.mimetype.check.whitelist.mimetypes in transformers.properties
|
||||
# so can be changed via JMX) contains pairs of declared and detected mimetypes that should
|
||||
# be allowed. This parameter value is a sequence of ; separated pairs. The declared and
|
||||
# derived mimetypes are also ; separated.
|
||||
# another property (transformer.strict.mimetype.check.whitelist.mimetypes) contains pairs
|
||||
# of declared and detected mimetypes that should be allowed. This parameter value is a
|
||||
# sequence of ; separated pairs. The declared and derived mimetypes are also ; separated.
|
||||
#
|
||||
transformer.strict.mimetype.check=true
|
||||
|
||||
# A white list of declared and detected mimetypes, that don't match, but should still be transformed.
|
||||
transformer.strict.mimetype.check.whitelist.mimetypes=application/eps;application/postscript;application/illustrator;application/pdf;application/x-tar;application/x-gtar;application/acp;application/zip;application/vnd.stardivision.math;application/x-tika-msoffice
|
||||
|
||||
#
|
||||
# Enable transformation retrying if the file has MIME type differ than file extension.
|
||||
# Ignored if transformer.strict.mimetype.check is true as these transformations
|
||||
@@ -1258,4 +1276,3 @@ messaging.subsystem.autoStart=true
|
||||
|
||||
# Raw events
|
||||
acs.repo.rendition.events.endpoint=jms:acs-repo-rendition-events?jmsMessageType=Text
|
||||
|
||||
|
@@ -53,6 +53,7 @@
|
||||
<property name="mimetypeService">
|
||||
<ref bean="mimetypeService" />
|
||||
</property>
|
||||
<property name="enabled" value="${legacy.transform.service.enabled}" />
|
||||
<property name="jodConverter">
|
||||
<ref bean="jodconverter.shared.instance" />
|
||||
</property>
|
||||
|
@@ -61,6 +61,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="enabled" value="${legacy.transform.service.enabled}" />
|
||||
</bean>
|
||||
|
||||
<bean id="transformer.worker.ImageMagick.processPropertiesWindows" class="org.springframework.beans.factory.config.MapFactoryBean">
|
||||
|
@@ -1,58 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "libreOffice",
|
||||
"version": "1",
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "doc", "targetExt": "doc" },
|
||||
{"sourceExt": "docx", "targetExt": "doc" },
|
||||
{"sourceExt": "doc", "maxSourceSizeBytes": 10485760, "targetExt": "pdf" },
|
||||
{"sourceExt": "xls", "maxSourceSizeBytes": 10485760, "targetExt": "pdf"},
|
||||
{"sourceExt": "ppt", "maxSourceSizeBytes": 6291456, "targetExt": "pdf" },
|
||||
{"sourceExt": "docx", "maxSourceSizeBytes": 786432, "targetExt": "pdf" },
|
||||
{"sourceExt": "xlsx", "maxSourceSizeBytes": 1572864, "targetExt": "pdf"},
|
||||
{"sourceExt": "pptx", "maxSourceSizeBytes": 4194304, "targetExt": "pdf" },
|
||||
{"sourceExt": "msg", "targetExt": "pdf"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tika",
|
||||
"version": "1",
|
||||
"transformOptions": [
|
||||
{
|
||||
"transformOptions": {
|
||||
"tikaOptions": [
|
||||
{"value": {"name": "transform"}},
|
||||
{"value": {"name": "includeContents"}},
|
||||
{"value": {"name": "notExtractBookmarksText"}},
|
||||
{"value": {"name": "targetMimetype"}},
|
||||
{"value": {"name": "targetEncoding"}}
|
||||
],
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "pdf", "maxSourceSizeBytes": 26214400, "targetExt": "txt" },
|
||||
{"sourceExt": "doc", "targetExt": "txt"},
|
||||
{"sourceExt": "xls", "targetExt": "txt" },
|
||||
{"sourceExt": "ppt", "targetExt": "txt" },
|
||||
{"sourceExt": "docx", "targetExt": "txt"},
|
||||
{"sourceExt": "xlsx", "targetExt": "txt" },
|
||||
{"sourceExt": "pptx", "targetExt": "txt" },
|
||||
{"sourceExt": "msg", "targetExt": "txt"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pdfRenderer",
|
||||
"version": "1",
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions": [
|
||||
{"value": {"name": "page"}},
|
||||
{"value": {"name": "width"}},
|
||||
{"value": {"name": "height"}},
|
||||
{"value": {"name": "allowPdfEnlargement"}},
|
||||
{"value": {"name": "maintainPdfAspectRatio"}}
|
||||
],
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "pdf", "targetExt": "png" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "imageMagick",
|
||||
"version": "1",
|
||||
"transformOptions": [
|
||||
"imagemagickOptions": [
|
||||
{"value": {"name": "alphaRemove"}},
|
||||
{"value": {"name": "autoOrient"}},
|
||||
{"value": {"name": "startPage"}},
|
||||
@@ -73,103 +35,110 @@
|
||||
{"value": {"name": "allowEnlargement"}},
|
||||
{"value": {"name": "maintainAspectRatio"}}
|
||||
]}}
|
||||
],
|
||||
]
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "gif", "targetExt": "gif" },
|
||||
{"sourceExt": "gif", "targetExt": "jpeg"},
|
||||
{"sourceExt": "gif", "targetExt": "png" },
|
||||
{"sourceExt": "gif", "targetExt": "tiff"},
|
||||
|
||||
{"sourceExt": "jpeg", "targetExt": "gif" },
|
||||
{"sourceExt": "jpeg", "targetExt": "jpeg"},
|
||||
{"sourceExt": "jpeg", "targetExt": "png" },
|
||||
{"sourceExt": "jpeg", "targetExt": "tiff"},
|
||||
|
||||
{"sourceExt": "png", "targetExt": "gif" },
|
||||
{"sourceExt": "png", "targetExt": "jpeg"},
|
||||
{"sourceExt": "png", "targetExt": "png" },
|
||||
{"sourceExt": "png", "targetExt": "tiff"},
|
||||
|
||||
{"sourceExt": "tiff", "targetExt": "gif" },
|
||||
{"sourceExt": "tiff", "targetExt": "tiff"}
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "application/msword" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "application/msword" },
|
||||
{"sourceMediaType": "application/msword", "maxSourceSizeBytes": 10485760, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "maxSourceSizeBytes": 10485760, "targetMediaType": "application/pdf"},
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "maxSourceSizeBytes": 6291456, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "maxSourceSizeBytes": 786432, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "maxSourceSizeBytes": 1572864, "targetMediaType": "application/pdf"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "maxSourceSizeBytes": 4194304, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "application/pdf"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "officeToImageViaPdf",
|
||||
"version": "1",
|
||||
"transformOptions": [
|
||||
{
|
||||
"group": {
|
||||
"required": true,
|
||||
"transformOptions": [
|
||||
{"value": {"name": "alphaRemove"}},
|
||||
{"value": {"name": "autoOrient"}},
|
||||
{"value": {"name": "startPage"}},
|
||||
{"value": {"name": "endPage"}},
|
||||
{"group": {"transformOptions": [
|
||||
{"value": {"name": "cropGravity"}},
|
||||
{"value": {"name": "cropWidth"}},
|
||||
{"value": {"name": "cropHeight"}},
|
||||
{"value": {"name": "cropPercentage"}},
|
||||
{"value": {"name": "cropXOffset"}},
|
||||
{"value": {"name": "cropYOffset"}}
|
||||
]}},
|
||||
{"group": {"transformOptions": [
|
||||
{"value": {"name": "thumbnail"}},
|
||||
{"value": {"name": "resizeHeight"}},
|
||||
{"value": {"name": "resizeWidth"}},
|
||||
{"value": {"name": "resizePercentage"}},
|
||||
{"value": {"name": "allowEnlargement"}},
|
||||
{"value": {"name": "maintainAspectRatio"}}
|
||||
]}}
|
||||
]}},{
|
||||
"group": {
|
||||
"required": false,
|
||||
"transformOptions": [
|
||||
{"value": {"name": "page"}},
|
||||
{"value": {"name": "width"}},
|
||||
{"value": {"name": "height"}},
|
||||
{"value": {"name": "allowPdfEnlargement"}},
|
||||
{"value": {"name": "maintainPdfAspectRatio"}}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "doc", "targetExt": "gif" },
|
||||
{"sourceExt": "doc", "targetExt": "jpeg"},
|
||||
{"sourceExt": "doc", "targetExt": "png" },
|
||||
{"sourceExt": "doc", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "application/pdf", "maxSourceSizeBytes": 26214400, "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "text/plain"},
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "text/plain"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "text/plain"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"tikaOptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/pdf", "targetMediaType": "image/png" }
|
||||
],
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "xls", "targetExt": "gif" },
|
||||
{"sourceExt": "xls", "targetExt": "jpeg"},
|
||||
{"sourceExt": "xls", "targetExt": "png" },
|
||||
{"sourceExt": "xls", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "ppt", "targetExt": "gif" },
|
||||
{"sourceExt": "ppt", "targetExt": "jpeg"},
|
||||
{"sourceExt": "ppt", "targetExt": "png" },
|
||||
{"sourceExt": "ppt", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "docx", "targetExt": "gif" },
|
||||
{"sourceExt": "docx", "targetExt": "jpeg"},
|
||||
{"sourceExt": "docx", "targetExt": "png" },
|
||||
{"sourceExt": "docx", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "image/tiff", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/tiff", "targetMediaType": "image/tiff"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"imagemagickOptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "xlsx", "targetExt": "gif" },
|
||||
{"sourceExt": "xlsx", "targetExt": "jpeg"},
|
||||
{"sourceExt": "xlsx", "targetExt": "png" },
|
||||
{"sourceExt": "xlsx", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "pptx", "targetExt": "gif" },
|
||||
{"sourceExt": "pptx", "targetExt": "jpeg"},
|
||||
{"sourceExt": "pptx", "targetExt": "png" },
|
||||
{"sourceExt": "pptx", "targetExt": "tiff"},
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceExt": "msg", "targetExt": "gif" },
|
||||
{"sourceExt": "msg", "targetExt": "jpeg"},
|
||||
{"sourceExt": "msg", "targetExt": "png" },
|
||||
{"sourceExt": "msg", "targetExt": "tiff"}
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/tiff"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions",
|
||||
"imagemagickOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"transformOptions": {
|
||||
"imagemagickOptions": [
|
||||
{"value": {"name": "alphaRemove"}},
|
||||
{"value": {"name": "autoOrient"}},
|
||||
{"value": {"name": "startPage"}},
|
||||
{"value": {"name": "endPage"}},
|
||||
{"group": {"transformOptions": [
|
||||
{"value": {"name": "cropGravity"}},
|
||||
{"value": {"name": "cropWidth"}},
|
||||
{"value": {"name": "cropHeight"}},
|
||||
{"value": {"name": "cropPercentage"}},
|
||||
{"value": {"name": "cropXOffset"}},
|
||||
{"value": {"name": "cropYOffset"}}
|
||||
]}},
|
||||
{"group": {"transformOptions": [
|
||||
{"value": {"name": "thumbnail"}},
|
||||
{"value": {"name": "resizeHeight"}},
|
||||
{"value": {"name": "resizeWidth"}},
|
||||
{"value": {"name": "resizePercentage"}},
|
||||
{"value": {"name": "allowEnlargement"}},
|
||||
{"value": {"name": "maintainAspectRatio"}}
|
||||
]}}
|
||||
]
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"transformerName": "imagemagick",
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/gif", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/jpeg", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "image/png", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "image/tiff", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "image/tiff", "targetMediaType": "image/tiff"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"imagemagickOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
29
src/main/resources/alfresco/transformers/0110-tika.json
Normal file
29
src/main/resources/alfresco/transformers/0110-tika.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"transformOptions": {
|
||||
"tikaOptions": [
|
||||
{"value": {"name": "transform"}},
|
||||
{"value": {"name": "includeContents"}},
|
||||
{"value": {"name": "notExtractBookmarksText"}},
|
||||
{"value": {"name": "targetMimetype"}},
|
||||
{"value": {"name": "targetEncoding"}}
|
||||
]
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"transformerName": "tika",
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/pdf", "maxSourceSizeBytes": 26214400, "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "text/plain"},
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "text/plain"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "text/plain" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "text/plain"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"tikaOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"transformOptions": {
|
||||
"pdfrendererOptions": [
|
||||
{"value": {"name": "page"}},
|
||||
{"value": {"name": "width"}},
|
||||
{"value": {"name": "height"}},
|
||||
{"value": {"name": "allowPdfEnlargement"}},
|
||||
{"value": {"name": "maintainPdfAspectRatio"}}
|
||||
]
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"transformerName": "pdfrenderer",
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/pdf", "targetMediaType": "image/png" }
|
||||
],
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"transformerName": "libreoffice",
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "application/msword" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "application/msword" },
|
||||
{"sourceMediaType": "application/msword", "maxSourceSizeBytes": 10485760, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "maxSourceSizeBytes": 10485760, "targetMediaType": "application/pdf"},
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "maxSourceSizeBytes": 6291456, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "maxSourceSizeBytes": 786432, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "maxSourceSizeBytes": 1572864, "targetMediaType": "application/pdf"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "maxSourceSizeBytes": 4194304, "targetMediaType": "application/pdf" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "application/pdf"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"transformerName": "officeToImageViaPdf",
|
||||
"transformerPipeline" : [
|
||||
{"transformerName": "libreoffice", "targetMediaType": "application/pdf"},
|
||||
{"transformerName": "pdfrenderer", "targetMediaType": "image/png"},
|
||||
{"transformerName": "imagemagick"}
|
||||
],
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-excel", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-powerpoint", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation", "targetMediaType": "image/tiff"},
|
||||
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/vnd.ms-outlook", "targetMediaType": "image/tiff"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions",
|
||||
"imagemagickOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -200,7 +200,8 @@ import org.junit.runners.Suite;
|
||||
org.alfresco.util.bean.HierarchicalBeanLoaderTest.class,
|
||||
org.alfresco.util.resource.HierarchicalResourceLoaderTest.class,
|
||||
org.alfresco.repo.events.ClientUtilTest.class,
|
||||
org.alfresco.repo.rendition2.RenditionService2Test.class
|
||||
org.alfresco.repo.rendition2.RenditionService2Test.class,
|
||||
org.alfresco.transform.client.model.config.TransformServiceRegistryImplTest.class
|
||||
})
|
||||
public class AllUnitTestsSuite
|
||||
{
|
||||
|
@@ -47,11 +47,18 @@ import org.junit.runners.Suite;
|
||||
// Requires a running ActiveMQ
|
||||
org.alfresco.repo.rawevents.EventBehaviourTest.class,
|
||||
org.alfresco.repo.rawevents.TransactionAwareEventProducerTest.class,
|
||||
|
||||
// Requires running transformers
|
||||
org.alfresco.repo.rendition2.RenditionService2IntegrationTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyLocalTransformClientIntegrationTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyLocalTransformServiceRegistryTest.class,
|
||||
org.alfresco.repo.rendition2.RenditionTest.class,
|
||||
org.alfresco.repo.rendition2.LocalTransformServiceRegistryTest.class,
|
||||
org.alfresco.repo.rendition2.LocalTransformClientIntegrationTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyTransformServiceRegistryTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyTransformClientIntegrationTest.class,
|
||||
org.alfresco.repo.rendition2.LocalRenditionTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyRenditionTest.class,
|
||||
org.alfresco.repo.rendition2.LegacyLocalRenditionTest.class,
|
||||
org.alfresco.repo.rendition2.NoneRenditionTest.class,
|
||||
|
||||
org.alfresco.repo.solr.SOLRTrackingComponentTest.class,
|
||||
org.alfresco.repo.tagging.TaggingServiceImplTest.class,
|
||||
org.alfresco.repo.transaction.AlfrescoTransactionSupportTest.class,
|
||||
@@ -64,6 +71,7 @@ import org.junit.runners.Suite;
|
||||
org.alfresco.repo.tenant.MultiTServiceImplTest.class,
|
||||
org.alfresco.repo.search.SearcherComponentTest.class,
|
||||
org.alfresco.repo.action.scheduled.ScheduledPersistedActionServiceTest.class,
|
||||
|
||||
org.alfresco.repo.rendition2.RenditionDefinitionTest.class
|
||||
})
|
||||
public class AppContext06TestSuite
|
||||
|
@@ -41,10 +41,7 @@ import org.mockito.MockitoAnnotations;
|
||||
* Test class for TransformerDebugLog.
|
||||
*
|
||||
* @author Alan Davis
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TransformerDebugLogTest
|
||||
{
|
||||
@Mock
|
||||
|
@@ -25,9 +25,9 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import org.alfresco.repo.rendition2.TransformClient;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
@@ -49,10 +49,7 @@ import static org.mockito.Mockito.when;
|
||||
* Test class for TransformerDebug.
|
||||
*
|
||||
* @author Alan Davis
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TransformerDebugTest
|
||||
{
|
||||
@Mock
|
||||
@@ -68,7 +65,7 @@ public class TransformerDebugTest
|
||||
private TransformerConfig transformerConfig;
|
||||
|
||||
@Mock
|
||||
private TransformationOptions options;
|
||||
private TransformClient transformClient;
|
||||
|
||||
@Mock
|
||||
private AbstractContentTransformerLimits transformer1;
|
||||
@@ -108,7 +105,14 @@ public class TransformerDebugTest
|
||||
when(transformer3.getName()).thenReturn("transformer3");
|
||||
when(transformer4.getName()).thenReturn("transformer4");
|
||||
|
||||
transformerDebug = new TransformerDebug(nodeService, mimetypeService, transformerRegistry, transformerConfig, log, debug);
|
||||
transformerDebug = new TransformerDebug();
|
||||
transformerDebug.setNodeService(nodeService);
|
||||
transformerDebug.setMimetypeService(mimetypeService);
|
||||
transformerDebug.setTransformerRegistry(transformerRegistry);
|
||||
transformerDebug.setTransformerConfig(transformerConfig);
|
||||
transformerDebug.setTransformerLog(log);
|
||||
transformerDebug.setTransformerDebugLog(debug);
|
||||
transformerDebug.setTransformClient(transformClient);
|
||||
|
||||
log.setTransformerDebug(transformerDebug);
|
||||
log.setTransformerConfig(transformerConfig);
|
||||
@@ -151,7 +155,7 @@ public class TransformerDebugTest
|
||||
{
|
||||
long sourceSize = 1024*1024*3/2;
|
||||
|
||||
transformerDebug.pushAvailable("sourceUrl", "application/pdf", "text/plain", options);
|
||||
transformerDebug.pushAvailable("sourceUrl", "application/pdf", "text/plain", null, null);
|
||||
|
||||
transformerDebug.unavailableTransformer(transformer1, "application/pdf", "text/plain", 50);
|
||||
transformerDebug.unavailableTransformer(transformer2, "application/pdf", "text/plain", 0);
|
||||
@@ -160,7 +164,7 @@ public class TransformerDebugTest
|
||||
|
||||
List<ContentTransformer> transformers = Arrays.asList(new ContentTransformer[] {});
|
||||
|
||||
transformerDebug.availableTransformers(transformers, sourceSize, options, "ContentService.transform(...)");
|
||||
transformerDebug.availableTransformers(transformers, sourceSize, null, null, "ContentService.transform(...)");
|
||||
|
||||
transformerDebug.popAvailable();
|
||||
|
||||
|
@@ -39,10 +39,7 @@ import org.mockito.MockitoAnnotations;
|
||||
* Test class for TransformerLog.
|
||||
*
|
||||
* @author Alan Davis
|
||||
*
|
||||
* @deprecated The transformations code is being moved out of the codebase and replaced by the new async RenditionService2 or other external libraries.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TransformerLogTest
|
||||
{
|
||||
@Mock
|
||||
|
@@ -36,6 +36,7 @@ import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
/**
|
||||
* Provides a base set of tests for {@link TransactionAwareEventProducer}
|
||||
@@ -51,6 +52,7 @@ public class TransactionAwareEventProducerTest extends BaseSpringTest
|
||||
@Autowired
|
||||
private TransactionAwareEventProducer eventProducer;
|
||||
@Autowired
|
||||
@Qualifier("alfrescoEventObjectMapper")
|
||||
private ObjectMapper messagingObjectMapper;
|
||||
|
||||
@Test
|
||||
|
@@ -28,6 +28,7 @@ package org.alfresco.repo.rendition2;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.thumbnail.ThumbnailRegistry;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
@@ -44,7 +45,7 @@ import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
@@ -72,10 +73,7 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest
|
||||
protected RenditionService2Impl renditionService2;
|
||||
|
||||
@Autowired
|
||||
protected RenditionDefinitionRegistry2 renditionDefinitionRegistry2;
|
||||
|
||||
@Autowired
|
||||
protected TransformClient transformClient;
|
||||
protected RenditionDefinitionRegistry2Impl renditionDefinitionRegistry2;
|
||||
|
||||
@Autowired
|
||||
protected RenditionService renditionService;
|
||||
@@ -107,6 +105,15 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest
|
||||
@Autowired
|
||||
protected PermissionService permissionService;
|
||||
|
||||
@Autowired
|
||||
protected TransformServiceRegistry transformServiceRegistry;
|
||||
|
||||
@Autowired
|
||||
protected LocalTransformServiceRegistry localTransformServiceRegistry;
|
||||
|
||||
@Autowired
|
||||
protected LegacyTransformServiceRegistry legacyTransformServiceRegistry;
|
||||
|
||||
static String PASSWORD = "password";
|
||||
|
||||
protected static final String ADMIN = "admin";
|
||||
@@ -115,17 +122,74 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
// Use the docker images for transforms
|
||||
// Use the docker images for transforms (legacy)
|
||||
System.setProperty("alfresco-pdf-renderer.url", "http://localhost:8090/");
|
||||
System.setProperty("img.url", "http://localhost:8091");
|
||||
System.setProperty("jodconverter.url", "http://localhost:8092/");
|
||||
System.setProperty("tika.url", "http://localhost:8093/");
|
||||
|
||||
// Use the docker images for transforms (local)
|
||||
System.setProperty("localTransformer.pdfrenderer.url", "http://localhost:8090/");
|
||||
System.setProperty("localTransformer.imagemagick.url", "http://localhost:8091");
|
||||
System.setProperty("localTransformer.libreoffice.url", "http://localhost:8092/");
|
||||
System.setProperty("localTransformer.tika.url", "http://localhost:8093/");
|
||||
}
|
||||
|
||||
protected static void none()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "false");
|
||||
System.setProperty("local.transform.service.enabled", "false");
|
||||
System.setProperty("legacy.transform.service.enabled", "false");
|
||||
}
|
||||
|
||||
protected static void legacy()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "false");
|
||||
System.setProperty("local.transform.service.enabled", "false");
|
||||
System.setProperty("legacy.transform.service.enabled", "true");
|
||||
}
|
||||
|
||||
protected static void local()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "false");
|
||||
System.setProperty("local.transform.service.enabled", "true");
|
||||
System.setProperty("legacy.transform.service.enabled", "false");
|
||||
}
|
||||
|
||||
protected static void service()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "true");
|
||||
System.setProperty("local.transform.service.enabled", "false");
|
||||
System.setProperty("legacy.transform.service.enabled", "false");
|
||||
}
|
||||
|
||||
protected static void legacyLocal()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "false");
|
||||
System.setProperty("local.transform.service.enabled", "true");
|
||||
System.setProperty("legacy.transform.service.enabled", "true");
|
||||
}
|
||||
|
||||
protected static void legacyLocalService()
|
||||
{
|
||||
System.setProperty("transform.service.enabled", "true");
|
||||
System.setProperty("local.transform.service.enabled", "true");
|
||||
System.setProperty("legacy.transform.service.enabled", "true");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
assertTrue("The RenditionService2 needs to be enabled", renditionService2.isEnabled());
|
||||
|
||||
legacyTransformServiceRegistry.setEnabled(Boolean.parseBoolean(System.getProperty("legacy.transform.service.enabled")));
|
||||
legacyTransformServiceRegistry.afterPropertiesSet();
|
||||
|
||||
localTransformServiceRegistry.setEnabled(Boolean.parseBoolean(System.getProperty("local.transform.service.enabled")));
|
||||
localTransformServiceRegistry.afterPropertiesSet();
|
||||
|
||||
renditionDefinitionRegistry2.setTransformServiceRegistry(transformServiceRegistry);
|
||||
thumbnailRegistry.setTransformServiceRegistry(transformServiceRegistry);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -141,6 +205,15 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest
|
||||
System.clearProperty("img.url");
|
||||
System.clearProperty("jodconverter.url");
|
||||
System.clearProperty("tika.url");
|
||||
|
||||
System.clearProperty("localTransformer.pdfrenderer.url");
|
||||
System.clearProperty("localTransformer.imagemagick.url");
|
||||
System.clearProperty("localTransformer.libreoffice.url");
|
||||
System.clearProperty("localTransformer.tika.url");
|
||||
|
||||
System.clearProperty("transform.service.enabled");
|
||||
System.clearProperty("local.transform.service.enabled");
|
||||
System.clearProperty("legacy.transform.service.enabled");
|
||||
}
|
||||
|
||||
protected void checkRendition(String testFileName, String renditionName, boolean expectedToPass)
|
||||
|
@@ -28,7 +28,6 @@ package org.alfresco.repo.rendition2;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
import org.alfresco.util.testing.category.DebugTests;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -45,11 +44,12 @@ import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* Test it is possible to create renditions from the quick files.
|
||||
* Abstract test class to check it is possible to create renditions from the quick files using combinations of
|
||||
* local transforms, legacy transforms and the Transform Service.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public class RenditionTest extends AbstractRenditionIntegrationTest
|
||||
public abstract class AbstractRenditionTest extends AbstractRenditionIntegrationTest
|
||||
{
|
||||
// This is the same order as produced by MimetypeMap
|
||||
public static final List<String> TAS_REST_API_SOURCE_EXTENSIONS = Arrays.asList(
|
||||
@@ -89,9 +89,7 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
|
||||
"wpd png avatar32",
|
||||
"wpd jpg imgpreview");
|
||||
|
||||
@Autowired
|
||||
private TransformServiceRegistry transformServiceRegistry;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
@@ -148,17 +146,15 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
|
||||
}
|
||||
else
|
||||
{
|
||||
String task = sourceExtension + " " + targetExtension + " " + renditionName;
|
||||
|
||||
try
|
||||
{
|
||||
checkRendition(testFileName, renditionName, !expectedToFail.contains(sourceTragetRendition));
|
||||
successes.add(task);
|
||||
successes.add(sourceTragetRendition);
|
||||
successCount++;
|
||||
}
|
||||
catch (AssertionFailedError e)
|
||||
{
|
||||
failures.add(task + " " + e.getMessage());
|
||||
failures.add(sourceTragetRendition + " " + e.getMessage());
|
||||
failedCount++;
|
||||
}
|
||||
}
|
||||
@@ -217,48 +213,6 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
|
||||
Collections.emptyList(), expectedRenditionCount, expectedFailedCount);
|
||||
}
|
||||
|
||||
@Category(DebugTests.class)
|
||||
@Test
|
||||
public void testTransformServiceConfig() throws Exception
|
||||
{
|
||||
internalTestTransformServiceConfig(57, 0);
|
||||
}
|
||||
|
||||
// Tests all renditions supported by the TransformServiceRegistry (in the case of Transform Service, see
|
||||
// transform-service-config.json and the LegacyLocalTransformServiceRegistry see the original ACS config).
|
||||
protected void internalTestTransformServiceConfig(int expectedRenditionCount, int expectedFailedCount) throws Exception
|
||||
{
|
||||
List<String> sourceExtensions = getAllSourceMimetypes();
|
||||
List<String> excludeList = new ArrayList<>();
|
||||
|
||||
for (String sourceExtension : sourceExtensions)
|
||||
{
|
||||
String sourceMimetype = mimetypeMap.getMimetype(sourceExtension);
|
||||
String testFileName = getTestFileName(sourceMimetype);
|
||||
if (testFileName != null)
|
||||
{
|
||||
Set<String> renditionNames = renditionDefinitionRegistry2.getRenditionNamesFrom(sourceMimetype, -1);
|
||||
for (String renditionName : renditionNames)
|
||||
{
|
||||
RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(renditionName);
|
||||
String targetMimetype = renditionDefinition.getTargetMimetype();
|
||||
String targetExtension = mimetypeMap.getExtension(targetMimetype);
|
||||
|
||||
String sourceTragetRendition = sourceExtension + ' ' + targetExtension + ' ' + renditionName;
|
||||
Map<String, String> actualOptions = renditionDefinition.getTransformOptions();
|
||||
if (!transformServiceRegistry.isSupported(sourceMimetype, -1L, targetMimetype,
|
||||
actualOptions, null))
|
||||
{
|
||||
excludeList.add(sourceTragetRendition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertRenditionsOkayFromSourceExtension(sourceExtensions, excludeList,
|
||||
Collections.emptyList(), expectedRenditionCount, expectedFailedCount);
|
||||
}
|
||||
|
||||
private List<String> getAllSourceMimetypes()
|
||||
{
|
||||
List<String> sourceExtensions = new ArrayList<>();
|
@@ -25,30 +25,30 @@
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Contains common code used in TransformClients.
|
||||
* Repeats quick file rendition tests with local transforms and legacy transformers enabled.
|
||||
* The Transform Service does not exist for the Community edition.
|
||||
* Should be the same result as with legacy or local transforms on their own.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public abstract class AbstractTransformClient implements InitializingBean
|
||||
@Deprecated
|
||||
public class LegacyLocalRenditionTest extends AbstractRenditionTest
|
||||
{
|
||||
protected NodeService nodeService;
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
legacyLocal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
PropertyCheck.mandatory(this, "nodeService", nodeService);
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Repeats quick file rendition tests with local transforms disabled but legacy transformers enabled.
|
||||
* The Transform Service does not exist for the Community edition.
|
||||
* Should be the same result as with local transforms.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public class LegacyRenditionTest extends AbstractRenditionTest
|
||||
{
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
legacy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link LegacyTransformClient}
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyTransformClientIntegrationTest extends LocalTransformClientIntegrationTest
|
||||
{
|
||||
@Autowired
|
||||
protected TransformClient legacyTransformClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
legacy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
transformClient = legacyTransformClient;
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING;
|
||||
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_PDF;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link LegacyTransformServiceRegistry}
|
||||
*/
|
||||
@Deprecated
|
||||
public class LegacyTransformServiceRegistryTest extends LocalTransformServiceRegistryTest
|
||||
{
|
||||
@Autowired
|
||||
private LegacyTransformServiceRegistry legacyTransformServiceRegistry;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
transformServiceRegistry = legacyTransformServiceRegistry;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
legacy();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
|
||||
protected void setEnabled(boolean enabled)
|
||||
{
|
||||
legacyTransformServiceRegistry.setEnabled(enabled);
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import org.alfresco.util.testing.category.DebugTests;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
/**
|
||||
* Repeats quick file rendition tests with local transforms enabled but legacy transformers disabled.
|
||||
* The Transform Service does not exist for the Community edition.
|
||||
* Should be the same result as with legacy transforms only.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public class LocalRenditionTest extends AbstractRenditionTest
|
||||
{
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
local();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
|
||||
// TODO this method will be removed when Local transformers support all 196 renditions supported by legacy
|
||||
@Override
|
||||
@Category(DebugTests.class)
|
||||
@Test
|
||||
public void testAllSourceExtensions() throws Exception
|
||||
{
|
||||
internalTestAllSourceExtensions(57, 0);
|
||||
}
|
||||
}
|
@@ -30,107 +30,89 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link LegacyLocalTransformClient}
|
||||
* Integration tests for {@link LocalTransformClient}
|
||||
*/
|
||||
public class LegacyLocalTransformClientIntegrationTest extends AbstractRenditionIntegrationTest
|
||||
public class LocalTransformClientIntegrationTest extends AbstractRenditionIntegrationTest
|
||||
{
|
||||
@Autowired
|
||||
protected TransformClient localTransformClient;
|
||||
|
||||
protected TransformClient transformClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
local();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
AuthenticationUtil.setRunAsUser(AuthenticationUtil.getAdminUserName());
|
||||
transformClient = localTransformClient;
|
||||
}
|
||||
|
||||
// PDF transformation
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfToJpegMedium() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "medium", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfToDoclib() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "doclib", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfJpegImgpreview() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "imgpreview", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfPngAvatar() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "avatar", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfPngAvatar32() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "avatar32", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderPdfFlashWebpreview() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.pdf", "webpreview", false);
|
||||
}
|
||||
|
||||
// DOCX transformation
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxJpegMedium() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "medium", true);
|
||||
checkClientRendition("quick.docx", "medium", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxDoclib() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "doclib", true);
|
||||
checkClientRendition("quick.docx", "doclib", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxJpegImgpreview() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "imgpreview", true);
|
||||
checkClientRendition("quick.docx", "imgpreview", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxPngAvatar() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "avatar", true);
|
||||
checkClientRendition("quick.docx", "avatar", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxPngAvatar32() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "avatar32", true);
|
||||
checkClientRendition("quick.docx", "avatar32", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxFlashWebpreview() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "webpreview", false);
|
||||
checkClientRendition("quick.docx", "webpreview", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalRenderDocxPdf() throws Exception
|
||||
{
|
||||
localCheckRendition("quick.docx", "pdf", false);
|
||||
checkClientRendition("quick.docx", "pdf", false);
|
||||
}
|
||||
|
||||
private void localCheckRendition(String testFileName, String renditionDefinitionName, boolean expectedToPass) throws InterruptedException
|
||||
protected void checkClientRendition(String testFileName, String renditionDefinitionName, boolean expectedToPass) throws InterruptedException
|
||||
{
|
||||
if (expectedToPass)
|
||||
{
|
||||
@@ -143,11 +125,12 @@ public class LegacyLocalTransformClientIntegrationTest extends AbstractRendition
|
||||
{
|
||||
RenditionDefinition2 renditionDefinition =
|
||||
renditionDefinitionRegistry2.getRenditionDefinition(renditionDefinitionName);
|
||||
transformClient.transform(
|
||||
sourceNode,
|
||||
renditionDefinition,
|
||||
AuthenticationUtil.getAdminUserName(),
|
||||
sourceContentHashCode);
|
||||
String contentUrl = contentData.getContentUrl();
|
||||
String sourceMimetype = contentData.getMimetype();
|
||||
long size = contentData.getSize();
|
||||
String adminUserName = AuthenticationUtil.getAdminUserName();
|
||||
transformClient.checkSupported(sourceNode, renditionDefinition, sourceMimetype, size, contentUrl);
|
||||
transformClient.transform(sourceNode, renditionDefinition, adminUserName, sourceContentHashCode);
|
||||
return null;
|
||||
});
|
||||
ChildAssociationRef childAssociationRef = null;
|
@@ -25,9 +25,12 @@
|
||||
*/
|
||||
package org.alfresco.repo.rendition2;
|
||||
|
||||
import com.sun.star.auth.InvalidArgumentException;
|
||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -38,28 +41,49 @@ import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_OPENXML_WORDPROCESS
|
||||
import static org.alfresco.repo.content.MimetypeMap.MIMETYPE_PDF;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link LegacyLocalTransformServiceRegistry}
|
||||
* Integration tests for {@link LocalTransformServiceRegistry}
|
||||
*/
|
||||
public class LegacyLocalTransformServiceRegistryTest extends AbstractRenditionIntegrationTest
|
||||
public class LocalTransformServiceRegistryTest extends AbstractRenditionIntegrationTest
|
||||
{
|
||||
private static final String RENDITION_NAME = "pdf";
|
||||
|
||||
@Autowired
|
||||
private LegacyLocalTransformServiceRegistry transformServiceRegistry;
|
||||
private LocalTransformServiceRegistry localTransformServiceRegistry;
|
||||
|
||||
@Autowired
|
||||
private RenditionDefinitionRegistry2 renditionDefinitionRegistry2;
|
||||
protected TransformServiceRegistry transformServiceRegistry;
|
||||
|
||||
private Map<String, String> options;
|
||||
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
local();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
transformServiceRegistry = localTransformServiceRegistry;
|
||||
|
||||
RenditionDefinition2 definition2 = renditionDefinitionRegistry2.getRenditionDefinition(RENDITION_NAME);
|
||||
options = definition2.getTransformOptions();
|
||||
}
|
||||
|
||||
protected void setEnabled(boolean enabled)
|
||||
{
|
||||
localTransformServiceRegistry.setEnabled(enabled);
|
||||
}
|
||||
private static final String RENDITION_NAME = "pdf";
|
||||
|
||||
@Autowired
|
||||
private LegacyTransformServiceRegistry legacyTransformServiceRegistry;
|
||||
|
||||
@Test
|
||||
public void testIsSupported()
|
||||
{
|
||||
@@ -71,7 +95,7 @@ public class LegacyLocalTransformServiceRegistryTest extends AbstractRenditionIn
|
||||
// Bad Source
|
||||
Assert.assertFalse(transformServiceRegistry.isSupported("docxBad", 1234, MIMETYPE_PDF, options, RENDITION_NAME));
|
||||
// Bad Target
|
||||
Assert.assertFalse(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, "pdfBad", options, RENDITION_NAME));
|
||||
Assert.assertFalse(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, "pdfBad", options, "pdfBad"));
|
||||
|
||||
// Good MaxSize docx max size is 768K
|
||||
Assert.assertTrue(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 768L*1024, MIMETYPE_PDF, options, RENDITION_NAME));
|
||||
@@ -89,7 +113,7 @@ public class LegacyLocalTransformServiceRegistryTest extends AbstractRenditionIn
|
||||
Assert.assertTrue(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, MIMETYPE_PDF, options, "custom"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testBadOptions()
|
||||
{
|
||||
// Source, Target and Props are in dictionary.properties
|
||||
@@ -105,12 +129,12 @@ public class LegacyLocalTransformServiceRegistryTest extends AbstractRenditionIn
|
||||
Assert.assertTrue(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, MIMETYPE_PDF, options, RENDITION_NAME));
|
||||
try
|
||||
{
|
||||
transformServiceRegistry.setEnabled(false);
|
||||
setEnabled(false);
|
||||
Assert.assertFalse(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, MIMETYPE_PDF, options, RENDITION_NAME));
|
||||
}
|
||||
finally
|
||||
{
|
||||
transformServiceRegistry.setEnabled(true);
|
||||
setEnabled(true);
|
||||
}
|
||||
Assert.assertTrue(transformServiceRegistry.isSupported(MIMETYPE_OPENXML_WORDPROCESSING, 1234, MIMETYPE_PDF, options, RENDITION_NAME));
|
||||
}
|
@@ -32,27 +32,26 @@ import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
/**
|
||||
* Disables local transform and repeats the RenditionTests
|
||||
* Repeats quick file rendition tests with local transforms and legacy transformers disabled.
|
||||
* The Transform Service does not exist for the Community edition.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
public class NoLocalTransformRenditionTest extends RenditionTest
|
||||
public class NoneRenditionTest extends AbstractRenditionTest
|
||||
{
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
System.setProperty("local.transform.service.enabled", "false");
|
||||
none();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.after();
|
||||
System.clearProperty("local.transform.service.enabled");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testTasRestApiRenditions() throws Exception
|
@@ -36,6 +36,9 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
@@ -48,6 +51,13 @@ import static org.junit.Assert.assertNotEquals;
|
||||
*/
|
||||
public class RenditionService2IntegrationTest extends AbstractRenditionIntegrationTest
|
||||
{
|
||||
@BeforeClass
|
||||
public static void before()
|
||||
{
|
||||
AbstractRenditionIntegrationTest.before();
|
||||
legacyLocal();
|
||||
}
|
||||
|
||||
// PDF transformation
|
||||
|
||||
@Test
|
||||
|
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||
import org.alfresco.repo.content.transform.LocalTransformServiceRegistry;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Extends the {@link TransformServiceRegistryImplTest} (used to test the config received from the Transform Service)
|
||||
* so that configuration for the local transformations may be tested. This includes pipelines and options specific
|
||||
* transform steps.
|
||||
*/
|
||||
public class LocalTransformServiceRegistryTest extends TransformServiceRegistryImplTest
|
||||
{
|
||||
protected LocalTransformServiceRegistry registry;
|
||||
private Properties properties;
|
||||
@Mock
|
||||
private TransformerDebug transformerDebug;
|
||||
|
||||
public static final String TRANSFORM_SERVICE_CONFIG = "alfresco/transformers";
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
properties = new Properties();
|
||||
properties.setProperty( "name.url", "dummy");
|
||||
properties.setProperty("transformer1.url", "dummy");
|
||||
properties.setProperty("transformer2.url", "dummy");
|
||||
properties.setProperty("transformer3.url", "dummy");
|
||||
properties.setProperty("transformer4.url", "dummy");
|
||||
properties.setProperty("transformer5.url", "dummy");
|
||||
properties.setProperty( "libreoffice.url", "dummy");
|
||||
properties.setProperty( "tika.url", "dummy");
|
||||
properties.setProperty( "pdfrenderer.url", "dummy");
|
||||
properties.setProperty( "imagemagick.url", "dummy");
|
||||
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected TransformServiceRegistryImpl buildTransformServiceRegistryImpl()
|
||||
{
|
||||
registry = new LocalTransformServiceRegistry();
|
||||
registry.setJsonObjectMapper(JSON_OBJECT_MAPPER);
|
||||
registry.setProperties(properties);
|
||||
registry.setTransformerDebug(transformerDebug);
|
||||
return registry;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown()
|
||||
{
|
||||
// shut down
|
||||
}
|
||||
|
||||
protected String getTransformServiceConfig()
|
||||
{
|
||||
return TRANSFORM_SERVICE_CONFIG;
|
||||
}
|
||||
|
||||
// TODO test pipeline
|
||||
|
||||
// TODO test strict mimetype check
|
||||
|
||||
// TODO test retry transform on different mimetype
|
||||
|
||||
// TODO test using system properties and alfresco-global.properties
|
||||
|
||||
// TODO test the JsonConverter
|
||||
}
|
@@ -29,12 +29,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper class that builds a {@link Transformer} given the source and target extensions and a pipeline of Transformers
|
||||
* for creating intermediary content, or a set of failover transformers.
|
||||
* Helper class that builds a {@link Transformer} given the source and target types and a pipeline of Transformers
|
||||
* for creating intermediary content.
|
||||
*/
|
||||
public class TransformBuilder
|
||||
{
|
||||
public Transformer buildPipeLine(String name, String version, List<SupportedSourceAndTarget> sourceAndTargetList,
|
||||
public Transformer buildPipeLine(String name, List<SupportedSourceAndTarget> sourceAndTargetList,
|
||||
List<ChildTransformer> transformerList)
|
||||
{
|
||||
List<TransformOption> options = new ArrayList<>(transformerList.size());
|
||||
@@ -47,13 +47,6 @@ public class TransformBuilder
|
||||
options.add(new TransformOptionGroup(t.isRequired(), t.getTransformer().getTransformOptions()));
|
||||
}
|
||||
});
|
||||
return new Transformer(name, version, options, sourceAndTargetList);
|
||||
return new Transformer(name, options, sourceAndTargetList);
|
||||
}
|
||||
|
||||
// TODO Commented out for now as it is unclear what the Transform service will support in terms of failover transformations.
|
||||
// Note: The use of a list of Transformers rather than ChildTransformers, as the supplied actual options would have
|
||||
// to match one or more of the transformer's options. Matching one or more options is not currently
|
||||
// implemented by the TransformServiceRegistry
|
||||
// public Transformer buildFailover(String name, String version, List<SupportedSourceAndTarget> sourceAndTargetList,
|
||||
// List<Transformer> transformerList)
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2019 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -26,6 +26,8 @@
|
||||
package org.alfresco.transform.client.model.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -35,7 +37,6 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -50,83 +51,48 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the config received from the Transform Service about what it supports.
|
||||
*/
|
||||
public class TransformServiceRegistryImplTest
|
||||
{
|
||||
public static final String GIF = "gif";
|
||||
public static final String JPEG = "jpeg";
|
||||
public static final String PNG = "png";
|
||||
public static final String TIFF = "tiff";
|
||||
public static final String PDF = "pdf";
|
||||
public static final String DOC = "doc";
|
||||
public static final String XLS = "xls";
|
||||
public static final String PPT = "ppt";
|
||||
public static final String DOCX = "docx";
|
||||
public static final String XLSX = "xlsx";
|
||||
public static final String PPTX = "pptx";
|
||||
public static final String MSG = "msg";
|
||||
public static final String TXT = "txt";
|
||||
private static Log log = LogFactory.getLog(TransformServiceRegistryImplTest.class);
|
||||
|
||||
public static final String GIF_MIMETYPE = "image/gif";
|
||||
public static final String JPEG_MIMETYPE = "image/jpeg";
|
||||
public static final String PNG_MIMETYPE = "image/png";
|
||||
public static final String TIFF_MIMETYPE = "image/tiff";
|
||||
public static final String PDF_MIMETYPE = "application/pdf";
|
||||
public static final String DOC_MIMETYPE = "application/msword";
|
||||
public static final String XLS_MIMETYPE = "application/vnd.ms-excel";
|
||||
public static final String PPT_MIMETYPE = "application/vnd.ms-powerpoint";
|
||||
public static final String DOCX_MIMETYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
|
||||
public static final String XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
||||
public static final String PPTX_MIMETYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
||||
public static final String MSG_MIMETYPE = "application/vnd.ms-outlook";
|
||||
public static final String TXT_MIMETYPE = "text/plain";
|
||||
public static final String GIF = "image/gif";
|
||||
public static final String JPEG = "image/jpeg";
|
||||
public static final String PNG = "image/png";
|
||||
public static final String TIFF = "image/tiff";
|
||||
public static final String PDF = "application/pdf";
|
||||
public static final String DOC = "application/msword";
|
||||
public static final String XLS = "application/vnd.ms-excel";
|
||||
public static final String PPT = "application/vnd.ms-powerpoint";
|
||||
public static final String MSG = "application/vnd.ms-outlook";
|
||||
public static final String TXT = "text/plain";
|
||||
|
||||
public static final String TRANSFORM_SERVICE_CONFIG = "alfresco/transform-service-config.json";
|
||||
public static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
private TransformServiceRegistryImpl registry;
|
||||
private TransformBuilder builder;
|
||||
private Transformer transformer;
|
||||
private ExtensionMap extensionMap;
|
||||
protected TransformBuilder builder;
|
||||
protected Transformer transformer;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
extensionMap = new ExtensionMap()
|
||||
{
|
||||
private Map<String, String> map = new HashMap<>();
|
||||
|
||||
{
|
||||
map.put(GIF, GIF_MIMETYPE);
|
||||
map.put(JPEG, JPEG_MIMETYPE);
|
||||
map.put(PNG, PNG_MIMETYPE);
|
||||
map.put(TIFF, TIFF_MIMETYPE);
|
||||
map.put(PDF, PDF_MIMETYPE);
|
||||
map.put(DOC, DOC_MIMETYPE);
|
||||
map.put(XLS, XLS_MIMETYPE);
|
||||
map.put(PPT, PPT_MIMETYPE);
|
||||
map.put(DOCX, DOCX_MIMETYPE);
|
||||
map.put(XLSX, XLSX_MIMETYPE);
|
||||
map.put(PPTX, PPTX_MIMETYPE);
|
||||
map.put(MSG, MSG_MIMETYPE);
|
||||
map.put(TXT, TXT_MIMETYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMimetype(String extension)
|
||||
{
|
||||
return map.get(extension);
|
||||
}
|
||||
};
|
||||
|
||||
registry = buildTransformServiceRegistryImpl();
|
||||
|
||||
builder = new TransformBuilder();
|
||||
}
|
||||
|
||||
private TransformServiceRegistryImpl buildTransformServiceRegistryImpl()
|
||||
protected TransformServiceRegistryImpl buildTransformServiceRegistryImpl()
|
||||
{
|
||||
TransformServiceRegistryImpl registry = new TransformServiceRegistryImpl();
|
||||
registry.setExtensionMap(extensionMap);
|
||||
TransformServiceRegistryImpl registry = new TransformServiceRegistryImpl()
|
||||
{
|
||||
@Override
|
||||
protected Log getLog()
|
||||
{
|
||||
return log;
|
||||
}
|
||||
};
|
||||
registry.setJsonObjectMapper(JSON_OBJECT_MAPPER);
|
||||
return registry;
|
||||
}
|
||||
@@ -137,6 +103,11 @@ public class TransformServiceRegistryImplTest
|
||||
// shut down
|
||||
}
|
||||
|
||||
protected String getTransformServiceConfig()
|
||||
{
|
||||
return TRANSFORM_SERVICE_CONFIG;
|
||||
}
|
||||
|
||||
private void assertAddToPossibleOptions(TransformOptionGroup transformOptionGroup, String actualOptionNames, String expectedNames, String expectedRequired)
|
||||
{
|
||||
Map<String, String> actualOptions = buildActualOptions(actualOptionNames);
|
||||
@@ -188,7 +159,7 @@ public class TransformServiceRegistryImplTest
|
||||
|
||||
private void assertTransformOptions(List<TransformOption> transformOptions)
|
||||
{
|
||||
transformer = new Transformer("name", "1",
|
||||
transformer = new Transformer("name",
|
||||
transformOptions,
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(DOC, TXT, -1),
|
||||
@@ -197,44 +168,56 @@ public class TransformServiceRegistryImplTest
|
||||
registry = buildTransformServiceRegistryImpl();
|
||||
registry.register(transformer);
|
||||
|
||||
assertTrue(registry.isSupported(XLS_MIMETYPE, 1024, TXT_MIMETYPE, Collections.emptyMap(), null));
|
||||
assertTrue(registry.isSupported(XLS_MIMETYPE, 1024000, TXT_MIMETYPE, null, null));
|
||||
assertFalse(registry.isSupported(XLS_MIMETYPE, 1024001, TXT_MIMETYPE, Collections.emptyMap(), null));
|
||||
assertTrue(registry.isSupported(DOC_MIMETYPE, 1024001, TXT_MIMETYPE, null, null));
|
||||
assertTrue(registry.isSupported(XLS, 1024, TXT, Collections.emptyMap(), null));
|
||||
assertTrue(registry.isSupported(XLS, 1024000, TXT, null, null));
|
||||
assertFalse(registry.isSupported(XLS, 1024001, TXT, Collections.emptyMap(), null));
|
||||
assertTrue(registry.isSupported(DOC, 1024001, TXT, null, null));
|
||||
}
|
||||
|
||||
private void assertSupported(String sourceExt, long sourceSizeInBytes, String targetExt,
|
||||
private void assertTransformerName(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
||||
Map<String, String> actualOptions, String expectedTransformerName,
|
||||
Transformer... transformers)
|
||||
{
|
||||
buildAndPopulateRegistry(transformers);
|
||||
String transformerName = registry.getTransformerName(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, null);
|
||||
assertEquals(sourceMimetype+" to "+targetMimetype+" should have returned "+expectedTransformerName, expectedTransformerName, transformerName);
|
||||
}
|
||||
|
||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
||||
Map<String, String> actualOptions, String unsupportedMsg)
|
||||
{
|
||||
assertSupported(sourceExt, sourceSizeInBytes, targetExt, actualOptions, unsupportedMsg, transformer);
|
||||
assertSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, unsupportedMsg, transformer);
|
||||
}
|
||||
|
||||
private void assertSupported(String sourceExt, long sourceSizeInBytes, String targetExt,
|
||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
||||
Map<String, String> actualOptions, String unsupportedMsg,
|
||||
Transformer... transformers)
|
||||
{
|
||||
buildAndPopulateRegistry(transformers);
|
||||
assertSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, null, unsupportedMsg);
|
||||
}
|
||||
|
||||
private void buildAndPopulateRegistry(Transformer[] transformers)
|
||||
{
|
||||
registry = buildTransformServiceRegistryImpl();
|
||||
for (Transformer transformer : transformers)
|
||||
{
|
||||
registry.register(transformer);
|
||||
}
|
||||
assertSupported(sourceExt, sourceSizeInBytes, targetExt, actualOptions, null, unsupportedMsg);
|
||||
}
|
||||
|
||||
private void assertSupported(String sourceExt, long sourceSizeInBytes, String targetExt,
|
||||
Map<String, String> actualOptions, String transformName,
|
||||
private void assertSupported(String sourceMimetype, long sourceSizeInBytes, String targetMimetype,
|
||||
Map<String, String> actualOptions, String renditionName,
|
||||
String unsupportedMsg)
|
||||
{
|
||||
String sourceMimetype = extensionMap.toMimetype(sourceExt);
|
||||
String targetMimetype = extensionMap.toMimetype(targetExt);
|
||||
boolean supported = registry.isSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, transformName);
|
||||
boolean supported = registry.isSupported(sourceMimetype, sourceSizeInBytes, targetMimetype, actualOptions, renditionName);
|
||||
if (unsupportedMsg == null || unsupportedMsg.isEmpty())
|
||||
{
|
||||
assertTrue(sourceExt+" to "+targetExt+" should be SUPPORTED", supported);
|
||||
assertTrue(sourceMimetype+" to "+targetMimetype+" should be SUPPORTED", supported);
|
||||
}
|
||||
else
|
||||
{
|
||||
assertFalse(sourceExt+" to "+targetExt+" should NOT be supported", supported);
|
||||
assertFalse(sourceMimetype+" to "+targetMimetype+" should NOT be supported", supported);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +235,7 @@ public class TransformServiceRegistryImplTest
|
||||
@Test
|
||||
public void testReadWriteJson() throws IOException
|
||||
{
|
||||
Transformer libreOffice = new Transformer("libreOffice", "1",
|
||||
Transformer libreoffice = new Transformer("libreoffice",
|
||||
null, // there are no options
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(DOC, PDF, -1),
|
||||
@@ -260,7 +243,7 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(PPT, PDF, -1),
|
||||
new SupportedSourceAndTarget(MSG, PDF, -1)));
|
||||
|
||||
Transformer pdfRenderer = new Transformer("pdfRenderer", "1",
|
||||
Transformer pdfrenderer = new Transformer("pdfrenderer",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "page"),
|
||||
new TransformOptionValue(false, "width"),
|
||||
@@ -270,7 +253,7 @@ public class TransformServiceRegistryImplTest
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(PDF, PNG, -1)));
|
||||
|
||||
Transformer tika = new Transformer("tika", "1",
|
||||
Transformer tika = new Transformer("tika",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "transform"),
|
||||
new TransformOptionValue(false, "includeContents"),
|
||||
@@ -284,7 +267,7 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(PPT, TXT, -1),
|
||||
new SupportedSourceAndTarget(MSG, TXT, -1)));
|
||||
|
||||
Transformer imageMagick = new Transformer("imageMagick", "1",
|
||||
Transformer imagemagick = new Transformer("imagemagick",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "alphaRemove"),
|
||||
new TransformOptionValue(false, "autoOrient"),
|
||||
@@ -322,7 +305,7 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(TIFF, PNG, -1),
|
||||
new SupportedSourceAndTarget(TIFF, TIFF, -1)));
|
||||
|
||||
Transformer officeToImage = builder.buildPipeLine("officeToImageViaPdf", "1",
|
||||
Transformer officeToImage = builder.buildPipeLine("transformer1",
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(DOC, GIF, -1),
|
||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
||||
@@ -341,11 +324,11 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(MSG, PNG, -1),
|
||||
new SupportedSourceAndTarget(MSG, TIFF, -1)),
|
||||
Arrays.asList(
|
||||
new ChildTransformer(false, libreOffice), // to pdf
|
||||
new ChildTransformer(false, pdfRenderer), // to png
|
||||
new ChildTransformer(true, imageMagick))); // to other image formats
|
||||
new ChildTransformer(false, libreoffice), // to pdf
|
||||
new ChildTransformer(false, pdfrenderer), // to png
|
||||
new ChildTransformer(true, imagemagick))); // to other image formats
|
||||
|
||||
List<Transformer> transformers1 = Arrays.asList(libreOffice, tika, pdfRenderer, imageMagick, officeToImage);
|
||||
List<Transformer> transformers1 = Arrays.asList(libreoffice, tika, pdfrenderer, imagemagick, officeToImage);
|
||||
|
||||
File tempFile = File.createTempFile("test", ".json");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
@@ -367,25 +350,22 @@ public class TransformServiceRegistryImplTest
|
||||
assertSupported(PDF, 1234, PNG, null, null, ""); // pdfrenderer
|
||||
assertSupported(JPEG,1234, GIF, null, null, ""); // imagemagick
|
||||
assertSupported(MSG, 1234, TXT, null, null, ""); // tika
|
||||
assertSupported(MSG, 1234, GIF, null, null, ""); // officeToImageViaPdf
|
||||
assertSupported(DOC, 1234, PNG, null, null, ""); // officeToImageViaPdf
|
||||
assertSupported(MSG, 1234, GIF, null, null, ""); // transformer1 (officeToImageViaPdf)
|
||||
assertSupported(DOC, 1234, PNG, null, null, ""); // transformer1 (officeToImageViaPdf)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsonConfig() throws IOException
|
||||
{
|
||||
try (Reader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().
|
||||
getResourceAsStream(TRANSFORM_SERVICE_CONFIG))))
|
||||
{
|
||||
registry.register(reader);
|
||||
registry.register(getTransformServiceConfig());
|
||||
|
||||
// Check the count of transforms supported
|
||||
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
||||
63, countSupportedTransforms(true));
|
||||
60, countSupportedTransforms(true));
|
||||
assertEquals("The number of source to target mimetypes transforms has changed. " +
|
||||
"There may be multiple transformers for the same combination. Config change?",
|
||||
63, countSupportedTransforms(false));
|
||||
60, countSupportedTransforms(false));
|
||||
|
||||
// Check a supported transform for each transformer.
|
||||
assertSupported(DOC, 1234, PDF, null, null, ""); // libreoffice
|
||||
@@ -399,15 +379,11 @@ public class TransformServiceRegistryImplTest
|
||||
invalidPdfOptions.put("allowEnlargement", "false");
|
||||
assertSupported(DOC, 1234, PDF, invalidPdfOptions, null, "Invalid as there is a extra option");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsonPipeline() throws IOException
|
||||
{
|
||||
try (Reader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().
|
||||
getResourceAsStream("alfresco/transform-service-config-test1.json"))))
|
||||
{
|
||||
registry.register(reader);
|
||||
registry.register("alfresco/transform-service-config-test1.json");
|
||||
|
||||
// Check the count of transforms supported
|
||||
assertEquals("The number of UNIQUE source to target mimetypes transforms has changed. Config change?",
|
||||
@@ -421,20 +397,20 @@ public class TransformServiceRegistryImplTest
|
||||
|
||||
// Check required and optional default correctly
|
||||
ConcurrentMap<String, List<TransformServiceRegistryImpl.SupportedTransform>> transformsToWord =
|
||||
registry.transformers.get("application/msword");
|
||||
List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms = transformsToWord.get("image/gif");
|
||||
registry.transformers.get(DOC);
|
||||
List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms = transformsToWord.get(GIF);
|
||||
TransformServiceRegistryImpl.SupportedTransform supportedTransform = supportedTransforms.get(0);
|
||||
|
||||
TransformOptionGroup imageMagick = (TransformOptionGroup)supportedTransform.transformOptions.transformOptions.get(0);
|
||||
TransformOptionGroup imagemagick = (TransformOptionGroup)supportedTransform.transformOptions.transformOptions.get(0);
|
||||
TransformOptionGroup pdf = (TransformOptionGroup)supportedTransform.transformOptions.transformOptions.get(1);
|
||||
|
||||
TransformOptionValue alphaRemove = (TransformOptionValue)imageMagick.transformOptions.get(0);
|
||||
TransformOptionGroup crop = (TransformOptionGroup)imageMagick.transformOptions.get(4);
|
||||
TransformOptionValue alphaRemove = (TransformOptionValue)imagemagick.transformOptions.get(0);
|
||||
TransformOptionGroup crop = (TransformOptionGroup)imagemagick.transformOptions.get(4);
|
||||
TransformOptionValue cropGravity = (TransformOptionValue)crop.transformOptions.get(0);
|
||||
TransformOptionValue cropWidth = (TransformOptionValue)crop.transformOptions.get(1);
|
||||
|
||||
assertTrue("The holding group should be required", supportedTransform.transformOptions.isRequired());
|
||||
assertTrue("imageMagick should be required as it is set", imageMagick.isRequired());
|
||||
assertFalse("imagemagick should be optional as it is not set", imagemagick.isRequired());
|
||||
assertFalse("pdf should be optional as required is not set", pdf.isRequired());
|
||||
assertEquals("alphaRemove", alphaRemove.getName());
|
||||
assertEquals("cropGravity", cropGravity.getName());
|
||||
@@ -458,7 +434,6 @@ public class TransformServiceRegistryImplTest
|
||||
actualOptions.put("maintainAspectRatio", "true");
|
||||
assertSupported(DOC,1234, PNG, actualOptions, null, "");
|
||||
}
|
||||
}
|
||||
|
||||
private int countSupportedTransforms(boolean unique)
|
||||
{
|
||||
@@ -627,7 +602,7 @@ public class TransformServiceRegistryImplTest
|
||||
@Test
|
||||
public void testSupported()
|
||||
{
|
||||
transformer = new Transformer("name", "1",
|
||||
transformer = new Transformer("name",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "page"),
|
||||
new TransformOptionValue(false, "width"),
|
||||
@@ -653,7 +628,7 @@ public class TransformServiceRegistryImplTest
|
||||
public void testCache()
|
||||
{
|
||||
// Note: transformNames are an alias for a set of actualOptions and the target mimetpe. The source mimetype may change.
|
||||
transformer = new Transformer("name", "1",
|
||||
transformer = new Transformer("name",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "page"),
|
||||
new TransformOptionValue(false, "width"),
|
||||
@@ -667,18 +642,50 @@ public class TransformServiceRegistryImplTest
|
||||
assertSupported(DOC, 1024, GIF, null, "doclib", "");
|
||||
assertSupported(MSG, 1024, GIF, null, "doclib", "");
|
||||
|
||||
assertEquals(102400L, registry.getMaxSize(DOC_MIMETYPE, GIF_MIMETYPE, null, "doclib"));
|
||||
assertEquals(-1L, registry.getMaxSize(MSG_MIMETYPE, GIF_MIMETYPE, null, "doclib"));
|
||||
assertEquals(102400L, registry.getMaxSize(DOC, GIF, null, "doclib"));
|
||||
assertEquals(-1L, registry.getMaxSize(MSG, GIF, null, "doclib"));
|
||||
|
||||
// Change the cached value and try and check we are now using the cached value.
|
||||
registry.cachedMaxSizes.get("doclib").put(DOC_MIMETYPE, 1234L);
|
||||
assertEquals(1234L, registry.getMaxSize(DOC_MIMETYPE, GIF_MIMETYPE, null, "doclib"));
|
||||
List<TransformServiceRegistryImpl.SupportedTransform> supportedTransforms = registry.cachedSupportedTransformList.get("doclib").get(DOC);
|
||||
supportedTransforms.get(0).maxSourceSizeBytes = 1234L;
|
||||
assertEquals(1234L, registry.getMaxSize(DOC, GIF, null, "doclib"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTransformerName()
|
||||
{
|
||||
Transformer t1 = new Transformer("transformer1", null,
|
||||
Arrays.asList(new SupportedSourceAndTarget(MSG, GIF, 100, 50)));
|
||||
Transformer t2 = new Transformer("transformer2", null,
|
||||
Arrays.asList(new SupportedSourceAndTarget(MSG, GIF, 200, 60)));
|
||||
Transformer t3 = new Transformer("transformer3", null,
|
||||
Arrays.asList(new SupportedSourceAndTarget(MSG, GIF, 200, 40)));
|
||||
Transformer t4 = new Transformer("transformer4", null,
|
||||
Arrays.asList(new SupportedSourceAndTarget(MSG, GIF, -1, 100)));
|
||||
Transformer t5 = new Transformer("transformer5", null,
|
||||
Arrays.asList(new SupportedSourceAndTarget(MSG, GIF, -1, 80)));
|
||||
|
||||
Map<String, String> actualOptions = null;
|
||||
|
||||
// Select on size - priority is ignored
|
||||
assertTransformerName(MSG, 100, GIF, actualOptions, "transformer1", t1, t2);
|
||||
assertTransformerName(MSG, 150, GIF, actualOptions, "transformer2", t1, t2);
|
||||
assertTransformerName(MSG, 250, GIF, actualOptions, null, t1, t2);
|
||||
// Select on priority - t1, t2 and t4 are discarded.
|
||||
// t3 is a higher priority and has a larger size than t1 and t2.
|
||||
// Similar story fo t4 with t5.
|
||||
assertTransformerName(MSG, 100, GIF, actualOptions, "transformer3", t1, t2, t3, t4, t5);
|
||||
assertTransformerName(MSG, 200, GIF, actualOptions, "transformer3", t1, t2, t3, t4, t5);
|
||||
// Select on size and priority, t1 and t2 discarded
|
||||
assertTransformerName(MSG, 200, GIF, actualOptions, "transformer3", t1, t2, t3, t4);
|
||||
assertTransformerName(MSG, 300, GIF, actualOptions, "transformer4", t1, t2, t3, t4);
|
||||
assertTransformerName(MSG, 300, GIF, actualOptions, "transformer5", t1, t2, t3, t4, t5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleTransformers()
|
||||
{
|
||||
Transformer transformer1 = new Transformer("transformer1", "1",
|
||||
Transformer transformer1 = new Transformer("transformer1",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "page"),
|
||||
new TransformOptionValue(false, "width"),
|
||||
@@ -688,7 +695,7 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
||||
new SupportedSourceAndTarget(MSG, GIF, -1)));
|
||||
|
||||
Transformer transformer2 = new Transformer("transformer2", "1",
|
||||
Transformer transformer2 = new Transformer("transformer2",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "opt1"),
|
||||
new TransformOptionValue(false, "opt2")),
|
||||
@@ -696,7 +703,7 @@ public class TransformServiceRegistryImplTest
|
||||
new SupportedSourceAndTarget(PDF, GIF, -1),
|
||||
new SupportedSourceAndTarget(PPT, JPEG, -1)));
|
||||
|
||||
Transformer transformer3 = new Transformer("transformer3", "1",
|
||||
Transformer transformer3 = new Transformer("transformer3",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "opt1")),
|
||||
Arrays.asList(
|
||||
@@ -725,13 +732,13 @@ public class TransformServiceRegistryImplTest
|
||||
@Test
|
||||
public void testPipeline()
|
||||
{
|
||||
Transformer transformer1 = new Transformer("transformer1", "1",
|
||||
Transformer transformer1 = new Transformer("transformer1",
|
||||
null, // there are no options
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(DOC, PDF, -1),
|
||||
new SupportedSourceAndTarget(MSG, PDF, -1)));
|
||||
|
||||
Transformer transformer2 = new Transformer("transformer2", "1",
|
||||
Transformer transformer2 = new Transformer("transformer2",
|
||||
Arrays.asList(
|
||||
new TransformOptionValue(false, "page"),
|
||||
new TransformOptionValue(false, "width"),
|
||||
@@ -764,7 +771,7 @@ public class TransformServiceRegistryImplTest
|
||||
|
||||
private void buildPipelineTransformer(Transformer transformer1, Transformer transformer2)
|
||||
{
|
||||
transformer = builder.buildPipeLine("officeToImage", "1",
|
||||
transformer = builder.buildPipeLine("transformer1",
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget(DOC, GIF, -1),
|
||||
new SupportedSourceAndTarget(DOC, JPEG, -1),
|
||||
@@ -773,14 +780,4 @@ public class TransformServiceRegistryImplTest
|
||||
new ChildTransformer(false, transformer1),
|
||||
new ChildTransformer(true, transformer2)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void textMissingMimetype()
|
||||
{
|
||||
transformer = new Transformer("name", "1",
|
||||
null, // there are no options
|
||||
Arrays.asList(
|
||||
new SupportedSourceAndTarget("rubbish", PDF, -1)));
|
||||
registry.register(transformer);
|
||||
}
|
||||
}
|
@@ -1,12 +1,13 @@
|
||||
[
|
||||
{
|
||||
"name": "officeToImageViaPdf",
|
||||
"version": "1",
|
||||
"transformOptions": [
|
||||
{
|
||||
"group": {
|
||||
"required": true,
|
||||
"transformOptions": [
|
||||
{
|
||||
"transformOptions": {
|
||||
"pdfrendererOptions": [
|
||||
{"value": {"name": "page"}},
|
||||
{"value": {"name": "width"}},
|
||||
{"value": {"name": "height"}},
|
||||
{"value": {"name": "allowPdfEnlargement"}},
|
||||
{"value": {"name": "maintainPdfAspectRatio"}}
|
||||
],
|
||||
"imagemagickOptions": [
|
||||
{"value": {"name": "alphaRemove"}},
|
||||
{"value": {"name": "autoOrient"}},
|
||||
{"value": {"name": "startPage"}},
|
||||
@@ -27,23 +28,20 @@
|
||||
{"value": {"name": "allowEnlargement"}},
|
||||
{"value": {"name": "maintainAspectRatio"}}
|
||||
]}}
|
||||
]}},{
|
||||
"group": {
|
||||
"transformOptions": [
|
||||
{"value": {"name": "page"}},
|
||||
{"value": {"name": "width"}},
|
||||
{"value": {"name": "height"}},
|
||||
{"value": {"name": "allowPdfEnlargement"}},
|
||||
{"value": {"name": "maintainPdfAspectRatio"}}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"supportedSourceAndTargetList": [
|
||||
{"sourceExt": "doc", "targetExt": "gif" },
|
||||
{"sourceExt": "doc", "targetExt": "jpeg"},
|
||||
{"sourceExt": "doc", "targetExt": "png" },
|
||||
{"sourceExt": "doc", "targetExt": "tiff"}
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/gif" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/jpeg"},
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/png" },
|
||||
{"sourceMediaType": "application/msword", "targetMediaType": "image/tiff"}
|
||||
],
|
||||
"transformOptions": [
|
||||
"pdfrendererOptions",
|
||||
"imagemagickOptions"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user