REPO-4082 Transformers should have unique option names (#291)

* REPO-4082 Transformers should have unique option names

In addition to making the transform options, the following tidy up activities were performed:

* Rendition 2 Definitions beans have been simplified so there is just one common parent,
   as this makes it clearer what the transform options are even if some of them are shared.
* Removal of "required": "false" from transform-service-config.json as this is the default.
   Test added to make sure it really is the default for option values and option groups.
*  Refactored some of the code in RenditionTest and a sub classes (in
    alfresco-enterprise-repository) now that the Transform Service is more stable.
    They are now able to share static finals.
This commit is contained in:
alandavis
2018-12-06 09:35:33 +00:00
committed by GitHub
parent ded9d4eb4a
commit 67b8bb3dd5
13 changed files with 352 additions and 239 deletions

View File

@@ -115,6 +115,7 @@ public class RemoteTransformerClient
if (args[i+1] != null) if (args[i+1] != null)
{ {
builder.addTextBody(args[i], args[i + 1]); builder.addTextBody(args[i], args[i + 1]);
sj.add(args[i] + '=' + args[i + 1]); sj.add(args[i] + '=' + args[i + 1]);
} }
} }

View File

@@ -33,7 +33,12 @@ import org.alfresco.repo.content.transform.ContentTransformerWorker;
import org.alfresco.repo.content.transform.RemoteTransformerClient; import org.alfresco.repo.content.transform.RemoteTransformerClient;
import org.alfresco.repo.content.transform.magick.ImageResizeOptions; import org.alfresco.repo.content.transform.magick.ImageResizeOptions;
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions; import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
import org.alfresco.service.cmr.repository.*; 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.PagedSourceOptions;
import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
@@ -46,9 +51,9 @@ import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static org.alfresco.repo.rendition2.RenditionDefinition2.ALLOW_ENLARGEMENT; import static org.alfresco.repo.rendition2.RenditionDefinition2.ALLOW_PDF_ENLARGEMENT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.HEIGHT; import static org.alfresco.repo.rendition2.RenditionDefinition2.HEIGHT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.MAINTAIN_ASPECT_RATIO; import static org.alfresco.repo.rendition2.RenditionDefinition2.MAINTAIN_PDF_ASPECT_RATIO;
import static org.alfresco.repo.rendition2.RenditionDefinition2.PAGE; import static org.alfresco.repo.rendition2.RenditionDefinition2.PAGE;
import static org.alfresco.repo.rendition2.RenditionDefinition2.WIDTH; import static org.alfresco.repo.rendition2.RenditionDefinition2.WIDTH;
@@ -380,8 +385,8 @@ public class AlfrescoPdfRendererContentTransformerWorker extends ContentTransfor
PAGE, page, PAGE, page,
WIDTH, width, WIDTH, width,
HEIGHT, height, HEIGHT, height,
ALLOW_ENLARGEMENT, allowEnlargement, ALLOW_PDF_ENLARGEMENT, allowEnlargement,
MAINTAIN_ASPECT_RATIO, maintainAspectRatio); MAINTAIN_PDF_ASPECT_RATIO, maintainAspectRatio);
} }
@Override @Override

View File

@@ -62,9 +62,6 @@ public interface RenditionDefinition2
public static final String RESIZE_HEIGHT = "resizeHeight"; public static final String RESIZE_HEIGHT = "resizeHeight";
public static final String RESIZE_PERCENTAGE = "resizePercentage"; public static final String RESIZE_PERCENTAGE = "resizePercentage";
// ImageMagick & PdfRenderer options
/** Indicates whether scaling operations should scale up or down (true or false). */ /** Indicates whether scaling operations should scale up or down (true or false). */
public static final String ALLOW_ENLARGEMENT = "allowEnlargement"; public static final String ALLOW_ENLARGEMENT = "allowEnlargement";
@@ -78,6 +75,12 @@ public interface RenditionDefinition2
public static final String WIDTH = "width"; public static final String WIDTH = "width";
public static final String HEIGHT = "height"; public static final String HEIGHT = "height";
/** Indicates whether scaling operations should scale up or down (true or false). */
public static final String ALLOW_PDF_ENLARGEMENT = "allowPdfEnlargement";
/** Indicates whether the aspect ratio of the image should be maintained (true or false). */
public static final String MAINTAIN_PDF_ASPECT_RATIO = "maintainPdfAspectRatio";
// Video options // Video options

View File

