Merged 5.1.N (5.1.2) to 5.2.N (5.2.1)

127377 rmunteanu: Merged 5.0.N (5.0.4) to 5.1.N (5.1.2)
      127306 cturlica: Merged V4.2-BUG-FIX (4.2.7) to 5.0.N (5.0.4)
         127272 arebegea: Merged V4.1-BUG-FIX (4.1.11) to V4.2-BUG-FIX (4.2.7)
            127195 cpopa: MNT-14453 : Deleting tag using TaggingService.deleteTag() causes issue where no more tags can be added to node
               - Amended TaggingService.deleteTag() so as to remove references to a tag before being deleted. 
               - Added 'nodeService.exists(beforeNodeRef)' checks in TaggingService.updateTags in order to protect against InvalidNodeRefException which may be thrown on nodes that still have references to tags deleted using the  current(incorrect) implementation of TaggingService.deleteTag() 
               - Created DOCS-2060 in order document the manual procedure of tag scope refresh.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@127399 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Raluca Munteanu
2016-05-25 14:41:02 +00:00
parent d9b3f6e93e
commit f36baf58d1
3 changed files with 61 additions and 4 deletions

View File

@@ -415,8 +415,12 @@ public class TaggingServiceImpl implements TaggingService,
// Queue all the before's for removal to the tag scope
for (NodeRef beforeNodeRef : beforeNodeRefs)
{
String tagName = getTagName(beforeNodeRef);
queueTagUpdate(nodeRef, tagName, false);
// Protect against InvalidNodeRefException(MNT-14453)
if (this.nodeService.exists(beforeNodeRef))
{
String tagName = getTagName(beforeNodeRef);
queueTagUpdate(nodeRef, tagName, false);
}
}
}
else if (afterNodeRefs != null && beforeNodeRefs != null)
@@ -430,7 +434,8 @@ public class TaggingServiceImpl implements TaggingService,
// remove the node ref from the after list
afterNodeRefs.remove(beforeNodeRef);
}
else
// Protect against InvalidNodeRefException(MNT-14453)
else if (this.nodeService.exists(beforeNodeRef))
{
String tagName = getTagName(beforeNodeRef);
queueTagUpdate(nodeRef, tagName, false);
@@ -477,6 +482,15 @@ public class TaggingServiceImpl implements TaggingService,
// Lower the case of the tag
tag = tag.toLowerCase();
// Find nodes which are tagged with the 'soon to be deleted' tag.
List<NodeRef> taggedNodes = this.findTaggedNodes(storeRef, tag);
// Clear the tag from the found nodes
for (NodeRef taggedNode : taggedNodes)
{
this.removeTag(taggedNode, tag);
}
NodeRef tagNodeRef = getTagNodeRef(storeRef, tag);
if (tagNodeRef != null)
{

View File

@@ -94,7 +94,7 @@ public interface TaggingService
NodeRef createTag(StoreRef storeRef, String tag);
/**
* Delete an existing tag
* Delete an existing tag and any references to it(cascade delete).
*
* @param storeRef store reference
* @param tag tag name

View File

@@ -46,6 +46,7 @@ import org.alfresco.repo.audit.AuditComponent;
import org.alfresco.repo.audit.AuditServiceImpl;
import org.alfresco.repo.audit.UserAuditFilter;
import org.alfresco.repo.jscript.ClasspathScriptLocation;
import org.alfresco.repo.node.NodeRefPropertyMethodInterceptor;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
@@ -122,6 +123,8 @@ public class TaggingServiceImplTest extends TestCase
private MutableAuthenticationService authenticationService;
private AsyncOccurs asyncOccurs;
private NodeRefPropertyMethodInterceptor nodeRefPropInterceptor;
private static StoreRef storeRef;
private static NodeRef rootNode;
private NodeRef folder;
@@ -181,6 +184,7 @@ public class TaggingServiceImplTest extends TestCase
this.personService = (PersonService)ctx.getBean("PersonService");
this.permissionService = (PermissionService)ctx.getBean("PermissionService");
this.authenticationService = (MutableAuthenticationService)ctx.getBean("authenticationService");
this.nodeRefPropInterceptor = (NodeRefPropertyMethodInterceptor)ctx.getBean("nodeRefPropertyInterceptor");
if (init == false)
{
@@ -2347,4 +2351,43 @@ public class TaggingServiceImplTest extends TestCase
}
});
}
/**
* Tests that when the deleteTag() method runs, it will remove invalid references to the deleted tag.
*/
public void testDeleteTag() throws Exception{
try{
// We instruct the 'nodeRefPropInterceptor' to skip processing on the 'get' methods.
// This is needed because this interceptor removes any properties which are invalid. e.g. have been deleted.
// We need to make sure that the 'taggable' property stays put.
nodeRefPropInterceptor.setFilterOnGet(false);
this.transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<Void>(){
@SuppressWarnings("unchecked")
@Override
public Void execute() throws Throwable
{
taggingService.clearTags(folder);
taggingService.addTag(folder, TAG_1);
// The deleteTag() should remove any reference to the deleted tag
List<NodeRef> taggableProperty = (List<NodeRef>) nodeService.getProperty(folder, ContentModel.PROP_TAGS);
assertTrue("Our folder should have a reference on one tag.", taggableProperty.size() == 1);
taggingService.deleteTag(TaggingServiceImplTest.storeRef, TAG_1);
// The deleteTag() should remove any reference to the deleted tag
taggableProperty = (List<NodeRef>) nodeService.getProperty(folder, ContentModel.PROP_TAGS);
assertTrue("Our folder shouldn't have any references left to deleted tags.", taggableProperty.size() == 0);
return null;
}
});
} finally{
nodeRefPropInterceptor.setFilterOnGet(true);
}
}
}