diff --git a/config/alfresco/model/contentModel.xml b/config/alfresco/model/contentModel.xml index d191032971..001b8e78c0 100644 --- a/config/alfresco/model/contentModel.xml +++ b/config/alfresco/model/contentModel.xml @@ -316,16 +316,16 @@ cm:content true + + Thumbnail Name + d:text + false + Thumbnailed Content Property Name d:qname true - - - Transformation Options Class - d:text - false - + @@ -839,6 +839,14 @@ Thumbnailed + + + Automatic Update + d:boolean + true + true + + @@ -854,60 +862,6 @@ - - - Image Transformation Options - - - Command Options - d:text - false - -1 - - - Resize The Image - d:boolean - false - - - Resize Width - d:int - false - -1 - - - Resize Height - d:int - false - - - Resize Maintain Aspect Ratio - d:boolean - true - - - Resize Percent - d:boolean - false - - - Resize To Thumbnail - d:boolean - false - - - - - - - - - Flash Version - d:text - - - - diff --git a/config/alfresco/thumbnail-service-context.xml b/config/alfresco/thumbnail-service-context.xml index e3e38ee4aa..36d1182739 100644 --- a/config/alfresco/thumbnail-service-context.xml +++ b/config/alfresco/thumbnail-service-context.xml @@ -96,6 +96,28 @@ + + + + false + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/model/ContentModel.java b/source/java/org/alfresco/model/ContentModel.java index 2b4288db4c..4ffc828d56 100644 --- a/source/java/org/alfresco/model/ContentModel.java +++ b/source/java/org/alfresco/model/ContentModel.java @@ -240,8 +240,9 @@ public interface ContentModel // Thumbnail Type static final QName TYPE_THUMBNAIL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "thumbnail"); + static final QName PROP_THUMBNAIL_NAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "thumbnailName"); static final QName PROP_CONTENT_PROPERTY_NAME = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "contentPropertyName"); - static final QName PROP_TRANSFORMATION_OPTIONS_CLASS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "cm:transformationOptionsClass"); + static final QName PROP_AUTOMATIC_UPDATE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "automaticUpdate"); // Thumbnailed Aspect static final QName ASPECT_THUMBNAILED = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "thumbnailed"); diff --git a/source/java/org/alfresco/repo/content/transform/magick/ImageTransformationOptions.java b/source/java/org/alfresco/repo/content/transform/magick/ImageTransformationOptions.java index f7fd9db599..abcd3756cd 100644 --- a/source/java/org/alfresco/repo/content/transform/magick/ImageTransformationOptions.java +++ b/source/java/org/alfresco/repo/content/transform/magick/ImageTransformationOptions.java @@ -24,15 +24,7 @@ */ package org.alfresco.repo.content.transform.magick; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.TransformationOptions; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; /** * Image transformation options @@ -41,16 +33,6 @@ import org.alfresco.service.namespace.QName; */ public class ImageTransformationOptions extends TransformationOptions { - /** imageTransformOptions aspect details */ - public static final QName ASPECT_IMAGE_TRANSFORATION_OPTIONS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "imageTransformationOptions"); - public static final QName PROP_COMMAND_OPTIONS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "commandOptions"); - public static final QName PROP_RESIZE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resize"); - public static final QName PROP_RESIZE_WIDTH = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resizeWidth"); - public static final QName PROP_RESIZE_HEIGHT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resizeHeight"); - public static final QName PROP_RESIZE_MAINTAIN_ASPECT_RATIO = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resizeMaintainAspectRatio"); - public static final QName PROP_RESIZE_PERCENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resizePercent"); - public static final QName PROP_RESIZE_TO_THUMBNAIL = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "resizeToThumbnail"); - /** Command string options, provided for backward compatibility */ private String commandOptions = ""; @@ -96,74 +78,4 @@ public class ImageTransformationOptions extends TransformationOptions { return resizeOptions; } - - /** - * Save the transformation options to the ImageTransformationOptions aspect. - * - * @see org.alfresco.service.cmr.repository.TransformationOptions#saveToNode(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeService) - */ - @Override - public void saveToNode(NodeRef nodeRef, NodeService nodeService) - { - super.saveToNode(nodeRef, nodeService); - - // Create a list of the properties - Map properties = new HashMap(7); - properties.put(PROP_COMMAND_OPTIONS, this.commandOptions); - if (this.resizeOptions != null) - { - properties.put(PROP_RESIZE, true); - properties.put(PROP_RESIZE_HEIGHT, this.resizeOptions.getHeight()); - properties.put(PROP_RESIZE_WIDTH, this.resizeOptions.getWidth()); - properties.put(PROP_RESIZE_MAINTAIN_ASPECT_RATIO, this.resizeOptions.isMaintainAspectRatio()); - properties.put(PROP_RESIZE_PERCENT, this.resizeOptions.isPercentResize()); - properties.put(PROP_RESIZE_TO_THUMBNAIL, this.resizeOptions.isResizeToThumbnail()); - } - else - { - properties.put(PROP_RESIZE, false); - } - - // Add the aspect - nodeService.addAspect(nodeRef, ASPECT_IMAGE_TRANSFORATION_OPTIONS, properties); - } - - /** - * Populate the image transformation options from the node provided. - * - * @see org.alfresco.service.cmr.repository.TransformationOptions#populateFromNode(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeService) - */ - @Override - public void populateFromNode(NodeRef nodeRef, NodeService nodeService) - { - super.populateFromNode(nodeRef, nodeService); - - // Check whether the node has the image transformation options aspect - if (nodeService.hasAspect(nodeRef, ASPECT_IMAGE_TRANSFORATION_OPTIONS) == true) - { - // Get the node's properties - Map properties = nodeService.getProperties(nodeRef); - - // Set the properties - this.commandOptions = (String)properties.get(PROP_COMMAND_OPTIONS); - - // Set the resize properties - Boolean isResize = (Boolean)properties.get(PROP_RESIZE); - if (isResize.booleanValue() == true) - { - int height = ((Long)properties.get(PROP_RESIZE_HEIGHT)).intValue(); - int width = ((Long)properties.get(PROP_RESIZE_WIDTH)).intValue(); - boolean maintainAspectRatio = ((Boolean)properties.get(PROP_RESIZE_MAINTAIN_ASPECT_RATIO)).booleanValue(); - boolean percentResize = ((Boolean)properties.get(PROP_RESIZE_PERCENT)).booleanValue(); - boolean resizeToThumbnail = ((Boolean)properties.get(PROP_RESIZE_TO_THUMBNAIL)).booleanValue(); - - this.resizeOptions = new ImageResizeOptions(); - this.resizeOptions.setHeight(height); - this.resizeOptions.setWidth(width); - this.resizeOptions.setMaintainAspectRatio(maintainAspectRatio); - this.resizeOptions.setPercentResize(percentResize); - this.resizeOptions.setResizeToThumbnail(resizeToThumbnail); - } - } - } } diff --git a/source/java/org/alfresco/repo/content/transform/swf/SWFTransformationOptions.java b/source/java/org/alfresco/repo/content/transform/swf/SWFTransformationOptions.java index 3ffefbbcf0..26316cf002 100644 --- a/source/java/org/alfresco/repo/content/transform/swf/SWFTransformationOptions.java +++ b/source/java/org/alfresco/repo/content/transform/swf/SWFTransformationOptions.java @@ -24,15 +24,7 @@ */ package org.alfresco.repo.content.transform.swf; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.TransformationOptions; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; /** * SFW transformation options @@ -41,9 +33,6 @@ import org.alfresco.service.namespace.QName; */ public class SWFTransformationOptions extends TransformationOptions { - private final static QName ASPECT_SWF_TRANSFORMATION_OPTIONS = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "swfTransformationOptions"); - private final static QName PROP_FLASH_VERSION = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "flashVerison"); - /** The version of the flash to convert to */ private String flashVersion = "9"; @@ -56,30 +45,4 @@ public class SWFTransformationOptions extends TransformationOptions { return flashVersion; } - - @Override - public void saveToNode(NodeRef nodeRef, NodeService nodeService) - { - super.saveToNode(nodeRef, nodeService); - - Map properties = new HashMap(7); - properties.put(PROP_FLASH_VERSION, this.flashVersion); - nodeService.addAspect(nodeRef, ASPECT_SWF_TRANSFORMATION_OPTIONS, properties); - } - - @Override - public void populateFromNode(NodeRef nodeRef, NodeService nodeService) - { - super.populateFromNode(nodeRef, nodeService); - - // Check whether the node has the image transformation options aspect - if (nodeService.hasAspect(nodeRef, ASPECT_SWF_TRANSFORMATION_OPTIONS) == true) - { - // Get the node's properties - Map properties = nodeService.getProperties(nodeRef); - - // Set the properties - this.flashVersion = (String)properties.get(PROP_FLASH_VERSION); - } - } } diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java index a7f0a7fedb..39ba6b0314 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptNode.java +++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java @@ -2002,12 +2002,25 @@ public class ScriptNode implements Serializable, Scopeable } /** + * Get the all the thumbnails for a given node's content property. * - * @return + * @return ScriptThumbnail list of thumbnails, empty if none available */ - public ScriptableHashMap getThumbnails() + public ScriptThumbnail[] getThumbnails() { - return null; + List thumbnails = this.services.getThumbnailService().getThumbnails( + this.nodeRef, + ContentModel.PROP_CONTENT, + null, + null); + + List result = new ArrayList(thumbnails.size()); + for (NodeRef thumbnail : thumbnails) + { + ScriptThumbnail scriptThumbnail = new ScriptThumbnail(thumbnail, this.services, this.scope); + result.add(scriptThumbnail); + } + return (ScriptThumbnail[])result.toArray(new ScriptThumbnail[result.size()]); } diff --git a/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImpl.java b/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImpl.java index f02188f00c..9905d98957 100644 --- a/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImpl.java +++ b/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImpl.java @@ -165,15 +165,10 @@ public class ThumbnailServiceImpl implements ThumbnailService String thumbnailFileName = generateThumbnailFileName(thumbnailName, mimetype); properties.put(ContentModel.PROP_NAME, thumbnailFileName); } + properties.put(ContentModel.PROP_THUMBNAIL_NAME, thumbnailName); // Add the name of the content property properties.put(ContentModel.PROP_CONTENT_PROPERTY_NAME, contentProperty); - - // Add the class name of the transformation options - if (transformationOptions != null) - { - properties.put(ContentModel.PROP_TRANSFORMATION_OPTIONS_CLASS, transformationOptions.getClass().getName()); - } // See if parent association details have been specified for the thumbnail if (assocDetails == null) @@ -220,9 +215,6 @@ public class ThumbnailServiceImpl implements ThumbnailService { // Do the thumnail transformation this.contentService.transform(reader, writer, transformationOptions); - - // Store the transformation options on the thumbnail - transformationOptions.saveToNode(thumbnail, this.nodeService); } // Return the created thumbnail @@ -248,31 +240,7 @@ public class ThumbnailServiceImpl implements ThumbnailService { // First check that we are dealing with a thumbnail if (ContentModel.TYPE_THUMBNAIL.equals(this.nodeService.getType(thumbnail)) == true) - { - // Get the transformation options -// TransformationOptions options = null; -// String transformationOptionsClassName = (String)this.nodeService.getProperty(thumbnail, ContentModel.PROP_TRANSFORMATION_OPTIONS_CLASS); -// if (transformationOptionsClassName == null) -// { -// options = new TransformationOptions(); -// } -// else -// { -// // Create an options object of the type specified on the thumbnail -// try -// { -// Class transformationClass = Class.forName(transformationOptionsClassName); -// options = (TransformationOptions)transformationClass.newInstance(); -// } -// catch (Exception exception) -// { -// throw new ThumbnailException(ERR_TRANS_CLASS); -// } -// -// // Populate the options from the node -// options.populateFromNode(thumbnail, this.nodeService); -// } - + { // Get the node that is the source of the thumbnail NodeRef node = null; List parents = this.nodeService.getParentAssocs(thumbnail, ContentModel.ASSOC_THUMBNAILS, RegexQNamePattern.MATCH_ALL); @@ -294,7 +262,7 @@ public class ThumbnailServiceImpl implements ThumbnailService // Get the reader and writer ContentReader reader = this.contentService.getReader(node, contentProperty); - ContentWriter writer = this.contentService.getWriter(node, ContentModel.PROP_CONTENT, true); + ContentWriter writer = this.contentService.getWriter(thumbnail, ContentModel.PROP_CONTENT, true); // Set the basic detail of the transformation options transformationOptions.setSourceNodeRef(node); diff --git a/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplTest.java b/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplTest.java index be905ea5fd..6158b987c3 100644 --- a/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplTest.java +++ b/source/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplTest.java @@ -37,6 +37,7 @@ import org.alfresco.repo.content.transform.AbstractContentTransformerTest; 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.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; @@ -109,7 +110,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest "small"); assertNotNull(thumbnail1); checkThumbnailed(jpgOrig, "small"); - checkThumbnail(thumbnail1, imageTransformationOptions); + checkThumbnail("small", thumbnail1); outputThumbnailTempContentLocation(thumbnail1, "jpg", "small - 64x64, marked as thumbnail"); // ===== small2: 64x64, aspect not maintained ==== @@ -126,7 +127,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest imageTransformationOptions2, "small2"); checkThumbnailed(jpgOrig, "small2"); - checkThumbnail(thumbnail2, imageTransformationOptions2); + checkThumbnail("small2", thumbnail2); outputThumbnailTempContentLocation(thumbnail2, "jpg", "small2 - 64x64, aspect not maintained"); // ===== half: 50%x50 ===== @@ -143,7 +144,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest imageTransformationOptions3, "half"); checkThumbnailed(jpgOrig, "half"); - checkThumbnail(thumbnail3, imageTransformationOptions3); + checkThumbnail("half", thumbnail3); outputThumbnailTempContentLocation(thumbnail3, "jpg", "half - 50%x50%"); @@ -161,7 +162,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest imageTransformationOptions4, "half2"); checkThumbnailed(gifOrig, "half2"); - checkThumbnail(thumbnail4, imageTransformationOptions4); + checkThumbnail("half2", thumbnail4); outputThumbnailTempContentLocation(thumbnail4, "jpg", "half2 - 50%x50%, from gif"); } } @@ -185,7 +186,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest "small"); assertNotNull(thumbnail1); checkThumbnailed(jpgOrig, "small"); - checkThumbnail(thumbnail1, imageTransformationOptions); + checkThumbnail("small", thumbnail1); try { @@ -252,7 +253,7 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest // Try and retrieve the thumbnail NodeRef result2 = this.thumbnailService.getThumbnailByName(jpgOrig, ContentModel.PROP_CONTENT, "small"); assertNotNull(result2); - checkThumbnail(result2, imageTransformationOptions); + checkThumbnail("small", result2); // Check for an other thumbnail that doesn't exist NodeRef result3 = this.thumbnailService.getThumbnailByName(jpgOrig, ContentModel.PROP_CONTENT, "anotherone"); @@ -270,48 +271,17 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest assertEquals(1, assocs.size()); } - private void checkThumbnail(NodeRef thumbnail, TransformationOptions transformationOptions) + private void checkThumbnail(String thumbnailName, NodeRef thumbnail) { // Check the thumbnail is of the correct type assertEquals(ContentModel.TYPE_THUMBNAIL, this.nodeService.getType(thumbnail)); - // Check the meta data on the thumnail - assertEquals(ContentModel.PROP_CONTENT, this.nodeService.getProperty(thumbnail, ContentModel.PROP_CONTENT_PROPERTY_NAME)); - assertEquals(transformationOptions.getClass().getName(), this.nodeService.getProperty(thumbnail, ContentModel.PROP_TRANSFORMATION_OPTIONS_CLASS)); + // 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)); - if (transformationOptions instanceof ImageTransformationOptions) - { - ImageTransformationOptions imageTransformationOptions = (ImageTransformationOptions)transformationOptions; - assertTrue(this.nodeService.hasAspect(thumbnail, ImageTransformationOptions.ASPECT_IMAGE_TRANSFORATION_OPTIONS)); - assertEquals( - imageTransformationOptions.getCommandOptions(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_COMMAND_OPTIONS)); - ImageResizeOptions resizeOptions = imageTransformationOptions.getResizeOptions(); - if (resizeOptions != null) - { - assertTrue((Boolean)this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE)); - assertEquals( - imageTransformationOptions.getResizeOptions().getHeight(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE_HEIGHT)); - assertEquals( - imageTransformationOptions.getResizeOptions().getWidth(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE_WIDTH)); - assertEquals( - imageTransformationOptions.getResizeOptions().isMaintainAspectRatio(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE_MAINTAIN_ASPECT_RATIO)); - assertEquals( - imageTransformationOptions.getResizeOptions().isPercentResize(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE_PERCENT)); - assertEquals( - imageTransformationOptions.getResizeOptions().isResizeToThumbnail(), - this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE_TO_THUMBNAIL)); - } - else - { - assertFalse((Boolean)this.nodeService.getProperty(thumbnail, ImageTransformationOptions.PROP_RESIZE)); - } - - } } private void outputThumbnailTempContentLocation(NodeRef thumbnail, String ext, String message) @@ -346,6 +316,37 @@ public class ThumbnailServiceImplTest extends BaseAlfrescoSpringTest return node; } + public void testAutoUpdate() throws Exception + { + if (contentService.getImageTransformer() != null) + { + final NodeRef jpgOrig = createOrigionalContent(this.folder, MimetypeMap.MIMETYPE_IMAGE_JPEG); + + ThumbnailDetails details = this.thumbnailService.getThumbnailRegistry().getThumbnailDetails("medium"); + final NodeRef thumbnail = this.thumbnailService.createThumbnail(jpgOrig, ContentModel.PROP_CONTENT, details.getMimetype(), details.getTransformationOptions(), details.getName()); + + setComplete(); + endTransaction(); + + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + 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); + writer.putContent(origFile); + + return null; + } + }); + + Thread.sleep(100000); + + } + } + // == Test the JavaScript API == public void testJSAPI() throws Exception diff --git a/source/java/org/alfresco/repo/thumbnail/ThumbnailedAspect.java b/source/java/org/alfresco/repo/thumbnail/ThumbnailedAspect.java new file mode 100644 index 0000000000..3244b5fd38 --- /dev/null +++ b/source/java/org/alfresco/repo/thumbnail/ThumbnailedAspect.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2005-2007 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 java.io.Serializable; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.content.ContentServicePolicies; +import org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy; +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.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +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 +{ + private PolicyComponent policyComponent; + private ThumbnailService thumbnailService; + private ActionService actionService; + private NodeService nodeService; + private DictionaryService dictionaryService; + + public void setPolicyComponent(PolicyComponent policyComponent) + { + this.policyComponent = policyComponent; + } + + public void setActionService(ActionService actionService) + { + this.actionService = actionService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setThumbnailService(ThumbnailService thumbnailService) + { + this.thumbnailService = thumbnailService; + } + + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + public void init() + { + this.policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), + ContentModel.ASPECT_THUMBNAILED, + new JavaBehaviour(this, "onUpdateProperties", Behaviour.NotificationFrequency.TRANSACTION_COMMIT)); + } + + public void onUpdateProperties( + NodeRef nodeRef, + Map before, + Map after) + { + // 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; + } + } + } + + private void queueUpdate(NodeRef nodeRef, QName contentProperty) + { + if (this.nodeService.exists(nodeRef) == true) + { + Boolean automaticUpdate = (Boolean)this.nodeService.getProperty(nodeRef, ContentModel.PROP_AUTOMATIC_UPDATE); + if (automaticUpdate != null && automaticUpdate.booleanValue() == true) + { + List 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(CreateThumbnailActionExecuter.PARAM_CONTENT_PROPERTY, contentProperty); + actionService.executeAction(action, thumbnail, false, true); + } + } + } + } +} diff --git a/source/java/org/alfresco/repo/thumbnail/UpdateThumbnailActionExecuter.java b/source/java/org/alfresco/repo/thumbnail/UpdateThumbnailActionExecuter.java new file mode 100644 index 0000000000..d09cce3b31 --- /dev/null +++ b/source/java/org/alfresco/repo/thumbnail/UpdateThumbnailActionExecuter.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2005-2007 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 java.util.List; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.action.ParameterDefinitionImpl; +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.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.thumbnail.ThumbnailService; +import org.alfresco.service.namespace.QName; + +/** + * Update thumbnail action executer. + * + * NOTE: This action is used to facilitate the async update of thumbnails. It is not intended for genereral usage. + * + * @author Roy Wetherall + */ +public class UpdateThumbnailActionExecuter extends ActionExecuterAbstractBase +{ + /** Thumbnail Service */ + private ThumbnailService thumbnailService; + + /** Node Service */ + private NodeService nodeService; + + /** Action name and parameters */ + public static final String NAME = "update-thumbnail"; + public static final String PARAM_CONTENT_PROPERTY = "content-property"; + + /** + * Set the thumbnail service + * + * @param thumbnailService the thumbnail service + */ + public void setThumbnailService(ThumbnailService thumbnailService) + { + this.thumbnailService = thumbnailService; + } + + /** + * Set the node service + * + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + protected void executeImpl(Action action, NodeRef actionedUponNodeRef) + { + if (this.nodeService.exists(actionedUponNodeRef) == true) + { + // Get the thumbnail Name + String thumbnailName = (String)this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_THUMBNAIL_NAME); + + // Get the details of the thumbnail + ThumbnailRegistry registry = this.thumbnailService.getThumbnailRegistry(); + ThumbnailDetails details = registry.getThumbnailDetails(thumbnailName); + if (details == null) + { + // Throw exception + throw new AlfrescoRuntimeException("The thumbnail name '" + thumbnailName + "' is not registered"); + } + + // Get the content property + QName contentProperty = (QName)action.getParameterValue(PARAM_CONTENT_PROPERTY); + if (contentProperty == null) + { + contentProperty = ContentModel.PROP_CONTENT; + } + + // Create the thumbnail + this.thumbnailService.updateThumbnail(actionedUponNodeRef, details.getTransformationOptions()); + } + } + + /** + * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List) + */ + @Override + protected void addParameterDefinitions(List paramList) + { + paramList.add(new ParameterDefinitionImpl(PARAM_CONTENT_PROPERTY, DataTypeDefinition.QNAME, false, getParamDisplayLabel(PARAM_CONTENT_PROPERTY))); + } + +} diff --git a/source/java/org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js b/source/java/org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js index f7f0e498b0..c938a8d274 100644 --- a/source/java/org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js +++ b/source/java/org/alfresco/repo/thumbnail/script/test_thumbnailAPI.js @@ -1,8 +1,16 @@ function testCreateThumbnail() { + var thumbs = jpgOrig.getThumbnails(); + test.assertNotNull(thumbs); + test.assertEquals(0, thumbs.length); + // Create a thumbnail var thumbnail = jpgOrig.createThumbnail("medium"); test.assertNotNull(thumbnail); + + thumbs = jpgOrig.getThumbnails(); + test.assertNotNull(thumbs); + test.assertEquals(1, thumbs.length); } function testThumbnailService() diff --git a/source/java/org/alfresco/service/cmr/repository/TransformationOptions.java b/source/java/org/alfresco/service/cmr/repository/TransformationOptions.java index 206929d912..29c18c0f94 100644 --- a/source/java/org/alfresco/service/cmr/repository/TransformationOptions.java +++ b/source/java/org/alfresco/service/cmr/repository/TransformationOptions.java @@ -207,28 +207,4 @@ public class TransformationOptions this.targetNodeRef = (NodeRef)optionsMap.get(OPT_TARGET_NODEREF); this.targetContentProperty = (QName)optionsMap.get(OPT_TARGET_CONTENT_PROPERTY); } - - /** - * Save the transformation options to the given node by applying the appropriate aspect - * and setting the meta data from the transformation options - * - * @param nodeRef the node reference - * @param nodeService the node service - */ - public void saveToNode(NodeRef nodeRef, NodeService nodeService) - { - // Do nothing for default transformation options - } - - /** - * Populate the transformation options from the meta data present on the appropraite - * aspect on the passed node. - * - * @param nodeRef the node reference - * @param nodeService the node service - */ - public void populateFromNode(NodeRef nodeRef, NodeService nodeService) - { - // Do nothing for the detauls transformation options - } }