@@ -46,6 +46,7 @@ import java.util.Set;
import java.util.StringJoiner; import java.util.StringJoiner;
import static org.alfresco.repo.rendition2.RenditionDefinition2.ALLOW_ENLARGEMENT; import static org.alfresco.repo.rendition2.RenditionDefinition2.ALLOW_ENLARGEMENT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.ALLOW_PDF_ENLARGEMENT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.AUTO_ORIENT; import static org.alfresco.repo.rendition2.RenditionDefinition2.AUTO_ORIENT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.CROP_GRAVITY; import static org.alfresco.repo.rendition2.RenditionDefinition2.CROP_GRAVITY;
import static org.alfresco.repo.rendition2.RenditionDefinition2.CROP_HEIGHT; import static org.alfresco.repo.rendition2.RenditionDefinition2.CROP_HEIGHT;
@@ -59,6 +60,7 @@ import static org.alfresco.repo.rendition2.RenditionDefinition2.FLASH_VERSION;
import static org.alfresco.repo.rendition2.RenditionDefinition2.HEIGHT; import static org.alfresco.repo.rendition2.RenditionDefinition2.HEIGHT;
import static org.alfresco.repo.rendition2.RenditionDefinition2.INCLUDE_CONTENTS; import static org.alfresco.repo.rendition2.RenditionDefinition2.INCLUDE_CONTENTS;
import static org.alfresco.repo.rendition2.RenditionDefinition2.MAINTAIN_ASPECT_RATIO; import static org.alfresco.repo.rendition2.RenditionDefinition2.MAINTAIN_ASPECT_RATIO;
import static org.alfresco.repo.rendition2.RenditionDefinition2.MAINTAIN_PDF_ASPECT_RATIO;
import static org.alfresco.repo.rendition2.RenditionDefinition2.MAX_SOURCE_SIZE_K_BYTES; import static org.alfresco.repo.rendition2.RenditionDefinition2.MAX_SOURCE_SIZE_K_BYTES;
import static org.alfresco.repo.rendition2.RenditionDefinition2.OFFSET; import static org.alfresco.repo.rendition2.RenditionDefinition2.OFFSET;
import static org.alfresco.repo.rendition2.RenditionDefinition2.PAGE; import static org.alfresco.repo.rendition2.RenditionDefinition2.PAGE;
@@ -96,7 +98,8 @@ public class TransformationOptionsConverter implements InitializingBean
private static Set<String> RESIZE_OPTIONS = new HashSet<>(Arrays.asList(new String[] private static Set<String> RESIZE_OPTIONS = new HashSet<>(Arrays.asList(new String[]
{ {
WIDTH, HEIGHT, WIDTH, HEIGHT, ALLOW_PDF_ENLARGEMENT, MAINTAIN_PDF_ASPECT_RATIO,
THUMBNAIL, RESIZE_WIDTH, RESIZE_HEIGHT, RESIZE_PERCENTAGE, THUMBNAIL, RESIZE_WIDTH, RESIZE_HEIGHT, RESIZE_PERCENTAGE,
ALLOW_ENLARGEMENT, MAINTAIN_ASPECT_RATIO ALLOW_ENLARGEMENT, MAINTAIN_ASPECT_RATIO
})); }));
@@ -112,7 +115,7 @@ public class TransformationOptionsConverter implements InitializingBean
private static Set<String> PDF_OPTIONS = new HashSet<>(Arrays.asList(new String[] private static Set<String> PDF_OPTIONS = new HashSet<>(Arrays.asList(new String[]
{ {
PAGE, WIDTH, HEIGHT PAGE, WIDTH, HEIGHT, ALLOW_PDF_ENLARGEMENT, MAINTAIN_PDF_ASPECT_RATIO
})); }));
private static Set<String> FLASH_OPTIONS = new HashSet<>(Arrays.asList(new String[] private static Set<String> FLASH_OPTIONS = new HashSet<>(Arrays.asList(new String[]
@@ -192,13 +195,16 @@ public class TransformationOptionsConverter implements InitializingBean
boolean hasOptions = !subclassOptionNames.isEmpty(); boolean hasOptions = !subclassOptionNames.isEmpty();
if (isPdfRendition || hasOptions) if (isPdfRendition || hasOptions)
{ {
// The "pdf" rendition used the wrong TransformationOptions subclass.
if (isPdfRendition || FLASH_OPTIONS.containsAll(subclassOptionNames)) if (isPdfRendition || FLASH_OPTIONS.containsAll(subclassOptionNames))
{ {
SWFTransformationOptions opts = new SWFTransformationOptions(); SWFTransformationOptions opts = new SWFTransformationOptions();
transformationOptions = opts; transformationOptions = opts;
opts.setFlashVersion(isPdfRendition ? "9" : options.get(FLASH_VERSION)); opts.setFlashVersion(isPdfRendition ? "9" : options.get(FLASH_VERSION));
} }
else if (IMAGE_OPTIONS.containsAll(subclassOptionNames) || PDF_OPTIONS.containsAll(subclassOptionNames)) // Even though the only standard rendition to use the pdf-renderer is "pdf" there may be custom renditions
// that use ImageTransformOptions to specify width, height etc.
else if (IMAGE_OPTIONS.containsAll(subclassOptionNames) || PDF_OPTIONS.containsAll(subclassOptionNames))
{ {
ImageTransformationOptions opts = new ImageTransformationOptions(); ImageTransformationOptions opts = new ImageTransformationOptions();
transformationOptions = opts; transformationOptions = opts;

View File

@@ -29,7 +29,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
/** /**
* Represents an individual transformer option or group of options that are required or optional. * Represents an individual transformer option or group of options that are required or optional (default).
*/ */
@JsonTypeInfo( @JsonTypeInfo(
use = JsonTypeInfo.Id.NAME, use = JsonTypeInfo.Id.NAME,

View File

@@ -35,7 +35,7 @@ import java.util.List;
public class TransformOptionGroup implements TransformOption public class TransformOptionGroup implements TransformOption
{ {
private boolean required; private boolean required;
private List<TransformOption> transformOptions; List<TransformOption> transformOptions;
public TransformOptionGroup() public TransformOptionGroup()
{ {

View File

@@ -42,13 +42,13 @@ import java.util.concurrent.ConcurrentMap;
import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT; import static org.alfresco.repo.rendition2.RenditionDefinition2.TIMEOUT;
/** /**
* Used by clients work out if a transformation is supported by the Transform Service. * Used by clients to work out if a transformation is supported by the Transform Service.
*/ */
public class TransformServiceRegistryImpl implements TransformServiceRegistry, InitializingBean public class TransformServiceRegistryImpl implements TransformServiceRegistry, InitializingBean
{ {
class SupportedTransform class SupportedTransform
{ {
private TransformOptionGroup transformOptions; TransformOptionGroup transformOptions;
private long maxSourceSizeBytes; private long maxSourceSizeBytes;
public SupportedTransform(List<TransformOption> transformOptions, long maxSourceSizeBytes) public SupportedTransform(List<TransformOption> transformOptions, long maxSourceSizeBytes)

View File

@@ -119,103 +119,115 @@
<property name="transformServiceRegistry" ref="transformServiceRegistry" /> <property name="transformServiceRegistry" ref="transformServiceRegistry" />
</bean> </bean>
<!-- The definitions --> <!-- Process raw content update events -->
<bean id="baseRenditionDefinition2" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl" abstract="true">
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
<constructor-arg name="transformOptions">
<map>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
</bean>
<bean id="baseResizeRenditionDefinition2" parent="baseRenditionDefinition2" abstract="true">
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Medium" parent="baseResizeRenditionDefinition2">
<constructor-arg name="renditionName" value="medium"/>
<constructor-arg name="targetMimetype" value="image/jpeg"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="resizeWidth" value="100"/>
<entry key="resizeHeight" value="100"/>
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2DocLib" parent="baseResizeRenditionDefinition2">
<constructor-arg name="renditionName" value="doclib"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="resizeWidth" value="100"/>
<entry key="resizeHeight" value="100"/>
<entry key="allowEnlargement" value="false" />
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Imgpreview" parent="baseResizeRenditionDefinition2">
<constructor-arg name="renditionName" value="imgpreview"/>
<constructor-arg name="targetMimetype" value="image/jpeg"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="resizeWidth" value="960"/>
<entry key="resizeHeight" value="960"/>
<entry key="allowEnlargement" value="false" />
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Avatar" parent="baseResizeRenditionDefinition2">
<constructor-arg name="renditionName" value="avatar"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="resizeWidth" value="64"/>
<entry key="resizeHeight" value="64"/>
<entry key="allowEnlargement" value="false" />
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Avatar32" parent="baseResizeRenditionDefinition2">
<constructor-arg name="renditionName" value="avatar32"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="resizeWidth" value="32"/>
<entry key="resizeHeight" value="32"/>
<entry key="allowEnlargement" value="false" />
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Webpreview" parent="baseRenditionDefinition2">
<constructor-arg name="renditionName" value="webpreview"/>
<constructor-arg name="targetMimetype" value="application/x-shockwave-flash"/>
<constructor-arg name="transformOptions">
<map merge="true">
<entry key="flashVersion" value="9"/>
</map>
</constructor-arg>
</bean>
<bean id="renditionDefinition2Pdf" parent="baseRenditionDefinition2">
<constructor-arg name="renditionName" value="pdf"/>
<constructor-arg name="targetMimetype" value="application/pdf"/>
</bean>
<bean id="renditionEventProcessor" class="org.alfresco.repo.rendition2.RenditionEventProcessor"> <bean id="renditionEventProcessor" class="org.alfresco.repo.rendition2.RenditionEventProcessor">
<property name="renditionService2" ref="renditionService2" /> <property name="renditionService2" ref="renditionService2" />
<property name="messagingObjectMapper" ref="alfrescoEventObjectMapper" /> <property name="messagingObjectMapper" ref="alfrescoEventObjectMapper" />
<property name="transactionService" ref="transactionService" /> <property name="transactionService" ref="transactionService" />
</bean> </bean>
<!-- The definitions -->
<bean id="renditionDefinition2Medium" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="medium"/>
<constructor-arg name="targetMimetype" value="image/jpeg"/>
<constructor-arg name="transformOptions">
<map>
<entry key="resizeWidth" value="100"/>
<entry key="resizeHeight" value="100"/>
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2DocLib" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="doclib"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map>
<entry key="resizeWidth" value="100"/>
<entry key="resizeHeight" value="100"/>
<entry key="allowEnlargement" value="false" />
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2Imgpreview" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="imgpreview"/>
<constructor-arg name="targetMimetype" value="image/jpeg"/>
<constructor-arg name="transformOptions">
<map>
<entry key="resizeWidth" value="960"/>
<entry key="resizeHeight" value="960"/>
<entry key="allowEnlargement" value="false" />
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2Avatar" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="avatar"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map>
<entry key="resizeWidth" value="64"/>
<entry key="resizeHeight" value="64"/>
<entry key="allowEnlargement" value="false" />
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2Avatar32" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="avatar32"/>
<constructor-arg name="targetMimetype" value="image/png"/>
<constructor-arg name="transformOptions">
<map>
<entry key="resizeWidth" value="32"/>
<entry key="resizeHeight" value="32"/>
<entry key="allowEnlargement" value="false" />
<entry key="maintainAspectRatio" value="true"/>
<entry key="thumbnail" value="true"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2Webpreview" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="webpreview"/>
<constructor-arg name="targetMimetype" value="application/x-shockwave-flash"/>
<constructor-arg name="transformOptions">
<map>
<entry key="flashVersion" value="9"/>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
<bean id="renditionDefinition2Pdf" class="org.alfresco.repo.rendition2.RenditionDefinition2Impl">
<constructor-arg name="renditionName" value="pdf"/>
<constructor-arg name="targetMimetype" value="application/pdf"/>
<constructor-arg name="transformOptions">
<map>
<entry key="timeout" value="${system.thumbnail.definition.default.timeoutMs}" />
</map>
</constructor-arg>
<constructor-arg name="registry" ref="renditionDefinitionRegistry2"/>
</bean>
</beans> </beans>

View File

@@ -4,7 +4,7 @@
"version": "1", "version": "1",
"supportedSourceAndTargetList": [ "supportedSourceAndTargetList": [
{"sourceExt": "doc", "targetExt": "doc" }, {"sourceExt": "doc", "targetExt": "doc" },
{"sourceExt": "docx", "targetExt": "doc" }, {"sourceExt": "docx", "targetExt": "doc" },
{"sourceExt": "doc", "maxSourceSizeBytes": 10485760, "targetExt": "pdf" }, {"sourceExt": "doc", "maxSourceSizeBytes": 10485760, "targetExt": "pdf" },
{"sourceExt": "xls", "maxSourceSizeBytes": 10485760, "targetExt": "pdf"}, {"sourceExt": "xls", "maxSourceSizeBytes": 10485760, "targetExt": "pdf"},
{"sourceExt": "ppt", "maxSourceSizeBytes": 6291456, "targetExt": "pdf" }, {"sourceExt": "ppt", "maxSourceSizeBytes": 6291456, "targetExt": "pdf" },
@@ -18,11 +18,11 @@
"name": "tika", "name": "tika",
"version": "1", "version": "1",
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "transform"}}, {"value": {"name": "transform"}},
{"value": {"required": false, "name": "includeContents"}}, {"value": {"name": "includeContents"}},
{"value": {"required": false, "name": "notExtractBookmarksText"}}, {"value": {"name": "notExtractBookmarksText"}},
{"value": {"required": false, "name": "targetMimetype"}}, {"value": {"name": "targetMimetype"}},
{"value": {"required": false, "name": "targetEncoding"}} {"value": {"name": "targetEncoding"}}
], ],
"supportedSourceAndTargetList": [ "supportedSourceAndTargetList": [
{"sourceExt": "pdf", "maxSourceSizeBytes": 26214400, "targetExt": "txt" }, {"sourceExt": "pdf", "maxSourceSizeBytes": 26214400, "targetExt": "txt" },
@@ -39,11 +39,11 @@
"name": "pdfRenderer", "name": "pdfRenderer",
"version": "1", "version": "1",
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "page"}}, {"value": {"name": "page"}},
{"value": {"required": false, "name": "width"}}, {"value": {"name": "width"}},
{"value": {"required": false, "name": "height"}}, {"value": {"name": "height"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowPdfEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainPdfAspectRatio"}}
], ],
"supportedSourceAndTargetList": [ "supportedSourceAndTargetList": [
{"sourceExt": "pdf", "targetExt": "png" } {"sourceExt": "pdf", "targetExt": "png" }
@@ -53,25 +53,25 @@
"name": "imageMagick", "name": "imageMagick",
"version": "1", "version": "1",
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "alphaRemove"}}, {"value": {"name": "alphaRemove"}},
{"value": {"required": false, "name": "autoOrient"}}, {"value": {"name": "autoOrient"}},
{"value": {"required": false, "name": "startPage"}}, {"value": {"name": "startPage"}},
{"value": {"required": false, "name": "endPage"}}, {"value": {"name": "endPage"}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "cropGravity"}}, {"value": {"name": "cropGravity"}},
{"value": {"required": false, "name": "cropWidth"}}, {"value": {"name": "cropWidth"}},
{"value": {"required": false, "name": "cropHeight"}}, {"value": {"name": "cropHeight"}},
{"value": {"required": false, "name": "cropPercentage"}}, {"value": {"name": "cropPercentage"}},
{"value": {"required": false, "name": "cropXOffset"}}, {"value": {"name": "cropXOffset"}},
{"value": {"required": false, "name": "cropYOffset"}} {"value": {"name": "cropYOffset"}}
]}}, ]}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "thumbnail"}}, {"value": {"name": "thumbnail"}},
{"value": {"required": false, "name": "resizeHeight"}}, {"value": {"name": "resizeHeight"}},
{"value": {"required": false, "name": "resizeWidth"}}, {"value": {"name": "resizeWidth"}},
{"value": {"required": false, "name": "resizePercentage"}}, {"value": {"name": "resizePercentage"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainAspectRatio"}}
]}} ]}}
], ],
"supportedSourceAndTargetList": [ "supportedSourceAndTargetList": [
@@ -102,35 +102,35 @@
"group": { "group": {
"required": true, "required": true,
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "alphaRemove"}}, {"value": {"name": "alphaRemove"}},
{"value": {"required": false, "name": "autoOrient"}}, {"value": {"name": "autoOrient"}},
{"value": {"required": false, "name": "startPage"}}, {"value": {"name": "startPage"}},
{"value": {"required": false, "name": "endPage"}}, {"value": {"name": "endPage"}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "cropGravity"}}, {"value": {"name": "cropGravity"}},
{"value": {"required": false, "name": "cropWidth"}}, {"value": {"name": "cropWidth"}},
{"value": {"required": false, "name": "cropHeight"}}, {"value": {"name": "cropHeight"}},
{"value": {"required": false, "name": "cropPercentage"}}, {"value": {"name": "cropPercentage"}},
{"value": {"required": false, "name": "cropXOffset"}}, {"value": {"name": "cropXOffset"}},
{"value": {"required": false, "name": "cropYOffset"}} {"value": {"name": "cropYOffset"}}
]}}, ]}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "thumbnail"}}, {"value": {"name": "thumbnail"}},
{"value": {"required": false, "name": "resizeHeight"}}, {"value": {"name": "resizeHeight"}},
{"value": {"required": false, "name": "resizeWidth"}}, {"value": {"name": "resizeWidth"}},
{"value": {"required": false, "name": "resizePercentage"}}, {"value": {"name": "resizePercentage"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainAspectRatio"}}
]}} ]}}
]}},{ ]}},{
"group": { "group": {
"required": false, "required": false,
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "page"}}, {"value": {"name": "page"}},
{"value": {"required": false, "name": "width"}}, {"value": {"name": "width"}},
{"value": {"required": false, "name": "height"}}, {"value": {"name": "height"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowPdfEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainPdfAspectRatio"}}
] ]
} }
} }

