diff --git a/config/alfresco/rendition-services-context.xml b/config/alfresco/rendition-services-context.xml index abf388ddc9..9b47f1c036 100644 --- a/config/alfresco/rendition-services-context.xml +++ b/config/alfresco/rendition-services-context.xml @@ -1,143 +1,143 @@ - - - - - - - - - - org.alfresco.service.cmr.rendition.RenditionService - - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - alfresco.messages.rendition-config - - - - - - - - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}content - - - - + + + + + + + + + + org.alfresco.service.cmr.rendition.RenditionService + + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + alfresco.messages.rendition-config + + + + + + + + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -153,13 +153,23 @@ - - - - - - - - - - + + + + + + + + + + + + + + renditionService + + + + + diff --git a/source/java/org/alfresco/repo/rendition/MockedTestServiceRegistry.java b/source/java/org/alfresco/repo/rendition/MockedTestServiceRegistry.java index e891e42803..24095f1a2d 100644 --- a/source/java/org/alfresco/repo/rendition/MockedTestServiceRegistry.java +++ b/source/java/org/alfresco/repo/rendition/MockedTestServiceRegistry.java @@ -46,6 +46,7 @@ import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; import org.alfresco.service.cmr.ml.EditionService; import org.alfresco.service.cmr.ml.MultilingualContentService; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; @@ -309,6 +310,13 @@ public class MockedTestServiceRegistry implements ServiceRegistry } + public RenditionService getRenditionService() + { + // TODO Auto-generated method stub + return null; + } + + public FileFolderService getFileFolderService() { // TODO Auto-generated method stub diff --git a/source/java/org/alfresco/repo/rendition/RenditionServiceIntegrationTest.java b/source/java/org/alfresco/repo/rendition/RenditionServiceIntegrationTest.java index 8ac1c445f1..c4b68d8bae 100644 --- a/source/java/org/alfresco/repo/rendition/RenditionServiceIntegrationTest.java +++ b/source/java/org/alfresco/repo/rendition/RenditionServiceIntegrationTest.java @@ -38,6 +38,7 @@ import org.alfresco.repo.action.executer.ExporterActionExecuter; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.content.transform.magick.ImageTransformationOptions; +import org.alfresco.repo.jscript.ClasspathScriptLocation; import org.alfresco.repo.model.Repository; import org.alfresco.repo.rendition.executer.AbstractRenderingEngine; import org.alfresco.repo.rendition.executer.FreemarkerRenderingEngine; @@ -57,6 +58,8 @@ import org.alfresco.service.cmr.repository.ContentData; 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.repository.StoreRef; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; @@ -86,18 +89,20 @@ public class RenditionServiceIntegrationTest extends BaseAlfrescoSpringTest private NodeRef renditionNode = null; + private NamespaceService namespaceService; private RenditionService renditionService; private Repository repositoryHelper; + private ScriptService scriptService; private RetryingTransactionHelper transactionHelper; - private NamespaceService namespaceService; @Override protected void onSetUpInTransaction() throws Exception { super.onSetUpInTransaction(); + this.namespaceService= (NamespaceService) this.applicationContext.getBean("namespaceService"); this.renditionService = (RenditionService) this.applicationContext.getBean("renditionService"); this.repositoryHelper = (Repository) this.applicationContext.getBean("repositoryHelper"); - this.namespaceService= (NamespaceService) this.applicationContext.getBean("namespaceService"); + this.scriptService = (ScriptService) this.applicationContext.getBean("scriptService"); this.transactionHelper = (RetryingTransactionHelper) this.applicationContext .getBean("retryingTransactionHelper"); @@ -1783,4 +1788,14 @@ public class RenditionServiceIntegrationTest extends BaseAlfrescoSpringTest compositeDefinition.addAction(rescaleImageDefinition); return compositeDefinition; } + + public void testJavascriptAPI() throws Exception + { + Map model = new HashMap(); + model.put("testSourceNode", this.nodeWithImageContent); + + ScriptLocation location = new ClasspathScriptLocation("org/alfresco/repo/rendition/script/test_renditionService.js"); + this.scriptService.executeScript(location, model); + } + } diff --git a/source/java/org/alfresco/repo/rendition/script/ScriptRenditionDefinition.java b/source/java/org/alfresco/repo/rendition/script/ScriptRenditionDefinition.java new file mode 100644 index 0000000000..9728c2e5b2 --- /dev/null +++ b/source/java/org/alfresco/repo/rendition/script/ScriptRenditionDefinition.java @@ -0,0 +1,65 @@ +/* + * 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 . + */ +package org.alfresco.repo.rendition.script; + +import java.io.Serializable; + +import org.alfresco.service.cmr.rendition.RenditionDefinition; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * RenditionDefinition JavaScript Object. This class is a JavaScript-friendly wrapper for + * the {@link RenditionDefinition renditionDefinition} class. + * + * @author Neil McErlean + */ +public final class ScriptRenditionDefinition implements Serializable +{ + private static final long serialVersionUID = 8132935577891455490L; + private final RenditionDefinition renditionDefinition; + private final NamespaceService namespaceService; + + public ScriptRenditionDefinition(NamespaceService namespaceService, RenditionDefinition renditionDefinition) + { + this.namespaceService = namespaceService; + this.renditionDefinition = renditionDefinition; + } + + /** + * Returns the name of this rendition definition in prefix:localName format. + * + * @return the name which uniquely identifies this rendition definition. + */ + public String getRenditionName() + { + QName qname = this.renditionDefinition.getRenditionName(); + return qname.toPrefixString(namespaceService); + } + + @Override + public String toString() + { + StringBuilder msg = new StringBuilder(); + msg.append(this.getClass().getSimpleName()) + .append("[").append(getRenditionName()).append("]"); + + return msg.toString(); + } +} diff --git a/source/java/org/alfresco/repo/rendition/script/ScriptRenditionService.java b/source/java/org/alfresco/repo/rendition/script/ScriptRenditionService.java new file mode 100644 index 0000000000..14218b6bde --- /dev/null +++ b/source/java/org/alfresco/repo/rendition/script/ScriptRenditionService.java @@ -0,0 +1,172 @@ +/* + * 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 . + */ +package org.alfresco.repo.rendition.script; + +import java.util.ArrayList; +import java.util.List; + +import org.alfresco.repo.jscript.BaseScopableProcessorExtension; +import org.alfresco.repo.jscript.ChildAssociation; +import org.alfresco.repo.jscript.ScriptNode; +import org.alfresco.repo.jscript.ValueConverter; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.rendition.RenditionDefinition; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Script object representing the rendition service. + * + * @author Neil McErlean + */ +public class ScriptRenditionService extends BaseScopableProcessorExtension +{ + private static Log logger = LogFactory.getLog(ScriptRenditionService.class); + + /** The Services registry */ + private ServiceRegistry serviceRegistry; + + private final ValueConverter valueConverter = new ValueConverter(); + + /** + * Set the service registry + * + * @param serviceRegistry the service registry. + */ + public void setServiceRegistry(ServiceRegistry serviceRegistry) + { + this.serviceRegistry = serviceRegistry; + } + + private RenditionDefinition loadRenditionDefinitionImpl(String shortFormQName) + { + QName renditionName = QName.createQName(shortFormQName, serviceRegistry.getNamespaceService()); + RenditionDefinition rendDef = serviceRegistry.getRenditionService().loadRenditionDefinition(renditionName); + return rendDef; + } + + /** + * This method renders the specified source node using the specified saved + * rendition definition. + * @param sourceNode the source node to be rendered. + * @param renditionDefshortQName the rendition definition to be used e.g. cm:doclib + * @return the parent association of the rendition node. + * @see org.alfresco.service.cmr.rendition.RenditionService#render(org.alfresco.service.cmr.repository.NodeRef, RenditionDefinition) + */ + public ChildAssociation render(ScriptNode sourceNode, String renditionDefshortQName) + { + if (logger.isDebugEnabled()) + { + StringBuilder msg = new StringBuilder(); + msg.append("Rendering source node '") + .append(sourceNode) + .append("' with renditionDef '").append(renditionDefshortQName) + .append("'"); + logger.debug(msg.toString()); + } + + RenditionDefinition rendDef = loadRenditionDefinitionImpl(renditionDefshortQName); + ChildAssociationRef result = this.serviceRegistry.getRenditionService().render(sourceNode.getNodeRef(), rendDef); + + if (logger.isDebugEnabled()) + { + StringBuilder msg = new StringBuilder(); + msg.append("Rendition: ").append(result); + logger.debug(msg.toString()); + } + + return (ChildAssociation)valueConverter.convertValueForScript(serviceRegistry, this.getScope(), null, result); + } + + /** + * This method gets all the renditions of the specified node. + * + * @param node the source node + * @return a list of parent associations for the renditions. + * @see org.alfresco.service.cmr.rendition.RenditionService#getRenditions(org.alfresco.service.cmr.repository.NodeRef) + */ + public ChildAssociation[] getRenditions(ScriptNode node) + { + List renditions = this.serviceRegistry.getRenditionService().getRenditions(node.getNodeRef()); + + ChildAssociation[] result = convertChildAssRefs(renditions); + + return result; + } + + /** + * This method gets all the renditions of the specified node filtered by + * MIME-type prefix. Renditions whose MIME-type string startsWith the prefix + * will be returned. + * + * @param node the source node for the renditions + * @param mimeTypePrefix a prefix to check against the rendition MIME-types. + * This must not be null and must not be an empty String + * @return a list of parent associations for the filtered renditions. + * @see org.alfresco.service.cmr.rendition.RenditionService#getRenditions(org.alfresco.service.cmr.repository.NodeRef) + */ + public ChildAssociation[] getRenditions(ScriptNode node, String mimeTypePrefix) + { + List renditions = this.serviceRegistry.getRenditionService().getRenditions(node.getNodeRef(), mimeTypePrefix); + + ChildAssociation[] result = convertChildAssRefs(renditions); + + return result; + } + + /** + * This method converts a list of (Java-ish) ChildAssociationRefs to an array + * of (JavaScript-ish) ChildAssociations. + * @param renditions + * @return + */ + private ChildAssociation[] convertChildAssRefs( + List renditions) + { + List childAssocs = new ArrayList(renditions.size()); + + for (ChildAssociationRef chAssRef : renditions) + { + ChildAssociation chAss = (ChildAssociation)valueConverter.convertValueForScript(serviceRegistry, getScope(), null, chAssRef); + childAssocs.add(chAss); + } + + ChildAssociation[] result = childAssocs.toArray(new ChildAssociation[0]); + return result; + } + + /** + * This method gets the rendition of the specified node identified by + * the provided rendition name. + * + * @param node the source node for the renditions + * @param renditionName the renditionName used to identify a rendition. e.g. cm:doclib + * @return the parent association for the rendition or null if there is no such rendition. + * @see org.alfresco.service.cmr.rendition.RenditionService#getRenditionByName(org.alfresco.service.cmr.repository.NodeRef, QName) + */ + public ChildAssociation getRenditionByName(ScriptNode node, String renditionName) + { + QName qname = QName.createQName(renditionName, serviceRegistry.getNamespaceService()); + ChildAssociationRef result = this.serviceRegistry.getRenditionService().getRenditionByName(node.getNodeRef(), qname); + + return (ChildAssociation) valueConverter.convertValueForScript(serviceRegistry, getScope(), null, result); + } +} diff --git a/source/java/org/alfresco/repo/rendition/script/test_renditionService.js b/source/java/org/alfresco/repo/rendition/script/test_renditionService.js new file mode 100644 index 0000000000..dd05a8106b --- /dev/null +++ b/source/java/org/alfresco/repo/rendition/script/test_renditionService.js @@ -0,0 +1,52 @@ +function testRenderNodeUsingRenditionDefinitionNames() +{ + // Produce two different renditions of the same source node + var renditionDefName1 = "cm:doclib"; + var renditionDefName2 = "cm:imgpreview"; + var childAssoc1 = renditionService.render(testSourceNode, renditionDefName1); + var childAssoc2 = renditionService.render(testSourceNode, renditionDefName2); + + // Assert that the returned ChildAssociation objects have the correct name and type. + test.assertNotNull(childAssoc1, "Rendition ChildAssoc1 was null."); + test.assertEquals(testSourceNode.id, childAssoc1.parent.id, "Rendition 1's parent was not source node"); + test.assertEquals("{http://www.alfresco.org/model/rendition/1.0}rendition", childAssoc1.type); + test.assertEquals("{http://www.alfresco.org/model/content/1.0}doclib", childAssoc1.name); + + test.assertNotNull(childAssoc2, "Rendition ChildAssoc2 was null."); + test.assertEquals(testSourceNode.id, childAssoc2.parent.id, "Rendition 2's parent was not source node"); + test.assertEquals("{http://www.alfresco.org/model/rendition/1.0}rendition", childAssoc2.type); + test.assertEquals("{http://www.alfresco.org/model/content/1.0}imgpreview", childAssoc2.name); +} + +function testGetRenditions() +{ + // Get all renditions + var allRenditionAssocs = renditionService.getRenditions(testSourceNode); + test.assertNotNull(allRenditionAssocs, "allRenditions returned null."); + test.assertEquals(2, allRenditionAssocs.length); + + // We've already checked the types and names, so there's no point rechecking. + + + // Get named renditions + var doclibRendition = renditionService.getRenditionByName(testSourceNode, "cm:doclib"); + test.assertNotNull(doclibRendition, "doclibRendition returned null."); + test.assertEquals("{http://www.alfresco.org/model/content/1.0}doclib", doclibRendition.name); + + var noSuchRendition = renditionService.getRenditionByName(testSourceNode, "cm:nonsense"); + test.assertNull(noSuchRendition, "noSuchRendition should have been null."); + + + // Get renditions by mimetype + var imageRenditions = renditionService.getRenditions(testSourceNode, "image"); + test.assertNotNull(imageRenditions, "imageRenditions returned null."); + test.assertEquals(2, imageRenditions.length); + + var swfRenditions = renditionService.getRenditions(testSourceNode, "application/x-shockwave-flash"); + test.assertNotNull(swfRenditions, "swfRenditions returned null."); + test.assertEquals(0, swfRenditions.length); +} + +// Execute tests +testRenderNodeUsingRenditionDefinitionNames(); +testGetRenditions(); diff --git a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java index 064badc269..b4a4ecc91c 100644 --- a/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java +++ b/source/java/org/alfresco/repo/service/ServiceDescriptorRegistry.java @@ -44,6 +44,7 @@ import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; import org.alfresco.service.cmr.ml.EditionService; import org.alfresco.service.cmr.ml.MultilingualContentService; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; @@ -512,6 +513,15 @@ public class ServiceDescriptorRegistry return (FormService)getService(FORM_SERVICE); } + /* (non-Javadoc) + * @see org.alfresco.service.ServiceRegistry#getRenditionService() + */ + public RenditionService getRenditionService() + { + return (RenditionService)getService(RENDITION_SERVICE); + } + + /* (non-Javadoc) * @see org.alfresco.service.ServiceRegistry#getInvitationService() */ diff --git a/source/java/org/alfresco/service/ServiceRegistry.java b/source/java/org/alfresco/service/ServiceRegistry.java index e652a4432d..e2b9f149f1 100644 --- a/source/java/org/alfresco/service/ServiceRegistry.java +++ b/source/java/org/alfresco/service/ServiceRegistry.java @@ -43,6 +43,7 @@ import org.alfresco.service.cmr.ml.ContentFilterLanguagesService; import org.alfresco.service.cmr.ml.EditionService; import org.alfresco.service.cmr.ml.MultilingualContentService; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; @@ -130,6 +131,7 @@ public interface ServiceRegistry static final QName FORM_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "FormService"); static final QName INVITATION_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "InvitationService"); static final QName PREFERENCE_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "PreferenceService"); + static final QName RENDITION_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "RenditionService"); // WCM / AVM static final QName AVM_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "AVMService"); @@ -487,6 +489,13 @@ public interface ServiceRegistry */ @NotAuditable FormService getFormService(); + + /** + * Get the rendition service (or null if one is not provided) + * @return + */ + @NotAuditable + RenditionService getRenditionService(); /** * Get the invitation service (or null if one is not provided)