diff --git a/config/alfresco/ownable-services-context.xml b/config/alfresco/ownable-services-context.xml index 43136fe7db..ba81a91c10 100644 --- a/config/alfresco/ownable-services-context.xml +++ b/config/alfresco/ownable-services-context.xml @@ -21,8 +21,8 @@ - - + + \ No newline at end of file diff --git a/source/java/org/alfresco/repo/ownable/impl/OwnableServiceImpl.java b/source/java/org/alfresco/repo/ownable/impl/OwnableServiceImpl.java index 2d54e6fb2d..b002351a9a 100644 --- a/source/java/org/alfresco/repo/ownable/impl/OwnableServiceImpl.java +++ b/source/java/org/alfresco/repo/ownable/impl/OwnableServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -21,11 +21,11 @@ package org.alfresco.repo.ownable.impl; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; -import org.alfresco.model.RenditionModel; import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.copy.CopyBehaviourCallback; import org.alfresco.repo.copy.CopyDetails; @@ -36,8 +36,8 @@ import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.tenant.TenantService; -import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -68,7 +68,7 @@ public class OwnableServiceImpl implements private PolicyComponent policyComponent; private TenantService tenantService; private Set storesToIgnorePolicies = Collections.emptySet(); - private DictionaryService dictionaryService; + private RenditionService renditionService; public OwnableServiceImpl() { @@ -113,11 +113,11 @@ public class OwnableServiceImpl implements /** - * @param dictionaryService the dictionaryService to set + * @param renditionService the renditionService to set */ - public void setDictionaryService(DictionaryService dictionaryService) + public void setRenditionService(RenditionService renditionService) { - this.dictionaryService = dictionaryService; + this.renditionService = renditionService; } public void afterPropertiesSet() throws Exception @@ -126,7 +126,7 @@ public class OwnableServiceImpl implements PropertyCheck.mandatory(this, "authenticationService", authenticationService); PropertyCheck.mandatory(this, "nodeOwnerCache", nodeOwnerCache); PropertyCheck.mandatory(this, "policyComponent", policyComponent); - PropertyCheck.mandatory(this, "dictionaryService", dictionaryService); + PropertyCheck.mandatory(this, "renditionService", renditionService); } public void init() @@ -175,7 +175,7 @@ public class OwnableServiceImpl implements new JavaBehaviour(this, "onCopyNode", NotificationFrequency.EVERY_EVENT)); } - // OwnableService implmentation + // OwnableService implementation public String getOwner(NodeRef nodeRef) { @@ -184,7 +184,7 @@ public class OwnableServiceImpl implements if (userName == null) { // If ownership is not explicitly set then we fall back to the creator - if(isRendition(nodeRef)) + if (isRendition(nodeRef)) { userName = getOwner(nodeService.getPrimaryParent(nodeRef).getParentRef()); } @@ -220,6 +220,23 @@ public class OwnableServiceImpl implements nodeService.setProperty(nodeRef, ContentModel.PROP_OWNER, userName); } cacheOwner(nodeRef, userName); + clearOwnerCacheForRenditions(nodeRef); + } + + private void clearOwnerCacheForRenditions(final NodeRef nodeRef) + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + List renditions = renditionService.getRenditions(nodeRef); + for (ChildAssociationRef rendition : renditions) + { + nodeOwnerCache.remove(rendition.getChildRef()); + } + return null; + } + }, AuthenticationUtil.getSystemUserName()); } public void takeOwnership(NodeRef nodeRef) @@ -338,18 +355,14 @@ public class OwnableServiceImpl implements } } - private boolean isRendition(NodeRef node) + private boolean isRendition(final NodeRef node) { - final QName aspectToCheckFor = RenditionModel.ASPECT_RENDITION; - - Set existingAspects = nodeService.getAspects(node); - for (QName nextAspect : existingAspects) + return AuthenticationUtil.runAs(new RunAsWork() { - if (nextAspect.equals(aspectToCheckFor) || dictionaryService.isSubClass(nextAspect, aspectToCheckFor)) + public Boolean doWork() throws Exception { - return true; + return renditionService.isRendition(node); } - } - return false; + }, AuthenticationUtil.getSystemUserName()); } } diff --git a/source/test-java/org/alfresco/repo/rendition/MultiUserRenditionTest.java b/source/test-java/org/alfresco/repo/rendition/MultiUserRenditionTest.java index f8a24ea4a6..20c8945935 100644 --- a/source/test-java/org/alfresco/repo/rendition/MultiUserRenditionTest.java +++ b/source/test-java/org/alfresco/repo/rendition/MultiUserRenditionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2014 Alfresco Software Limited. * * This file is part of Alfresco * @@ -36,7 +36,6 @@ import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.model.Repository; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.RetryingTransactionHelper; -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.repository.ContentWriter; @@ -50,6 +49,7 @@ import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ApplicationContextHelper; +import org.alfresco.util.Pair; import org.alfresco.util.PropertyMap; import org.junit.After; import org.junit.Before; @@ -226,6 +226,52 @@ public class MultiUserRenditionTest }); } + @Test + public void testRenditionOwnerHasChangedAfterSourceOwnerChange() + { + // Now have each user create a rendition (thumbnail) of the other user's content node. + final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib"); + + // Create another doc as non-admin + AuthenticationUtil.setFullyAuthenticatedUser(NON_ADMIN_USER); + final Pair nonAdminNodes = txnHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback>() + { + public Pair execute() throws Throwable + { + NodeRef nonAdminPdfNode = createPdfDocumentAsCurrentlyAuthenticatedUser(NON_ADMIN_USER + "_content"); + renditionService.render(nonAdminPdfNode, doclibRendDefQName); + // caches rendition owner + NodeRef nonAdminRenditionNode = renditionService.getRenditions(nonAdminPdfNode).get(0).getChildRef(); + ownableService.getOwner(nonAdminRenditionNode); + return new Pair(nonAdminPdfNode, nonAdminRenditionNode); + } + }); + this.nodesToBeTidiedUp.add(nonAdminNodes.getFirst()); + this.nodesToBeTidiedUp.add(nonAdminNodes.getSecond()); + + // change source owner to be Admin + AuthenticationUtil.setFullyAuthenticatedUser(ADMIN_USER); + txnHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + ownableService.setOwner(nonAdminNodes.getFirst(), ADMIN_USER); + return null; + } + }); + + // test that rendition owner also has changed + txnHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + assertEquals("Incorrect rendition owner", ADMIN_USER, ownableService.getOwner(nonAdminNodes.getFirst())); + assertEquals("Incorrect rendition owner", ADMIN_USER, ownableService.getOwner(nonAdminNodes.getSecond())); + return null; + } + }); + } + @After public void tidyUpUnwantedNodeRefs() { AuthenticationUtil.setFullyAuthenticatedUser(ADMIN_USER);