View File

@@ -74,4 +74,10 @@ public class NoLocalTransformRenditionTest extends RenditionTest
{ {
internalTestGifRenditions(0, 0); internalTestGifRenditions(0, 0);
} }
@Test
public void testAllTransformServiceConfigRenditions() throws Exception
{
internalTestTasRestApiRenditions(0, 0);
}
} }

View File

@@ -28,16 +28,19 @@ package org.alfresco.repo.rendition2;
import junit.framework.AssertionFailedError; import junit.framework.AssertionFailedError;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.thumbnail.ThumbnailDefinition; import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.transform.client.model.config.TransformServiceRegistry;
import org.alfresco.util.testing.category.DebugTests; import org.alfresco.util.testing.category.DebugTests;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringJoiner; import java.util.StringJoiner;
@@ -48,6 +51,47 @@ import java.util.StringJoiner;
*/ */
public class RenditionTest extends AbstractRenditionIntegrationTest public class RenditionTest extends AbstractRenditionIntegrationTest
{ {
// This is the same order as produced by MimetypeMap
public static final List<String> TAS_REST_API_SOURCE_EXTENSIONS = Arrays.asList(
"gif", "jpg", "png", "msg", "doc","ppt", "xls", "docx", "pptx", "xlsx");
public static final List<String> TAS_REST_API_EXCLUDE_LIST = Collections.EMPTY_LIST;
public static final List<String> ALL_SOURCE_EXTENSIONS_EXCLUDE_LIST = Arrays.asList(
"key jpg imgpreview",
"key jpg medium",
"key png doclib",
"key png avatar",
"key png avatar32",
"pages jpg imgpreview",
"pages jpg medium",
"pages png doclib",
"pages png avatar",
"pages png avatar32",
"numbers jpg imgpreview",
"numbers jpg medium",
"numbers png doclib",
"numbers png avatar",
"numbers png avatar32",
"tiff jpg imgpreview",
"tiff jpg medium",
"tiff png doclib",
"tiff png avatar",
"tiff png avatar32",
"wpd pdf pdf",
"wpd jpg medium",
"wpd png doclib",
"wpd png avatar",
"wpd png avatar32",
"wpd jpg imgpreview");
@Autowired
private TransformServiceRegistry transformServiceRegistry;
@Before @Before
public void setUp() throws Exception public void setUp() throws Exception
{ {
@@ -70,10 +114,10 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
private void assertRenditionsOkayFromSourceExtension(List<String> sourceExtensions, List<String> excludeList, List<String> expectedToFail, private void assertRenditionsOkayFromSourceExtension(List<String> sourceExtensions, List<String> excludeList, List<String> expectedToFail,
int expectedRenditionCount, int expectedFailedCount) throws Exception int expectedRenditionCount, int expectedFailedCount) throws Exception
{ {
int expectedSuccessCount = expectedRenditionCount - Math.min(excludeList.size(), expectedRenditionCount) - expectedFailedCount;
int renditionCount = 0; int renditionCount = 0;
int failedCount = 0; int failedCount = 0;
int successCount = 0; int successCount = 0;
int excludedCount = 0;
RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2(); RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2();
StringJoiner failures = new StringJoiner("\n"); StringJoiner failures = new StringJoiner("\n");
StringJoiner successes = new StringJoiner("\n"); StringJoiner successes = new StringJoiner("\n");
@@ -98,7 +142,11 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
String targetExtension = mimetypeMap.getExtension(targetMimetype); String targetExtension = mimetypeMap.getExtension(targetMimetype);
String sourceTragetRendition = sourceExtension + ' ' + targetExtension + ' ' + renditionName; String sourceTragetRendition = sourceExtension + ' ' + targetExtension + ' ' + renditionName;
if (!excludeList.contains(sourceTragetRendition)) if (excludeList.contains(sourceTragetRendition))
{
excludedCount++;
}
else
{ {
String task = sourceExtension + " " + targetExtension + " " + renditionName; String task = sourceExtension + " " + targetExtension + " " + renditionName;
@@ -117,6 +165,8 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
} }
} }
} }
int expectedSuccessCount = expectedRenditionCount - excludedCount - expectedFailedCount;
System.out.println("FAILURES:\n"+failures+"\n"); System.out.println("FAILURES:\n"+failures+"\n");
System.out.println("SUCCESSES:\n"+successes+"\n"); System.out.println("SUCCESSES:\n"+successes+"\n");
System.out.println("renditionCount: "+renditionCount+" expected "+expectedRenditionCount); System.out.println("renditionCount: "+renditionCount+" expected "+expectedRenditionCount);
@@ -140,7 +190,7 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
assertEquals("Added or removed a definition (rendition-service2-contex.xml)?", 7, renditionNames.size()); assertEquals("Added or removed a definition (rendition-service2-contex.xml)?", 7, renditionNames.size());
} }
@Test @Category(DebugTests.class)
public void testTasRestApiRenditions() throws Exception public void testTasRestApiRenditions() throws Exception
{ {
internalTestTasRestApiRenditions(62, 0); internalTestTasRestApiRenditions(62, 0);
@@ -148,15 +198,7 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
protected void internalTestTasRestApiRenditions(int expectedRenditionCount, int expectedFailedCount) throws Exception protected void internalTestTasRestApiRenditions(int expectedRenditionCount, int expectedFailedCount) throws Exception
{ {
assertRenditionsOkayFromSourceExtension(Arrays.asList("doc", "xls", "ppt", "docx", "xlsx", "pptx", "msg", "pdf", "png", "gif", "jpg"), assertRenditionsOkayFromSourceExtension(TAS_REST_API_SOURCE_EXTENSIONS, TAS_REST_API_EXCLUDE_LIST,
Arrays.asList(new String[]{
"docx jpg imgpreview",
"docx jpg medium",
"xlsx jpg imgpreview",
"xlsx jpg medium",
}),
Collections.emptyList(), expectedRenditionCount, expectedFailedCount); Collections.emptyList(), expectedRenditionCount, expectedFailedCount);
} }
@@ -168,6 +210,56 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
} }
protected void internalTestAllSourceExtensions(int expectedRenditionCount, int expectedFailedCount) throws Exception protected void internalTestAllSourceExtensions(int expectedRenditionCount, int expectedFailedCount) throws Exception
{
List<String> sourceExtensions = getAllSourceMimetypes();
assertRenditionsOkayFromSourceExtension(sourceExtensions,
ALL_SOURCE_EXTENSIONS_EXCLUDE_LIST,
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<>(); List<String> sourceExtensions = new ArrayList<>();
for (String sourceMimetype : mimetypeMap.getMimetypes()) for (String sourceMimetype : mimetypeMap.getMimetypes())
@@ -175,46 +267,7 @@ public class RenditionTest extends AbstractRenditionIntegrationTest
String sourceExtension = mimetypeMap.getExtension(sourceMimetype); String sourceExtension = mimetypeMap.getExtension(sourceMimetype);
sourceExtensions.add(sourceExtension); sourceExtensions.add(sourceExtension);
} }
assertRenditionsOkayFromSourceExtension(sourceExtensions, return sourceExtensions;
Arrays.asList(new String[]{
"docx jpg imgpreview",
"docx jpg medium",
"xlsx jpg imgpreview",
"xlsx jpg medium",
"key jpg imgpreview",
"key jpg medium",
"key png doclib",
"key png avatar",
"key png avatar32",
"pages jpg imgpreview",
"pages jpg medium",
"pages png doclib",
"pages png avatar",
"pages png avatar32",
"numbers jpg imgpreview",
"numbers jpg medium",
"numbers png doclib",
"numbers png avatar",
"numbers png avatar32",
"tiff jpg imgpreview",
"tiff jpg medium",
"tiff png doclib",
"tiff png avatar",
"tiff png avatar32",
"wpd pdf pdf",
"wpd jpg medium",
"wpd png doclib",
"wpd png avatar",
"wpd png avatar32",
"wpd jpg imgpreview"
}),
Collections.emptyList(), expectedRenditionCount, expectedFailedCount);
} }
@Test @Test

