mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merging DEV_TEMPORARY to HEAD (RenditionService)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19103 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -19,30 +19,43 @@
|
||||
package org.alfresco.repo.thumbnail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.rendition.executer.AbstractRenderingEngine;
|
||||
import org.alfresco.service.cmr.rendition.RenditionDefinition;
|
||||
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailException;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Registry of all the thumbnail details available
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ThumbnailRegistry
|
||||
{
|
||||
/** Content service */
|
||||
private ContentService contentService;
|
||||
|
||||
/** Map of thumbnail defintion */
|
||||
private Map<String, ThumbnailDefinition> thumbnailDefinitions = new HashMap<String, ThumbnailDefinition>(7);
|
||||
/** Rendition service */
|
||||
private RenditionService renditionService;
|
||||
|
||||
private List<String> thumbnails;
|
||||
|
||||
/** This flag indicates whether the thumbnail definitions have been lazily loaded or not. */
|
||||
private boolean thumbnailDefinitionsInited = false;
|
||||
|
||||
/** Map of thumbnail definition */
|
||||
private Map<String, ThumbnailDefinition> thumbnailDefinitions = new HashMap<String, ThumbnailDefinition>();
|
||||
|
||||
/** Cache to store mimetype to thumbnailDefinition mapping */
|
||||
private Map<String, List<ThumbnailDefinition>> mimetypeMap = new HashMap<String, List<ThumbnailDefinition>>(17);
|
||||
|
||||
|
||||
/**
|
||||
* Content service
|
||||
*
|
||||
@@ -54,36 +67,63 @@ public class ThumbnailRegistry
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number of thumbnail defintions
|
||||
* Rendition service
|
||||
*
|
||||
* @param thumbnailDefinitions list of thumbnail details
|
||||
* @param renditionService rendition service
|
||||
*/
|
||||
public void setThumbnailDefinitions(List<ThumbnailDefinition> thumbnailDefinitions)
|
||||
public void setRenditionService(RenditionService renditionService)
|
||||
{
|
||||
for (ThumbnailDefinition value : thumbnailDefinitions)
|
||||
{
|
||||
addThumbnailDefinition(value);
|
||||
}
|
||||
this.renditionService = renditionService;
|
||||
}
|
||||
|
||||
public void setThumbnails(final List<String> thumbnails)
|
||||
{
|
||||
this.thumbnails = thumbnails;
|
||||
|
||||
// We'll not populate the data fields in the ThumbnailRegistry here, instead preferring
|
||||
// to do it lazily later.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all the thumbnail defintions
|
||||
* Get a list of all the thumbnail definitions
|
||||
*
|
||||
* @return Collection<ThumbnailDefinition> colleciton of thumbnail defintions
|
||||
* @return Collection<ThumbnailDefinition> collection of thumbnail definitions
|
||||
*/
|
||||
public List<ThumbnailDefinition> getThumbnailDefinitions()
|
||||
{
|
||||
if (thumbnailDefinitionsInited == false)
|
||||
{
|
||||
this.initThumbnailDefinitions();
|
||||
thumbnailDefinitionsInited = true;
|
||||
}
|
||||
return new ArrayList<ThumbnailDefinition>(this.thumbnailDefinitions.values());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mimetype
|
||||
* @return
|
||||
*/
|
||||
public List<ThumbnailDefinition> getThumnailDefintions(String mimetype)
|
||||
private void initThumbnailDefinitions()
|
||||
{
|
||||
List<ThumbnailDefinition> result = this.mimetypeMap.get(mimetype);;
|
||||
ThumbnailRenditionConvertor thumbnailRenditionConvertor = new ThumbnailRenditionConvertor();
|
||||
|
||||
for (String thumbnailDefinitionName : this.thumbnails)
|
||||
{
|
||||
QName qName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbnailDefinitionName);
|
||||
RenditionDefinition rAction = renditionService
|
||||
.loadRenditionDefinition(qName);
|
||||
|
||||
ThumbnailDefinition thDefn = thumbnailRenditionConvertor.convert(rAction);
|
||||
|
||||
thumbnailDefinitions.put(thumbnailDefinitionName, thDefn);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ThumbnailDefinition> getThumbnailDefinitions(String mimetype)
|
||||
{
|
||||
if (thumbnailDefinitionsInited == false)
|
||||
{
|
||||
this.initThumbnailDefinitions();
|
||||
thumbnailDefinitionsInited = true;
|
||||
}
|
||||
|
||||
List<ThumbnailDefinition> result = this.mimetypeMap.get(mimetype);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
@@ -107,12 +147,28 @@ public class ThumbnailRegistry
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a thumnail details
|
||||
*
|
||||
* @param mimetype
|
||||
* @return
|
||||
* @deprecated Use {@link #getThumbnailDefinitions(String)} instead.
|
||||
*/
|
||||
public List<ThumbnailDefinition> getThumnailDefintions(String mimetype)
|
||||
{
|
||||
return this.getThumbnailDefinitions(mimetype);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a thumbnail details
|
||||
*
|
||||
* @param thumbnailDetails thumbnail details
|
||||
*/
|
||||
public void addThumbnailDefinition(ThumbnailDefinition thumbnailDetails)
|
||||
{
|
||||
if (thumbnailDefinitionsInited == false)
|
||||
{
|
||||
this.initThumbnailDefinitions();
|
||||
thumbnailDefinitionsInited = true;
|
||||
}
|
||||
String thumbnailName = thumbnailDetails.getName();
|
||||
if (thumbnailName == null)
|
||||
{
|
||||
@@ -130,6 +186,11 @@ public class ThumbnailRegistry
|
||||
*/
|
||||
public ThumbnailDefinition getThumbnailDefinition(String thumbnailName)
|
||||
{
|
||||
if (thumbnailDefinitionsInited == false)
|
||||
{
|
||||
this.initThumbnailDefinitions();
|
||||
thumbnailDefinitionsInited = true;
|
||||
}
|
||||
return this.thumbnailDefinitions.get(thumbnailName);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 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.repo.thumbnail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.content.transform.magick.ImageResizeOptions;
|
||||
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
|
||||
import org.alfresco.repo.content.transform.swf.SWFTransformationOptions;
|
||||
import org.alfresco.repo.rendition.executer.AbstractRenderingEngine;
|
||||
import org.alfresco.repo.rendition.executer.ImageRenderingEngine;
|
||||
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.thumbnail.ThumbnailParentAssociationDetails;
|
||||
|
||||
/**
|
||||
* A helper class to convert {@link TransformationOptions transformationOptions} (a thumbnail-specific
|
||||
* class) to rendition-specific parameters and vice versa.
|
||||
*
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ThumbnailRenditionConvertor
|
||||
{
|
||||
public Map<String, Serializable> convert(TransformationOptions transformationOptions, ThumbnailParentAssociationDetails assocDetails)
|
||||
{
|
||||
Map<String, Serializable> parameters = new HashMap<String, Serializable>();
|
||||
|
||||
// parameters common to all transformations
|
||||
putParameterIfNotNull(AbstractRenderingEngine.PARAM_SOURCE_CONTENT_PROPERTY, transformationOptions.getSourceContentProperty(), parameters);
|
||||
putParameterIfNotNull(AbstractRenderingEngine.PARAM_TARGET_CONTENT_PROPERTY, transformationOptions.getTargetContentProperty(), parameters);
|
||||
putParameterIfNotNull(RenditionService.PARAM_DESTINATION_NODE, transformationOptions.getTargetNodeRef(), parameters);
|
||||
|
||||
// putParameterIfNotNull(ImageRenderingEngine.PARAM_ASSOC_NAME, assocDetails.getAssociationName(), parameters);
|
||||
// putParameterIfNotNull(ImageRenderingEngine.PARAM_ASSOC_TYPE, assocDetails.getAssociationType(), parameters);
|
||||
|
||||
if (transformationOptions instanceof SWFTransformationOptions)
|
||||
{
|
||||
SWFTransformationOptions swfTransformationOptions = (SWFTransformationOptions)transformationOptions;
|
||||
putParameterIfNotNull(ReformatRenderingEngine.PARAM_FLASH_VERSION, swfTransformationOptions.getFlashVersion(), parameters);
|
||||
}
|
||||
else if (transformationOptions instanceof ImageTransformationOptions)
|
||||
{
|
||||
ImageTransformationOptions imTransformationOptions = (ImageTransformationOptions)transformationOptions;
|
||||
putParameterIfNotNull(ImageRenderingEngine.PARAM_COMMAND_OPTIONS, imTransformationOptions.getCommandOptions(), parameters);
|
||||
|
||||
ImageResizeOptions imgResizeOptions = imTransformationOptions.getResizeOptions();
|
||||
if (imgResizeOptions != null)
|
||||
{
|
||||
int width = imgResizeOptions.getWidth();
|
||||
parameters.put(ImageRenderingEngine.PARAM_RESIZE_WIDTH, width);
|
||||
|
||||
int height = imgResizeOptions.getHeight();
|
||||
parameters.put(ImageRenderingEngine.PARAM_RESIZE_HEIGHT, height);
|
||||
|
||||
boolean maintainAspectRatio = imgResizeOptions.isMaintainAspectRatio();
|
||||
parameters.put(ImageRenderingEngine.PARAM_MAINTAIN_ASPECT_RATIO, maintainAspectRatio);
|
||||
|
||||
boolean percentResize = imgResizeOptions.isPercentResize();
|
||||
parameters.put(ImageRenderingEngine.PARAM_IS_PERCENT_RESIZE, percentResize);
|
||||
|
||||
boolean resizeToThumbnail = imgResizeOptions.isResizeToThumbnail();
|
||||
parameters.put(ImageRenderingEngine.PARAM_RESIZE_TO_THUMBNAIL, resizeToThumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private void putParameterIfNotNull(String paramName, Serializable paramValue, Map<String, Serializable> params)
|
||||
{
|
||||
if (paramValue != null)
|
||||
{
|
||||
params.put(paramName, paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
public ThumbnailDefinition convert(RenditionDefinition renditionDefinition)
|
||||
{
|
||||
ThumbnailDefinition thDefn = new ThumbnailDefinition();
|
||||
|
||||
Map<String, Serializable> params = renditionDefinition.getParameterValues();
|
||||
|
||||
//parameters common to all the built-in thumbnail definitions
|
||||
Serializable mimeTypeParam = params.get(AbstractRenderingEngine.PARAM_MIME_TYPE);
|
||||
thDefn.setMimetype((String) mimeTypeParam);
|
||||
thDefn.setName(renditionDefinition.getRenditionName().getLocalName());
|
||||
|
||||
Serializable placeHolderResourcePathParam = params.get(AbstractRenderingEngine.PARAM_PLACEHOLDER_RESOURCE_PATH);
|
||||
if (placeHolderResourcePathParam != null)
|
||||
{
|
||||
thDefn.setPlaceHolderResourcePath((String)placeHolderResourcePathParam);
|
||||
}
|
||||
|
||||
//TODO src/target contentProp & nodeRef
|
||||
|
||||
TransformationOptions transformationOptions = null;
|
||||
Serializable flashVersion = renditionDefinition.getParameterValue(ReformatRenderingEngine.PARAM_FLASH_VERSION);
|
||||
if (flashVersion != null)
|
||||
{
|
||||
// Thumbnails based on SWFTransformationOptions
|
||||
transformationOptions = new SWFTransformationOptions();
|
||||
SWFTransformationOptions swfTranOpts = (SWFTransformationOptions)transformationOptions;
|
||||
swfTranOpts.setFlashVersion((String)flashVersion);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Thumbnails based on ImageTransformationOptions
|
||||
transformationOptions = new ImageTransformationOptions();
|
||||
ImageTransformationOptions imgTrOpts = (ImageTransformationOptions)transformationOptions;
|
||||
|
||||
ImageResizeOptions resizeOptions = new ImageResizeOptions();
|
||||
Serializable xsize = renditionDefinition.getParameterValue(ImageRenderingEngine.PARAM_RESIZE_WIDTH);
|
||||
if (xsize != null)
|
||||
{
|
||||
// Saved actions with int parameters seem to be coming back as Longs. TODO Investigate
|
||||
resizeOptions.setWidth(((Long) xsize).intValue());
|
||||
}
|
||||
|
||||
Serializable ysize = renditionDefinition.getParameterValue(ImageRenderingEngine.PARAM_RESIZE_HEIGHT);
|
||||
if (ysize != null)
|
||||
{
|
||||
resizeOptions.setHeight(((Long) ysize).intValue());
|
||||
}
|
||||
|
||||
Serializable maintainAspectRatio = renditionDefinition.getParameterValue(ImageRenderingEngine.PARAM_MAINTAIN_ASPECT_RATIO);
|
||||
if (maintainAspectRatio != null)
|
||||
{
|
||||
resizeOptions.setMaintainAspectRatio((Boolean) maintainAspectRatio);
|
||||
}
|
||||
|
||||
Serializable resizeToThumbnail = renditionDefinition.getParameterValue(ImageRenderingEngine.PARAM_RESIZE_TO_THUMBNAIL);
|
||||
if (resizeToThumbnail != null)
|
||||
{
|
||||
resizeOptions.setResizeToThumbnail((Boolean) resizeToThumbnail);
|
||||
}
|
||||
|
||||
imgTrOpts.setResizeOptions(resizeOptions);
|
||||
}
|
||||
|
||||
thDefn.setTransformationOptions(transformationOptions);
|
||||
|
||||
return thDefn;
|
||||
}
|
||||
}
|
@@ -19,21 +19,24 @@
|
||||
package org.alfresco.repo.thumbnail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
|
||||
import org.alfresco.repo.content.transform.swf.SWFTransformationOptions;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.rendition.executer.ImageRenderingEngine;
|
||||
import org.alfresco.repo.rendition.executer.ReformatRenderingEngine;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.rendition.RenditionDefinition;
|
||||
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.rendition.RenditionServiceException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.TransformationOptions;
|
||||
@@ -42,14 +45,14 @@ import org.alfresco.service.cmr.thumbnail.ThumbnailParentAssociationDetails;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ThumbnailServiceImpl implements ThumbnailService
|
||||
{
|
||||
@@ -79,6 +82,19 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
/** Thumbnail registry */
|
||||
private ThumbnailRegistry thumbnailRegistry;
|
||||
|
||||
/** Rendition service */
|
||||
private RenditionService renditionService;
|
||||
|
||||
/**
|
||||
* Set the rendition service.
|
||||
*
|
||||
* @param renditionService
|
||||
*/
|
||||
public void setRenditionService(RenditionService renditionService)
|
||||
{
|
||||
this.renditionService = renditionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node service
|
||||
*
|
||||
@@ -168,118 +184,89 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
logger.debug("Creating thumbnail: There is already a thumbnail with the name '" + thumbnailName + "' (node=" + node.toString() + "; contentProperty=" + contentProperty.toString() + "; mimetype=" + mimetype);
|
||||
}
|
||||
|
||||
// We can't continue because there is already an thumbnail with the given name for that content property
|
||||
// We can't continue because there is already a thumbnail with the given name for that content property
|
||||
throw new ThumbnailException(ERR_DUPLICATE_NAME);
|
||||
}
|
||||
|
||||
NodeRef thumbnail = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<NodeRef>()
|
||||
ChildAssociationRef thumbnailRef = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<ChildAssociationRef>()
|
||||
{
|
||||
public NodeRef doWork() throws Exception
|
||||
public ChildAssociationRef doWork() throws Exception
|
||||
{
|
||||
NodeRef thumbnail;
|
||||
|
||||
// Apply the thumbnailed aspect to the node if it doesn't already have it
|
||||
if (nodeService.hasAspect(node, ContentModel.ASPECT_THUMBNAILED) == false)
|
||||
{
|
||||
// Ensure we do not update the 'modifier' due to thumbnail addition
|
||||
behaviourFilter.disableBehaviour(node, ContentModel.ASPECT_AUDITABLE);
|
||||
try
|
||||
{
|
||||
nodeService.addAspect(node, ContentModel.ASPECT_THUMBNAILED, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
behaviourFilter.enableBehaviour(node, ContentModel.ASPECT_AUDITABLE);
|
||||
}
|
||||
}
|
||||
|
||||
// Need a variable scoped to this inner class in order to assign a new value to it.
|
||||
String localThumbnailName = thumbnailName;
|
||||
// Get the name of the thumbnail and add to properties map
|
||||
String thumbName = thumbnailName;
|
||||
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(4);
|
||||
if (thumbName == null || thumbName.length() == 0)
|
||||
if (localThumbnailName == null || localThumbnailName.length() == 0)
|
||||
{
|
||||
thumbName = GUID.generate();
|
||||
localThumbnailName = GUID.generate();
|
||||
}
|
||||
else
|
||||
{
|
||||
String thumbnailFileName = generateThumbnailFileName(thumbName, mimetype);
|
||||
properties.put(ContentModel.PROP_NAME, thumbnailFileName);
|
||||
}
|
||||
properties.put(ContentModel.PROP_THUMBNAIL_NAME, thumbName);
|
||||
|
||||
// Add the name of the content property
|
||||
properties.put(ContentModel.PROP_CONTENT_PROPERTY_NAME, contentProperty);
|
||||
|
||||
// See if parent association details have been specified for the thumbnail
|
||||
if (assocDetails == null)
|
||||
{
|
||||
// Create the thumbnail using the thumbnails child association
|
||||
thumbnail = nodeService.createNode(
|
||||
node,
|
||||
ContentModel.ASSOC_THUMBNAILS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbName),
|
||||
ContentModel.TYPE_THUMBNAIL,
|
||||
properties).getChildRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the thumbnail using the specified parent assoc details
|
||||
thumbnail = nodeService.createNode(
|
||||
assocDetails.getParent(),
|
||||
assocDetails.getAssociationType(),
|
||||
assocDetails.getAssociationName(),
|
||||
ContentModel.TYPE_THUMBNAIL,
|
||||
properties).getChildRef();
|
||||
// We're prepending the cm namespace here.
|
||||
QName thumbnailQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, localThumbnailName);
|
||||
|
||||
// Associate the new thumbnail to the source
|
||||
nodeService.addChild(
|
||||
node,
|
||||
thumbnail,
|
||||
ContentModel.ASSOC_THUMBNAILS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbName));
|
||||
}
|
||||
|
||||
// Get the content reader and writer for content nodes
|
||||
ContentReader reader = contentService.getReader(node, contentProperty);
|
||||
ContentWriter writer = contentService.getWriter(thumbnail, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding(reader.getEncoding());
|
||||
|
||||
// Catch the failure to create the thumbnail
|
||||
if (contentService.isTransformable(reader, writer, transformationOptions) == false)
|
||||
RenditionDefinition renderingAction = renditionService.loadRenditionDefinition(thumbnailQName);
|
||||
if (renderingAction == null)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Creating thumbnail: There is no transformer to generate the thumbnail required (node=" + node.toString() + "; contentProperty=" + contentProperty.toString() + "; mimetype=" + mimetype + ")");
|
||||
}
|
||||
// If the provided thumbnailName does not map to a built-in rendition definition
|
||||
// then we must create a dynamic rendition definition for this thumbnail.
|
||||
// To do this we must have a renderingEngineName.
|
||||
//
|
||||
// The transformation will either be a imageRenderingEngine or a reformat (pdf2swf)
|
||||
String renderingEngineName = getRenderingEngineNameFor(transformationOptions);
|
||||
|
||||
// Throw exception indicating that the thumbnail could not be created
|
||||
throw new ThumbnailException(MessageFormat.format(ERR_NO_CREATE, reader.getMimetype(), writer.getMimetype()));
|
||||
renderingAction = renditionService.createRenditionDefinition(thumbnailQName, renderingEngineName);
|
||||
}
|
||||
else
|
||||
Map<String, Serializable> params = new ThumbnailRenditionConvertor().convert(transformationOptions, assocDetails);
|
||||
for (String key : params.keySet())
|
||||
{
|
||||
// Do the thumbnail transformation
|
||||
contentService.transform(reader, writer, transformationOptions);
|
||||
renderingAction.setParameterValue(key, params.get(key));
|
||||
}
|
||||
|
||||
|
||||
return thumbnail;
|
||||
ChildAssociationRef chAssRef = null;
|
||||
try
|
||||
{
|
||||
chAssRef = renditionService.render(node, renderingAction);
|
||||
} catch (RenditionServiceException rsx)
|
||||
{
|
||||
throw new ThumbnailException(rsx.getMessage(), rsx);
|
||||
}
|
||||
|
||||
return chAssRef;
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
// Return the created thumbnail
|
||||
return thumbnail;
|
||||
return getThumbnailNode(thumbnailRef);
|
||||
}
|
||||
|
||||
private String getRenderingEngineNameFor(TransformationOptions options)
|
||||
{
|
||||
if (options instanceof ImageTransformationOptions)
|
||||
{
|
||||
return ImageRenderingEngine.NAME;
|
||||
}
|
||||
else if (options instanceof SWFTransformationOptions)
|
||||
{
|
||||
return ReformatRenderingEngine.NAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO What can we do here? Can we treat this as an error?
|
||||
// Isn't this a 'standard' TransformationOptions?
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the thumbnail name from the name and destination mimertype
|
||||
* This method returns the NodeRef for the thumbnail, using the ChildAssociationRef
|
||||
* that links the sourceNode to its associated Thumbnail node.
|
||||
*
|
||||
* @param thumbnailName the thumbnail name
|
||||
* @param destinationMimetype the destination name
|
||||
* @return String the thumbnail file name
|
||||
* @param thumbnailRef the ChildAssociationRef containing the child NodeRef.
|
||||
* @return the NodeRef of the thumbnail itself.
|
||||
*/
|
||||
private String generateThumbnailFileName(String thumbnailName, String destinationMimetype)
|
||||
public NodeRef getThumbnailNode(ChildAssociationRef thumbnailRef)
|
||||
{
|
||||
return thumbnailName + "." + this.mimetypeMap.getExtension(destinationMimetype);
|
||||
return thumbnailRef.getChildRef();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,75 +274,61 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
*/
|
||||
public void updateThumbnail(final NodeRef thumbnail, final TransformationOptions transformationOptions)
|
||||
{
|
||||
// Seeing as how this always gives its own options, maybe this should be a delete and recreate?
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Updating thumbnail (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
|
||||
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||
// First check that we are dealing with a rendition object
|
||||
if (renditionService.isRendition(thumbnail))
|
||||
{
|
||||
public Object doWork() throws Exception
|
||||
// Get the node that is the source of the thumbnail
|
||||
ChildAssociationRef parentAssoc = renditionService.getSourceNode(thumbnail);
|
||||
|
||||
if (parentAssoc == null)
|
||||
{
|
||||
// First check that we are dealing with a thumbnail
|
||||
if (ContentModel.TYPE_THUMBNAIL.equals(nodeService.getType(thumbnail)) == true)
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
// Get the node that is the source of the thumbnail
|
||||
NodeRef node = null;
|
||||
List<ChildAssociationRef> parents = nodeService.getParentAssocs(thumbnail, ContentModel.ASSOC_THUMBNAILS, RegexQNamePattern.MATCH_ALL);
|
||||
if (parents.size() == 0)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Updating thumbnail: The thumbnails parent cannot be found (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
|
||||
throw new ThumbnailException(ERR_NO_PARENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = parents.get(0).getParentRef();
|
||||
}
|
||||
|
||||
// Get the content property
|
||||
QName contentProperty = (QName)nodeService.getProperty(thumbnail, ContentModel.PROP_CONTENT_PROPERTY_NAME);
|
||||
|
||||
// Get the reader and writer
|
||||
ContentReader reader = contentService.getReader(node, contentProperty);
|
||||
ContentWriter writer = contentService.getWriter(thumbnail, ContentModel.PROP_CONTENT, true);
|
||||
|
||||
// Set the basic detail of the transformation options
|
||||
transformationOptions.setSourceNodeRef(node);
|
||||
transformationOptions.setSourceContentProperty(contentProperty);
|
||||
transformationOptions.setTargetNodeRef(thumbnail);
|
||||
transformationOptions.setTargetContentProperty(ContentModel.PROP_CONTENT);
|
||||
|
||||
// Catch the failure to create the thumbnail
|
||||
if (contentService.isTransformable(reader, writer, transformationOptions) == false)
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Updating thumbnail: there is not transformer to update the thumbnail with (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
|
||||
// Throw exception indicating that the thumbnail could not be created
|
||||
throw new ThumbnailException(MessageFormat.format(ERR_NO_CREATE, reader.getMimetype(), writer.getMimetype()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do the thumbnail transformation
|
||||
contentService.transform(reader, writer, transformationOptions);
|
||||
}
|
||||
logger.debug("Updating thumbnail: The thumbnails parent cannot be found (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Updating thumbnail: cannot update a thumbnail node that isn't the correct thumbnail type (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new ThumbnailException(ERR_NO_PARENT);
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
|
||||
final QName renditionAssociationName = parentAssoc.getQName();
|
||||
NodeRef sourceNode = parentAssoc.getParentRef();
|
||||
|
||||
// Get the content property
|
||||
QName contentProperty = (QName)nodeService.getProperty(thumbnail, ContentModel.PROP_CONTENT_PROPERTY_NAME);
|
||||
|
||||
// Set the basic detail of the transformation options
|
||||
transformationOptions.setSourceNodeRef(sourceNode);
|
||||
transformationOptions.setSourceContentProperty(contentProperty);
|
||||
transformationOptions.setTargetContentProperty(ContentModel.PROP_CONTENT);
|
||||
|
||||
// Do the thumbnail transformation
|
||||
RenditionDefinition rendDefn = renditionService.loadRenditionDefinition(renditionAssociationName);
|
||||
if (rendDefn == null)
|
||||
{
|
||||
String renderingEngineName = getRenderingEngineNameFor(transformationOptions);
|
||||
|
||||
rendDefn = renditionService.createRenditionDefinition(parentAssoc.getQName(), renderingEngineName);
|
||||
}
|
||||
Map<String, Serializable> params = new ThumbnailRenditionConvertor().convert(transformationOptions, null);
|
||||
for (String key : params.keySet())
|
||||
{
|
||||
rendDefn.setParameterValue(key, params.get(key));
|
||||
}
|
||||
|
||||
renditionService.render(sourceNode, rendDefn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
logger.debug("Updating thumbnail: cannot update a thumbnail node that isn't the correct thumbnail type (thumbnail=" + thumbnail.toString() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,8 +336,6 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
*/
|
||||
public NodeRef getThumbnailByName(NodeRef node, QName contentProperty, String thumbnailName)
|
||||
{
|
||||
NodeRef thumbnail = null;
|
||||
|
||||
//
|
||||
// NOTE:
|
||||
//
|
||||
@@ -377,21 +348,21 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
logger.debug("Getting thumbnail by name (nodeRef=" + node.toString() + "; contentProperty=" + contentProperty.toString() + "; thumbnailName=" + thumbnailName + ")");
|
||||
}
|
||||
|
||||
// Check that the node has the thumbnailed aspect applied
|
||||
if (nodeService.hasAspect(node, ContentModel.ASPECT_THUMBNAILED) == true)
|
||||
// Thumbnails have a cm: prefix.
|
||||
QName namespacedThumbnailName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbnailName);
|
||||
|
||||
ChildAssociationRef existingRendition = renditionService.getRenditionByName(node, namespacedThumbnailName);
|
||||
NodeRef thumbnail = null;
|
||||
|
||||
// Check the child to see if it matches the content property we are concerned about.
|
||||
// We can assume there will only ever be one per content property since createThumbnail enforces this.
|
||||
if (existingRendition != null)
|
||||
{
|
||||
// Get all the thumbnails that match the thumbnail name
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(node, ContentModel.ASSOC_THUMBNAILS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, thumbnailName));
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
NodeRef child = existingRendition.getChildRef();
|
||||
Serializable contentPropertyName = this.nodeService.getProperty(child, ContentModel.PROP_CONTENT_PROPERTY_NAME);
|
||||
if (contentProperty.equals(contentPropertyName) == true)
|
||||
{
|
||||
// Check the child to see if it matches the content property we are concerned about.
|
||||
// We can assume there will only ever be one per content property since createThumbnail enforces this.
|
||||
NodeRef child = assoc.getChildRef();
|
||||
if (contentProperty.equals(this.nodeService.getProperty(child, ContentModel.PROP_CONTENT_PROPERTY_NAME)) == true)
|
||||
{
|
||||
thumbnail = child;
|
||||
break;
|
||||
}
|
||||
thumbnail = child;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,24 +388,21 @@ public class ThumbnailServiceImpl implements ThumbnailService
|
||||
logger.debug("Getting thumbnails (nodeRef=" + node.toString() + "; contentProperty=" + contentProperty.toString() + "; mimetype=" + mimetype + ")");
|
||||
}
|
||||
|
||||
// Check that the node has the thumbnailed aspect applied
|
||||
if (nodeService.hasAspect(node, ContentModel.ASPECT_THUMBNAILED) == true)
|
||||
List<ChildAssociationRef> renditions = this.renditionService.getRenditions(node);
|
||||
|
||||
for (ChildAssociationRef assoc : renditions)
|
||||
{
|
||||
// Get all the thumbnails that match the thumbnail name
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(node, ContentModel.ASSOC_THUMBNAILS, RegexQNamePattern.MATCH_ALL);
|
||||
for (ChildAssociationRef assoc : assocs)
|
||||
// Check the child to see if it matches the content property we are concerned about.
|
||||
// We can assume there will only ever be one per content property since createThumbnail enforces this.
|
||||
NodeRef child = assoc.getChildRef();
|
||||
if (contentProperty.equals(this.nodeService.getProperty(child, ContentModel.PROP_CONTENT_PROPERTY_NAME)) == true &&
|
||||
matchMimetypeOptions(child, mimetype, options) == true)
|
||||
{
|
||||
// Check the child to see if it matches the content property we are concerned about.
|
||||
// We can assume there will only ever be one per content property since createThumbnail enforces this.
|
||||
NodeRef child = assoc.getChildRef();
|
||||
if (contentProperty.equals(this.nodeService.getProperty(child, ContentModel.PROP_CONTENT_PROPERTY_NAME)) == true &&
|
||||
matchMimetypeOptions(child, mimetype, options) == true)
|
||||
{
|
||||
thumbnails.add(child);
|
||||
}
|
||||
thumbnails.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Ensure this doesn't return non-thumbnail renditions.
|
||||
return thumbnails;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.thumbnail;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.ActionImpl;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.magick.ImageResizeOptions;
|
||||
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
|
||||
import org.alfresco.repo.rendition.PerformRenditionActionExecuter;
|
||||
import org.alfresco.repo.rendition.RenditionServiceImpl;
|
||||
import org.alfresco.repo.rendition.executer.AbstractRenderingEngine;
|
||||
import org.alfresco.repo.rendition.executer.ImageRenderingEngine;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.rendition.RenditionDefinition;
|
||||
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.thumbnail.ThumbnailParentAssociationDetails;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
/**
|
||||
* Thumbnail service implementation unit test
|
||||
*
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ThumbnailServiceImplParameterTest
|
||||
{
|
||||
// Mocked services.
|
||||
private ActionService mockActionService = mock(ActionService.class);
|
||||
|
||||
// Real services - backed by mocked services.
|
||||
private RenditionServiceImpl renditionService;
|
||||
private ThumbnailService thumbnailService;
|
||||
|
||||
private final NodeRef dummyNodeRef1 = new NodeRef("workspace", "dummy", "dummyID_1");
|
||||
private final NodeRef dummyNodeRef2 = new NodeRef("workspace", "dummy", "dummyID_2");
|
||||
private final NodeRef dummyNodeRef3 = new NodeRef("workspace", "dummy", "dummyID_3");
|
||||
|
||||
@Before
|
||||
public void initMockObjects()
|
||||
{
|
||||
when(mockActionService.createAction(PerformRenditionActionExecuter.NAME))
|
||||
.thenReturn(new ActionImpl(dummyNodeRef2, "id", PerformRenditionActionExecuter.NAME, new HashMap<String, Serializable>()));
|
||||
renditionService = new RenditionServiceImpl()
|
||||
{
|
||||
@Override
|
||||
public RenditionDefinition loadRenditionDefinition(QName renderingActionName)
|
||||
{
|
||||
// We're intentionally returning null for this test.
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
renditionService.setActionService(mockActionService);
|
||||
|
||||
ThumbnailServiceImpl thumbs = new ThumbnailServiceImpl()
|
||||
{
|
||||
@Override
|
||||
public NodeRef getThumbnailByName(NodeRef node,
|
||||
QName contentProperty, String thumbnailName)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* In this test the thumbnailRef will be null, so we need to ensure
|
||||
* it is not dereferenced here.
|
||||
*/
|
||||
@Override
|
||||
public NodeRef getThumbnailNode(ChildAssociationRef thumbnailRef)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
};
|
||||
thumbs.setRenditionService(renditionService);
|
||||
thumbnailService = thumbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test method ensures that the parameters on thumbnail-create are
|
||||
* passed through the RenditionService to the ActionService
|
||||
*/
|
||||
@Test
|
||||
public void createThumbnailPassesParametersToActionService()
|
||||
{
|
||||
// As most of the services are mocked out, the actual values used here
|
||||
// don't matter.
|
||||
final Map<String, Serializable> parametersUnderTest = new HashMap<String, Serializable>();
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_RESIZE_WIDTH, new Integer(42));
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_RESIZE_HEIGHT, new Integer(93));
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_COMMAND_OPTIONS, "foo");
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_MAINTAIN_ASPECT_RATIO, Boolean.TRUE);
|
||||
parametersUnderTest.put(ImageRenderingEngine.PARAM_RESIZE_TO_THUMBNAIL, Boolean.FALSE);
|
||||
parametersUnderTest.put(AbstractRenderingEngine.PARAM_TARGET_CONTENT_PROPERTY, ContentModel.PROP_CONTENT);
|
||||
parametersUnderTest.put(RenditionService.PARAM_DESTINATION_NODE, dummyNodeRef2);
|
||||
|
||||
|
||||
ImageTransformationOptions imageTransOpts = new ImageTransformationOptions();
|
||||
imageTransOpts.setTargetNodeRef(dummyNodeRef2);
|
||||
|
||||
imageTransOpts.setTargetContentProperty((QName) parametersUnderTest.get(ImageRenderingEngine.PARAM_TARGET_CONTENT_PROPERTY));
|
||||
imageTransOpts.setCommandOptions((String) parametersUnderTest.get(ImageRenderingEngine.PARAM_COMMAND_OPTIONS));
|
||||
|
||||
ImageResizeOptions resizeOptions = new ImageResizeOptions();
|
||||
resizeOptions.setHeight((Integer) parametersUnderTest.get(ImageRenderingEngine.PARAM_RESIZE_HEIGHT));
|
||||
resizeOptions.setWidth((Integer) parametersUnderTest.get(ImageRenderingEngine.PARAM_RESIZE_WIDTH));
|
||||
resizeOptions.setMaintainAspectRatio((Boolean) parametersUnderTest.get(ImageRenderingEngine.PARAM_MAINTAIN_ASPECT_RATIO));
|
||||
resizeOptions.setResizeToThumbnail((Boolean) parametersUnderTest.get(ImageRenderingEngine.PARAM_RESIZE_TO_THUMBNAIL));
|
||||
imageTransOpts.setResizeOptions(resizeOptions);
|
||||
|
||||
ThumbnailParentAssociationDetails assocDetails = new ThumbnailParentAssociationDetails(dummyNodeRef3,
|
||||
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||
"homerSimpson"));
|
||||
|
||||
// Now request the creation of the the thumbnail.
|
||||
thumbnailService.createThumbnail(dummyNodeRef1, ContentModel.PROP_CONTENT, MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransOpts, "bartSimpson", assocDetails);
|
||||
|
||||
|
||||
ArgumentCaptor<Action> argument = ArgumentCaptor.forClass(Action.class);
|
||||
verify(mockActionService).executeAction(argument.capture(), any(NodeRef.class), anyBoolean(), anyBoolean());
|
||||
final Action performRenditionAction = argument.getValue();
|
||||
final RenditionDefinition renditionDefn = (RenditionDefinition) performRenditionAction.getParameterValue(PerformRenditionActionExecuter.PARAM_RENDITION_DEFINITION);
|
||||
Map<String, Serializable> parameters = renditionDefn.getParameterValues();
|
||||
|
||||
for (String s : parametersUnderTest.keySet())
|
||||
{
|
||||
if (parameters.keySet().contains(s) == false || parameters.get(s) == null || parameters.get(s).toString().length() == 0)
|
||||
{
|
||||
fail("Missing parameter " + s);
|
||||
}
|
||||
assertEquals("Parameter " + s + " had wrong value.",
|
||||
parametersUnderTest.get(s), parameters.get(s));
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,6 +16,7 @@
|
||||
* 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.repo.thumbnail;
|
||||
|
||||
import java.io.File;
|
||||
@@ -26,6 +27,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.model.RenditionModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
@@ -33,13 +35,16 @@ import org.alfresco.repo.content.transform.magick.ImageResizeOptions;
|
||||
import org.alfresco.repo.content.transform.magick.ImageTransformationOptions;
|
||||
import org.alfresco.repo.jscript.ClasspathScriptLocation;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
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.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.ScriptLocation;
|
||||
import org.alfresco.service.cmr.repository.ScriptService;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailException;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailParentAssociationDetails;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -50,160 +55,189 @@ import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||
* Thumbnail service implementation unit test
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
||||
public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
||||
{
|
||||
private ThumbnailService thumbnailService;
|
||||
private RenditionService renditionService;
|
||||
private ThumbnailService thumbnailService;
|
||||
private ScriptService scriptService;
|
||||
private MimetypeMap mimetypeMap;
|
||||
private MimetypeMap mimetypeMap;
|
||||
private NodeRef folder;
|
||||
|
||||
|
||||
/**
|
||||
* Called during the transaction setup
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
super.onSetUpInTransaction();
|
||||
|
||||
|
||||
// Get the required services
|
||||
this.thumbnailService = (ThumbnailService)this.applicationContext.getBean("ThumbnailService");
|
||||
this.mimetypeMap = (MimetypeMap)this.applicationContext.getBean("mimetypeService");
|
||||
this.scriptService = (ScriptService)this.applicationContext.getBean("ScriptService");
|
||||
|
||||
this.renditionService = (RenditionService) this.applicationContext.getBean("RenditionService");
|
||||
this.thumbnailService = (ThumbnailService) this.applicationContext.getBean("ThumbnailService");
|
||||
this.mimetypeMap = (MimetypeMap) this.applicationContext.getBean("mimetypeService");
|
||||
this.scriptService = (ScriptService) this.applicationContext.getBean("ScriptService");
|
||||
|
||||
// Create a folder and some content
|
||||
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>(1);
|
||||
folderProps.put(ContentModel.PROP_NAME, "testFolder");
|
||||
this.folder = this.nodeService.createNode(
|
||||
this.rootNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"),
|
||||
ContentModel.TYPE_FOLDER).getChildRef();
|
||||
this.folder = this.nodeService.createNode(this.rootNodeRef, ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"), ContentModel.TYPE_FOLDER)
|
||||
.getChildRef();
|
||||
}
|
||||
|
||||
private void checkTransformer()
|
||||
{
|
||||
ContentTransformer transformer = this.contentService.getImageTransformer();
|
||||
if (transformer == null)
|
||||
{
|
||||
fail("No transformer returned for 'getImageTransformer'");
|
||||
}
|
||||
assertNotNull("No transformer returned for 'getImageTransformer'", transformer);
|
||||
|
||||
// Check that it is working
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
if (!transformer.isTransformable(
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions))
|
||||
if (!transformer.isTransformable(MimetypeMap.MIMETYPE_IMAGE_JPEG, MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions))
|
||||
{
|
||||
fail("Image transformer is not working. Please check your image conversion command setup.");
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreateRenditionThumbnailFromImage() throws Exception
|
||||
{
|
||||
QName qname = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||
|
||||
ThumbnailDefinition details = thumbnailService.getThumbnailRegistry().getThumbnailDefinition(
|
||||
qname.getLocalName());
|
||||
assertEquals("doclib", details.getName());
|
||||
assertEquals("image/png", details.getMimetype());
|
||||
assertEquals("alfresco/thumbnail/thumbnail_placeholder_doclib.png", details.getPlaceHolderResourcePath());
|
||||
|
||||
checkTransformer();
|
||||
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
NodeRef thumbnail0 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, details.getTransformationOptions(), "doclib");
|
||||
assertNotNull(thumbnail0);
|
||||
checkRenditioned(jpgOrig, "doclib");
|
||||
checkRendition("doclib", thumbnail0);
|
||||
outputThumbnailTempContentLocation(thumbnail0, "jpg", "doclib test");
|
||||
}
|
||||
|
||||
public void testCreateRenditionThumbnailFromPdf() throws Exception
|
||||
{
|
||||
QName qname = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||
|
||||
ThumbnailDefinition details = thumbnailService.getThumbnailRegistry().getThumbnailDefinition(
|
||||
qname.getLocalName());
|
||||
assertEquals("doclib", details.getName());
|
||||
assertEquals("image/png", details.getMimetype());
|
||||
assertEquals("alfresco/thumbnail/thumbnail_placeholder_doclib.png", details.getPlaceHolderResourcePath());
|
||||
|
||||
checkTransformer();
|
||||
|
||||
NodeRef pdfOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_PDF);
|
||||
|
||||
NodeRef thumbnail0 = this.thumbnailService.createThumbnail(pdfOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, details.getTransformationOptions(), "doclib");
|
||||
assertNotNull(thumbnail0);
|
||||
checkRenditioned(pdfOrig, "doclib");
|
||||
checkRendition("doclib", thumbnail0);
|
||||
outputThumbnailTempContentLocation(thumbnail0, "jpg", "doclib test");
|
||||
}
|
||||
|
||||
public void testCreateThumbnailFromImage() throws Exception
|
||||
{
|
||||
checkTransformer();
|
||||
|
||||
NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
NodeRef gifOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_GIF);
|
||||
|
||||
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
NodeRef gifOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_GIF);
|
||||
|
||||
// ===== small: 64x64, marked as thumbnail ====
|
||||
|
||||
|
||||
ImageResizeOptions imageResizeOptions = new ImageResizeOptions();
|
||||
imageResizeOptions.setWidth(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setResizeToThumbnail(true);
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
//ThumbnailDetails createOptions = new ThumbnailDetails();
|
||||
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions,
|
||||
"small");
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
// ThumbnailDetails createOptions = new ThumbnailDetails();
|
||||
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions, "small");
|
||||
assertNotNull(thumbnail1);
|
||||
checkThumbnailed(jpgOrig, "small");
|
||||
checkThumbnail("small", thumbnail1);
|
||||
checkRenditioned(jpgOrig, "small");
|
||||
checkRendition("small", thumbnail1);
|
||||
outputThumbnailTempContentLocation(thumbnail1, "jpg", "small - 64x64, marked as thumbnail");
|
||||
|
||||
|
||||
// ===== small2: 64x64, aspect not maintained ====
|
||||
|
||||
|
||||
ImageResizeOptions imageResizeOptions2 = new ImageResizeOptions();
|
||||
imageResizeOptions2.setWidth(64);
|
||||
imageResizeOptions2.setHeight(64);
|
||||
imageResizeOptions2.setHeight(64);
|
||||
imageResizeOptions2.setMaintainAspectRatio(false);
|
||||
ImageTransformationOptions imageTransformationOptions2 = new ImageTransformationOptions();
|
||||
imageTransformationOptions2.setResizeOptions(imageResizeOptions2);
|
||||
//ThumbnailDetails createOptions2 = new ThumbnailDetails();
|
||||
NodeRef thumbnail2 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions2,
|
||||
"small2");
|
||||
checkThumbnailed(jpgOrig, "small2");
|
||||
checkThumbnail("small2", thumbnail2);
|
||||
imageTransformationOptions2.setResizeOptions(imageResizeOptions2);
|
||||
// ThumbnailDetails createOptions2 = new ThumbnailDetails();
|
||||
NodeRef thumbnail2 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions2, "small2");
|
||||
checkRenditioned(jpgOrig, "small2");
|
||||
checkRendition("small2", thumbnail2);
|
||||
outputThumbnailTempContentLocation(thumbnail2, "jpg", "small2 - 64x64, aspect not maintained");
|
||||
|
||||
// ===== half: 50%x50 =====
|
||||
|
||||
|
||||
// ===== half: 50%x50 =====
|
||||
|
||||
ImageResizeOptions imageResizeOptions3 = new ImageResizeOptions();
|
||||
imageResizeOptions3.setWidth(50);
|
||||
imageResizeOptions3.setHeight(50);
|
||||
imageResizeOptions3.setHeight(50);
|
||||
imageResizeOptions3.setPercentResize(true);
|
||||
ImageTransformationOptions imageTransformationOptions3 = new ImageTransformationOptions();
|
||||
imageTransformationOptions3.setResizeOptions(imageResizeOptions3);
|
||||
// ThumbnailDetails createOptions3 = new ThumbnailDetails();
|
||||
NodeRef thumbnail3 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions3,
|
||||
"half");
|
||||
checkThumbnailed(jpgOrig, "half");
|
||||
checkThumbnail("half", thumbnail3);
|
||||
imageTransformationOptions3.setResizeOptions(imageResizeOptions3);
|
||||
// ThumbnailDetails createOptions3 = new ThumbnailDetails();
|
||||
NodeRef thumbnail3 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions3, "half");
|
||||
checkRenditioned(jpgOrig, "half");
|
||||
checkRendition("half", thumbnail3);
|
||||
outputThumbnailTempContentLocation(thumbnail3, "jpg", "half - 50%x50%");
|
||||
|
||||
|
||||
// ===== half2: 50%x50 from gif =====
|
||||
|
||||
|
||||
// ===== half2: 50%x50 from gif =====
|
||||
|
||||
ImageResizeOptions imageResizeOptions4 = new ImageResizeOptions();
|
||||
imageResizeOptions4.setWidth(50);
|
||||
imageResizeOptions4.setHeight(50);
|
||||
imageResizeOptions4.setHeight(50);
|
||||
imageResizeOptions4.setPercentResize(true);
|
||||
ImageTransformationOptions imageTransformationOptions4 = new ImageTransformationOptions();
|
||||
imageTransformationOptions4.setResizeOptions(imageResizeOptions4);
|
||||
// ThumbnailDetails createOptions4 = new ThumbnailDetails();
|
||||
NodeRef thumbnail4 = this.thumbnailService.createThumbnail(gifOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions4,
|
||||
"half2");
|
||||
checkThumbnailed(gifOrig, "half2");
|
||||
checkThumbnail("half2", thumbnail4);
|
||||
imageTransformationOptions4.setResizeOptions(imageResizeOptions4);
|
||||
// ThumbnailDetails createOptions4 = new ThumbnailDetails();
|
||||
NodeRef thumbnail4 = this.thumbnailService.createThumbnail(gifOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions4, "half2");
|
||||
checkRenditioned(gifOrig, "half2");
|
||||
checkRendition("half2", thumbnail4);
|
||||
outputThumbnailTempContentLocation(thumbnail4, "jpg", "half2 - 50%x50%, from gif");
|
||||
}
|
||||
|
||||
public void testDuplicationNames()
|
||||
throws Exception
|
||||
|
||||
public void testDuplicationNames() throws Exception
|
||||
{
|
||||
checkTransformer();
|
||||
|
||||
NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
ImageResizeOptions imageResizeOptions = new ImageResizeOptions();
|
||||
imageResizeOptions.setWidth(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setResizeToThumbnail(true);
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
//ThumbnailDetails createOptions = new ThumbnailDetails();
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions,
|
||||
"small");
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
// ThumbnailDetails createOptions = new ThumbnailDetails();
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions, "small");
|
||||
assertNotNull(thumbnail1);
|
||||
checkThumbnailed(jpgOrig, "small");
|
||||
checkThumbnail("small", thumbnail1);
|
||||
|
||||
checkRenditioned(jpgOrig, "small");
|
||||
checkRendition("small", thumbnail1);
|
||||
|
||||
try
|
||||
{
|
||||
this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions,
|
||||
"small");
|
||||
this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT, MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions, "small");
|
||||
fail("A duplicate exception should have been raised");
|
||||
}
|
||||
catch (ThumbnailException exception)
|
||||
@@ -211,180 +245,182 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
||||
// OK since this should have been thrown
|
||||
}
|
||||
}
|
||||
|
||||
public void testThumbnailUpdate()
|
||||
throws Exception
|
||||
|
||||
public void testThumbnailUpdate() throws Exception
|
||||
{
|
||||
checkTransformer();
|
||||
|
||||
|
||||
// First create a thumbnail
|
||||
NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
ImageResizeOptions imageResizeOptions = new ImageResizeOptions();
|
||||
imageResizeOptions.setWidth(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setResizeToThumbnail(true);
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions,
|
||||
"small");
|
||||
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions, "small");
|
||||
|
||||
// Update the thumbnail
|
||||
this.thumbnailService.updateThumbnail(thumbnail1, imageTransformationOptions);
|
||||
}
|
||||
|
||||
public void testGetThumbnailByName()
|
||||
throws Exception
|
||||
|
||||
public void testGetThumbnailByName() throws Exception
|
||||
{
|
||||
checkTransformer();
|
||||
|
||||
NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
// Check for missing thumbnail
|
||||
NodeRef result1 = this.thumbnailService.getThumbnailByName(jpgOrig, ContentModel.PROP_CONTENT, "small");
|
||||
assertNull("The thumbnail 'small' should have been missing", result1);
|
||||
|
||||
|
||||
// Create the thumbnail
|
||||
ImageResizeOptions imageResizeOptions = new ImageResizeOptions();
|
||||
imageResizeOptions.setWidth(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setResizeToThumbnail(true);
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions,
|
||||
"small");
|
||||
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT, MimetypeMap.MIMETYPE_IMAGE_JPEG,
|
||||
imageTransformationOptions, "small");
|
||||
|
||||
// Try and retrieve the thumbnail
|
||||
NodeRef result2 = this.thumbnailService.getThumbnailByName(jpgOrig, ContentModel.PROP_CONTENT, "small");
|
||||
assertNotNull(result2);
|
||||
checkThumbnail("small", result2);
|
||||
|
||||
checkRendition("small", result2);
|
||||
|
||||
// Check for an other thumbnail that doesn't exist
|
||||
NodeRef result3 = this.thumbnailService.getThumbnailByName(jpgOrig, ContentModel.PROP_CONTENT, "anotherone");
|
||||
assertNull("The thumbnail 'anotherone' should have been missing", result3);
|
||||
}
|
||||
|
||||
// TODO test getThumbnails
|
||||
|
||||
private void checkThumbnailed(NodeRef thumbnailed, String assocName)
|
||||
|
||||
private void checkRenditioned(NodeRef thumbnailed, String assocName)
|
||||
{
|
||||
assertTrue("Thumbnailed aspect should have been applied", this.nodeService.hasAspect(thumbnailed, ContentModel.ASPECT_THUMBNAILED));
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(thumbnailed, RegexQNamePattern.MATCH_ALL, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, assocName));
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
assertTrue("Renditioned aspect should have been applied", this.nodeService.hasAspect(thumbnailed,
|
||||
RenditionModel.ASPECT_RENDITIONED));
|
||||
if (assocName != null)
|
||||
{
|
||||
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(thumbnailed, RegexQNamePattern.MATCH_ALL,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, assocName));
|
||||
assertNotNull(assocs);
|
||||
assertEquals(1, assocs.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkThumbnail(String thumbnailName, NodeRef thumbnail)
|
||||
|
||||
private void checkRendition(String thumbnailName, NodeRef thumbnail)
|
||||
{
|
||||
// Check the thumbnail is of the correct type
|
||||
assertEquals(ContentModel.TYPE_THUMBNAIL, this.nodeService.getType(thumbnail));
|
||||
|
||||
// Check the name
|
||||
assertEquals(thumbnailName, this.nodeService.getProperty(thumbnail, ContentModel.PROP_THUMBNAIL_NAME));
|
||||
|
||||
// Check the contet property value
|
||||
assertEquals(ContentModel.PROP_CONTENT, this.nodeService.getProperty(thumbnail, ContentModel.PROP_CONTENT_PROPERTY_NAME));
|
||||
|
||||
assertTrue("Thumbnail should have been a rendition",
|
||||
renditionService.isRendition(thumbnail));
|
||||
|
||||
// Check the name
|
||||
if (thumbnailName != null)
|
||||
{
|
||||
assertEquals(thumbnailName, this.nodeService.getProperty(thumbnail, ContentModel.PROP_NAME));
|
||||
}
|
||||
|
||||
// Check the content property value
|
||||
assertEquals(ContentModel.PROP_CONTENT, this.nodeService.getProperty(thumbnail,
|
||||
ContentModel.PROP_CONTENT_PROPERTY_NAME));
|
||||
}
|
||||
|
||||
private void outputThumbnailTempContentLocation(NodeRef thumbnail, String ext, String message)
|
||||
throws IOException
|
||||
|
||||
private void outputThumbnailTempContentLocation(NodeRef thumbnail, String ext, String message) throws IOException
|
||||
{
|
||||
File tempFile = File.createTempFile("thumbnailServiceImpTest", "." + ext);
|
||||
ContentReader reader = this.contentService.getReader(thumbnail, ContentModel.PROP_CONTENT);
|
||||
reader.getContent(tempFile);
|
||||
System.out.println(message + ": " + tempFile.getPath());
|
||||
System.out.println(message + ": " + tempFile.getPath());
|
||||
}
|
||||
|
||||
private NodeRef createOrigionalContent(NodeRef folder, String mimetype)
|
||||
throws IOException
|
||||
|
||||
/**
|
||||
* This method creates a node under the specified folder whose content is
|
||||
* taken from the quick file corresponding to the specified MIME type.
|
||||
*
|
||||
* @param parentFolder
|
||||
* @param mimetype
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private NodeRef createOriginalContent(NodeRef parentFolder, String mimetype) throws IOException
|
||||
{
|
||||
String ext = this.mimetypeMap.getExtension(mimetype);
|
||||
File origFile = AbstractContentTransformerTest.loadQuickTestFile(ext);
|
||||
|
||||
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
|
||||
props.put(ContentModel.PROP_NAME, "origional." + ext);
|
||||
NodeRef node = this.nodeService.createNode(
|
||||
folder,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "origional." + ext),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
props).getChildRef();
|
||||
|
||||
props.put(ContentModel.PROP_NAME, "origional." + ext);
|
||||
NodeRef node = this.nodeService.createNode(parentFolder, ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "original." + ext),
|
||||
ContentModel.TYPE_CONTENT, props).getChildRef();
|
||||
|
||||
ContentWriter writer = this.contentService.getWriter(node, ContentModel.PROP_CONTENT, true);
|
||||
writer.setMimetype(mimetype);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.putContent(origFile);
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testAutoUpdate() throws Exception
|
||||
{
|
||||
checkTransformer();
|
||||
|
||||
final NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
|
||||
final NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
ThumbnailDefinition details = this.thumbnailService.getThumbnailRegistry().getThumbnailDefinition("medium");
|
||||
@SuppressWarnings("unused")
|
||||
final NodeRef thumbnail = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT, details.getMimetype(), details.getTransformationOptions(), details.getName());
|
||||
|
||||
final NodeRef thumbnail = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT, details
|
||||
.getMimetype(), details.getTransformationOptions(), details.getName());
|
||||
|
||||
setComplete();
|
||||
endTransaction();
|
||||
|
||||
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Object>()
|
||||
{
|
||||
public Object execute() throws Exception
|
||||
{
|
||||
{
|
||||
String ext = ThumbnailServiceImplTest.this.mimetypeMap.getExtension(MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
File origFile = AbstractContentTransformerTest.loadQuickTestFile(ext);
|
||||
|
||||
ContentWriter writer = ThumbnailServiceImplTest.this.contentService.getWriter(jpgOrig, ContentModel.PROP_CONTENT, true);
|
||||
|
||||
ContentWriter writer = ThumbnailServiceImplTest.this.contentService.getWriter(jpgOrig,
|
||||
ContentModel.PROP_CONTENT, true);
|
||||
writer.putContent(origFile);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO
|
||||
// this test should wait for the async action to run .. will need to commit transaction for that thou!
|
||||
|
||||
//Thread.sleep(1000);
|
||||
|
||||
// TODO
|
||||
// this test should wait for the async action to run .. will need to
|
||||
// commit transaction for that thou!
|
||||
|
||||
// Thread.sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
public void testHTMLToImageAndSWF() throws Exception
|
||||
{
|
||||
NodeRef nodeRef = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_HTML);
|
||||
NodeRef nodeRef = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_HTML);
|
||||
ThumbnailDefinition def = this.thumbnailService.getThumbnailRegistry().getThumbnailDefinition("medium");
|
||||
|
||||
if (this.contentService.getTransformer(MimetypeMap.MIMETYPE_HTML, def.getMimetype(), def.getTransformationOptions()) != null)
|
||||
{
|
||||
NodeRef thumb = this.thumbnailService.createThumbnail(
|
||||
nodeRef,
|
||||
ContentModel.PROP_CONTENT,
|
||||
def.getMimetype(),
|
||||
def.getTransformationOptions(),
|
||||
def.getName());
|
||||
|
||||
ContentTransformer transformer = this.contentService.getTransformer(MimetypeMap.MIMETYPE_HTML, def
|
||||
.getMimetype(), def.getTransformationOptions());
|
||||
if (transformer != null)
|
||||
{
|
||||
NodeRef thumb = this.thumbnailService.createThumbnail(nodeRef, ContentModel.PROP_CONTENT,
|
||||
def.getMimetype(), def.getTransformationOptions(), def.getName());
|
||||
assertNotNull(thumb);
|
||||
ContentReader reader = this.contentService.getReader(thumb, ContentModel.PROP_CONTENT);
|
||||
assertNotNull(reader);
|
||||
assertEquals(def.getMimetype(), reader.getMimetype());
|
||||
assertTrue(reader.getSize() != 0);
|
||||
}
|
||||
|
||||
|
||||
def = this.thumbnailService.getThumbnailRegistry().getThumbnailDefinition("webpreview");
|
||||
if (this.contentService.getTransformer(MimetypeMap.MIMETYPE_HTML, def.getMimetype(), def.getTransformationOptions()) != null)
|
||||
{
|
||||
NodeRef thumb = this.thumbnailService.createThumbnail(
|
||||
nodeRef,
|
||||
ContentModel.PROP_CONTENT,
|
||||
def.getMimetype(),
|
||||
def.getTransformationOptions(),
|
||||
def.getName());
|
||||
if (transformer != null)
|
||||
{
|
||||
NodeRef thumb = this.thumbnailService.createThumbnail(nodeRef, ContentModel.PROP_CONTENT,
|
||||
def.getMimetype(), def.getTransformationOptions(), def.getName());
|
||||
assertNotNull(thumb);
|
||||
ContentReader reader = this.contentService.getReader(thumb, ContentModel.PROP_CONTENT);
|
||||
assertNotNull(reader);
|
||||
@@ -393,34 +429,111 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest
|
||||
}
|
||||
}
|
||||
|
||||
public void testThumbnailServiceCreateApi() throws Exception
|
||||
{
|
||||
// Create a second folder
|
||||
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>();
|
||||
folderProps.put(ContentModel.PROP_NAME, "otherTestFolder");
|
||||
NodeRef otherFolder = this.nodeService.createNode(this.rootNodeRef, ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "otherTestFolder"), ContentModel.TYPE_FOLDER)
|
||||
.getChildRef();
|
||||
|
||||
checkTransformer();
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
|
||||
ImageResizeOptions imageResizeOptions = new ImageResizeOptions();
|
||||
imageResizeOptions.setWidth(64);
|
||||
imageResizeOptions.setHeight(64);
|
||||
imageResizeOptions.setResizeToThumbnail(true);
|
||||
ImageTransformationOptions imageTransformationOptions = new ImageTransformationOptions();
|
||||
imageTransformationOptions.setResizeOptions(imageResizeOptions);
|
||||
|
||||
// Create thumbnail - same MIME type
|
||||
NodeRef thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_JPEG, imageTransformationOptions, "smallJpeg");
|
||||
assertNotNull(thumbnail1);
|
||||
checkRenditioned(jpgOrig, "smallJpeg");
|
||||
checkRendition("smallJpeg", thumbnail1);
|
||||
outputThumbnailTempContentLocation(thumbnail1, "jpg", "smallJpeg - 64x64, marked as thumbnail");
|
||||
|
||||
// Create thumbnail - different MIME type
|
||||
thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_PNG, imageTransformationOptions, "smallPng");
|
||||
assertNotNull(thumbnail1);
|
||||
checkRenditioned(jpgOrig, "smallPng");
|
||||
checkRendition("smallPng", thumbnail1);
|
||||
outputThumbnailTempContentLocation(thumbnail1, "png", "smallPng - 64x64, marked as thumbnail");
|
||||
|
||||
// Create thumbnail - different content property
|
||||
// TODO
|
||||
|
||||
// Create thumbnail - different command options
|
||||
// We'll pass illegal command options to ImageMagick in order to trigger an exception
|
||||
Exception x = null;
|
||||
try
|
||||
{
|
||||
imageTransformationOptions.setCommandOptions("-noSuchOption");
|
||||
thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_PNG, imageTransformationOptions, "smallCO");
|
||||
} catch (ContentIOException ciox)
|
||||
{
|
||||
x = ciox;
|
||||
ciox.printStackTrace();
|
||||
}
|
||||
assertNotNull("Expected exception from ImageMagick due to invalid option", x);
|
||||
// Reset the command options
|
||||
imageTransformationOptions.setCommandOptions("");
|
||||
|
||||
|
||||
// Create thumbnail - different target assoc details
|
||||
ThumbnailParentAssociationDetails tpad
|
||||
= new ThumbnailParentAssociationDetails(otherFolder,
|
||||
QName.createQName(NamespaceService.RENDITION_MODEL_1_0_URI, "foo"),
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "bar"));
|
||||
thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_PNG, imageTransformationOptions, "targetDetails", tpad);
|
||||
assertNotNull(thumbnail1);
|
||||
checkRenditioned(jpgOrig, "targetDetails");
|
||||
checkRendition("targetDetails", thumbnail1);
|
||||
outputThumbnailTempContentLocation(thumbnail1, "png", "targetDetails - 64x64, marked as thumbnail");
|
||||
|
||||
|
||||
|
||||
// Create thumbnail - null thumbnail name
|
||||
thumbnail1 = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT,
|
||||
MimetypeMap.MIMETYPE_IMAGE_PNG, imageTransformationOptions, null);
|
||||
assertNotNull(thumbnail1);
|
||||
checkRenditioned(jpgOrig, null);
|
||||
checkRendition(null, thumbnail1);
|
||||
outputThumbnailTempContentLocation(thumbnail1, "png", "'null' - 64x64, marked as thumbnail");
|
||||
}
|
||||
|
||||
public void testRegistry()
|
||||
{
|
||||
ThumbnailRegistry thumbnailRegistry = this.thumbnailService.getThumbnailRegistry();
|
||||
List<ThumbnailDefinition> defs = thumbnailRegistry.getThumnailDefintions(MimetypeMap.MIMETYPE_HTML);
|
||||
List<ThumbnailDefinition> defs = thumbnailRegistry.getThumbnailDefinitions(MimetypeMap.MIMETYPE_HTML);
|
||||
System.out.println("Definitions ...");
|
||||
for (ThumbnailDefinition def : defs)
|
||||
{
|
||||
System.out.println("Thumbnail Available: " + def.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// == Test the JavaScript API ==
|
||||
|
||||
|
||||
public void testJSAPI() throws Exception
|
||||
{
|
||||
NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
NodeRef gifOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_GIF);
|
||||
NodeRef pdfOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_PDF);
|
||||
NodeRef docOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_WORD);
|
||||
|
||||
NodeRef jpgOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG);
|
||||
NodeRef gifOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_GIF);
|
||||
NodeRef pdfOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_PDF);
|
||||
NodeRef docOrig = createOriginalContent(this.folder, MimetypeMap.MIMETYPE_WORD);
|
||||
|
||||
Map<String, Object> model = new HashMap<String, Object>(2);
|
||||
model.put("jpgOrig", jpgOrig);
|
||||
model.put("gifOrig", gifOrig);
|
||||
model.put("pdfOrig", pdfOrig);
|
||||
model.put("docOrig", docOrig);
|
||||
|
||||
|
||||
ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js");
|
||||
this.scriptService.executeScript(location, model);
|
||||
}
|
||||
|
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 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.repo.thumbnail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.copy.CopyBehaviourCallback;
|
||||
import org.alfresco.repo.copy.CopyDetails;
|
||||
import org.alfresco.repo.copy.CopyServicePolicies;
|
||||
import org.alfresco.repo.copy.DefaultCopyBehaviourCallback;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.policy.Behaviour;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.action.CompositeAction;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.EqualsHelper;
|
||||
|
||||
/**
|
||||
* Thumbnailed aspect behaviour bean
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class ThumbnailedAspect implements NodeServicePolicies.OnUpdatePropertiesPolicy,
|
||||
CopyServicePolicies.OnCopyNodePolicy
|
||||
{
|
||||
/** Services */
|
||||
private PolicyComponent policyComponent;
|
||||
private ThumbnailService thumbnailService;
|
||||
private ActionService actionService;
|
||||
private NodeService nodeService;
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
/**
|
||||
* Set the policy component
|
||||
*
|
||||
* @param policyComponent policy component
|
||||
*/
|
||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action service
|
||||
*
|
||||
* @param actionService action service
|
||||
*/
|
||||
public void setActionService(ActionService actionService)
|
||||
{
|
||||
this.actionService = actionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node service
|
||||
*
|
||||
* @param nodeService node service
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnail service
|
||||
*
|
||||
* @param thumbnailService thumbnail service
|
||||
*/
|
||||
public void setThumbnailService(ThumbnailService thumbnailService)
|
||||
{
|
||||
this.thumbnailService = thumbnailService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dictionary service
|
||||
*
|
||||
* @param dictionaryService dictionary service
|
||||
*/
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise method
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||
ContentModel.ASPECT_THUMBNAILED,
|
||||
new JavaBehaviour(this, "onUpdateProperties", Behaviour.NotificationFrequency.TRANSACTION_COMMIT));
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
QName.createQName(NamespaceService.ALFRESCO_URI, "getCopyCallback"),
|
||||
ContentModel.ASPECT_THUMBNAILED,
|
||||
new JavaBehaviour(this, "getCopyCallback"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy#onUpdateProperties(org.alfresco.service.cmr.repository.NodeRef, java.util.Map, java.util.Map)
|
||||
*/
|
||||
public void onUpdateProperties(
|
||||
NodeRef nodeRef,
|
||||
Map<QName, Serializable> before,
|
||||
Map<QName, Serializable> after)
|
||||
{
|
||||
// Ignore working copies
|
||||
if (this.nodeService.exists(nodeRef) == true &&
|
||||
this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false)
|
||||
{
|
||||
// check if any of the content properties have changed
|
||||
for (QName propertyQName : after.keySet())
|
||||
{
|
||||
// is this a content property?
|
||||
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
|
||||
if (propertyDef == null)
|
||||
{
|
||||
// the property is not recognised
|
||||
continue;
|
||||
}
|
||||
if (!propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
|
||||
{
|
||||
// not a content type
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ContentData beforeValue = (ContentData) before.get(propertyQName);
|
||||
ContentData afterValue = (ContentData) after.get(propertyQName);
|
||||
|
||||
// Figure out if the content is new or not
|
||||
boolean newContent = false;
|
||||
String beforeContentUrl = null;
|
||||
if (beforeValue != null)
|
||||
{
|
||||
beforeContentUrl = beforeValue.getContentUrl();
|
||||
}
|
||||
String afterContentUrl = null;
|
||||
if (afterValue != null)
|
||||
{
|
||||
afterContentUrl = afterValue.getContentUrl();
|
||||
}
|
||||
if (beforeContentUrl == null && afterContentUrl != null)
|
||||
{
|
||||
newContent = true;
|
||||
}
|
||||
|
||||
if (afterValue != null && afterValue.getContentUrl() == null)
|
||||
{
|
||||
// no URL - ignore
|
||||
}
|
||||
else if (newContent == false && EqualsHelper.nullSafeEquals(beforeValue, afterValue) == false)
|
||||
{
|
||||
// Queue the update
|
||||
queueUpdate(nodeRef, propertyQName);
|
||||
}
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
// properties don't conform to model
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue the update to happen asynchronously
|
||||
*
|
||||
* @param nodeRef node reference
|
||||
* @param contentProperty content property
|
||||
*/
|
||||
private void queueUpdate(NodeRef nodeRef, QName contentProperty)
|
||||
{
|
||||
Boolean automaticUpdate = (Boolean)this.nodeService.getProperty(nodeRef, ContentModel.PROP_AUTOMATIC_UPDATE);
|
||||
if (automaticUpdate != null && automaticUpdate.booleanValue() == true)
|
||||
{
|
||||
CompositeAction compositeAction = actionService.createCompositeAction();
|
||||
List<NodeRef> thumbnails = this.thumbnailService.getThumbnails(nodeRef, contentProperty, null, null);
|
||||
|
||||
for (NodeRef thumbnail : thumbnails)
|
||||
{
|
||||
// Execute the update thumbnail action async for each thumbnail
|
||||
Action action = actionService.createAction(UpdateThumbnailActionExecuter.NAME);
|
||||
action.setParameterValue(UpdateThumbnailActionExecuter.PARAM_CONTENT_PROPERTY, contentProperty);
|
||||
action.setParameterValue(UpdateThumbnailActionExecuter.PARAM_THUMBNAIL_NODE, thumbnail);
|
||||
compositeAction.addAction(action);
|
||||
}
|
||||
|
||||
actionService.executeAction(compositeAction, nodeRef, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns {@link ThumbnailedAspectCopyBehaviourCallback}
|
||||
*/
|
||||
public CopyBehaviourCallback getCopyCallback(QName classRef, CopyDetails copyDetails)
|
||||
{
|
||||
return ThumbnailedAspectCopyBehaviourCallback.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Behaviour for the {@link ContentModel#ASPECT_THUMBNAILED <b>cm:thumbnailed</b>} aspect.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.2
|
||||
*/
|
||||
private static class ThumbnailedAspectCopyBehaviourCallback extends DefaultCopyBehaviourCallback
|
||||
{
|
||||
private static final CopyBehaviourCallback INSTANCE = new ThumbnailedAspectCopyBehaviourCallback();
|
||||
|
||||
/**
|
||||
* @return Returns <tt>true</tt> always
|
||||
*/
|
||||
@Override
|
||||
public boolean getMustCopy(QName classQName, CopyDetails copyDetails)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy thumbnail-related associations, {@link ContentModel#ASSOC_THUMBNAILS} regardless of
|
||||
* cascade options.
|
||||
*/
|
||||
@Override
|
||||
public ChildAssocCopyAction getChildAssociationCopyAction(
|
||||
QName classQName,
|
||||
CopyDetails copyDetails,
|
||||
CopyChildAssociationDetails childAssocCopyDetails)
|
||||
{
|
||||
ChildAssociationRef childAssocRef = childAssocCopyDetails.getChildAssocRef();
|
||||
if (childAssocRef.getTypeQName().equals(ContentModel.ASSOC_THUMBNAILS))
|
||||
{
|
||||
return ChildAssocCopyAction.COPY_CHILD;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException(
|
||||
"Behaviour should have been invoked: \n" +
|
||||
" Aspect: " + this.getClass().getName() + "\n" +
|
||||
" " + childAssocCopyDetails + "\n" +
|
||||
" " + copyDetails);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy only the {@link ContentModel#PROP_AUTOMATIC_UPDATE}
|
||||
*/
|
||||
@Override
|
||||
public Map<QName, Serializable> getCopyProperties(
|
||||
QName classQName,
|
||||
CopyDetails copyDetails,
|
||||
Map<QName, Serializable> properties)
|
||||
{
|
||||
Map<QName, Serializable> newProperties = new HashMap<QName, Serializable>(5);
|
||||
Serializable value = properties.get(ContentModel.PROP_AUTOMATIC_UPDATE);
|
||||
newProperties.put(ContentModel.PROP_AUTOMATIC_UPDATE, value);
|
||||
return newProperties;
|
||||
}
|
||||
}
|
||||
}
|
@@ -27,20 +27,31 @@ import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
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.thumbnail.ThumbnailService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Update thumbnail action executer.
|
||||
*
|
||||
* NOTE: This action is used to facilitate the async update of thumbnails. It is not intended for genereral usage.
|
||||
* NOTE: This action is used to facilitate the async update of thumbnails. It is not intended for general usage.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class UpdateThumbnailActionExecuter extends ActionExecuterAbstractBase
|
||||
{
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(UpdateThumbnailActionExecuter.class);
|
||||
|
||||
/** Rendition Service */
|
||||
private RenditionService renditionService;
|
||||
|
||||
/** Thumbnail Service */
|
||||
private ThumbnailService thumbnailService;
|
||||
|
||||
@@ -52,6 +63,16 @@ public class UpdateThumbnailActionExecuter extends ActionExecuterAbstractBase
|
||||
public static final String PARAM_CONTENT_PROPERTY = "content-property";
|
||||
public static final String PARAM_THUMBNAIL_NODE = "thumbnail-node";
|
||||
|
||||
/**
|
||||
* Injects the rendition service.
|
||||
*
|
||||
* @param renditionService the rendition service.
|
||||
*/
|
||||
public void setRenditionService(RenditionService renditionService)
|
||||
{
|
||||
this.renditionService = renditionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnail service
|
||||
*
|
||||
@@ -86,17 +107,17 @@ public class UpdateThumbnailActionExecuter extends ActionExecuterAbstractBase
|
||||
}
|
||||
|
||||
if (this.nodeService.exists(thumbnailNodeRef) == true &&
|
||||
ContentModel.TYPE_THUMBNAIL.equals(this.nodeService.getType(thumbnailNodeRef)) == true)
|
||||
renditionService.isRendition(thumbnailNodeRef))
|
||||
{
|
||||
// Get the thumbnail Name
|
||||
String thumbnailName = (String)this.nodeService.getProperty(thumbnailNodeRef, ContentModel.PROP_THUMBNAIL_NAME);
|
||||
ChildAssociationRef parent = renditionService.getSourceNode(thumbnailNodeRef);
|
||||
String thumbnailName = parent.getQName().getLocalName();
|
||||
|
||||
// Get the details of the thumbnail
|
||||
ThumbnailRegistry registry = this.thumbnailService.getThumbnailRegistry();
|
||||
ThumbnailDefinition details = registry.getThumbnailDefinition(thumbnailName);
|
||||
if (details == null)
|
||||
{
|
||||
// Throw exception
|
||||
throw new AlfrescoRuntimeException("The thumbnail name '" + thumbnailName + "' is not registered");
|
||||
}
|
||||
|
||||
@@ -121,5 +142,4 @@ public class UpdateThumbnailActionExecuter extends ActionExecuterAbstractBase
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_CONTENT_PROPERTY, DataTypeDefinition.QNAME, false, getParamDisplayLabel(PARAM_CONTENT_PROPERTY)));
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_THUMBNAIL_NODE, DataTypeDefinition.QNAME, false, getParamDisplayLabel(PARAM_THUMBNAIL_NODE)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,20 +18,31 @@
|
||||
*/
|
||||
package org.alfresco.repo.thumbnail.script;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.RenditionModel;
|
||||
import org.alfresco.repo.jscript.ScriptNode;
|
||||
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
/**
|
||||
* @author Roy Wetherall
|
||||
* @author Neil McErlean
|
||||
*/
|
||||
public class ScriptThumbnail extends ScriptNode
|
||||
{
|
||||
private static final long serialVersionUID = 7854749986083635678L;
|
||||
|
||||
/** Logger */
|
||||
private static Log logger = LogFactory.getLog(ScriptThumbnail.class);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -49,7 +60,25 @@ public class ScriptThumbnail extends ScriptNode
|
||||
*/
|
||||
public void update()
|
||||
{
|
||||
String name = (String)services.getNodeService().getProperty(nodeRef, ContentModel.PROP_THUMBNAIL_NAME);
|
||||
List<ChildAssociationRef> parentRefs = services.getNodeService().getParentAssocs(nodeRef, RenditionModel.ASSOC_RENDITION, RegexQNamePattern.MATCH_ALL);
|
||||
// There should in fact only ever be one parent association of type rendition on any rendition node.
|
||||
if (parentRefs.size() != 1)
|
||||
{
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Node ")
|
||||
.append(nodeRef)
|
||||
.append(" has ")
|
||||
.append(parentRefs.size())
|
||||
.append(" rendition parents. Unable to update.");
|
||||
if (logger.isWarnEnabled())
|
||||
{
|
||||
logger.warn(msg.toString());
|
||||
}
|
||||
throw new AlfrescoRuntimeException(msg.toString());
|
||||
}
|
||||
|
||||
String name = parentRefs.get(0).getQName().getLocalName();
|
||||
|
||||
ThumbnailDefinition def = services.getThumbnailService().getThumbnailRegistry().getThumbnailDefinition(name);
|
||||
services.getThumbnailService().updateThumbnail(this.nodeRef, def.getTransformationOptions());
|
||||
}
|
||||
|
Reference in New Issue
Block a user