mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged BRANCHES/DEV/RGAUSS/HEAD-SOURCE-TARGET-TRANS-OPTIONS to HEAD:
45449: ALF-13254: TransformationOptions Should Have Separate Source and Target Options - Added SerializedTransformationOptionsAccessor interface which defines the methods used in the protected AbstractRenderingEngine.RenderContext class in a public manner - Changed AbstractRenderingEngine.RenderContext to implement SerializedTransformationOptionsAccessor - Added TransformationSourceOptions interface which also contains TransformationSourceOptionsSerializer interface which uses SerializedTransformationOptionsAccessor for deserialization - Added base AbstractTransformationSourceOptions class - Added PagedSourceOptions class which extends TransformationSourceOptions for start and end page options - Added TemporalSourceOptions class which extends TransformationSourceOptions for time-based offset and duration options - Changed TransformationOptions to contain TransformationSourceOptions held as a map with class as key - Changed ImageTransformationOptions to extend copyFrom - Changed ImageMagickContentTransformerWorker.getSourcePageRange to check for paged source options in the TransformationOptions passed in - Added ImageMagickContentTransformerTest.testPageSourceOptions to test null, default, page 2, and invalid options - Changed ThumbnailRenditionConvertor to iterate the transformationOptions.sourceOptionsList and use each serializer to add to the parameters - Changed AbstractTransformationRenderingEngine to iterate a list of TransformationSourceOptionsSerializers and use each to deserialize the RenderContext parameters and construct a TransformationSourceOptions object - Changed rendition-services-context.xml to set imageRenderingEngine's list of known sourceOptionsSerializers - Changed ThumbnailServiceImplParameterTest to test paged and temporal options - Added ThumbanailServiceImplTest.testCreateRenditionThumbnailFromPdfPage2 which tests grabbing the second page of a PDF git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@46062 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -138,6 +138,12 @@
|
||||
<bean id="imageRenderingEngine"
|
||||
class="org.alfresco.repo.rendition.executer.ImageRenderingEngine"
|
||||
parent="baseRenderingAction">
|
||||
<property name="sourceOptionsSerializers">
|
||||
<list>
|
||||
<bean class="org.alfresco.service.cmr.repository.PagedSourceOptions" factory-method="createSerializerInstance" />
|
||||
<bean class="org.alfresco.service.cmr.repository.TemporalSourceOptions" factory-method="createSerializerInstance" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="freemarkerRenderingEngine"
|
||||
|
@@ -18,14 +18,23 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.transform.magick;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
import org.alfresco.repo.content.transform.ProxyContentTransformer;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationSourceOptions;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.content.transform.magick.JMagickContentTransformer
|
||||
@@ -73,6 +82,95 @@ public class ImageMagickContentTransformerTest extends AbstractContentTransforme
|
||||
assertEquals("Mimetype should be supported", true, reliability);
|
||||
}
|
||||
|
||||
protected void transform(String sourceMimetype, String targetMimetype, TransformationOptions options) throws IOException
|
||||
{
|
||||
String[] quickFiles = getQuickFilenames(sourceMimetype);
|
||||
for (String quickFile : quickFiles)
|
||||
{
|
||||
String sourceExtension = quickFile.substring(quickFile.lastIndexOf('.')+1);
|
||||
String targetExtension = mimetypeService.getExtension(targetMimetype);
|
||||
|
||||
// is there a test file for this conversion?
|
||||
File sourceFile = AbstractContentTransformerTest.loadNamedQuickTestFile(quickFile);
|
||||
if (sourceFile == null)
|
||||
{
|
||||
continue; // no test file available for that extension
|
||||
}
|
||||
ContentReader sourceReader = new FileContentReader(sourceFile);
|
||||
|
||||
// make a writer for the target file
|
||||
File targetFile = TempFileProvider.createTempFile(
|
||||
getClass().getSimpleName() + "_" + getName() + "_" + sourceExtension + "_",
|
||||
"." + targetExtension);
|
||||
ContentWriter targetWriter = new FileContentWriter(targetFile);
|
||||
|
||||
// do the transformation
|
||||
sourceReader.setMimetype(sourceMimetype);
|
||||
targetWriter.setMimetype(targetMimetype);
|
||||
transformer.transform(sourceReader.getReader(), targetWriter, options);
|
||||
ContentReader targetReader = targetWriter.getReader();
|
||||
assertTrue(targetReader.getSize() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void testPageSourceOptions() throws Exception
|
||||
{
|
||||
// Test empty source options
|
||||
ImageTransformationOptions options = new ImageTransformationOptions();
|
||||
this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options);
|
||||
|
||||
// Test first page
|
||||
options = new ImageTransformationOptions();
|
||||
List<TransformationSourceOptions> sourceOptionsList = new ArrayList<TransformationSourceOptions>();
|
||||
sourceOptionsList.add(PagedSourceOptions.getPage1Instance());
|
||||
options.setSourceOptionsList(sourceOptionsList);
|
||||
this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options);
|
||||
|
||||
// Test second page
|
||||
options = new ImageTransformationOptions();
|
||||
sourceOptionsList = new ArrayList<TransformationSourceOptions>();
|
||||
PagedSourceOptions sourceOptions = new PagedSourceOptions();
|
||||
sourceOptions.setStartPageNumber(2);
|
||||
sourceOptions.setEndPageNumber(2);
|
||||
sourceOptionsList.add(sourceOptions);
|
||||
options.setSourceOptionsList(sourceOptionsList);
|
||||
this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options);
|
||||
|
||||
// Test page range invalid for target type
|
||||
options = new ImageTransformationOptions();
|
||||
sourceOptionsList = new ArrayList<TransformationSourceOptions>();
|
||||
sourceOptions = new PagedSourceOptions();
|
||||
sourceOptions.setStartPageNumber(1);
|
||||
sourceOptions.setEndPageNumber(2);
|
||||
sourceOptionsList.add(sourceOptions);
|
||||
options.setSourceOptionsList(sourceOptionsList);
|
||||
try {
|
||||
this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options);
|
||||
fail("An exception regarding an invalid page range should have been thrown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// failure expected
|
||||
}
|
||||
|
||||
// Test page out of range
|
||||
options = new ImageTransformationOptions();
|
||||
sourceOptionsList = new ArrayList<TransformationSourceOptions>();
|
||||
sourceOptions = new PagedSourceOptions();
|
||||
sourceOptions.setStartPageNumber(3);
|
||||
sourceOptions.setEndPageNumber(3);
|
||||
sourceOptionsList.add(sourceOptions);
|
||||
options.setSourceOptionsList(sourceOptionsList);
|
||||
try {
|
||||
this.transform(MimetypeMap.MIMETYPE_PDF, MimetypeMap.MIMETYPE_IMAGE_PNG, options);
|
||||
fail("An exception regarding an invalid page range should have been thrown");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// failure expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock mimetype service which returns a limited set of mimetypes
|
||||
* as {@link AbstractContentTransformerTest#testAllConversions()} will
|
||||
|
@@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.util.exec.RuntimeExec;
|
||||
import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
|
||||
@@ -295,13 +296,13 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not page range is required for the given source and target mimetypes.
|
||||
* Determines whether or not a single page range is required for the given source and target mimetypes.
|
||||
*
|
||||
* @param sourceMimetype
|
||||
* @param targetMimetype
|
||||
* @return whether or not a page range must be specified for the transformer to read the target files
|
||||
*/
|
||||
private boolean isSourcePageRangeRequired(String sourceMimetype, String targetMimetype)
|
||||
private boolean isSingleSourcePageRangeRequired(String sourceMimetype, String targetMimetype)
|
||||
{
|
||||
// Need a page source if we're transforming from PDF or TIFF to an image other than TIFF
|
||||
return ((sourceMimetype.equals(MimetypeMap.MIMETYPE_PDF) ||
|
||||
@@ -322,7 +323,43 @@ public class ImageMagickContentTransformerWorker extends AbstractImageMagickCont
|
||||
*/
|
||||
private String getSourcePageRange(TransformationOptions options, String sourceMimetype, String targetMimetype)
|
||||
{
|
||||
if (options.getPageLimit() == 1 || isSourcePageRangeRequired(sourceMimetype, targetMimetype))
|
||||
// Check for PagedContentSourceOptions in the options
|
||||
if (options instanceof ImageTransformationOptions)
|
||||
{
|
||||
ImageTransformationOptions imageOptions = (ImageTransformationOptions) options;
|
||||
PagedSourceOptions pagedSourceOptions = imageOptions.getSourceOptions(PagedSourceOptions.class);
|
||||
if (pagedSourceOptions != null)
|
||||
{
|
||||
if (pagedSourceOptions.getStartPageNumber() != null &&
|
||||
pagedSourceOptions.getEndPageNumber() != null)
|
||||
{
|
||||
if (pagedSourceOptions.getStartPageNumber().equals(pagedSourceOptions.getEndPageNumber()))
|
||||
{
|
||||
return "[" + (pagedSourceOptions.getStartPageNumber() - 1) + "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSingleSourcePageRangeRequired(sourceMimetype, targetMimetype))
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"A single page is required for targets of type " + targetMimetype);
|
||||
}
|
||||
return "[" + (pagedSourceOptions.getStartPageNumber() - 1) +
|
||||
"-" + (pagedSourceOptions.getEndPageNumber() - 1) + "]";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO specified start to end of doc and start of doc to specified end not yet supported
|
||||
// Just grab a single page specified by either start or end
|
||||
if (pagedSourceOptions.getStartPageNumber() != null)
|
||||
return "[" + (pagedSourceOptions.getStartPageNumber() - 1) + "]";
|
||||
if (pagedSourceOptions.getEndPageNumber() != null)
|
||||
return "[" + (pagedSourceOptions.getEndPageNumber() - 1) + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.getPageLimit() == 1 || isSingleSourcePageRangeRequired(sourceMimetype, targetMimetype))
|
||||
{
|
||||
return "[0]";
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -143,4 +143,20 @@ public class ImageTransformationOptions extends TransformationOptions
|
||||
{
|
||||
this.autoOrient = autoOrient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(TransformationOptions origOptions) {
|
||||
super.copyFrom(origOptions);
|
||||
if (origOptions != null)
|
||||
{
|
||||
if (origOptions instanceof ImageTransformationOptions)
|
||||
{
|
||||
// Clone ImageTransformationOptions
|
||||
this.setCommandOptions(((ImageTransformationOptions) origOptions).getCommandOptions());
|
||||
this.setResizeOptions(((ImageTransformationOptions) origOptions).getResizeOptions());
|
||||
this.setCropOptions(((ImageTransformationOptions) origOptions).getCropOptions());
|
||||
this.setAutoOrient(((ImageTransformationOptions) origOptions).isAutoOrient());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -59,6 +59,7 @@ 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.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.SerializedTransformationOptionsAccessor;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -732,7 +733,7 @@ public abstract class AbstractRenderingEngine extends ActionExecuterAbstractBase
|
||||
return result;
|
||||
}
|
||||
|
||||
protected class RenderingContext
|
||||
protected class RenderingContext implements SerializedTransformationOptionsAccessor
|
||||
{
|
||||
private final NodeRef sourceNode;
|
||||
private final RenditionDefinition definition;
|
||||
@@ -792,31 +793,11 @@ public abstract class AbstractRenderingEngine extends ActionExecuterAbstractBase
|
||||
return this.definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for the named parameter from the . Checks the type of
|
||||
* the parameter is correct and throws and Exception if it isn't.
|
||||
* Returns <code>null</code> if the parameter value is <code>null</code>
|
||||
*
|
||||
* @param paramName the name of the parameter being checked.
|
||||
* @param clazz the expected {@link Class} of the parameter value.
|
||||
* @return the parameter value or <code>null</code>.
|
||||
*/
|
||||
public <T> T getCheckedParam(String paramName, Class<T> clazz)
|
||||
{
|
||||
return AbstractRenderingEngine.getCheckedParam(paramName, clazz, definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for the named parameter. Checks the type of the
|
||||
* parameter is the same as the type of <code>defaultValue</code> and
|
||||
* throws a {@link RenditionServiceException} if it isn't. Returns
|
||||
* <code>defaultValue</code> if the parameter value is <code>null</code>
|
||||
*
|
||||
* @param <T>
|
||||
* @param paramName
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
|
||||
public <T> T getParamWithDefault(String paramName, T defaultValue)
|
||||
{
|
||||
return AbstractRenderingEngine.getParamWithDefault(paramName, defaultValue, definition);
|
||||
|
@@ -32,6 +32,8 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NoTransformerException;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptionLimits;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationSourceOptions.TransformationSourceOptionsSerializer;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -82,6 +84,18 @@ public abstract class AbstractTransformationRenderingEngine extends AbstractRend
|
||||
private static final String TRANSFORMER_NOT_EXISTS_MESSAGE_PATTERN = "Transformer for '%s' source mime type and '%s' target mime type was not found. Operation can't be performed";
|
||||
private static final String NOT_TRANSFORMABLE_MESSAGE_PATTERN = "Content not transformable for '%s' source mime type and '%s' target mime type. Operation can't be performed";
|
||||
private static final String TRANSFORMING_ERROR_MESSAGE = "Some error occurred during document transforming. Error message: ";
|
||||
|
||||
private Collection<TransformationSourceOptionsSerializer> sourceOptionsSerializers;
|
||||
|
||||
public Collection<TransformationSourceOptionsSerializer> getSourceOptionsSerializers()
|
||||
{
|
||||
return sourceOptionsSerializers;
|
||||
}
|
||||
|
||||
public void setSourceOptionsSerializers(Collection<TransformationSourceOptionsSerializer> sourceOptionsSerializers)
|
||||
{
|
||||
this.sourceOptionsSerializers = sourceOptionsSerializers;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -184,6 +198,18 @@ public abstract class AbstractTransformationRenderingEngine extends AbstractRend
|
||||
{
|
||||
options.setPageLimit(pageLimit);
|
||||
}
|
||||
|
||||
if (getSourceOptionsSerializers() != null)
|
||||
{
|
||||
for (TransformationSourceOptionsSerializer sourceSerializer : getSourceOptionsSerializers())
|
||||
{
|
||||
TransformationSourceOptions sourceOptions = sourceSerializer.deserialize(context);
|
||||
if (sourceOptions != null)
|
||||
{
|
||||
options.addSourceOptions(sourceOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ import org.alfresco.repo.rendition.executer.ReformatRenderingEngine;
|
||||
import org.alfresco.service.cmr.rendition.RenditionDefinition;
|
||||
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
import org.alfresco.service.cmr.repository.TransformationSourceOptions;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailParentAssociationDetails;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -185,6 +186,14 @@ public class ThumbnailRenditionConvertor
|
||||
parameters.put(ImageRenderingEngine.PARAM_ALLOW_ENLARGEMENT, allowEnlargement);
|
||||
}
|
||||
}
|
||||
if (transformationOptions.getSourceOptionsList() != null)
|
||||
{
|
||||
for (TransformationSourceOptions sourceOptions : transformationOptions.getSourceOptionsList())
|
||||
{
|
||||
sourceOptions.getSerializer().serialize(sourceOptions, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Handle RuntimeExecutableTransformationOptions
|
||||
return parameters;
|
||||
}
|
||||
|
@@ -45,6 +45,10 @@ import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions.PagedSourceOptionsSerializer;
|
||||
import org.alfresco.service.cmr.repository.TemporalSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.TemporalSourceOptions.TemporalSourceOptionsSerializer;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailParentAssociationDetails;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -135,6 +139,9 @@ public class ThumbnailServiceImplParameterTest
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_ALLOW_ENLARGEMENT, Boolean.TRUE);
|
||||
parametersUnderTest.put(AbstractRenderingEngine.PARAM_TARGET_CONTENT_PROPERTY, ContentModel.PROP_CONTENT);
|
||||
parametersUnderTest.put(RenditionService.PARAM_DESTINATION_NODE, dummyNodeRef2);
|
||||
parametersUnderTest.put(PagedSourceOptionsSerializer.PARAM_SOURCE_START_PAGE, new Integer(2));
|
||||
parametersUnderTest.put(PagedSourceOptionsSerializer.PARAM_SOURCE_END_PAGE, new Integer(2));
|
||||
parametersUnderTest.put(TemporalSourceOptionsSerializer.PARAM_SOURCE_TIME_OFFSET, "00:00:00.5");
|
||||
|
||||
|
||||
ImageTransformationOptions imageTransOpts = new ImageTransformationOptions();
|
||||
@@ -151,6 +158,15 @@ public class ThumbnailServiceImplParameterTest
|
||||
resizeOptions.setAllowEnlargement((Boolean) parametersUnderTest.get(ImageRenderingEngine.PARAM_ALLOW_ENLARGEMENT));
|
||||
imageTransOpts.setResizeOptions(resizeOptions);
|
||||
|
||||
PagedSourceOptions pagedSourceOptions = new PagedSourceOptions();
|
||||
pagedSourceOptions.setStartPageNumber((Integer) parametersUnderTest.get(PagedSourceOptionsSerializer.PARAM_SOURCE_START_PAGE));
|
||||
pagedSourceOptions.setEndPageNumber((Integer) parametersUnderTest.get(PagedSourceOptionsSerializer.PARAM_SOURCE_END_PAGE));
|
||||
imageTransOpts.addSourceOptions(pagedSourceOptions);
|
||||
|
||||
TemporalSourceOptions temporalSourceOptions = new TemporalSourceOptions();
|
||||
temporalSourceOptions.setOffset((String) parametersUnderTest.get(TemporalSourceOptionsSerializer.PARAM_SOURCE_TIME_OFFSET));
|
||||
imageTransOpts.addSourceOptions(temporalSourceOptions);
|
||||
|
||||
ThumbnailParentAssociationDetails assocDetails = new ThumbnailParentAssociationDetails(dummyNodeRef3,
|
||||
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||
"homerSimpson"));
|
||||
|
@@ -49,6 +49,7 @@ import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentServiceTransientException;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions;
|
||||
import org.alfresco.service.cmr.repository.ScriptLocation;
|
||||
import org.alfresco.service.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
@@ -175,6 +176,39 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
||||
checkRendition("doclib", thumbnail0);
|
||||
outputThumbnailTempContentLocation(thumbnail0, "jpg", "doclib test");
|
||||
}
|
||||
|
||||
public void testCreateRenditionThumbnailFromPdfPage2() throws Exception
|
||||
{
|
||||
ImageTransformationOptions options = new ImageTransformationOptions();
|
||||
PagedSourceOptions pagedSourceOptions = new PagedSourceOptions();
|
||||
pagedSourceOptions.setStartPageNumber(new Integer(2));
|
||||
pagedSourceOptions.setEndPageNumber(new Integer(2));
|
||||
options.addSourceOptions(pagedSourceOptions);
|
||||
|
||||
ThumbnailDefinition thumbnailDefinition = new ThumbnailDefinition(MimetypeMap.MIMETYPE_PDF, options, "doclib_2");
|
||||
thumbnailService.getThumbnailRegistry().addThumbnailDefinition(thumbnailDefinition);
|
||||
|
||||
checkTransformer();
|
||||
|
||||
NodeRef pdfOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_PDF);
|
||||
|
||||
NodeRef thumbnail0 = this.thumbnailService.createThumbnail(pdfOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, thumbnailDefinition.getTransformationOptions(), "doclib_2");
|
||||
assertNotNull(thumbnail0);
|
||||
checkRenditioned(pdfOrig, "doclib_2");
|
||||
checkRendition("doclib_2", thumbnail0);
|
||||
|
||||
// Check the length
|
||||
File tempFile = TempFileProvider.createTempFile("thumbnailServiceImplTest", ".jpg");
|
||||
ContentReader reader = this.contentService.getReader(thumbnail0, ContentModel.PROP_CONTENT);
|
||||
|
||||
long size = reader.getSize();
|
||||
System.out.println("size=" + size);
|
||||
assertTrue("Page 2 should be blank and less than 4500 bytes", size < 4500);
|
||||
|
||||
reader.getContent(tempFile);
|
||||
System.out.println("doclib_2 test: " + tempFile.getPath());
|
||||
}
|
||||
|
||||
public void testCreateThumbnailFromImage() throws Exception
|
||||
{
|
||||
|
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base implementation of TransformationSourceOptions which holds applicable mimetypes
|
||||
* and handles merge of options.
|
||||
*
|
||||
* @author Ray Gauss II
|
||||
*/
|
||||
public abstract class AbstractTransformationSourceOptions implements TransformationSourceOptions, Cloneable
|
||||
{
|
||||
protected static final String MIMETYPE_VIDEO_PREFIX = "video/";
|
||||
protected static final String MIMETYPE_AUDIO_PREFIX = "audio/";
|
||||
|
||||
/** The list of applicable mimetypes */
|
||||
private List<String> applicabledMimetypes;
|
||||
|
||||
/**
|
||||
* Gets the list of applicable mimetypes
|
||||
*
|
||||
* @return the applicable mimetypes
|
||||
*/
|
||||
public List<String> getApplicabledMimetypes()
|
||||
{
|
||||
return applicabledMimetypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of applicable mimetypes
|
||||
*
|
||||
* @param applicableMimetypes the applicable mimetypes
|
||||
*/
|
||||
public void setApplicableMimetypes(List<String> applicabledMimetypes)
|
||||
{
|
||||
this.applicabledMimetypes = applicabledMimetypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not these transformation source options apply for the
|
||||
* given mimetype
|
||||
*
|
||||
* @param mimetype the mimetype of the source
|
||||
* @return if these transformation source options apply
|
||||
*/
|
||||
public boolean isApplicableForMimetype(String mimetype)
|
||||
{
|
||||
if (mimetype != null && applicabledMimetypes != null) { return applicabledMimetypes.contains(mimetype); }
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractTransformationSourceOptions clone() throws CloneNotSupportedException
|
||||
{
|
||||
return (AbstractTransformationSourceOptions) super.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>TransformationSourceOptions</code> object from this
|
||||
* one, merging any non-null overriding fields in the given
|
||||
* <code>overridingOptions</code>
|
||||
*
|
||||
* @param overridingOptions
|
||||
* @return a merged <code>TransformationSourceOptions</code> object
|
||||
*/
|
||||
public TransformationSourceOptions mergedOptions(TransformationSourceOptions overridingOptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
AbstractTransformationSourceOptions mergedOptions = this.clone();
|
||||
mergedOptions.setApplicableMimetypes(this.getApplicabledMimetypes());
|
||||
|
||||
return mergedOptions;
|
||||
}
|
||||
catch (CloneNotSupportedException e)
|
||||
{
|
||||
// Not thrown
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given paramValue to the given params if it's not null.
|
||||
*
|
||||
* @param paramName
|
||||
* @param paramValue
|
||||
* @param params
|
||||
*/
|
||||
protected void putParameterIfNotNull(String paramName, Serializable paramValue, Map<String, Serializable> params)
|
||||
{
|
||||
if (paramValue != null)
|
||||
{
|
||||
params.put(paramName, paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.AbstractTransformationSourceOptions;
|
||||
|
||||
/**
|
||||
* Paged content conversion options to specify a page number range.
|
||||
* <p>
|
||||
* The page numbering index starts with 1.
|
||||
* <p>
|
||||
* If only the start page number is specified transformers should attempt
|
||||
* a page range from that page number to the end if possible.
|
||||
* <p>
|
||||
* If only an end page number is specified transformers should attempt
|
||||
* a page range from the start to that page if possible.
|
||||
*
|
||||
* @author Ray Gauss II
|
||||
*/
|
||||
public class PagedSourceOptions extends AbstractTransformationSourceOptions
|
||||
{
|
||||
public static final Integer PAGE_1 = new Integer(1);
|
||||
|
||||
/** The start of the page range in the source document */
|
||||
private Integer startPageNumber;
|
||||
|
||||
/** The end of the page range in the source document */
|
||||
private Integer endPageNumber;
|
||||
|
||||
protected static List<String> getDefaultApplicableMimetypes()
|
||||
{
|
||||
List<String> defaults = new ArrayList<String>(17);
|
||||
defaults.add(MimetypeMap.MIMETYPE_PDF);
|
||||
defaults.add(MimetypeMap.MIMETYPE_WORD);
|
||||
defaults.add(MimetypeMap.MIMETYPE_PPT);
|
||||
defaults.add(MimetypeMap.MIMETYPE_IMAGE_TIFF);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_PRESENTATION);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_PRESENTATION_TEMPLATE);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_TEXT_TEMPLATE);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENOFFICE1_WRITER);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENOFFICE1_IMPRESS);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENXML_PRESENTATION);
|
||||
defaults.add(MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING);
|
||||
defaults.add(MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS);
|
||||
defaults.add(MimetypeMap.MIMETYPE_STAROFFICE5_IMPRESS_PACKED);
|
||||
defaults.add(MimetypeMap.MIMETYPE_STAROFFICE5_WRITER);
|
||||
defaults.add(MimetypeMap.MIMETYPE_STAROFFICE5_WRITER_GLOBAL);
|
||||
defaults.add(MimetypeMap.MIMETYPE_IWORK_KEYNOTE);
|
||||
defaults.add(MimetypeMap.MIMETYPE_IWORK_PAGES);
|
||||
defaults.add(MimetypeMap.MIMETYPE_WORDPERFECT);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
public PagedSourceOptions()
|
||||
{
|
||||
super();
|
||||
setApplicableMimetypes(PagedSourceOptions.getDefaultApplicableMimetypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page number to start from in the source document
|
||||
*
|
||||
* @return the start page number
|
||||
*/
|
||||
public Integer getStartPageNumber()
|
||||
{
|
||||
return startPageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the page number to start from in the source document
|
||||
*
|
||||
* @param startPageNumber the start page number
|
||||
*/
|
||||
public void setStartPageNumber(Integer startPageNumber)
|
||||
{
|
||||
this.startPageNumber = startPageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page number to end at in the source document
|
||||
*
|
||||
* @return the start page number
|
||||
*/
|
||||
public Integer getEndPageNumber()
|
||||
{
|
||||
return endPageNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the page number to end at in the source document
|
||||
*
|
||||
* @param endPageNumber the end page number
|
||||
*/
|
||||
public void setEndPageNumber(Integer endPageNumber)
|
||||
{
|
||||
this.endPageNumber = endPageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptions mergedOptions(TransformationSourceOptions overridingOptions)
|
||||
{
|
||||
if (overridingOptions instanceof PagedSourceOptions)
|
||||
{
|
||||
PagedSourceOptions mergedOptions = (PagedSourceOptions) super.mergedOptions(overridingOptions);
|
||||
|
||||
if (((PagedSourceOptions) overridingOptions).getStartPageNumber() != null)
|
||||
{
|
||||
mergedOptions.setStartPageNumber(((PagedSourceOptions) overridingOptions).getStartPageNumber());
|
||||
}
|
||||
if (((PagedSourceOptions) overridingOptions).getEndPageNumber() != null)
|
||||
{
|
||||
mergedOptions.setEndPageNumber(((PagedSourceOptions) overridingOptions).getEndPageNumber());
|
||||
}
|
||||
return mergedOptions;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets paged source options which specify just the first page.
|
||||
*
|
||||
* @return the page one source options
|
||||
*/
|
||||
public static PagedSourceOptions getPage1Instance() {
|
||||
PagedSourceOptions sourceOptions = new PagedSourceOptions();
|
||||
sourceOptions.setStartPageNumber(PAGE_1);
|
||||
sourceOptions.setEndPageNumber(PAGE_1);
|
||||
return sourceOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptionsSerializer getSerializer()
|
||||
{
|
||||
return PagedSourceOptions.createSerializerInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the options serializer
|
||||
*
|
||||
* @return the options serializer
|
||||
*/
|
||||
public static TransformationSourceOptionsSerializer createSerializerInstance()
|
||||
{
|
||||
return (new PagedSourceOptions()).new PagedSourceOptionsSerializer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for paged source options
|
||||
*/
|
||||
public class PagedSourceOptionsSerializer implements TransformationSourceOptionsSerializer
|
||||
{
|
||||
public static final String PARAM_SOURCE_START_PAGE = "source_start_page";
|
||||
public static final String PARAM_SOURCE_END_PAGE = "source_end_page";
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptions deserialize(SerializedTransformationOptionsAccessor serializedOptions)
|
||||
{
|
||||
int startPageNumber = serializedOptions.getIntegerParam(PARAM_SOURCE_START_PAGE, 1);
|
||||
int endPageNumber = serializedOptions.getIntegerParam(PARAM_SOURCE_END_PAGE, 1);
|
||||
|
||||
PagedSourceOptions sourceOptions = new PagedSourceOptions();
|
||||
sourceOptions.setStartPageNumber(startPageNumber);
|
||||
sourceOptions.setEndPageNumber(endPageNumber);
|
||||
return sourceOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(TransformationSourceOptions sourceOptions,
|
||||
Map<String, Serializable> parameters)
|
||||
{
|
||||
if (parameters == null || sourceOptions == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PagedSourceOptions pagedSourceOptions = (PagedSourceOptions) sourceOptions;
|
||||
parameters.put(PARAM_SOURCE_START_PAGE, pagedSourceOptions.getStartPageNumber());
|
||||
parameters.put(PARAM_SOURCE_END_PAGE, pagedSourceOptions.getEndPageNumber());
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import org.alfresco.service.cmr.rendition.RenditionServiceException;
|
||||
|
||||
/**
|
||||
* Defines methods for retrieving parameter values for use in building
|
||||
* transformation options.
|
||||
*
|
||||
* @author Ray Gauss II
|
||||
*/
|
||||
public interface SerializedTransformationOptionsAccessor
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the value for the named parameter. Checks the type of
|
||||
* the parameter is correct and throws and Exception if it isn't.
|
||||
* Returns <code>null</code> if the parameter value is <code>null</code>
|
||||
*
|
||||
* @param paramName the name of the parameter being checked.
|
||||
* @param clazz the expected {@link Class} of the parameter value.
|
||||
* @return the parameter value or <code>null</code>.
|
||||
*/
|
||||
public <T> T getCheckedParam(String paramName, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Gets the value for the named parameter. Checks the type of the
|
||||
* parameter is the same as the type of <code>defaultValue</code> and
|
||||
* throws a {@link RenditionServiceException} if it isn't. Returns
|
||||
* <code>defaultValue</code> if the parameter value is <code>null</code>
|
||||
*
|
||||
* @param <T>
|
||||
* @param paramName
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public <T> T getParamWithDefault(String paramName, T defaultValue);
|
||||
|
||||
/**
|
||||
* Gets the int value for the named parameter. Returns
|
||||
* <code>defaultValue</code> if the parameter value is <code>null</code>.
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public int getIntegerParam(String key, int defaultValue);
|
||||
|
||||
}
|
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.AbstractTransformationSourceOptions;
|
||||
|
||||
/**
|
||||
* Time-based content conversion options to specify an offset and duration.
|
||||
* Useful for audio and video.
|
||||
* <p>
|
||||
* If only the offset is specified transformers should attempt
|
||||
* a transform from that offset to the end if possible.
|
||||
* <p>
|
||||
* If only a duration is specified transformers should attempt
|
||||
* a transform from the start until that duration is reached if possible.
|
||||
*
|
||||
* @author Ray Gauss II
|
||||
*/
|
||||
public class TemporalSourceOptions extends AbstractTransformationSourceOptions
|
||||
{
|
||||
|
||||
/** The offset time code from which to start the transformation */
|
||||
private String offset;
|
||||
|
||||
/** The duration of the target video after the transformation */
|
||||
private String duration;
|
||||
|
||||
public boolean isApplicableForMimetype(String sourceMimetype)
|
||||
{
|
||||
return ((sourceMimetype != null &&
|
||||
sourceMimetype.startsWith(MIMETYPE_VIDEO_PREFIX) ||
|
||||
sourceMimetype.startsWith(MIMETYPE_AUDIO_PREFIX)) ||
|
||||
super.isApplicableForMimetype(sourceMimetype));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offset time code from which to start the transformation
|
||||
* with a format of hh:mm:ss[.xxx]
|
||||
*
|
||||
* @return the offset
|
||||
*/
|
||||
public String getOffset()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset time code from which to start the transformation
|
||||
* with a format of hh:mm:ss[.xxx]
|
||||
*
|
||||
* @param offset
|
||||
*/
|
||||
public void setOffset(String offset)
|
||||
{
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the duration of the source to read
|
||||
* with a format of hh:mm:ss[.xxx]
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getDuration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration of the source to read
|
||||
* with a format of hh:mm:ss[.xxx]
|
||||
*
|
||||
* @param duration
|
||||
*/
|
||||
public void setDuration(String duration)
|
||||
{
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptions mergedOptions(TransformationSourceOptions overridingOptions)
|
||||
{
|
||||
if (overridingOptions instanceof TemporalSourceOptions)
|
||||
{
|
||||
TemporalSourceOptions mergedOptions = (TemporalSourceOptions) super.mergedOptions(overridingOptions);
|
||||
|
||||
if (((TemporalSourceOptions) overridingOptions).getOffset() != null)
|
||||
{
|
||||
mergedOptions.setOffset(((TemporalSourceOptions) overridingOptions).getOffset());
|
||||
}
|
||||
if (((TemporalSourceOptions) overridingOptions).getDuration() != null)
|
||||
{
|
||||
mergedOptions.setDuration(((TemporalSourceOptions) overridingOptions).getDuration());
|
||||
}
|
||||
return mergedOptions;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptionsSerializer getSerializer()
|
||||
{
|
||||
return TemporalSourceOptions.createSerializerInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the options serializer
|
||||
*
|
||||
* @return the options serializer
|
||||
*/
|
||||
public static TransformationSourceOptionsSerializer createSerializerInstance()
|
||||
{
|
||||
return (new TemporalSourceOptions()).new TemporalSourceOptionsSerializer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for temporal source options
|
||||
*/
|
||||
public class TemporalSourceOptionsSerializer implements TransformationSourceOptionsSerializer
|
||||
{
|
||||
public static final String PARAM_SOURCE_TIME_OFFSET = "source_time_offset";
|
||||
public static final String PARAM_SOURCE_TIME_DURATION = "source_time_duration";
|
||||
|
||||
@Override
|
||||
public TransformationSourceOptions deserialize(SerializedTransformationOptionsAccessor serializedOptions)
|
||||
{
|
||||
String offset = serializedOptions.getCheckedParam(PARAM_SOURCE_TIME_OFFSET, String.class);
|
||||
String duration = serializedOptions.getCheckedParam(PARAM_SOURCE_TIME_DURATION, String.class);
|
||||
|
||||
if (offset == null && duration == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
TemporalSourceOptions sourceOptions = new TemporalSourceOptions();
|
||||
sourceOptions.setOffset(offset);
|
||||
sourceOptions.setDuration(duration);
|
||||
return sourceOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(TransformationSourceOptions sourceOptions,
|
||||
Map<String, Serializable> parameters)
|
||||
{
|
||||
if (parameters == null || sourceOptions == null)
|
||||
return;
|
||||
TemporalSourceOptions temporalSourceOptions = (TemporalSourceOptions) sourceOptions;
|
||||
parameters.put(PARAM_SOURCE_TIME_OFFSET, temporalSourceOptions.getOffset());
|
||||
parameters.put(PARAM_SOURCE_TIME_DURATION, temporalSourceOptions.getDuration());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -18,11 +18,16 @@
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.service.cmr.repository.datatype.TypeConverter;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Class containing values of options that are passed to content transformers. These options
|
||||
@@ -37,6 +42,8 @@ import org.alfresco.service.namespace.QName;
|
||||
*/
|
||||
public class TransformationOptions implements Cloneable
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(TransformationOptions.class);
|
||||
|
||||
/** Option map names to preserve backward compatibility */
|
||||
public static final String OPT_SOURCE_NODEREF = "contentReaderNodeRef";
|
||||
public static final String OPT_SOURCE_CONTENT_PROPERTY = "sourceContentProperty";
|
||||
@@ -61,6 +68,9 @@ public class TransformationOptions implements Cloneable
|
||||
|
||||
/** Time, KBytes and page limits */
|
||||
private TransformationOptionLimits limits = new TransformationOptionLimits();
|
||||
|
||||
/** Source options based on its mimetype */
|
||||
private Map<Class<? extends TransformationSourceOptions>, TransformationSourceOptions> sourceOptionsMap;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
@@ -124,6 +134,7 @@ public class TransformationOptions implements Cloneable
|
||||
public void copyFrom(TransformationOptions otherOptions)
|
||||
{
|
||||
this.set(otherOptions.toMap());
|
||||
this.setSourceOptionsList(otherOptions.getSourceOptionsList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,7 +430,87 @@ public class TransformationOptions implements Cloneable
|
||||
{
|
||||
this.limits = limits;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the map of source options further describing how the source should
|
||||
* be transformed based on its mimetype
|
||||
*
|
||||
* @return the source mimetype to source options map
|
||||
*/
|
||||
protected Map<Class<? extends TransformationSourceOptions>, TransformationSourceOptions> getSourceOptionsMap()
|
||||
{
|
||||
return sourceOptionsMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immutable list of source options further describing how the source should
|
||||
* be transformed based on its mimetype.
|
||||
* Use {@link TransformationOptions#addSourceOptions(TransformationSourceOptions)}
|
||||
* to add source options.
|
||||
*
|
||||
* @return the source options list
|
||||
*/
|
||||
public Collection<TransformationSourceOptions> getSourceOptionsList()
|
||||
{
|
||||
if (sourceOptionsMap == null)
|
||||
return null;
|
||||
return sourceOptionsMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of source options further describing how the source should
|
||||
* be transformed based on its mimetype.
|
||||
*
|
||||
* @param sourceOptionsList the source options list
|
||||
*/
|
||||
public void setSourceOptionsList(Collection<TransformationSourceOptions> sourceOptionsList)
|
||||
{
|
||||
if (sourceOptionsList != null)
|
||||
{
|
||||
for (TransformationSourceOptions sourceOptions : sourceOptionsList)
|
||||
{
|
||||
addSourceOptions(sourceOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given sourceOptions to the sourceOptionsMap.
|
||||
* <p>
|
||||
* Note that if source options of the same class already exists a new
|
||||
* merged source options object is added.
|
||||
*
|
||||
* @param sourceOptions
|
||||
*/
|
||||
public void addSourceOptions(TransformationSourceOptions sourceOptions)
|
||||
{
|
||||
if (sourceOptionsMap == null)
|
||||
{
|
||||
sourceOptionsMap = new HashMap<Class<? extends TransformationSourceOptions>, TransformationSourceOptions>(1);
|
||||
}
|
||||
TransformationSourceOptions newOptions = sourceOptions;
|
||||
TransformationSourceOptions existingOptions = sourceOptionsMap.get(sourceOptions.getClass());
|
||||
if (existingOptions != null)
|
||||
{
|
||||
newOptions = existingOptions.mergedOptions(sourceOptions);
|
||||
}
|
||||
sourceOptionsMap.put(sourceOptions.getClass(), newOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the appropriate source options for the given mimetype if available.
|
||||
*
|
||||
* @param sourceMimetype
|
||||
* @return the source options for the mimetype
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends TransformationSourceOptions> T getSourceOptions(Class<T> clazz)
|
||||
{
|
||||
if (sourceOptionsMap == null)
|
||||
return null;
|
||||
return (T) sourceOptionsMap.get(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the transformation options into a map.
|
||||
* <p>
|
||||
|
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.rendition.executer.AbstractRenderingEngine;
|
||||
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.repository.PagedSourceOptions;
|
||||
|
||||
/**
|
||||
* Defines options and demarcations needed to describe the details of how
|
||||
* the source should be transformed, independent of the target requirements.
|
||||
* <p>
|
||||
* See {@link PagedSourceOptions} for an example implementation that
|
||||
* describes the page number that should be used from the source content.
|
||||
*
|
||||
* @author Ray Gauss II
|
||||
*/
|
||||
public interface TransformationSourceOptions
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the list of applicable mimetypes
|
||||
*
|
||||
* @return the applicable mimetypes
|
||||
*/
|
||||
public List<String> getApplicabledMimetypes();
|
||||
|
||||
/**
|
||||
* Gets whether or not these transformation source options apply for the
|
||||
* given mimetype
|
||||
*
|
||||
* @param mimetype the mimetype of the source
|
||||
* @return if these transformation source options apply
|
||||
*/
|
||||
public boolean isApplicableForMimetype(String mimetype);
|
||||
|
||||
/**
|
||||
* Creates a new <code>TransformationSourceOptions</code> object from this
|
||||
* one, merging any non-null overriding fields in the given
|
||||
* <code>overridingOptions</code>
|
||||
*
|
||||
* @param overridingOptions
|
||||
* @return a merged <code>TransformationSourceOptions</code> object
|
||||
*/
|
||||
public TransformationSourceOptions mergedOptions(TransformationSourceOptions overridingOptions);
|
||||
|
||||
/**
|
||||
* Gets the serializer for the source options.
|
||||
*
|
||||
* @return the serializer
|
||||
*/
|
||||
public TransformationSourceOptionsSerializer getSerializer();
|
||||
|
||||
/**
|
||||
* Defines methods for serializing the source options into a parameter map and
|
||||
* deserializing from a serialized options accessor.
|
||||
* <p>
|
||||
* This is primarily used when interacting with the {@link RenditionService}
|
||||
* with {@link AbstractRenderingEngine}'s RenderContext being an implementer
|
||||
* of this interface.
|
||||
*/
|
||||
public interface TransformationSourceOptionsSerializer
|
||||
{
|
||||
|
||||
/**
|
||||
* Serializes the given transformation source options into the given parameter map.
|
||||
*
|
||||
* @param transformationSourceOptions
|
||||
* @param parameters
|
||||
*/
|
||||
public void serialize(TransformationSourceOptions transformationSourceOptions, Map<String, Serializable> parameters);
|
||||
|
||||
/**
|
||||
* Gets the parameters from the serialized options accessor and builds a source options object.
|
||||
*
|
||||
* @param serializedOptions
|
||||
* @return the deserialized source options
|
||||
*/
|
||||
public TransformationSourceOptions deserialize(SerializedTransformationOptionsAccessor serializedOptions);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user