View File

@@ -265,8 +265,8 @@ public class TransformServiceRegistryImplTest
new TransformOptionValue(false, "page"), new TransformOptionValue(false, "page"),
new TransformOptionValue(false, "width"), new TransformOptionValue(false, "width"),
new TransformOptionValue(false, "height"), new TransformOptionValue(false, "height"),
new TransformOptionValue(false, "allowEnlargement"), new TransformOptionValue(false, "allowPdfEnlargement"),
new TransformOptionValue(false, "maintainAspectRatio")), new TransformOptionValue(false, "maintainPdfAspectRatio")),
Arrays.asList( Arrays.asList(
new SupportedSourceAndTarget(PDF, PNG, -1))); new SupportedSourceAndTarget(PDF, PNG, -1)));
@@ -416,6 +416,34 @@ public class TransformServiceRegistryImplTest
"There may be multiple transformers for the same combination. Config change?", "There may be multiple transformers for the same combination. Config change?",
4, countSupportedTransforms(false)); 4, countSupportedTransforms(false));
ConcurrentMap<String, List<TransformServiceRegistryImpl.SupportedTransform>> transformer =
registry.transformers.get("officeToImageViaPdf");
// 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");
TransformServiceRegistryImpl.SupportedTransform supportedTransform = supportedTransforms.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 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("pdf should be optional as required is not set", pdf.isRequired());
assertEquals("alphaRemove", alphaRemove.getName());
assertEquals("cropGravity", cropGravity.getName());
assertEquals("cropWidth", cropWidth.getName());
assertFalse("alphaRemove should be optional as required is not set", alphaRemove.isRequired());
assertFalse("crop should be optional as required is not set", crop.isRequired());
assertTrue("cropGravity should be required as it is set", cropGravity.isRequired());
assertFalse("cropWidth should be optional as required is not set", cropWidth.isRequired());
// Check a supported transform for each transformer. // Check a supported transform for each transformer.
assertSupported(DOC,1234, GIF, null, null, ""); assertSupported(DOC,1234, GIF, null, null, "");
assertSupported(DOC,1234, PNG, null, null, ""); assertSupported(DOC,1234, PNG, null, null, "");

View File

@@ -7,35 +7,34 @@
"group": { "group": {
"required": true, "required": true,
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "alphaRemove"}}, {"value": {"name": "alphaRemove"}},
{"value": {"required": false, "name": "autoOrient"}}, {"value": {"name": "autoOrient"}},
{"value": {"required": false, "name": "startPage"}}, {"value": {"name": "startPage"}},
{"value": {"required": false, "name": "endPage"}}, {"value": {"name": "endPage"}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "cropGravity"}}, {"value": {"required": "true", "name": "cropGravity"}},
{"value": {"required": false, "name": "cropWidth"}}, {"value": {"name": "cropWidth"}},
{"value": {"required": false, "name": "cropHeight"}}, {"value": {"name": "cropHeight"}},
{"value": {"required": false, "name": "cropPercentage"}}, {"value": {"name": "cropPercentage"}},
{"value": {"required": false, "name": "cropXOffset"}}, {"value": {"name": "cropXOffset"}},
{"value": {"required": false, "name": "cropYOffset"}} {"value": {"name": "cropYOffset"}}
]}}, ]}},
{"group": {"required": false, "transformOptions": [ {"group": {"transformOptions": [
{"value": {"required": false, "name": "thumbnail"}}, {"value": {"name": "thumbnail"}},
{"value": {"required": false, "name": "resizeHeight"}}, {"value": {"name": "resizeHeight"}},
{"value": {"required": false, "name": "resizeWidth"}}, {"value": {"name": "resizeWidth"}},
{"value": {"required": false, "name": "resizePercentage"}}, {"value": {"name": "resizePercentage"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainAspectRatio"}}
]}} ]}}
]}},{ ]}},{
"group": { "group": {
"required": false,
"transformOptions": [ "transformOptions": [
{"value": {"required": false, "name": "page"}}, {"value": {"name": "page"}},
{"value": {"required": false, "name": "width"}}, {"value": {"name": "width"}},
{"value": {"required": false, "name": "height"}}, {"value": {"name": "height"}},
{"value": {"required": false, "name": "allowEnlargement"}}, {"value": {"name": "allowPdfEnlargement"}},
{"value": {"required": false, "name": "maintainAspectRatio"}} {"value": {"name": "maintainPdfAspectRatio"}}
] ]
} }
} }