From a549859cbeb4f928beb98fd4800883d4c61bb20c Mon Sep 17 00:00:00 2001 From: Tom Page Date: Thu, 23 Mar 2023 09:05:53 +0000 Subject: [PATCH 01/16] ACS-4863 Add method validateOrLookupNode without path. --- .../java/org/alfresco/rest/api/Nodes.java | 12 ++++++++++ .../rest/api/impl/CategoriesImpl.java | 6 ++--- .../org/alfresco/rest/api/impl/NodesImpl.java | 23 +++++++++++-------- .../alfresco/rest/api/impl/QueriesImpl.java | 2 +- .../rest/api/impl/RenditionsImpl.java | 2 +- .../org/alfresco/rest/api/impl/TagsImpl.java | 4 ++-- .../mapper/rules/RestRuleModelMapper.java | 2 +- .../RestRuleSimpleConditionModelMapper.java | 2 +- .../impl/rules/ActionParameterConverter.java | 2 +- .../rest/api/impl/rules/NodeValidator.java | 2 +- .../nodes/NodeActionDefinitionsRelation.java | 6 +---- .../rest/api/nodes/NodeParentsRelation.java | 12 +++++----- .../nodes/NodeSecondaryChildrenRelation.java | 6 ++--- .../rest/api/nodes/NodeSourcesRelation.java | 6 ++--- .../rest/api/nodes/NodeTargetsRelation.java | 6 ++--- .../rest/api/nodes/NodeVersionsRelation.java | 18 +++++++-------- .../rest/api/impl/CategoriesImplTest.java | 20 ++++++++-------- .../alfresco/rest/api/impl/TagsImplTest.java | 10 ++++---- .../mapper/rules/RestRuleModelMapperTest.java | 2 +- ...estRuleSimpleConditionModelMapperTest.java | 2 +- .../rules/ActionParameterConverterTest.java | 7 +++--- .../api/impl/rules/NodeValidatorTest.java | 17 +++++++------- .../rest/api/search/ResultMapperTests.java | 6 ++--- 23 files changed, 93 insertions(+), 82 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java index 6fa9272e3d..9a606ad049 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java @@ -39,6 +39,8 @@ import org.alfresco.rest.api.model.LockInfo; import org.alfresco.rest.api.model.Node; import org.alfresco.rest.api.model.PathInfo; import org.alfresco.rest.api.model.UserInfo; +import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.resource.content.BasicContentInfo; import org.alfresco.rest.framework.resource.content.BinaryResource; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; @@ -208,6 +210,16 @@ public interface Nodes NodeRef validateNode(StoreRef storeRef, String nodeId); NodeRef validateNode(String nodeId); NodeRef validateNode(NodeRef nodeRef); + + /** + * Check that the specified id refers to a valid node. + * + * @param nodeId The node id to look up using SpacesStore or an alias like -root-. + * @return The node ref. + * @throws InvalidArgumentException if the specified node id is not a valid format. + * @throws EntityNotFoundException if the specified node was not found in the database. + */ + NodeRef validateOrLookupNode(String nodeId); NodeRef validateOrLookupNode(String nodeId, String path); boolean nodeMatches(NodeRef nodeRef, Set expectedTypes, Set excludedTypes); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java index 7023d2625b..53f9eddab8 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java @@ -189,7 +189,7 @@ public class CategoriesImpl implements Categories @Override public List listCategoriesForNode(final String nodeId, final Parameters parameters) { - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId); verifyReadPermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -211,7 +211,7 @@ public class CategoriesImpl implements Categories throw new InvalidArgumentException(NOT_A_VALID_CATEGORY); } - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -237,7 +237,7 @@ public class CategoriesImpl implements Categories public void unlinkNodeFromCategory(final StoreRef storeRef, final String nodeId, final String categoryId, final Parameters parameters) { final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, categoryId); - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index 4032bd1c43..6abf370923 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -649,6 +649,11 @@ public class NodesImpl implements Nodes return nodeService.getPrimaryParent(nodeRef).getParentRef(); } + public NodeRef validateOrLookupNode(String nodeId) + { + return validateOrLookupNode(nodeId); + } + public NodeRef validateOrLookupNode(String nodeId, String path) { NodeRef parentNodeRef; @@ -1356,7 +1361,7 @@ public class NodesImpl implements Nodes private void calculateRelativePath(String parentFolderNodeId, Node node) { - NodeRef rootNodeRef = validateOrLookupNode(parentFolderNodeId, null); + NodeRef rootNodeRef = validateOrLookupNode(parentFolderNodeId); try { // get the path elements @@ -1741,7 +1746,7 @@ public class NodesImpl implements Nodes @Override public void deleteNode(String nodeId, Parameters parameters) { - NodeRef nodeRef = validateOrLookupNode(nodeId, null); + NodeRef nodeRef = validateOrLookupNode(nodeId); if (isSpecialNode(nodeRef, getNodeType(nodeRef))) { @@ -1785,7 +1790,7 @@ public class NodesImpl implements Nodes validateProperties(nodeInfo.getProperties(), EXCLUDED_NS, Arrays.asList()); // check that requested parent node exists and it's type is a (sub-)type of folder - NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null); + NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId); // node name - mandatory String nodeName = nodeInfo.getName(); @@ -2290,7 +2295,7 @@ public class NodesImpl implements Nodes validateAspects(nodeInfo.getAspectNames(), EXCLUDED_NS, EXCLUDED_ASPECTS); validateProperties(nodeInfo.getProperties(), EXCLUDED_NS, Arrays.asList()); - final NodeRef nodeRef = validateOrLookupNode(nodeId, null); + final NodeRef nodeRef = validateOrLookupNode(nodeId); QName nodeTypeQName = getNodeType(nodeRef); @@ -2523,8 +2528,8 @@ public class NodesImpl implements Nodes throw new InvalidArgumentException("Missing targetParentId"); } - final NodeRef parentNodeRef = validateOrLookupNode(targetParentId, null); - final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId, null); + final NodeRef parentNodeRef = validateOrLookupNode(targetParentId); + final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId); FileInfo fi = moveOrCopyImpl(sourceNodeRef, parentNodeRef, name, isCopy); return getFolderOrDocument(fi.getNodeRef().getId(), parameters); @@ -2954,7 +2959,7 @@ public class NodesImpl implements Nodes throw new InvalidArgumentException("The request content-type is not multipart: "+parentFolderNodeId); } - NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null); + NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId); if (!nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) { throw new InvalidArgumentException("NodeId of folder is expected: " + parentNodeRef.getId()); @@ -3385,7 +3390,7 @@ public class NodesImpl implements Nodes @Override public Node lock(String nodeId, LockInfo lockInfo, Parameters parameters) { - NodeRef nodeRef = validateOrLookupNode(nodeId, null); + NodeRef nodeRef = validateOrLookupNode(nodeId); if (isSpecialNode(nodeRef, getNodeType(nodeRef))) { @@ -3424,7 +3429,7 @@ public class NodesImpl implements Nodes @Override public Node unlock(String nodeId, Parameters parameters) { - NodeRef nodeRef = validateOrLookupNode(nodeId, null); + NodeRef nodeRef = validateOrLookupNode(nodeId); if (isSpecialNode(nodeRef, getNodeType(nodeRef))) { diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/QueriesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/QueriesImpl.java index c86c064e8d..654833a6cd 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/QueriesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/QueriesImpl.java @@ -185,7 +185,7 @@ public class QueriesImpl implements Queries, InitializingBean String rootNodeId = parameters.getParameter(PARAM_ROOT_NODE_ID); if (rootNodeId != null) { - NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId, null); + NodeRef nodeRef = nodes.validateOrLookupNode(rootNodeId); query.append("PATH:\"").append(getQNamePath(nodeRef.getId())).append("//*\" AND ("); } if (term != null) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java index b70dcd8401..28f4456d1c 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/RenditionsImpl.java @@ -695,7 +695,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware { if (versionLabelId != null) { - nodeRef = nodes.validateOrLookupNode(nodeRef.getId(), null); + nodeRef = nodes.validateOrLookupNode(nodeRef.getId()); VersionHistory vh = versionService.getVersionHistory(nodeRef); if (vh != null) { diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java index d703b86262..a697f9bad4 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java @@ -117,7 +117,7 @@ public class TagsImpl implements Tags public List addTags(String nodeId, final List tags) { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId); if (!typeConstraint.matches(nodeRef)) { throw new UnsupportedResourceOperationException("Cannot tag this node"); @@ -241,7 +241,7 @@ public class TagsImpl implements Tags public CollectionWithPagingInfo getTags(String nodeId, Parameters params) { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId); PagingResults> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging())); Integer totalItems = results.getTotalResultCount().getFirst(); List> page = results.getPage(); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java index 192fb654ca..05e3ba406b 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapper.java @@ -134,7 +134,7 @@ public class RestRuleModelMapper implements RestModelMapper @@ -59,7 +55,7 @@ public class NodeActionDefinitionsRelation extends AbstractNodeRelation @Override public CollectionWithPagingInfo readAll(String entityResourceId, Parameters params) { - NodeRef parentNodeRef = nodes.validateOrLookupNode(entityResourceId, null); + NodeRef parentNodeRef = nodes.validateOrLookupNode(entityResourceId); return actions.getActionDefinitions(parentNodeRef, params); } } diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java index d2440a2266..9803b58357 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeParentsRelation.java @@ -25,6 +25,11 @@ */ package org.alfresco.rest.api.nodes; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.alfresco.rest.antlr.WhereClauseParser; import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.Node; @@ -41,11 +46,6 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - /** * Node Parents * @@ -67,7 +67,7 @@ public class NodeParentsRelation extends AbstractNodeRelation implements Relatio @WebApiDescription(title = "Return a list of parent nodes based on child assocs") public CollectionWithPagingInfo readAll(String childNodeId, Parameters parameters) { - NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId, null); + NodeRef childNodeRef = nodes.validateOrLookupNode(childNodeId); QNamePattern assocTypeQNameParam = RegexQNamePattern.MATCH_ALL; diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSecondaryChildrenRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSecondaryChildrenRelation.java index aa17a20561..21dded1b01 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSecondaryChildrenRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSecondaryChildrenRelation.java @@ -25,6 +25,8 @@ */ package org.alfresco.rest.api.nodes; +import java.util.List; + import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.AssocChild; import org.alfresco.rest.api.model.Node; @@ -41,8 +43,6 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; -import java.util.List; - /** * Node Secondary Children * @@ -71,7 +71,7 @@ public class NodeSecondaryChildrenRelation extends AbstractNodeRelation implemen @WebApiDescription(title = "Return a paged list of secondary child nodes based on child assocs") public CollectionWithPagingInfo readAll(String parentNodeId, Parameters parameters) { - NodeRef parentNodeRef = nodes.validateOrLookupNode(parentNodeId, null); + NodeRef parentNodeRef = nodes.validateOrLookupNode(parentNodeId); QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java index 743716fef3..c900e53794 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeSourcesRelation.java @@ -25,6 +25,8 @@ */ package org.alfresco.rest.api.nodes; +import java.util.List; + import org.alfresco.rest.api.model.Node; import org.alfresco.rest.framework.WebApiDescription; import org.alfresco.rest.framework.resource.RelationshipResource; @@ -35,8 +37,6 @@ import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QNamePattern; -import java.util.List; - /** * Node Sources - list node (peer) associations from target to sources * @@ -54,7 +54,7 @@ public class NodeSourcesRelation extends AbstractNodeRelation implements Relatio @WebApiDescription(title = "Return a paged list of sources nodes based on (peer) assocs") public CollectionWithPagingInfo readAll(String targetNodeId, Parameters parameters) { - NodeRef targetNodeRef = nodes.validateOrLookupNode(targetNodeId, null); + NodeRef targetNodeRef = nodes.validateOrLookupNode(targetNodeId); QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java index f4ac2c04fe..9948d82ee3 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeTargetsRelation.java @@ -25,6 +25,8 @@ */ package org.alfresco.rest.api.nodes; +import java.util.List; + import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.model.AssocTarget; import org.alfresco.rest.api.model.Node; @@ -40,8 +42,6 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; -import java.util.List; - /** * Node Targets * @@ -64,7 +64,7 @@ public class NodeTargetsRelation extends AbstractNodeRelation implements @WebApiDescription(title = "Return a paged list of target nodes based on (peer) assocs") public CollectionWithPagingInfo readAll(String sourceNodeId, Parameters parameters) { - NodeRef sourceNodeRef = nodes.validateOrLookupNode(sourceNodeId, null); + NodeRef sourceNodeRef = nodes.validateOrLookupNode(sourceNodeId); QNamePattern assocTypeQNameParam = getAssocTypeFromWhereElseAll(parameters); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java index db8274dadb..363bda8566 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeVersionsRelation.java @@ -25,6 +25,13 @@ */ package org.alfresco.rest.api.nodes; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletResponse; + import org.alfresco.model.ContentModel; import org.alfresco.repo.content.directurl.DirectAccessUrlDisabledException; import org.alfresco.repo.node.integrity.IntegrityException; @@ -65,13 +72,6 @@ import org.alfresco.util.ParameterCheck; import org.alfresco.util.PropertyCheck; import org.springframework.beans.factory.InitializingBean; -import javax.servlet.http.HttpServletResponse; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Node Versions - version history * @@ -117,7 +117,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements @WebApiDescription(title = "Return version history as a paged list of version node infos") public CollectionWithPagingInfo readAll(String nodeId, Parameters parameters) { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId); VersionHistory vh = versionService.getVersionHistory(nodeRef); @@ -293,7 +293,7 @@ public class NodeVersionsRelation extends AbstractNodeRelation implements public Version findVersion(String nodeId, String versionLabelId) { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId); VersionHistory vh = versionService.getVersionHistory(nodeRef); if (vh != null) { diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java index 1c7445cb6d..6d9dc98410 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java @@ -128,7 +128,7 @@ public class CategoriesImplTest { given(authorityServiceMock.hasAdminAuthority()).willReturn(true); given(nodesMock.validateNode(CATEGORY_ID)).willReturn(CATEGORY_NODE_REF); - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); given(nodesMock.isSubClass(any(), any(), anyBoolean())).willReturn(true); given(typeConstraint.matches(any())).willReturn(true); given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED); @@ -900,7 +900,7 @@ public class CategoriesImplTest // when final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1011,12 +1011,12 @@ public class CategoriesImplTest @Test public void testLinkNodeToCategories_withInvalidNodeId() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).shouldHaveNoInteractions(); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1031,7 +1031,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1118,7 +1118,7 @@ public class CategoriesImplTest objectUnderTest.unlinkNodeFromCategory(CONTENT_NODE_ID, CATEGORY_ID, parametersMock); then(nodesMock).should().validateNode(CATEGORY_ID); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1155,7 +1155,7 @@ public class CategoriesImplTest // when final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1176,12 +1176,12 @@ public class CategoriesImplTest @Test public void testListCategoriesForNode_withInvalidNodeId() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) .isInstanceOf(EntityNotFoundException.class); @@ -1195,7 +1195,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java index f874db09e2..5f22dfb0c1 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java @@ -422,7 +422,7 @@ public class TagsImplTest @Test public void testAddTags() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(true); List> pairs = List.of(new Pair<>("tagA", new NodeRef("tag://A/")), new Pair<>("tagB", new NodeRef("tag://B/"))); List tagNames = pairs.stream().map(Pair::getFirst).collect(toList()); @@ -438,7 +438,7 @@ public class TagsImplTest @Test(expected = InvalidArgumentException.class) public void testAddTagsToInvalidNode() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willThrow(new InvalidArgumentException()); List tags = List.of(Tag.builder().tag("tag1").create()); objectUnderTest.addTags(CONTENT_NODE_ID, tags); @@ -447,7 +447,7 @@ public class TagsImplTest @Test(expected = UnsupportedResourceOperationException.class) public void testAddTagsToWrongTypeOfNode() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(false); List tags = List.of(Tag.builder().tag("tag1").create()); @@ -458,7 +458,7 @@ public class TagsImplTest @Test public void testGetTagsForNode() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); given(parametersMock.getPaging()).willReturn(pagingMock); List> pairs = List.of(new Pair<>(new NodeRef("tag://A/"), "tagA"), new Pair<>(new NodeRef("tag://B/"), "tagB")); given(taggingServiceMock.getTags(eq(CONTENT_NODE_REF), any(PagingRequest.class))).willReturn(pagingResultsMock); @@ -474,7 +474,7 @@ public class TagsImplTest @Test (expected = InvalidArgumentException.class) public void testGetTagsFromInvalidNode() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willThrow(new InvalidArgumentException()); objectUnderTest.getTags(CONTENT_NODE_ID, parametersMock); } diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java index bcf7eacf78..3bdb322955 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleModelMapperTest.java @@ -134,7 +134,7 @@ public class RestRuleModelMapperTest // when final org.alfresco.service.cmr.rule.Rule actualRuleModel = objectUnderTest.toServiceModel(rule); - then(nodesMock).should().validateOrLookupNode(RULE_ID, null); + then(nodesMock).should().validateOrLookupNode(RULE_ID); then(nodesMock).shouldHaveNoMoreInteractions(); then(actionMapperMock).should().toServiceModel(List.of(action)); then(actionMapperMock).shouldHaveNoMoreInteractions(); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java index bbe7d00c94..edf16d3e09 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/mapper/rules/RestRuleSimpleConditionModelMapperTest.java @@ -275,7 +275,7 @@ public class RestRuleSimpleConditionModelMapperTest { final SimpleCondition simpleCondition = createSimpleCondition(PARAM_CATEGORY); final NodeRef defaultNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARAMETER_DEFAULT); - given(nodesMock.validateOrLookupNode(PARAMETER_DEFAULT, null)).willReturn(defaultNodeRef); + given(nodesMock.validateOrLookupNode(PARAMETER_DEFAULT)).willReturn(defaultNodeRef); // when final ActionCondition actualActionCondition = objectUnderTest.toServiceModel(simpleCondition); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java index 98d24839e8..236a02247c 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/ActionParameterConverterTest.java @@ -44,7 +44,6 @@ import java.io.Serializable; import java.util.List; import java.util.Map; -import com.fasterxml.jackson.core.JsonProcessingException; import org.alfresco.repo.action.executer.AddFeaturesActionExecuter; import org.alfresco.repo.action.executer.CheckInActionExecuter; import org.alfresco.repo.action.executer.CheckOutActionExecuter; @@ -129,8 +128,8 @@ public class ActionParameterConverterTest @Before public void setUp() { - given(nodes.validateOrLookupNode(DUMMY_FOLDER_NODE_ID, null)).willReturn(DUMMY_FOLDER_NODE); - given(nodes.validateOrLookupNode(DUMMY_SCRIPT_NODE_ID, null)).willReturn(DUMMY_SCRIPT_NODE); + given(nodes.validateOrLookupNode(DUMMY_FOLDER_NODE_ID)).willReturn(DUMMY_FOLDER_NODE); + given(nodes.validateOrLookupNode(DUMMY_SCRIPT_NODE_ID)).willReturn(DUMMY_SCRIPT_NODE); given(permissionService.hasReadPermission(DUMMY_FOLDER_NODE)).willReturn(ALLOWED); given(permissionService.hasReadPermission(DUMMY_SCRIPT_NODE)).willReturn(ALLOWED); } @@ -598,7 +597,7 @@ public class ActionParameterConverterTest String permissionDeniedNodeId = "permission://denied/node"; final Map params = Map.of(PARAM_DESTINATION_FOLDER, permissionDeniedNodeId); NodeRef permissionDeniedNode = new NodeRef(permissionDeniedNodeId); - given(nodes.validateOrLookupNode(permissionDeniedNodeId, null)).willReturn(permissionDeniedNode); + given(nodes.validateOrLookupNode(permissionDeniedNodeId)).willReturn(permissionDeniedNode); given(permissionService.hasReadPermission(permissionDeniedNode)).willReturn(DENIED); given(actionService.getActionDefinition(name)).willReturn(actionDefinition); diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/NodeValidatorTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/NodeValidatorTest.java index f71f32156e..770d8da82b 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/NodeValidatorTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/NodeValidatorTest.java @@ -101,7 +101,7 @@ public class NodeValidatorTest public void setUp() throws Exception { MockitoAnnotations.openMocks(this); - given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef); + given(nodesMock.validateOrLookupNode(FOLDER_NODE_ID)).willReturn(folderNodeRef); given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef); given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef); given(nodesMock.nodeMatches(any(), any(), any())).willReturn(true); @@ -115,7 +115,7 @@ public class NodeValidatorTest // when final NodeRef nodeRef = nodeValidator.validateFolderNode(FOLDER_NODE_ID, false); - then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID); then(nodesMock).should().nodeMatches(folderNodeRef, Set.of(TYPE_FOLDER), null); then(nodesMock).shouldHaveNoMoreInteractions(); then(permissionServiceMock).should().hasReadPermission(folderNodeRef); @@ -128,13 +128,13 @@ public class NodeValidatorTest @Test public void testValidateFolderNode_notExistingFolder() { - given(nodesMock.validateOrLookupNode(any(), any())).willThrow(new EntityNotFoundException(FOLDER_NODE_ID)); + given(nodesMock.validateOrLookupNode(FOLDER_NODE_ID)).willThrow(new EntityNotFoundException(FOLDER_NODE_ID)); //when assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy( () -> nodeValidator.validateFolderNode(FOLDER_NODE_ID, false)); - then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID); then(nodesMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).shouldHaveNoInteractions(); } @@ -148,7 +148,7 @@ public class NodeValidatorTest assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy( () -> nodeValidator.validateFolderNode(FOLDER_NODE_ID, false)); - then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID, null); + then(nodesMock).should().validateOrLookupNode(FOLDER_NODE_ID); then(nodesMock).should().nodeMatches(folderNodeRef, Set.of(TYPE_FOLDER), null); then(nodesMock).shouldHaveNoMoreInteractions(); then(ruleServiceMock).shouldHaveNoInteractions(); @@ -431,11 +431,12 @@ public class NodeValidatorTest then(ruleServiceMock).shouldHaveNoMoreInteractions(); } - private void resetNodesMock() { + private void resetNodesMock() + { reset(nodesMock); - given(nodesMock.validateOrLookupNode(eq(FOLDER_NODE_ID), any())).willReturn(folderNodeRef); + given(nodesMock.validateOrLookupNode(FOLDER_NODE_ID)).willReturn(folderNodeRef); given(nodesMock.validateNode(RULE_SET_ID)).willReturn(ruleSetNodeRef); given(nodesMock.validateNode(RULE_ID)).willReturn(ruleNodeRef); given(nodesMock.nodeMatches(ruleSetNodeRef, Set.of(ContentModel.TYPE_SYSTEM_FOLDER), null)).willReturn(true); } -} \ No newline at end of file +} diff --git a/remote-api/src/test/java/org/alfresco/rest/api/search/ResultMapperTests.java b/remote-api/src/test/java/org/alfresco/rest/api/search/ResultMapperTests.java index aa6b5b1aab..8bb7a576ca 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/search/ResultMapperTests.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/search/ResultMapperTests.java @@ -37,10 +37,8 @@ import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.notNull; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.notNull; import static org.mockito.Mockito.when; import java.io.Serializable; @@ -186,7 +184,7 @@ public class ResultMapperTests when(sr.getVersionService()).thenReturn(versionService); when(sr.getNodeService()).thenReturn(nodeService); - when(nodes.validateOrLookupNode(nullable(String.class), nullable(String.class))).thenAnswer(invocation -> + when(nodes.validateOrLookupNode(nullable(String.class))).thenAnswer(invocation -> { Object[] args = invocation.getArguments(); String aNode = (String)args[0]; From 10b0d7b5f02b1f0cfa7d2b55144eef988d946b44 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Thu, 23 Mar 2023 16:01:07 +0000 Subject: [PATCH 02/16] ACS-4863 Ensure we don't accidentally introduce circular reference. --- .../src/main/java/org/alfresco/rest/api/impl/NodesImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index 6abf370923..ab1893d762 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -651,7 +651,7 @@ public class NodesImpl implements Nodes public NodeRef validateOrLookupNode(String nodeId) { - return validateOrLookupNode(nodeId); + return validateOrLookupNode(nodeId, null); } public NodeRef validateOrLookupNode(String nodeId, String path) From 6d1dcf6c7eeb3948d57fa63946f7cbc6a4da862e Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 07:03:39 +0000 Subject: [PATCH 03/16] [maven-release-plugin][skip ci] prepare release 20.115 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index f55945724e..33cff05db1 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.115-SNAPSHOT + 20.115 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index b74c8ff8fa..53b021e737 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.115-SNAPSHOT + 20.115 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 7a3594d78f..2948802788 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 0774fbc220..377f07d669 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.115-SNAPSHOT + 20.115 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 2b8bad72e8..5fee4f6b48 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.115-SNAPSHOT + 20.115 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 00a291f41f..ab13d92f30 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.115-SNAPSHOT + 20.115 diff --git a/amps/pom.xml b/amps/pom.xml index 9e06143cac..6647e8b396 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 74fd2a21d0..06ace7ad39 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.115-SNAPSHOT + 20.115 diff --git a/core/pom.xml b/core/pom.xml index f7a8fef550..76862d3aa4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/data-model/pom.xml b/data-model/pom.xml index fcfdd094e3..68f0d0726c 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/mmt/pom.xml b/mmt/pom.xml index 348f93d991..657d5920fa 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 427b46aa7f..d769b53704 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 06d724c7c1..9e1d199b03 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/pom.xml b/packaging/pom.xml index 32f2ebeef7..49c9bbc6e2 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 8ce9eb2808..87ea6b64fa 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 56e3deaee3..8e0d16eea4 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 11aff83759..297000188b 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 2e383c8b99..884c2c8a98 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 5c1655d94a..c63f9a9738 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 2782d7d6b3..f4fbc5fd6a 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115-SNAPSHOT + 20.115 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 2a4eaf7fec..744fbb4dca 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115-SNAPSHOT + 20.115 diff --git a/pom.xml b/pom.xml index 0abeb08b4b..f7913c0687 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.115-SNAPSHOT + 20.115 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 20.115 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index d5be55ac9d..cf22a0b669 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 diff --git a/repository/pom.xml b/repository/pom.xml index 7b62a433a9..a049cd8066 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115-SNAPSHOT + 20.115 From 279679d78a93bca99d9a9157d90424f6e4db7832 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 07:03:42 +0000 Subject: [PATCH 04/16] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 33cff05db1..40ff317685 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.115 + 20.116-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 53b021e737..8436aaf5ce 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.115 + 20.116-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 2948802788..debc82aa9c 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 377f07d669..8f717cb912 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.115 + 20.116-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 5fee4f6b48..87e389eb5f 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.115 + 20.116-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index ab13d92f30..f9139988f4 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.115 + 20.116-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index 6647e8b396..9546ca05dc 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 06ace7ad39..0ad07c55ca 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.115 + 20.116-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 76862d3aa4..fb5a07f5b6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index 68f0d0726c..f0af6a5b78 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 657d5920fa..15f8d923d5 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index d769b53704..2b1196731c 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 9e1d199b03..b1fc36c630 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index 49c9bbc6e2..2f06fb361b 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 87ea6b64fa..e16dfaff72 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 8e0d16eea4..346c2de3f2 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 297000188b..2bb68cdfd7 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 884c2c8a98..cb0b84f113 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index c63f9a9738..68273db05d 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index f4fbc5fd6a..9deb2d3125 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.115 + 20.116-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 744fbb4dca..8b689082a4 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.115 + 20.116-SNAPSHOT diff --git a/pom.xml b/pom.xml index f7913c0687..737710c127 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.115 + 20.116-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 20.115 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index cf22a0b669..107d304b8c 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index a049cd8066..5867188017 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.115 + 20.116-SNAPSHOT From 70b7d5a1f884300437d815ccaf4cd1d604512fb4 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 24 Mar 2023 08:20:50 +0000 Subject: [PATCH 05/16] Revert "ACS-4863 Allow referencing nodes by aliases for tag and category application. (#1822)" This reverts commit dafa77d0a08d9a65fbdcfda151e4e27cf851f7b7. --- .../rest/api/impl/CategoriesImpl.java | 6 +- .../org/alfresco/rest/api/impl/TagsImpl.java | 83 ++++++++++-------- .../rest/api/impl/CategoriesImplTest.java | 20 ++--- .../alfresco/rest/api/impl/TagsImplTest.java | 87 +++---------------- 4 files changed, 71 insertions(+), 125 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java index 7023d2625b..e78f7856d4 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java @@ -189,7 +189,7 @@ public class CategoriesImpl implements Categories @Override public List listCategoriesForNode(final String nodeId, final Parameters parameters) { - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateNode(nodeId); verifyReadPermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -211,7 +211,7 @@ public class CategoriesImpl implements Categories throw new InvalidArgumentException(NOT_A_VALID_CATEGORY); } - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateNode(nodeId); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -237,7 +237,7 @@ public class CategoriesImpl implements Categories public void unlinkNodeFromCategory(final StoreRef storeRef, final String nodeId, final String categoryId, final Parameters parameters) { final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, categoryId); - final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); + final NodeRef contentNodeRef = nodes.validateNode(nodeId); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java index d703b86262..e6fec46b07 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java @@ -25,12 +25,11 @@ */ package org.alfresco.rest.api.impl; -import static java.util.stream.Collectors.toList; - import static org.alfresco.rest.antlr.WhereClauseParser.EQUALS; import static org.alfresco.rest.antlr.WhereClauseParser.IN; import static org.alfresco.rest.antlr.WhereClauseParser.MATCHES; +import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -115,30 +114,44 @@ public class TagsImpl implements Tags this.authorityService = authorityService; } - public List addTags(String nodeId, final List tags) - { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); - if (!typeConstraint.matches(nodeRef)) - { - throw new UnsupportedResourceOperationException("Cannot tag this node"); - } + public List addTags(String nodeId, final List tags) + { + NodeRef nodeRef = nodes.validateNode(nodeId); + if(!typeConstraint.matches(nodeRef)) + { + throw new UnsupportedResourceOperationException("Cannot tag this node"); + } - List tagValues = tags.stream().map(Tag::getTag).collect(toList()); - try - { - List> tagNodeRefs = taggingService.addTags(nodeRef, tagValues); - List ret = new ArrayList<>(tags.size()); - for (Pair pair : tagNodeRefs) + List tagValues = new AbstractList() { - ret.add(new Tag(pair.getSecond(), pair.getFirst())); + @Override + public String get(int arg0) + { + String tag = tags.get(arg0).getTag(); + return tag; + } + + @Override + public int size() + { + return tags.size(); + } + }; + try + { + List> tagNodeRefs = taggingService.addTags(nodeRef, tagValues); + List ret = new ArrayList(tags.size()); + for(Pair pair : tagNodeRefs) + { + ret.add(new Tag(pair.getSecond(), pair.getFirst())); + } + return ret; } - return ret; - } - catch (IllegalArgumentException e) - { - throw new InvalidArgumentException(e.getMessage()); - } - } + catch(IllegalArgumentException e) + { + throw new InvalidArgumentException(e.getMessage()); + } + } public void deleteTag(String nodeId, String tagId) { @@ -241,17 +254,17 @@ public class TagsImpl implements Tags public CollectionWithPagingInfo getTags(String nodeId, Parameters params) { - NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); - PagingResults> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging())); - Integer totalItems = results.getTotalResultCount().getFirst(); - List> page = results.getPage(); - List tags = new ArrayList<>(page.size()); - for(Pair pair : page) - { - tags.add(new Tag(pair.getFirst(), pair.getSecond())); - } + NodeRef nodeRef = nodes.validateNode(nodeId); + PagingResults> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging())); + Integer totalItems = results.getTotalResultCount().getFirst(); + List> page = results.getPage(); + List tags = new ArrayList(page.size()); + for(Pair pair : page) + { + tags.add(new Tag(pair.getFirst(), pair.getSecond())); + } - return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue())); + return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue())); } @Experimental @@ -263,7 +276,7 @@ public class TagsImpl implements Tags .filter(Objects::nonNull) .map(Tag::getTag) .distinct() - .collect(toList()); + .collect(Collectors.toList()); if (CollectionUtils.isEmpty(tagNames)) { @@ -277,7 +290,7 @@ public class TagsImpl implements Tags { tag.setCount(0); } - }).collect(toList()); + }).collect(Collectors.toList()); } private void verifyAdminAuthority() diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java index 1c7445cb6d..575f0cc0dc 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java @@ -128,7 +128,7 @@ public class CategoriesImplTest { given(authorityServiceMock.hasAdminAuthority()).willReturn(true); given(nodesMock.validateNode(CATEGORY_ID)).willReturn(CATEGORY_NODE_REF); - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); given(nodesMock.isSubClass(any(), any(), anyBoolean())).willReturn(true); given(typeConstraint.matches(any())).willReturn(true); given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED); @@ -900,7 +900,7 @@ public class CategoriesImplTest // when final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1011,12 +1011,12 @@ public class CategoriesImplTest @Test public void testLinkNodeToCategories_withInvalidNodeId() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).shouldHaveNoInteractions(); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1031,7 +1031,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1118,7 +1118,7 @@ public class CategoriesImplTest objectUnderTest.unlinkNodeFromCategory(CONTENT_NODE_ID, CATEGORY_ID, parametersMock); then(nodesMock).should().validateNode(CATEGORY_ID); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1155,7 +1155,7 @@ public class CategoriesImplTest // when final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1176,12 +1176,12 @@ public class CategoriesImplTest @Test public void testListCategoriesForNode_withInvalidNodeId() { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) .isInstanceOf(EntityNotFoundException.class); @@ -1195,7 +1195,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); + then(nodesMock).should().validateNode(CONTENT_NODE_ID); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java index f874db09e2..8b668abef1 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java @@ -25,8 +25,6 @@ */ package org.alfresco.rest.api.impl; -import static java.util.stream.Collectors.toList; - import static org.alfresco.rest.api.impl.TagsImpl.NOT_A_VALID_TAG; import static org.alfresco.rest.api.impl.TagsImpl.NO_PERMISSION_TO_MANAGE_A_TAG; import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; @@ -43,6 +41,7 @@ import static org.mockito.BDDMockito.then; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; @@ -51,7 +50,6 @@ import org.alfresco.rest.api.model.Tag; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; -import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; @@ -65,7 +63,6 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.util.Pair; -import org.alfresco.util.TypeConstraint; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -80,9 +77,7 @@ public class TagsImplTest private static final String PARENT_NODE_ID = "tag:tag-root"; private static final String TAG_NAME = "tag-dummy-name"; private static final NodeRef TAG_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(TAG_NAME)); - private static final NodeRef TAG_PARENT_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_NODE_ID); - private static final String CONTENT_NODE_ID = "content-node-id"; - private static final NodeRef CONTENT_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, CONTENT_NODE_ID); + private static final NodeRef TAG_PARENT_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_NODE_ID); private final RecognizedParamsExtractor queryExtractor = new RecognizedParamsExtractor() {}; @@ -102,8 +97,6 @@ public class TagsImplTest private Paging pagingMock; @Mock private PagingResults> pagingResultsMock; - @Mock - private TypeConstraint typeConstraintMock; @InjectMocks private TagsImpl objectUnderTest; @@ -129,7 +122,7 @@ public class TagsImplTest then(taggingServiceMock).should().getTags(eq(STORE_REF_WORKSPACE_SPACESSTORE), any(PagingRequest.class), isNull(), isNull()); then(taggingServiceMock).shouldHaveNoMoreInteractions(); - final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream().peek(tag -> tag.setCount(0)).collect(toList()); + final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream().peek(tag -> tag.setCount(0)).collect(Collectors.toList()); assertEquals(expectedTags, actualTags.getCollection()); } @@ -147,7 +140,7 @@ public class TagsImplTest then(taggingServiceMock).should().findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE); final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream() .peek(tag -> tag.setCount(0)) - .collect(toList()); + .collect(Collectors.toList()); assertEquals(expectedTags, actualTags.getCollection()); } @@ -402,7 +395,7 @@ public class TagsImplTest final List expectedTags = createTagsWithNodeRefs(tagNames).stream() .peek(tag -> tag.setCount(0)) - .collect(toList()); + .collect(Collectors.toList()); assertThat(actualCreatedTags) .isNotNull() .isEqualTo(expectedTags); @@ -412,78 +405,18 @@ public class TagsImplTest public void testGetTagByIdNotFoundValidation() { given(primaryParentMock.getParentRef()).willReturn(TAG_NODE_REF); - objectUnderTest.getTag(STORE_REF_WORKSPACE_SPACESSTORE,TAG_ID); + objectUnderTest.getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,TAG_ID); then(nodeServiceMock).shouldHaveNoInteractions(); - then(nodesMock).should().validateNode(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID); + then(nodesMock).should().validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID); then(nodesMock).shouldHaveNoMoreInteractions(); then(taggingServiceMock).shouldHaveNoInteractions(); } - @Test - public void testAddTags() - { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); - given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(true); - List> pairs = List.of(new Pair<>("tagA", new NodeRef("tag://A/")), new Pair<>("tagB", new NodeRef("tag://B/"))); - List tagNames = pairs.stream().map(Pair::getFirst).collect(toList()); - List tags = tagNames.stream().map(name -> Tag.builder().tag(name).create()).collect(toList()); - given(taggingServiceMock.addTags(CONTENT_NODE_REF, tagNames)).willReturn(pairs); - - List actual = objectUnderTest.addTags(CONTENT_NODE_ID, tags); - - List expected = pairs.stream().map(pair -> new Tag(pair.getSecond(), pair.getFirst())).collect(toList()); - assertEquals("Unexpected tags returned.", expected, actual); - } - - @Test(expected = InvalidArgumentException.class) - public void testAddTagsToInvalidNode() - { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); - List tags = List.of(Tag.builder().tag("tag1").create()); - - objectUnderTest.addTags(CONTENT_NODE_ID, tags); - } - - @Test(expected = UnsupportedResourceOperationException.class) - public void testAddTagsToWrongTypeOfNode() - { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); - given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(false); - - List tags = List.of(Tag.builder().tag("tag1").create()); - - objectUnderTest.addTags(CONTENT_NODE_ID, tags); - } - - @Test - public void testGetTagsForNode() - { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); - given(parametersMock.getPaging()).willReturn(pagingMock); - List> pairs = List.of(new Pair<>(new NodeRef("tag://A/"), "tagA"), new Pair<>(new NodeRef("tag://B/"), "tagB")); - given(taggingServiceMock.getTags(eq(CONTENT_NODE_REF), any(PagingRequest.class))).willReturn(pagingResultsMock); - given(pagingResultsMock.getTotalResultCount()).willReturn(new Pair<>(null, null)); - given(pagingResultsMock.getPage()).willReturn(pairs); - - CollectionWithPagingInfo actual = objectUnderTest.getTags(CONTENT_NODE_ID, parametersMock); - - List tags = pairs.stream().map(pair -> Tag.builder().tag(pair.getSecond()).nodeRef(pair.getFirst()).create()).collect(toList()); - assertEquals(actual.getCollection(), tags); - } - - @Test (expected = InvalidArgumentException.class) - public void testGetTagsFromInvalidNode() - { - given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); - - objectUnderTest.getTags(CONTENT_NODE_ID, parametersMock); - } - private static List> createTagAndNodeRefPairs(final List tagNames) { return tagNames.stream() .map(tagName -> createPair(tagName, new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(tagName)))) - .collect(toList()); + .collect(Collectors.toList()); } private static Pair createPair(final String tagName, final NodeRef nodeRef) @@ -493,12 +426,12 @@ public class TagsImplTest private static List createTags(final List tagNames) { - return tagNames.stream().map(TagsImplTest::createTag).collect(toList()); + return tagNames.stream().map(TagsImplTest::createTag).collect(Collectors.toList()); } private static List createTagsWithNodeRefs(final List tagNames) { - return tagNames.stream().map(TagsImplTest::createTagWithNodeRef).collect(toList()); + return tagNames.stream().map(TagsImplTest::createTagWithNodeRef).collect(Collectors.toList()); } private static Tag createTag(final String tagName) From 219acd6c53b4af5cd4594fcba6beaf5bc44bc727 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 24 Mar 2023 08:21:11 +0000 Subject: [PATCH 06/16] Revert "Revert "ACS-4863 Allow referencing nodes by aliases for tag and category application. (#1822)"" This reverts commit 70b7d5a1f884300437d815ccaf4cd1d604512fb4. --- .../rest/api/impl/CategoriesImpl.java | 6 +- .../org/alfresco/rest/api/impl/TagsImpl.java | 83 ++++++++---------- .../rest/api/impl/CategoriesImplTest.java | 20 ++--- .../alfresco/rest/api/impl/TagsImplTest.java | 87 ++++++++++++++++--- 4 files changed, 125 insertions(+), 71 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java index e78f7856d4..7023d2625b 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/CategoriesImpl.java @@ -189,7 +189,7 @@ public class CategoriesImpl implements Categories @Override public List listCategoriesForNode(final String nodeId, final Parameters parameters) { - final NodeRef contentNodeRef = nodes.validateNode(nodeId); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); verifyReadPermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -211,7 +211,7 @@ public class CategoriesImpl implements Categories throw new InvalidArgumentException(NOT_A_VALID_CATEGORY); } - final NodeRef contentNodeRef = nodes.validateNode(nodeId); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); @@ -237,7 +237,7 @@ public class CategoriesImpl implements Categories public void unlinkNodeFromCategory(final StoreRef storeRef, final String nodeId, final String categoryId, final Parameters parameters) { final NodeRef categoryNodeRef = getCategoryNodeRef(storeRef, categoryId); - final NodeRef contentNodeRef = nodes.validateNode(nodeId); + final NodeRef contentNodeRef = nodes.validateOrLookupNode(nodeId, null); verifyChangePermission(contentNodeRef); verifyNodeType(contentNodeRef); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java index e6fec46b07..d703b86262 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/TagsImpl.java @@ -25,11 +25,12 @@ */ package org.alfresco.rest.api.impl; +import static java.util.stream.Collectors.toList; + import static org.alfresco.rest.antlr.WhereClauseParser.EQUALS; import static org.alfresco.rest.antlr.WhereClauseParser.IN; import static org.alfresco.rest.antlr.WhereClauseParser.MATCHES; -import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -114,44 +115,30 @@ public class TagsImpl implements Tags this.authorityService = authorityService; } - public List addTags(String nodeId, final List tags) - { - NodeRef nodeRef = nodes.validateNode(nodeId); - if(!typeConstraint.matches(nodeRef)) - { - throw new UnsupportedResourceOperationException("Cannot tag this node"); - } + public List addTags(String nodeId, final List tags) + { + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + if (!typeConstraint.matches(nodeRef)) + { + throw new UnsupportedResourceOperationException("Cannot tag this node"); + } - List tagValues = new AbstractList() + List tagValues = tags.stream().map(Tag::getTag).collect(toList()); + try + { + List> tagNodeRefs = taggingService.addTags(nodeRef, tagValues); + List ret = new ArrayList<>(tags.size()); + for (Pair pair : tagNodeRefs) { - @Override - public String get(int arg0) - { - String tag = tags.get(arg0).getTag(); - return tag; - } - - @Override - public int size() - { - return tags.size(); - } - }; - try - { - List> tagNodeRefs = taggingService.addTags(nodeRef, tagValues); - List ret = new ArrayList(tags.size()); - for(Pair pair : tagNodeRefs) - { - ret.add(new Tag(pair.getSecond(), pair.getFirst())); - } - return ret; + ret.add(new Tag(pair.getSecond(), pair.getFirst())); } - catch(IllegalArgumentException e) - { - throw new InvalidArgumentException(e.getMessage()); - } - } + return ret; + } + catch (IllegalArgumentException e) + { + throw new InvalidArgumentException(e.getMessage()); + } + } public void deleteTag(String nodeId, String tagId) { @@ -254,17 +241,17 @@ public class TagsImpl implements Tags public CollectionWithPagingInfo getTags(String nodeId, Parameters params) { - NodeRef nodeRef = nodes.validateNode(nodeId); - PagingResults> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging())); - Integer totalItems = results.getTotalResultCount().getFirst(); - List> page = results.getPage(); - List tags = new ArrayList(page.size()); - for(Pair pair : page) - { - tags.add(new Tag(pair.getFirst(), pair.getSecond())); - } + NodeRef nodeRef = nodes.validateOrLookupNode(nodeId, null); + PagingResults> results = taggingService.getTags(nodeRef, Util.getPagingRequest(params.getPaging())); + Integer totalItems = results.getTotalResultCount().getFirst(); + List> page = results.getPage(); + List tags = new ArrayList<>(page.size()); + for(Pair pair : page) + { + tags.add(new Tag(pair.getFirst(), pair.getSecond())); + } - return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue())); + return CollectionWithPagingInfo.asPaged(params.getPaging(), tags, results.hasMoreItems(), (totalItems == null ? null : totalItems.intValue())); } @Experimental @@ -276,7 +263,7 @@ public class TagsImpl implements Tags .filter(Objects::nonNull) .map(Tag::getTag) .distinct() - .collect(Collectors.toList()); + .collect(toList()); if (CollectionUtils.isEmpty(tagNames)) { @@ -290,7 +277,7 @@ public class TagsImpl implements Tags { tag.setCount(0); } - }).collect(Collectors.toList()); + }).collect(toList()); } private void verifyAdminAuthority() diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java index 575f0cc0dc..1c7445cb6d 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/CategoriesImplTest.java @@ -128,7 +128,7 @@ public class CategoriesImplTest { given(authorityServiceMock.hasAdminAuthority()).willReturn(true); given(nodesMock.validateNode(CATEGORY_ID)).willReturn(CATEGORY_NODE_REF); - given(nodesMock.validateNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); given(nodesMock.isSubClass(any(), any(), anyBoolean())).willReturn(true); given(typeConstraint.matches(any())).willReturn(true); given(permissionServiceMock.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED); @@ -900,7 +900,7 @@ public class CategoriesImplTest // when final List actualLinkedCategories = objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, categoryLinks, parametersMock); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1011,12 +1011,12 @@ public class CategoriesImplTest @Test public void testLinkNodeToCategories_withInvalidNodeId() { - given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).shouldHaveNoInteractions(); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1031,7 +1031,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.linkNodeToCategories(CONTENT_NODE_ID, List.of(CATEGORY), parametersMock)); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) @@ -1118,7 +1118,7 @@ public class CategoriesImplTest objectUnderTest.unlinkNodeFromCategory(CONTENT_NODE_ID, CATEGORY_ID, parametersMock); then(nodesMock).should().validateNode(CATEGORY_ID); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).should().hasPermission(CONTENT_NODE_REF, PermissionService.CHANGE_PERMISSIONS); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1155,7 +1155,7 @@ public class CategoriesImplTest // when final List actualCategories = objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(permissionServiceMock).shouldHaveNoMoreInteractions(); then(typeConstraint).should().matches(CONTENT_NODE_REF); @@ -1176,12 +1176,12 @@ public class CategoriesImplTest @Test public void testListCategoriesForNode_withInvalidNodeId() { - given(nodesMock.validateNode(CONTENT_NODE_ID)).willThrow(EntityNotFoundException.class); + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(EntityNotFoundException.class); // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) .isInstanceOf(EntityNotFoundException.class); @@ -1195,7 +1195,7 @@ public class CategoriesImplTest // when final Throwable actualException = catchThrowable(() -> objectUnderTest.listCategoriesForNode(CONTENT_NODE_ID, parametersMock)); - then(nodesMock).should().validateNode(CONTENT_NODE_ID); + then(nodesMock).should().validateOrLookupNode(CONTENT_NODE_ID, null); then(permissionServiceMock).should().hasReadPermission(CONTENT_NODE_REF); then(nodeServiceMock).shouldHaveNoInteractions(); assertThat(actualException) diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java index 8b668abef1..f874db09e2 100644 --- a/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/TagsImplTest.java @@ -25,6 +25,8 @@ */ package org.alfresco.rest.api.impl; +import static java.util.stream.Collectors.toList; + import static org.alfresco.rest.api.impl.TagsImpl.NOT_A_VALID_TAG; import static org.alfresco.rest.api.impl.TagsImpl.NO_PERMISSION_TO_MANAGE_A_TAG; import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; @@ -41,7 +43,6 @@ import static org.mockito.BDDMockito.then; import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; @@ -50,6 +51,7 @@ import org.alfresco.rest.api.model.Tag; import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; +import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Paging; import org.alfresco.rest.framework.resource.parameters.Parameters; @@ -63,6 +65,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.util.Pair; +import org.alfresco.util.TypeConstraint; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -77,7 +80,9 @@ public class TagsImplTest private static final String PARENT_NODE_ID = "tag:tag-root"; private static final String TAG_NAME = "tag-dummy-name"; private static final NodeRef TAG_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(TAG_NAME)); - private static final NodeRef TAG_PARENT_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_NODE_ID); + private static final NodeRef TAG_PARENT_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, PARENT_NODE_ID); + private static final String CONTENT_NODE_ID = "content-node-id"; + private static final NodeRef CONTENT_NODE_REF = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, CONTENT_NODE_ID); private final RecognizedParamsExtractor queryExtractor = new RecognizedParamsExtractor() {}; @@ -97,6 +102,8 @@ public class TagsImplTest private Paging pagingMock; @Mock private PagingResults> pagingResultsMock; + @Mock + private TypeConstraint typeConstraintMock; @InjectMocks private TagsImpl objectUnderTest; @@ -122,7 +129,7 @@ public class TagsImplTest then(taggingServiceMock).should().getTags(eq(STORE_REF_WORKSPACE_SPACESSTORE), any(PagingRequest.class), isNull(), isNull()); then(taggingServiceMock).shouldHaveNoMoreInteractions(); - final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream().peek(tag -> tag.setCount(0)).collect(Collectors.toList()); + final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream().peek(tag -> tag.setCount(0)).collect(toList()); assertEquals(expectedTags, actualTags.getCollection()); } @@ -140,7 +147,7 @@ public class TagsImplTest then(taggingServiceMock).should().findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE); final List expectedTags = createTagsWithNodeRefs(List.of(TAG_NAME)).stream() .peek(tag -> tag.setCount(0)) - .collect(Collectors.toList()); + .collect(toList()); assertEquals(expectedTags, actualTags.getCollection()); } @@ -395,7 +402,7 @@ public class TagsImplTest final List expectedTags = createTagsWithNodeRefs(tagNames).stream() .peek(tag -> tag.setCount(0)) - .collect(Collectors.toList()); + .collect(toList()); assertThat(actualCreatedTags) .isNotNull() .isEqualTo(expectedTags); @@ -405,18 +412,78 @@ public class TagsImplTest public void testGetTagByIdNotFoundValidation() { given(primaryParentMock.getParentRef()).willReturn(TAG_NODE_REF); - objectUnderTest.getTag(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,TAG_ID); + objectUnderTest.getTag(STORE_REF_WORKSPACE_SPACESSTORE,TAG_ID); then(nodeServiceMock).shouldHaveNoInteractions(); - then(nodesMock).should().validateNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID); + then(nodesMock).should().validateNode(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID); then(nodesMock).shouldHaveNoMoreInteractions(); then(taggingServiceMock).shouldHaveNoInteractions(); } + @Test + public void testAddTags() + { + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(true); + List> pairs = List.of(new Pair<>("tagA", new NodeRef("tag://A/")), new Pair<>("tagB", new NodeRef("tag://B/"))); + List tagNames = pairs.stream().map(Pair::getFirst).collect(toList()); + List tags = tagNames.stream().map(name -> Tag.builder().tag(name).create()).collect(toList()); + given(taggingServiceMock.addTags(CONTENT_NODE_REF, tagNames)).willReturn(pairs); + + List actual = objectUnderTest.addTags(CONTENT_NODE_ID, tags); + + List expected = pairs.stream().map(pair -> new Tag(pair.getSecond(), pair.getFirst())).collect(toList()); + assertEquals("Unexpected tags returned.", expected, actual); + } + + @Test(expected = InvalidArgumentException.class) + public void testAddTagsToInvalidNode() + { + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); + List tags = List.of(Tag.builder().tag("tag1").create()); + + objectUnderTest.addTags(CONTENT_NODE_ID, tags); + } + + @Test(expected = UnsupportedResourceOperationException.class) + public void testAddTagsToWrongTypeOfNode() + { + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(false); + + List tags = List.of(Tag.builder().tag("tag1").create()); + + objectUnderTest.addTags(CONTENT_NODE_ID, tags); + } + + @Test + public void testGetTagsForNode() + { + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willReturn(CONTENT_NODE_REF); + given(parametersMock.getPaging()).willReturn(pagingMock); + List> pairs = List.of(new Pair<>(new NodeRef("tag://A/"), "tagA"), new Pair<>(new NodeRef("tag://B/"), "tagB")); + given(taggingServiceMock.getTags(eq(CONTENT_NODE_REF), any(PagingRequest.class))).willReturn(pagingResultsMock); + given(pagingResultsMock.getTotalResultCount()).willReturn(new Pair<>(null, null)); + given(pagingResultsMock.getPage()).willReturn(pairs); + + CollectionWithPagingInfo actual = objectUnderTest.getTags(CONTENT_NODE_ID, parametersMock); + + List tags = pairs.stream().map(pair -> Tag.builder().tag(pair.getSecond()).nodeRef(pair.getFirst()).create()).collect(toList()); + assertEquals(actual.getCollection(), tags); + } + + @Test (expected = InvalidArgumentException.class) + public void testGetTagsFromInvalidNode() + { + given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID, null)).willThrow(new InvalidArgumentException()); + + objectUnderTest.getTags(CONTENT_NODE_ID, parametersMock); + } + private static List> createTagAndNodeRefPairs(final List tagNames) { return tagNames.stream() .map(tagName -> createPair(tagName, new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID.concat("-").concat(tagName)))) - .collect(Collectors.toList()); + .collect(toList()); } private static Pair createPair(final String tagName, final NodeRef nodeRef) @@ -426,12 +493,12 @@ public class TagsImplTest private static List createTags(final List tagNames) { - return tagNames.stream().map(TagsImplTest::createTag).collect(Collectors.toList()); + return tagNames.stream().map(TagsImplTest::createTag).collect(toList()); } private static List createTagsWithNodeRefs(final List tagNames) { - return tagNames.stream().map(TagsImplTest::createTagWithNodeRef).collect(Collectors.toList()); + return tagNames.stream().map(TagsImplTest::createTagWithNodeRef).collect(toList()); } private static Tag createTag(final String tagName) From 9899f16d6164e9c70d9b1aff8fb2ca02009a7673 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:03:48 +0000 Subject: [PATCH 07/16] [maven-release-plugin][skip ci] prepare release 20.116 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 40ff317685..5932b9f1f8 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.116-SNAPSHOT + 20.116 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 8436aaf5ce..94f9b7c9c6 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.116-SNAPSHOT + 20.116 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index debc82aa9c..a6d743e978 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 8f717cb912..30b82c1d98 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.116-SNAPSHOT + 20.116 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 87e389eb5f..d3736db863 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.116-SNAPSHOT + 20.116 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index f9139988f4..ffcdeb28f4 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.116-SNAPSHOT + 20.116 diff --git a/amps/pom.xml b/amps/pom.xml index 9546ca05dc..012d0a36d8 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 0ad07c55ca..f8f0466d08 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.116-SNAPSHOT + 20.116 diff --git a/core/pom.xml b/core/pom.xml index fb5a07f5b6..e732c7b164 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/data-model/pom.xml b/data-model/pom.xml index f0af6a5b78..dfeb685daa 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/mmt/pom.xml b/mmt/pom.xml index 15f8d923d5..0743daed23 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 2b1196731c..f520bacb85 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index b1fc36c630..d3c4fdf131 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/pom.xml b/packaging/pom.xml index 2f06fb361b..d5aa7f161b 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index e16dfaff72..74cf01e382 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 346c2de3f2..b08976960c 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 2bb68cdfd7..bf559efbc5 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index cb0b84f113..708f2da396 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 68273db05d..3915b9a82e 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 9deb2d3125..3a34fb9204 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116-SNAPSHOT + 20.116 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 8b689082a4..2c2db8e066 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116-SNAPSHOT + 20.116 diff --git a/pom.xml b/pom.xml index 737710c127..1461ed67b3 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.116-SNAPSHOT + 20.116 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 20.116 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 107d304b8c..9b1e0c642e 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 diff --git a/repository/pom.xml b/repository/pom.xml index 5867188017..695784ef2b 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116-SNAPSHOT + 20.116 From 5769cbe54e670d04058260f8f414d13e0cc6351f Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:03:52 +0000 Subject: [PATCH 08/16] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 5932b9f1f8..98781b3f6b 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.116 + 20.117-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 94f9b7c9c6..d0bd3817e3 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.116 + 20.117-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index a6d743e978..14345c810e 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 30b82c1d98..3b39a4eaa7 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.116 + 20.117-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index d3736db863..d14798b0b4 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.116 + 20.117-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index ffcdeb28f4..1d6800ed5a 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.116 + 20.117-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index 012d0a36d8..e7953bdc40 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index f8f0466d08..0d6d28a04a 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.116 + 20.117-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index e732c7b164..56fa775ee4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index dfeb685daa..12777b0bcf 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 0743daed23..174ad64649 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index f520bacb85..3c803b1e8d 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index d3c4fdf131..b18c8b9949 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index d5aa7f161b..07b56a4104 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 74cf01e382..9f2a30111e 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index b08976960c..c3bba31f34 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index bf559efbc5..466e9b97e3 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 708f2da396..2b3ecef6a9 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 3915b9a82e..bc858b0b6c 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 3a34fb9204..098bfdcbac 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.116 + 20.117-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 2c2db8e066..333d8de3b5 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.116 + 20.117-SNAPSHOT diff --git a/pom.xml b/pom.xml index 1461ed67b3..7d68f64909 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.116 + 20.117-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 20.116 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 9b1e0c642e..4a70fc01bc 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index 695784ef2b..39ee8438b0 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.116 + 20.117-SNAPSHOT From ef089472fbb7d4054e0db87936eab4b1c3e98a50 Mon Sep 17 00:00:00 2001 From: Krystian Dabrowski <98942253+krdabrowski@users.noreply.github.com> Date: Fri, 24 Mar 2023 10:55:12 +0100 Subject: [PATCH 09/16] ACS-4915: Editing an orphaned tag results in the tag being deleted (#1823) * ACS-4915: Editing an orphaned tag results in the tag being deleted --- .../alfresco/rest/tags/UpdateTagTests.java | 27 +- .../repo/tagging/TaggingServiceImpl.java | 3216 ++++++++--------- .../tagging/TaggingServiceImplUnitTest.java | 80 +- 3 files changed, 1709 insertions(+), 1614 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/UpdateTagTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/UpdateTagTests.java index b450d3ee51..8bb303060c 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/UpdateTagTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/UpdateTagTests.java @@ -1,5 +1,7 @@ package org.alfresco.rest.tags; +import static org.alfresco.utility.report.log.Step.STEP; + import org.alfresco.rest.model.RestErrorModel; import org.alfresco.rest.model.RestTagModel; import org.alfresco.utility.Utility; @@ -41,6 +43,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(randomTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(randomTag); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, @@ -158,8 +161,8 @@ public class UpdateTagTests extends TagsDataPrep { String invalidTagBody = ".\"/<>*"; RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag")); - Utility.sleep(500, 20000, () -> - { + Utility.sleep(500, 20000, () -> + { restClient.withCoreAPI().usingTag(tag).update(invalidTagBody); restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST) .assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody)); @@ -178,6 +181,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(largeStringTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(largeStringTag); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, @@ -192,6 +196,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(shortStringTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(shortStringTag); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, @@ -206,6 +211,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(specialCharsString); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(specialCharsString); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, @@ -223,6 +229,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(oldExistingTag).update(existingTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(existingTag); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, @@ -242,6 +249,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.withCoreAPI().usingTag(newTagModel).update(newTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(newTag); + returnedModel.assertThat().field("id").isNotNull(); } @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, @@ -255,6 +263,7 @@ public class UpdateTagTests extends TagsDataPrep returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(oldTag).update(newTag); restClient.assertStatusCodeIs(HttpStatus.OK); returnedModel.assertThat().field("tag").is(newTag); + returnedModel.assertThat().field("id").isNotNull(); restClient.withCoreAPI().usingResource(document).deleteTag(returnedModel); restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT); @@ -262,4 +271,18 @@ public class UpdateTagTests extends TagsDataPrep restClient.withCoreAPI().usingResource(document).addTag(newTag); restClient.assertStatusCodeIs(HttpStatus.CREATED); } + + @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, + description = "Verify Admin user updates orphan tags and status code is 200") + @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY }) + public void adminIsAbleToUpdateOrphanTag() + { + STEP("Update orphan tag and expect 200"); + final String newTagName = RandomData.getRandomName("new"); + returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(orphanTag).update(newTagName); + + restClient.assertStatusCodeIs(HttpStatus.OK); + returnedModel.assertThat().field("tag").is(newTagName); + returnedModel.assertThat().field("id").isNotNull(); + } } \ No newline at end of file diff --git a/repository/src/main/java/org/alfresco/repo/tagging/TaggingServiceImpl.java b/repository/src/main/java/org/alfresco/repo/tagging/TaggingServiceImpl.java index 29fac1fe33..6cbb7d2cca 100644 --- a/repository/src/main/java/org/alfresco/repo/tagging/TaggingServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/tagging/TaggingServiceImpl.java @@ -1,1608 +1,1608 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2023 Alfresco Software Limited - * %% - * This file is part of the Alfresco software. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * 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 . - * #L% - */ -package org.alfresco.repo.tagging; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.text.Collator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.alfresco.model.ContentModel; -import org.alfresco.query.EmptyPagingResults; -import org.alfresco.query.PagingRequest; -import org.alfresco.query.PagingResults; -import org.alfresco.repo.audit.AuditComponent; -import org.alfresco.repo.coci.CheckOutCheckInServicePolicies; -import org.alfresco.repo.copy.CopyServicePolicies; -import org.alfresco.repo.copy.CopyServicePolicies.BeforeCopyPolicy; -import org.alfresco.repo.copy.CopyServicePolicies.OnCopyCompletePolicy; -import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy; -import org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy; -import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy; -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.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.TransactionListener; -import org.alfresco.service.Experimental; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.CategoryService; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchParameters; -import org.alfresco.service.cmr.search.SearchParameters.FieldFacet; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.tagging.TagDetails; -import org.alfresco.service.cmr.tagging.TagScope; -import org.alfresco.service.cmr.tagging.TaggingService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.ISO9075; -import org.alfresco.util.Pair; -import org.alfresco.util.ParameterCheck; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Tagging service implementation - * - * @author Roy Wetherall - */ -public class TaggingServiceImpl implements TaggingService, - TransactionListener, - NodeServicePolicies.BeforeDeleteNodePolicy, - NodeServicePolicies.OnMoveNodePolicy, - CopyServicePolicies.OnCopyCompletePolicy, - CopyServicePolicies.BeforeCopyPolicy -{ - protected static final String TAGGING_AUDIT_APPLICATION_NAME = "Alfresco Tagging Service"; - protected static final String TAGGING_AUDIT_ROOT_PATH = "/tagging"; - protected static final String TAGGING_AUDIT_KEY_NODEREF = "node"; - protected static final String TAGGING_AUDIT_KEY_TAGS = "tags"; - - private static Log logger = LogFactory.getLog(TaggingServiceImpl.class); - - private static Collator collator = Collator.getInstance(); - - private NodeService nodeService; - private NodeService nodeServiceInternal; - private CategoryService categoryService; - private SearchService searchService; - private ActionService actionService; - private ContentService contentService; - private NamespaceService namespaceService; - private PolicyComponent policyComponent; - private AuditComponent auditComponent; - - /** Tag Details Delimiter */ - private static final String TAG_DETAILS_DELIMITER = "|"; - /** Next tag delimiter */ - private static final String NEXT_TAG_DELIMITER = "\n"; - - private static Set FORBIDDEN_TAGS_SEQUENCES = new HashSet(Arrays.asList(new String[] {NEXT_TAG_DELIMITER, TAG_DETAILS_DELIMITER})); - - /** Policy behaviour */ - private JavaBehaviour updateTagBehaviour; - private JavaBehaviour createTagBehaviour; - - /** - * Set the cateogry service - */ - public void setCategoryService(CategoryService categoryService) - { - this.categoryService = categoryService; - } - - /** - * Set the node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param nodeServiceInternal service to use when permission checks are not required - */ - public void setNodeServiceInternal(NodeService nodeServiceInternal) - { - this.nodeServiceInternal = nodeServiceInternal; - } - - /** - * Set the search service - */ - public void setSearchService(SearchService searchService) - { - this.searchService = searchService; - } - - /** - * Set the action service - */ - public void setActionService(ActionService actionService) - { - this.actionService = actionService; - } - - /** - * Set the content service - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - /** - * Set the namespace service - */ - public void setNamespaceService(NamespaceService namespaceService) - { - this.namespaceService = namespaceService; - } - - /** - * Policy component - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; - } - - /** - * Set the audit component - */ - public void setAuditComponent(AuditComponent auditComponent) - { - this.auditComponent = auditComponent; - } - - /** - * Init method - */ - public void init() - { - // Register policy behaviours - this.policyComponent.bindClassBehaviour( - QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), - ContentModel.ASPECT_TAGGABLE, - new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.EVERY_EVENT)); - - // Create tag behaviour - createTagBehaviour = new JavaBehaviour(this, "createTags", NotificationFrequency.FIRST_EVENT); - this.policyComponent.bindClassBehaviour( - OnCreateNodePolicy.QNAME, - ContentModel.ASPECT_TAGGABLE, - createTagBehaviour); - - // We need to register on content and folders, rather than - // tagable, so we can pick up when things start and - // stop being tagged - updateTagBehaviour = new JavaBehaviour(this, "updateTags", NotificationFrequency.EVERY_EVENT); - this.policyComponent.bindClassBehaviour( - OnUpdatePropertiesPolicy.QNAME, - ContentModel.TYPE_CONTENT, - updateTagBehaviour); - this.policyComponent.bindClassBehaviour( - OnUpdatePropertiesPolicy.QNAME, - ContentModel.TYPE_FOLDER, - updateTagBehaviour); - - // We need to know when you move or copy nodes - this.policyComponent.bindClassBehaviour( - OnMoveNodePolicy.QNAME, - ContentModel.ASPECT_TAGGABLE, - new JavaBehaviour(this, "onMoveNode", NotificationFrequency.EVERY_EVENT)); - this.policyComponent.bindClassBehaviour( - BeforeCopyPolicy.QNAME, - ContentModel.ASPECT_TAGGABLE, - new JavaBehaviour(this, "beforeCopy", NotificationFrequency.EVERY_EVENT)); - this.policyComponent.bindClassBehaviour( - OnCopyCompletePolicy.QNAME, - ContentModel.ASPECT_TAGGABLE, - new JavaBehaviour(this, "onCopyComplete", NotificationFrequency.EVERY_EVENT)); - - this.policyComponent.bindClassBehaviour( - CheckOutCheckInServicePolicies.OnCheckOut.QNAME, - ContentModel.ASPECT_TAGGABLE, - new JavaBehaviour(this, "afterCheckOut", NotificationFrequency.EVERY_EVENT)); - } - - /** - * Called after a copy / delete / move, to trigger a - * tag scope update of all the tags on the node. - * Will update all parent tag scopes for the node, by either - * adding or removing all tags from the node (based on the - * isAdd parameter). - */ - private void updateAllScopeTags(NodeRef nodeRef, Boolean isAdd) - { - ChildAssociationRef assocRef = this.nodeService.getPrimaryParent(nodeRef); - if (assocRef != null) - { - updateAllScopeTags(nodeRef, assocRef.getParentRef(), isAdd); - } - } - @SuppressWarnings("unchecked") - private void updateAllScopeTags(NodeRef nodeRef, NodeRef parentNodeRef, Boolean isAdd) - { - if (parentNodeRef != null) - { - // Grab an currently pending changes for this node - Map> allQueuedUpdates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); - Map nodeQueuedUpdates = null; - if (allQueuedUpdates != null) - { - nodeQueuedUpdates = allQueuedUpdates.get(nodeRef); - } - - // Record the changes for the node, cancelling out existing - // changes if needed - List tags = getTags(nodeRef); - Map tagUpdates = new HashMap(tags.size()); - for (String tag : tags) - { - tagUpdates.put(tag, isAdd); - - if (nodeQueuedUpdates != null) - { - Boolean queuedOp = (Boolean)nodeQueuedUpdates.get(tag); - if ((queuedOp != null) && (queuedOp.booleanValue() == isAdd.booleanValue())) - { - // dequeue - will be handled synchronously - nodeQueuedUpdates.remove(tag); - } - } - } - - // Find the parent tag scopes and update them - updateTagScope(parentNodeRef, tagUpdates); - } - } - - /** - * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef) - */ - public void beforeDeleteNode(NodeRef nodeRef) - { - if (this.nodeService.exists(nodeRef) == true && - this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true && !this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY)) - { - updateAllScopeTags(nodeRef, Boolean.FALSE); - } - } - - /** - * Fired once per node, before a copy overrides one node (which is possibly newly created) with the contents - * of another one. - * We should remove any tags from the scope, as they'll shortly be overwritten. - */ - public void beforeCopy(QName classRef, NodeRef sourceNodeRef, NodeRef targetNodeRef) - { - if (this.nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_TAGGABLE)) - { - updateAllScopeTags(targetNodeRef, Boolean.FALSE); - } - } - - /** - * Fired once per node that was copied, after the copy has completed. - * We need to add in all the tags to the scope. - */ - public void onCopyComplete(QName classRef, NodeRef sourceNodeRef, NodeRef targetNodeRef, boolean copyToNewNode, - Map copyMap) - { - if (this.nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_TAGGABLE)) - { - updateAllScopeTags(targetNodeRef, Boolean.TRUE); - } - } - - public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) - { - NodeRef oldRef = oldChildAssocRef.getChildRef(); - NodeRef oldParent = oldChildAssocRef.getParentRef(); - NodeRef newRef = newChildAssocRef.getChildRef(); - NodeRef newParent = newChildAssocRef.getParentRef(); - - // Do nothing if it's a "rename" not a move - if (oldParent.equals(newParent)) - { - return; - } - - // It has moved somewhere - // Remove the tags from the old location - if (this.nodeService.hasAspect(oldRef, ContentModel.ASPECT_TAGGABLE)) - { - // Use the parent we were passed in, rather than re-fetching - // via the node, as we need to reference the old scope! - ChildAssociationRef scopeParent; - if (oldChildAssocRef.isPrimary()) - { - scopeParent = oldChildAssocRef; - } - else - { - scopeParent = this.nodeService.getPrimaryParent(oldParent); - } - if (scopeParent != null) - { - updateAllScopeTags(oldRef, scopeParent.getParentRef(), Boolean.FALSE); - } - } - // Add the tags at its new location - if (this.nodeService.hasAspect(newRef, ContentModel.ASPECT_TAGGABLE)) - { - updateAllScopeTags(newRef, Boolean.TRUE); - } - } - - public void createTags(ChildAssociationRef childAssocRef) - { - NodeRef nodeRef = childAssocRef.getChildRef(); - Map before = new HashMap(0); - Map after = nodeService.getProperties(nodeRef); - - updateTags(nodeRef, before, after); - } - - /** - * Update tag policy behaviour - */ - @SuppressWarnings("unchecked") - public void updateTags(NodeRef nodeRef, Map before, Map after) - { - List beforeNodeRefs = (List)before.get(ContentModel.PROP_TAGS); - List afterNodeRefs = (List)after.get(ContentModel.PROP_TAGS); - - if (beforeNodeRefs == null && afterNodeRefs != null) - { - // Queue all the after's for addition to the tag scopes - for (NodeRef afterNodeRef : afterNodeRefs) - { - String tagName = getTagName(afterNodeRef); - queueTagUpdate(nodeRef, tagName, true); - } - } - else if (afterNodeRefs == null && beforeNodeRefs != null) - { - // Queue all the before's for removal to the tag scope - for (NodeRef beforeNodeRef : beforeNodeRefs) - { - // Protect against InvalidNodeRefException(MNT-14453) - if (this.nodeService.exists(beforeNodeRef)) - { - String tagName = getTagName(beforeNodeRef); - queueTagUpdate(nodeRef, tagName, false); - } - } - } - else if (afterNodeRefs != null && beforeNodeRefs != null) - { - //Create a copy of the afterNodeRefs so we don't affect the properties we were given - afterNodeRefs = new ArrayList(afterNodeRefs); - for (NodeRef beforeNodeRef : beforeNodeRefs) - { - if (afterNodeRefs.contains(beforeNodeRef) == true) - { - // remove the node ref from the after list - afterNodeRefs.remove(beforeNodeRef); - } - // Protect against InvalidNodeRefException(MNT-14453) - else if (this.nodeService.exists(beforeNodeRef)) - { - String tagName = getTagName(beforeNodeRef); - queueTagUpdate(nodeRef, tagName, false); - } - } - for (NodeRef afterNodeRef : afterNodeRefs) - { - String tagName = getTagName(afterNodeRef); - queueTagUpdate(nodeRef, tagName, true); - } - } - } - - public String getTagName(NodeRef nodeRef) - { - return (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#isTag(StoreRef, java.lang.String) - */ - public boolean isTag(StoreRef storeRef, String tag) - { - // Lower the case of the tag - return (getTagNodeRef(storeRef, tag.toLowerCase()) != null); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#createTag(StoreRef, java.lang.String) - */ - public NodeRef createTag(StoreRef storeRef, String tag) - { - // Lower the case of the tag - tag = tag.toLowerCase(); - - return getTagNodeRef(storeRef, tag, true); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#deleteTag(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) - */ - public void deleteTag(StoreRef storeRef, String tag) - { - // Lower the case of the tag - tag = tag.toLowerCase(); - - // Find nodes which are tagged with the 'soon to be deleted' tag. - List 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) - { - this.categoryService.deleteCategory(tagNodeRef); - } - } - - public NodeRef changeTag(StoreRef storeRef, String existingTag, String newTag) - { - if(existingTag == null) - { - throw new TaggingException("Existing tag cannot be null"); - } - - if(newTag == null) - { - throw new TaggingException("New tag cannot be null"); - } - - if(existingTag.equals(newTag)) - { - throw new TaggingException("New and existing tags are the same"); - } - - if(getTagNodeRef(storeRef, existingTag) == null) - { - throw new NonExistentTagException("Tag " + existingTag + " not found"); - } - - if(getTagNodeRef(storeRef, newTag) != null) - { - throw new TagExistsException("Tag " + newTag + " already exists"); - } - - List taggedNodes = findTaggedNodes(storeRef, existingTag); - for(NodeRef nodeRef : taggedNodes) - { - removeTag(nodeRef, existingTag); - addTag(nodeRef, newTag); - } - - deleteTag(storeRef, existingTag); - - return getTagNodeRef(storeRef, newTag); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(StoreRef) - */ - public List getTags(StoreRef storeRef) - { - ParameterCheck.mandatory("storeRef", storeRef); - - Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); - List result = new ArrayList(rootCategories.size()); - for (ChildAssociationRef rootCategory : rootCategories) - { - String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); - result.add(name); - } - return result; - } - - public Pair, Integer> getPagedTags(StoreRef storeRef, int fromTag, int pageSize) - { - ParameterCheck.mandatory("storeRef", storeRef); - ParameterCheck.mandatory("fromTag", fromTag); - ParameterCheck.mandatory("pageSize", pageSize); - - Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); - - final int totalCount = rootCategories.size(); - final int startIndex = Math.max(fromTag, 0); - final int endIndex = Math.min(fromTag + pageSize, totalCount); - List result = new ArrayList(pageSize); - int index = 0; - // paging for not sorted tag names - for (ChildAssociationRef rootCategory : rootCategories) - { - if (startIndex > index++) - { - continue; - } - String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); - result.add(name); - if (index == endIndex) - { - break; - } - } - return new Pair, Integer> (result, totalCount); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) - */ - public List getTags(StoreRef storeRef, String filter) - { - ParameterCheck.mandatory("storeRef", storeRef); - - List result = null; - if (filter == null || filter.length() == 0) - { - result = getTags(storeRef); - } - else - { - Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); - result = new ArrayList(rootCategories.size()); - for (ChildAssociationRef rootCategory : rootCategories) - { - String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); - if (name.contains(filter.toLowerCase()) == true) - { - result.add(name); - } - } - } - - return result; - } - - public Pair, Integer> getPagedTags(StoreRef storeRef, String filter, int fromTag, int pageSize) - { - ParameterCheck.mandatory("storeRef", storeRef); - ParameterCheck.mandatory("fromTag", fromTag); - ParameterCheck.mandatory("pageSize", pageSize); - - if (filter == null || filter.length() == 0) - { - return getPagedTags(storeRef, fromTag, pageSize); - } - else - { - Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, filter); - - final int totalCount = rootCategories.size(); - final int startIndex = Math.max(fromTag, 0); - final int endIndex = Math.min(fromTag + pageSize, totalCount); - List result = new ArrayList(pageSize); - int index = 0; - // paging for not sorted tag names - for (ChildAssociationRef rootCategory : rootCategories) - { - if (startIndex > index++) - { - continue; - } - String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); - result.add(name); - if (index == endIndex) - { - break; - } - } - return new Pair, Integer> (result, totalCount); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#hasTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) - */ - public boolean hasTag(NodeRef nodeRef, String tag) - { - List tags = getTags(nodeRef); - return (tags.contains(tag.toLowerCase())); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#addTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) - */ - @SuppressWarnings("unchecked") - public NodeRef addTag(final NodeRef nodeRef, final String tagName) - { - NodeRef newTagNodeRef = null; - - if(tagName == null) - { - throw new IllegalArgumentException("Must provide a non-null tag"); - } - - updateTagBehaviour.disable(); - createTagBehaviour.disable(); - try - { - // Lower the case of the tag - String tag = tagName.toLowerCase(); - - // Get the tag node reference - newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag, true); - - List tagNodeRefs = new ArrayList(5); - if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == false) - { - // Add the aspect - nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGGABLE, null); - } - else - { - // Get the current tags - List currentTagNodes = (List)nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); - if (currentTagNodes != null) - { - tagNodeRefs = currentTagNodes; - } - } - - // Add the new tag (assuming it's not already been added - if (tagNodeRefs.contains(newTagNodeRef) == false) - { - tagNodeRefs.add(newTagNodeRef); - nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)tagNodeRefs); - queueTagUpdate(nodeRef, tag, true); - } - } - finally - { - updateTagBehaviour.enable(); - createTagBehaviour.enable(); - } - - return newTagNodeRef; - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#addTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) - */ - public List> addTags(NodeRef nodeRef, List tags) - { - List> ret = new ArrayList>(); - for (String tag : tags) - { - NodeRef tagNodeRef = addTag(nodeRef, tag); - ret.add(new Pair(tag, tagNodeRef)); - } - return ret; - } - - /** - * Gets the node reference for a given tag. - *

- * Returns null if tag is not present. - * - * @param storeRef store reference - * @param tag tag - * @return NodeRef tag node reference or null not exist - */ - public NodeRef getTagNodeRef(StoreRef storeRef, String tag) - { - return getTagNodeRef(storeRef, tag, false); - } - - /** - * Gets the node reference for a given tag. - *

- * Returns null if tag is not present and not created. - * - * @param storeRef store reference - * @param tag tag - * @param create create a node if one doesn't exist? - * @return NodeRef tag node reference or null not exist - */ - private NodeRef getTagNodeRef(StoreRef storeRef, String tag, boolean create) - { - for (String forbiddenSequence : FORBIDDEN_TAGS_SEQUENCES) - { - if (create && tag.contains(forbiddenSequence)) - { - throw new IllegalArgumentException("Tag name must not contain " + StringEscapeUtils.escapeJava(forbiddenSequence) + " char sequence"); - } - } - - NodeRef tagNodeRef = null; - Collection results = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, tag, create); - if (!results.isEmpty()) - { - tagNodeRef = results.iterator().next().getChildRef(); - } - return tagNodeRef; - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#removeTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) - */ - @SuppressWarnings("unchecked") - public void removeTag(NodeRef nodeRef, String tag) - { - updateTagBehaviour.disable(); - createTagBehaviour.disable(); - try - { - // Lower the case of the tag - tag = tag.toLowerCase(); - - // Check for the taggable aspect - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) - { - // Get the tag node reference - NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag); - if (newTagNodeRef != null) - { - // Get the current tags - List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); - if (currentTagNodes != null && - currentTagNodes.size() != 0 && - currentTagNodes.contains(newTagNodeRef) == true) - { - currentTagNodes.remove(newTagNodeRef); - this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)currentTagNodes); - queueTagUpdate(nodeRef, tag, false); - } - } - } - } - finally - { - updateTagBehaviour.enable(); - createTagBehaviour.enable(); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#removeTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) - */ - public void removeTags(NodeRef nodeRef, List tags) - { - for (String tag : tags) - { - removeTag(nodeRef, tag); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.query.PagingRequest) - */ - @SuppressWarnings("unchecked") - // TODO canned query - public PagingResults> getTags(NodeRef nodeRef, PagingRequest pagingRequest) - { - // Check for the taggable aspect - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) - { - // Get the current tags - List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); - if (currentTagNodes != null) - { - final int totalItems = currentTagNodes.size(); - int skipCount = pagingRequest.getSkipCount(); - int maxItems = pagingRequest.getMaxItems(); - int end = maxItems == Integer.MAX_VALUE ? totalItems : skipCount + maxItems; - int size = (maxItems == Integer.MAX_VALUE ? totalItems : maxItems); - - final List> sortedTags = new ArrayList>(size); - // grab all tags and sort (assume fairly low number of tags) - for(NodeRef tagNode : currentTagNodes) - { - String tag = (String)this.nodeService.getProperty(tagNode, ContentModel.PROP_NAME); - sortedTags.add(new Pair(tagNode, tag)); - } - Collections.sort(sortedTags, new Comparator>() - { - @Override - public int compare(Pair o1, Pair o2) - { - String tag1 = o1.getSecond(); - String tag2 = o2.getSecond(); - return collator.compare(tag1, tag2); - } - }); - - final List> result = new ArrayList>(size); - Iterator> it = sortedTags.iterator(); - for(int count = 0; count < end && it.hasNext(); count++) - { - Pair tagPair = it.next(); - - if(count < skipCount) - { - continue; - } - - result.add(tagPair); - } - currentTagNodes = null; - final boolean hasMoreItems = end < totalItems; - - return new PagingResults>() - { - @Override - public List> getPage() - { - return result; - } - - @Override - public boolean hasMoreItems() - { - return hasMoreItems; - } - - @Override - public Pair getTotalResultCount() - { - Integer total = Integer.valueOf(totalItems); - return new Pair(total, total); - } - - @Override - public String getQueryExecutionId() - { - return null; - } - }; - } - } - - return new EmptyPagingResults>(); - } - - public PagingResults> getTags(StoreRef storeRef, PagingRequest pagingRequest) - { - return getTags(storeRef, pagingRequest, null, null); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, org.alfresco.query.PagingRequest) - */ - public PagingResults> getTags(StoreRef storeRef, PagingRequest pagingRequest, Collection exactNamesFilter, Collection alikeNamesFilter) - { - ParameterCheck.mandatory("storeRef", storeRef); - - PagingResults rootCategories = categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, pagingRequest, true, - exactNamesFilter, alikeNamesFilter); - - return mapPagingResult(rootCategories, - (childAssociation) -> new Pair<>(childAssociation.getChildRef(), childAssociation.getQName().getLocalName())); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef) - */ - @SuppressWarnings("unchecked") - public List getTags(NodeRef nodeRef) - { - List result = new ArrayList(10); - - // Check for the taggable aspect - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) - { - // Get the current tags - List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); - if (currentTagNodes != null) - { - for (NodeRef currentTagNode : currentTagNodes) - { - String tag = (String)this.nodeService.getProperty(currentTagNode, ContentModel.PROP_NAME); - result.add(tag); - } - } - } - - return result; - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#setTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) - */ - public void setTags(NodeRef nodeRef, List tags) - { - updateTagBehaviour.disable(); - createTagBehaviour.disable(); - try - { - List tagNodeRefs = new ArrayList(tags.size()); - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == false) - { - // Add the aspect - this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGGABLE, null); - } - - // Get the current list of tags - List oldTags = getTags(nodeRef); - - for (String tag : tags) - { - // Lower the case of the tag - tag = tag.toLowerCase(); - - // Get the tag node reference - NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag, true); - - if (tagNodeRefs.contains(newTagNodeRef) == false) - { - // Add to the list - tagNodeRefs.add(newTagNodeRef); - - // Trigger scope update - if (oldTags.contains(tag) == false) - { - queueTagUpdate(nodeRef, tag, true); - } - else - { - // Remove the tag from the old list - oldTags.remove(tag); - } - } - } - - // Remove the old tags from the tag scope - for (String oldTag : oldTags) - { - queueTagUpdate(nodeRef, oldTag, false); - } - - // Update category property - this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)tagNodeRefs); - } - finally - { - updateTagBehaviour.enable(); - createTagBehaviour.enable(); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#clearTags(org.alfresco.service.cmr.repository.NodeRef) - */ - public void clearTags(NodeRef nodeRef) - { - setTags(nodeRef, Collections.emptyList()); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#isTagScope(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean isTagScope(NodeRef nodeRef) - { - // Determines whether the node has the tag scope aspect - return this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE); - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#addTagScope(org.alfresco.service.cmr.repository.NodeRef) - */ - public void addTagScope(NodeRef nodeRef) - { - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == false) - { - // Add the tag scope aspect - this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE, null); - - // Refresh the tag scope - refreshTagScope(nodeRef, false); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#refreshTagScope(org.alfresco.service.cmr.repository.NodeRef, boolean) - */ - public void refreshTagScope(NodeRef nodeRef, boolean async) - { - if (this.nodeService.exists(nodeRef) == true && - this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true) - { - Action action = this.actionService.createAction(RefreshTagScopeActionExecuter.NAME); - this.actionService.executeAction(action, nodeRef, false, async); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#removeTagScope(org.alfresco.service.cmr.repository.NodeRef) - */ - public void removeTagScope(NodeRef nodeRef) - { - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true) - { - this.nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findTagScope(org.alfresco.service.cmr.repository.NodeRef) - */ - public TagScope findTagScope(NodeRef nodeRef) - { - TagScope tagScope = null; - - if (this.nodeService.exists(nodeRef) == true) - { - List tagScopeNodeRefs = new ArrayList(3); - getTagScopes(nodeRef, tagScopeNodeRefs, true); - if (tagScopeNodeRefs.size() != 0) - { - tagScope = new TagScopeImpl(tagScopeNodeRefs.get(0), getTagDetails(tagScopeNodeRefs.get(0))); - } - } - - return tagScope; - } - - /** - * Gets the tag details list for a given tag scope node reference - * - * @param nodeRef tag scope node reference - * @return List ordered list of tag details for the tag scope - */ - private List getTagDetails(NodeRef nodeRef) - { - List tagDetails = new ArrayList(13); - ContentReader reader = this.contentService.getReader(nodeRef, ContentModel.PROP_TAGSCOPE_CACHE); - if (reader != null) - { - tagDetails = TaggingServiceImpl.readTagDetails(reader.getContentInputStream()); - } - return tagDetails; - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findAllTagScopes(org.alfresco.service.cmr.repository.NodeRef) - */ - public List findAllTagScopes(NodeRef nodeRef) - { - List result = null; - - if (this.nodeService.exists(nodeRef) == true) - { - List tagScopeNodeRefs = new ArrayList(3); - getTagScopes(nodeRef, tagScopeNodeRefs); - if (tagScopeNodeRefs.size() != 0) - { - result = new ArrayList(tagScopeNodeRefs.size()); - for (NodeRef tagScopeNodeRef : tagScopeNodeRefs) - { - result.add(new TagScopeImpl(tagScopeNodeRef, getTagDetails(tagScopeNodeRef))); - } - } - else - { - result = Collections.emptyList(); - } - } - - return result; - } - - /** - * Traverses up the node's primary parent placing ALL found tag scope's in a list. - *

- * - * @param nodeRef node reference - * @param tagScopes list of tag scopes - */ - private void getTagScopes(NodeRef nodeRef, List tagScopes) - { - getTagScopes(nodeRef, tagScopes, false); - } - - /** - * Traverses up the node's primary parent placing found tag scope's in a list. - *

- * If none are found then the list is empty. - * - * @param nodeRef node reference - * @param tagScopes list of tag scopes - * @param firstOnly true => only return first tag scope that is found - */ - private void getTagScopes(final NodeRef nodeRef, List tagScopes, boolean firstOnly) - { - Boolean hasAspect = AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public Boolean doWork() throws Exception - { - return new Boolean(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE)); - } - }, AuthenticationUtil.getSystemUserName()); - - if (Boolean.TRUE.equals(hasAspect) == true) - { - tagScopes.add(nodeRef); - if (firstOnly) - { - return; - } - } - - NodeRef parent = AuthenticationUtil.runAs(new RunAsWork() - { - @Override - public NodeRef doWork() throws Exception - { - NodeRef result = null; - ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); - if (assoc != null) - { - result = assoc.getParentRef(); - } - return result; - } - }, AuthenticationUtil.getSystemUserName()); - - if (parent != null) - { - getTagScopes(parent, tagScopes, firstOnly); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String) - */ - public List findTaggedNodes(StoreRef storeRef, String tag) - { - // Lower the case of the tag - tag = tag.toLowerCase(); - ResultSet resultSet= null; - - try - { - // Do the search for nodes - resultSet = this.searchService.query( - storeRef, - SearchService.LANGUAGE_LUCENE, - "+PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); - List nodeRefs = resultSet.getNodeRefs(); - return nodeRefs; - } - finally - { - if(resultSet != null) {resultSet.close();} - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String, org.alfresco.service.cmr.repository.NodeRef) - */ - public List findTaggedNodes(StoreRef storeRef, String tag, NodeRef nodeRef) - { - // Lower the case of the tag - tag = tag.toLowerCase(); - - // Get path - Path nodePath = this.nodeService.getPath(nodeRef); - String pathString = nodePath.toPrefixString(this.namespaceService); - ResultSet resultSet = null; - - try - { - // Do query - resultSet = this.searchService.query( - storeRef, - SearchService.LANGUAGE_LUCENE, - "+PATH:\"" + pathString + "//*\" +PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); - List nodeRefs = resultSet.getNodeRefs(); - return nodeRefs; - } - finally - { - if(resultSet != null) {resultSet.close();} - } - } - - /** - * Helper method that takes an input stream and converts it into a list of tag details - * - * @param is input stream - * @return List list of tag details - */ - /*package*/ static List readTagDetails(InputStream is) - { - List result = new ArrayList(25); - BufferedReader reader = null; - try - { - reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); - String nextLine = reader.readLine(); - while (nextLine != null) - { - String[] values = nextLine.split("\\" + TAG_DETAILS_DELIMITER); - if(values.length == 1) - { - if(logger.isDebugEnabled()) - { - logger.debug("No count for tag "+values[0]); - } - } - else if (values.length > 1) - { - try - { - result.add(new TagDetailsImpl(values[0], Integer.parseInt(values[1]))); - if(values.length > 2) - { - if(logger.isDebugEnabled()) - { - logger.debug("Ignoring extra guff for tag: " + values[0]); - } - } - } - catch(NumberFormatException nfe) - { - if(logger.isDebugEnabled()) - { - logger.debug("Invalid tag count for " + values[0] + "<"+values[1]+">"); - } - } - } - - nextLine = reader.readLine(); - } - } - catch (Exception exception) - { - logger.warn("Unable to read tag details", exception); - } - finally - { - try { reader.close(); } catch (Exception e) {} - } - - return result; - } - - /** - * Helper method to convert a list of tag details into a string. - * - * @param tagDetails list of tag details - * @return String string of tag details - */ - /*package*/ static String tagDetailsToString(List tagDetails) - { - StringBuffer result = new StringBuffer(255); - - boolean bFirst = true; - for (TagDetails details : tagDetails) - { - if (bFirst == false) - { - result.append(NEXT_TAG_DELIMITER); - } - else - { - bFirst = false; - } - - result.append(details.getName()); - result.append(TAG_DETAILS_DELIMITER); - result.append(details.getCount()); - } - - return result.toString(); - } - - // ===== Methods Dealing with TagScope Updates ==== // - - public static final String TAG_UPDATES = "tagUpdates"; - - /** - * Triggers an async update of all the relevant tag scopes when a tag is - * added or removed from a node. - * Uses the audit service as a persisted queue to hold the list of changes, - * and triggers an sync action to work on the entries in the queue for us. - * This should avoid contention problems and race conditions. - * - * @param nodeRef node reference - * @param updates Map - */ - private void updateTagScope(NodeRef nodeRef, Map updates) - { - // First up, locate all the tag scopes for this node - // (Need to do a recursive search up to the root) - ArrayList tagScopeNodeRefs = new ArrayList(3); - getTagScopes(nodeRef, tagScopeNodeRefs); - - if(tagScopeNodeRefs.size() == 0) - { - if(logger.isDebugEnabled()) - { - logger.debug("No tag scopes found for " + nodeRef + " so no scope updates needed"); - } - return; - } - - // Turn from tag+yes/no into tag+1/-1 - // (Later we may roll things up better to be tag+#/-#) - HashMap changes = new HashMap(updates.size()); - for(String tag : updates.keySet()) - { - int val = -1; - if(updates.get(tag)) - val = 1; - changes.put(tag, val); - } - - // Next, queue the updates for each tag scope - for(NodeRef tagScopeNode : tagScopeNodeRefs) - { - Map auditValues = new HashMap(); - auditValues.put(TAGGING_AUDIT_KEY_TAGS, changes); - auditValues.put(TAGGING_AUDIT_KEY_NODEREF, tagScopeNode.toString()); - auditComponent.recordAuditValues(TAGGING_AUDIT_ROOT_PATH, auditValues); - } - if(logger.isDebugEnabled()) - { - logger.debug("Queueing async tag scope updates to tag scopes " + tagScopeNodeRefs + " of " + changes); - } - - // Finally, trigger the action to process the updates - // This will happen asynchronously - Action action = this.actionService.createAction(UpdateTagScopesActionExecuter.NAME); - action.setParameterValue(UpdateTagScopesActionExecuter.PARAM_TAG_SCOPES, tagScopeNodeRefs); - this.actionService.executeAction(action, null, false, true); - } - - /** - * Records the fact that the given tag for the given node will need to - * be added or removed from its parent tags scopes. - * {@link #updateTagScope(NodeRef, Map)} will schedule the update - * to occur, and an async action will do it. - */ - @SuppressWarnings("unchecked") - private void queueTagUpdate(NodeRef nodeRef, String tag, boolean add) - { - // Get the updates map - Map> updates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); - if (updates == null) - { - updates = new HashMap>(10); - AlfrescoTransactionSupport.bindResource(TAG_UPDATES, updates); - AlfrescoTransactionSupport.bindListener(this); - } - - // Add the details of the update to the map - Map nodeDetails = updates.get(nodeRef); - if (nodeDetails == null) - { - nodeDetails = new HashMap(10); - nodeDetails.put(tag, Boolean.valueOf(add)); - updates.put(nodeRef, nodeDetails); - } - else - { - Boolean currentValue = nodeDetails.get(tag); - if (currentValue == null) - { - nodeDetails.put(tag, Boolean.valueOf(add)); - updates.put(nodeRef, nodeDetails); - } - else if (currentValue.booleanValue() != add) - { - // If the boolean value is different then the tag had been added and removed or - // removed and then added in the same transaction. In both cases the net change is none. - // So remove the entry in the update map - nodeDetails.remove(tag); - } - // Otherwise do nothing because we have already noted the update - } - - } - - // ===== Transaction Listener Callback Methods ===== // - - /** - * @see org.alfresco.repo.transaction.TransactionListener#afterCommit() - */ - public void afterCommit() - { - - } - - /** - * @see org.alfresco.repo.transaction.TransactionListener#afterRollback() - */ - public void afterRollback() - { - } - - /** - * @see org.alfresco.repo.transaction.TransactionListener#beforeCommit(boolean) - */ - @SuppressWarnings("unchecked") - public void beforeCommit(boolean readOnly) - { - Map> updates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); - if (updates != null) - { - for (NodeRef nodeRef : updates.keySet()) - { - Map tagUpdates = updates.get(nodeRef); - if (tagUpdates != null && tagUpdates.size() != 0) - { - // Anything can happen during the transaction - if (!nodeServiceInternal.exists(nodeRef)) - { - continue; - } - updateTagScope(nodeRef, tagUpdates); - } - } - } - } - - /** - * @see org.alfresco.repo.transaction.TransactionListener#beforeCompletion() - */ - public void beforeCompletion() - { - } - - /** - * @see org.alfresco.repo.transaction.TransactionListener#flush() - */ - public void flush() - { - } - - public void afterCheckOut(NodeRef workingCopy) - { - if (this.nodeService.exists(workingCopy) == true && this.nodeService.hasAspect(workingCopy, ContentModel.ASPECT_TAGGABLE) == true - && this.nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)) - { - updateAllScopeTags(workingCopy, Boolean.FALSE); - } - } - - /** - * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodesAndCountByTagName(StoreRef) - */ - @Override - public List> findTaggedNodesAndCountByTagName(StoreRef storeRef) - { - String queryTaggeble = "ASPECT:\"" + ContentModel.ASPECT_TAGGABLE + "\"" + "-ASPECT:\"" + ContentModel.ASPECT_WORKING_COPY + "\""; - SearchParameters sp = new SearchParameters(); - sp.setQuery(queryTaggeble); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.addStore(storeRef); - sp.addFieldFacet(new FieldFacet("TAG")); - - ResultSet resultSet = null; - try - { - // Do the search for nodes - resultSet = this.searchService.query(sp); - return resultSet.getFieldFacet("TAG"); - } - finally - { - if (resultSet != null) - { - resultSet.close(); - } - } - } - - @Experimental - @Override - public List> createTags(final StoreRef storeRef, final List tagNames) - { - updateTagBehaviour.disable(); - createTagBehaviour.disable(); - try - { - return tagNames.stream() - .map(String::toLowerCase) - .peek(tagName -> categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, tagName, false).stream() - .filter(association -> Objects.nonNull(association.getChildRef())) - .findAny() - .ifPresent(association -> { throw new DuplicateChildNodeNameException(association.getParentRef(), association.getTypeQName(), tagName, null); })) - .map(tagName -> new Pair<>(tagName, getTagNodeRef(storeRef, tagName, true))) - .collect(Collectors.toList()); - } - finally - { - updateTagBehaviour.enable(); - createTagBehaviour.enable(); - } - } - - private PagingResults mapPagingResult(final PagingResults pagingResults, final Function mapper) - { - return new PagingResults() - { - @Override - public List getPage() - { - return pagingResults.getPage().stream() - .map(mapper) - .collect(Collectors.toList()); - } - - @Override - public boolean hasMoreItems() - { - return pagingResults.hasMoreItems(); - } - - @Override - public Pair getTotalResultCount() - { - return pagingResults.getTotalResultCount(); - } - - @Override - public String getQueryExecutionId() - { - return pagingResults.getQueryExecutionId(); - } - }; - } -} +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2023 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * 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 . + * #L% + */ +package org.alfresco.repo.tagging; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.alfresco.model.ContentModel; +import org.alfresco.query.EmptyPagingResults; +import org.alfresco.query.PagingRequest; +import org.alfresco.query.PagingResults; +import org.alfresco.repo.audit.AuditComponent; +import org.alfresco.repo.coci.CheckOutCheckInServicePolicies; +import org.alfresco.repo.copy.CopyServicePolicies; +import org.alfresco.repo.copy.CopyServicePolicies.BeforeCopyPolicy; +import org.alfresco.repo.copy.CopyServicePolicies.OnCopyCompletePolicy; +import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy; +import org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy; +import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy; +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.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.TransactionListener; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Path; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.CategoryService; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchParameters.FieldFacet; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.tagging.TagDetails; +import org.alfresco.service.cmr.tagging.TagScope; +import org.alfresco.service.cmr.tagging.TaggingService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.ISO9075; +import org.alfresco.util.Pair; +import org.alfresco.util.ParameterCheck; +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Tagging service implementation + * + * @author Roy Wetherall + */ +public class TaggingServiceImpl implements TaggingService, + TransactionListener, + NodeServicePolicies.BeforeDeleteNodePolicy, + NodeServicePolicies.OnMoveNodePolicy, + CopyServicePolicies.OnCopyCompletePolicy, + CopyServicePolicies.BeforeCopyPolicy +{ + protected static final String TAGGING_AUDIT_APPLICATION_NAME = "Alfresco Tagging Service"; + protected static final String TAGGING_AUDIT_ROOT_PATH = "/tagging"; + protected static final String TAGGING_AUDIT_KEY_NODEREF = "node"; + protected static final String TAGGING_AUDIT_KEY_TAGS = "tags"; + + private static Log logger = LogFactory.getLog(TaggingServiceImpl.class); + + private static Collator collator = Collator.getInstance(); + + private NodeService nodeService; + private NodeService nodeServiceInternal; + private CategoryService categoryService; + private SearchService searchService; + private ActionService actionService; + private ContentService contentService; + private NamespaceService namespaceService; + private PolicyComponent policyComponent; + private AuditComponent auditComponent; + + /** Tag Details Delimiter */ + private static final String TAG_DETAILS_DELIMITER = "|"; + /** Next tag delimiter */ + private static final String NEXT_TAG_DELIMITER = "\n"; + + private static Set FORBIDDEN_TAGS_SEQUENCES = new HashSet(Arrays.asList(new String[] {NEXT_TAG_DELIMITER, TAG_DETAILS_DELIMITER})); + + /** Policy behaviour */ + private JavaBehaviour updateTagBehaviour; + private JavaBehaviour createTagBehaviour; + + /** + * Set the cateogry service + */ + public void setCategoryService(CategoryService categoryService) + { + this.categoryService = categoryService; + } + + /** + * Set the node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param nodeServiceInternal service to use when permission checks are not required + */ + public void setNodeServiceInternal(NodeService nodeServiceInternal) + { + this.nodeServiceInternal = nodeServiceInternal; + } + + /** + * Set the search service + */ + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + /** + * Set the action service + */ + public void setActionService(ActionService actionService) + { + this.actionService = actionService; + } + + /** + * Set the content service + */ + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + /** + * Set the namespace service + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + /** + * Policy component + */ + public void setPolicyComponent(PolicyComponent policyComponent) + { + this.policyComponent = policyComponent; + } + + /** + * Set the audit component + */ + public void setAuditComponent(AuditComponent auditComponent) + { + this.auditComponent = auditComponent; + } + + /** + * Init method + */ + public void init() + { + // Register policy behaviours + this.policyComponent.bindClassBehaviour( + QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), + ContentModel.ASPECT_TAGGABLE, + new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.EVERY_EVENT)); + + // Create tag behaviour + createTagBehaviour = new JavaBehaviour(this, "createTags", NotificationFrequency.FIRST_EVENT); + this.policyComponent.bindClassBehaviour( + OnCreateNodePolicy.QNAME, + ContentModel.ASPECT_TAGGABLE, + createTagBehaviour); + + // We need to register on content and folders, rather than + // tagable, so we can pick up when things start and + // stop being tagged + updateTagBehaviour = new JavaBehaviour(this, "updateTags", NotificationFrequency.EVERY_EVENT); + this.policyComponent.bindClassBehaviour( + OnUpdatePropertiesPolicy.QNAME, + ContentModel.TYPE_CONTENT, + updateTagBehaviour); + this.policyComponent.bindClassBehaviour( + OnUpdatePropertiesPolicy.QNAME, + ContentModel.TYPE_FOLDER, + updateTagBehaviour); + + // We need to know when you move or copy nodes + this.policyComponent.bindClassBehaviour( + OnMoveNodePolicy.QNAME, + ContentModel.ASPECT_TAGGABLE, + new JavaBehaviour(this, "onMoveNode", NotificationFrequency.EVERY_EVENT)); + this.policyComponent.bindClassBehaviour( + BeforeCopyPolicy.QNAME, + ContentModel.ASPECT_TAGGABLE, + new JavaBehaviour(this, "beforeCopy", NotificationFrequency.EVERY_EVENT)); + this.policyComponent.bindClassBehaviour( + OnCopyCompletePolicy.QNAME, + ContentModel.ASPECT_TAGGABLE, + new JavaBehaviour(this, "onCopyComplete", NotificationFrequency.EVERY_EVENT)); + + this.policyComponent.bindClassBehaviour( + CheckOutCheckInServicePolicies.OnCheckOut.QNAME, + ContentModel.ASPECT_TAGGABLE, + new JavaBehaviour(this, "afterCheckOut", NotificationFrequency.EVERY_EVENT)); + } + + /** + * Called after a copy / delete / move, to trigger a + * tag scope update of all the tags on the node. + * Will update all parent tag scopes for the node, by either + * adding or removing all tags from the node (based on the + * isAdd parameter). + */ + private void updateAllScopeTags(NodeRef nodeRef, Boolean isAdd) + { + ChildAssociationRef assocRef = this.nodeService.getPrimaryParent(nodeRef); + if (assocRef != null) + { + updateAllScopeTags(nodeRef, assocRef.getParentRef(), isAdd); + } + } + @SuppressWarnings("unchecked") + private void updateAllScopeTags(NodeRef nodeRef, NodeRef parentNodeRef, Boolean isAdd) + { + if (parentNodeRef != null) + { + // Grab an currently pending changes for this node + Map> allQueuedUpdates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); + Map nodeQueuedUpdates = null; + if (allQueuedUpdates != null) + { + nodeQueuedUpdates = allQueuedUpdates.get(nodeRef); + } + + // Record the changes for the node, cancelling out existing + // changes if needed + List tags = getTags(nodeRef); + Map tagUpdates = new HashMap(tags.size()); + for (String tag : tags) + { + tagUpdates.put(tag, isAdd); + + if (nodeQueuedUpdates != null) + { + Boolean queuedOp = (Boolean)nodeQueuedUpdates.get(tag); + if ((queuedOp != null) && (queuedOp.booleanValue() == isAdd.booleanValue())) + { + // dequeue - will be handled synchronously + nodeQueuedUpdates.remove(tag); + } + } + } + + // Find the parent tag scopes and update them + updateTagScope(parentNodeRef, tagUpdates); + } + } + + /** + * @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef) + */ + public void beforeDeleteNode(NodeRef nodeRef) + { + if (this.nodeService.exists(nodeRef) == true && + this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true && !this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY)) + { + updateAllScopeTags(nodeRef, Boolean.FALSE); + } + } + + /** + * Fired once per node, before a copy overrides one node (which is possibly newly created) with the contents + * of another one. + * We should remove any tags from the scope, as they'll shortly be overwritten. + */ + public void beforeCopy(QName classRef, NodeRef sourceNodeRef, NodeRef targetNodeRef) + { + if (this.nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_TAGGABLE)) + { + updateAllScopeTags(targetNodeRef, Boolean.FALSE); + } + } + + /** + * Fired once per node that was copied, after the copy has completed. + * We need to add in all the tags to the scope. + */ + public void onCopyComplete(QName classRef, NodeRef sourceNodeRef, NodeRef targetNodeRef, boolean copyToNewNode, + Map copyMap) + { + if (this.nodeService.hasAspect(targetNodeRef, ContentModel.ASPECT_TAGGABLE)) + { + updateAllScopeTags(targetNodeRef, Boolean.TRUE); + } + } + + public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) + { + NodeRef oldRef = oldChildAssocRef.getChildRef(); + NodeRef oldParent = oldChildAssocRef.getParentRef(); + NodeRef newRef = newChildAssocRef.getChildRef(); + NodeRef newParent = newChildAssocRef.getParentRef(); + + // Do nothing if it's a "rename" not a move + if (oldParent.equals(newParent)) + { + return; + } + + // It has moved somewhere + // Remove the tags from the old location + if (this.nodeService.hasAspect(oldRef, ContentModel.ASPECT_TAGGABLE)) + { + // Use the parent we were passed in, rather than re-fetching + // via the node, as we need to reference the old scope! + ChildAssociationRef scopeParent; + if (oldChildAssocRef.isPrimary()) + { + scopeParent = oldChildAssocRef; + } + else + { + scopeParent = this.nodeService.getPrimaryParent(oldParent); + } + if (scopeParent != null) + { + updateAllScopeTags(oldRef, scopeParent.getParentRef(), Boolean.FALSE); + } + } + // Add the tags at its new location + if (this.nodeService.hasAspect(newRef, ContentModel.ASPECT_TAGGABLE)) + { + updateAllScopeTags(newRef, Boolean.TRUE); + } + } + + public void createTags(ChildAssociationRef childAssocRef) + { + NodeRef nodeRef = childAssocRef.getChildRef(); + Map before = new HashMap(0); + Map after = nodeService.getProperties(nodeRef); + + updateTags(nodeRef, before, after); + } + + /** + * Update tag policy behaviour + */ + @SuppressWarnings("unchecked") + public void updateTags(NodeRef nodeRef, Map before, Map after) + { + List beforeNodeRefs = (List)before.get(ContentModel.PROP_TAGS); + List afterNodeRefs = (List)after.get(ContentModel.PROP_TAGS); + + if (beforeNodeRefs == null && afterNodeRefs != null) + { + // Queue all the after's for addition to the tag scopes + for (NodeRef afterNodeRef : afterNodeRefs) + { + String tagName = getTagName(afterNodeRef); + queueTagUpdate(nodeRef, tagName, true); + } + } + else if (afterNodeRefs == null && beforeNodeRefs != null) + { + // Queue all the before's for removal to the tag scope + for (NodeRef beforeNodeRef : beforeNodeRefs) + { + // Protect against InvalidNodeRefException(MNT-14453) + if (this.nodeService.exists(beforeNodeRef)) + { + String tagName = getTagName(beforeNodeRef); + queueTagUpdate(nodeRef, tagName, false); + } + } + } + else if (afterNodeRefs != null && beforeNodeRefs != null) + { + //Create a copy of the afterNodeRefs so we don't affect the properties we were given + afterNodeRefs = new ArrayList(afterNodeRefs); + for (NodeRef beforeNodeRef : beforeNodeRefs) + { + if (afterNodeRefs.contains(beforeNodeRef) == true) + { + // remove the node ref from the after list + afterNodeRefs.remove(beforeNodeRef); + } + // Protect against InvalidNodeRefException(MNT-14453) + else if (this.nodeService.exists(beforeNodeRef)) + { + String tagName = getTagName(beforeNodeRef); + queueTagUpdate(nodeRef, tagName, false); + } + } + for (NodeRef afterNodeRef : afterNodeRefs) + { + String tagName = getTagName(afterNodeRef); + queueTagUpdate(nodeRef, tagName, true); + } + } + } + + public String getTagName(NodeRef nodeRef) + { + return (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#isTag(StoreRef, java.lang.String) + */ + public boolean isTag(StoreRef storeRef, String tag) + { + // Lower the case of the tag + return (getTagNodeRef(storeRef, tag.toLowerCase()) != null); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#createTag(StoreRef, java.lang.String) + */ + public NodeRef createTag(StoreRef storeRef, String tag) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + return getTagNodeRef(storeRef, tag, true); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#deleteTag(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) + */ + public void deleteTag(StoreRef storeRef, String tag) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + // Find nodes which are tagged with the 'soon to be deleted' tag. + List 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) + { + this.categoryService.deleteCategory(tagNodeRef); + } + } + + public NodeRef changeTag(StoreRef storeRef, String existingTag, String newTag) + { + if (existingTag == null) + { + throw new TaggingException("Existing tag cannot be null"); + } + + if (newTag == null) + { + throw new TaggingException("New tag cannot be null"); + } + + if (existingTag.equals(newTag)) + { + throw new TaggingException("New and existing tags are the same"); + } + + if (getTagNodeRef(storeRef, existingTag) == null) + { + throw new NonExistentTagException("Tag " + existingTag + " not found"); + } + + if (getTagNodeRef(storeRef, newTag) != null) + { + throw new TagExistsException("Tag " + newTag + " already exists"); + } + + List taggedNodes = findTaggedNodes(storeRef, existingTag); + for (NodeRef nodeRef : taggedNodes) + { + removeTag(nodeRef, existingTag); + addTag(nodeRef, newTag); + } + + deleteTag(storeRef, existingTag); + + return getTagNodeRef(storeRef, newTag, true); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(StoreRef) + */ + public List getTags(StoreRef storeRef) + { + ParameterCheck.mandatory("storeRef", storeRef); + + Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); + List result = new ArrayList(rootCategories.size()); + for (ChildAssociationRef rootCategory : rootCategories) + { + String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); + result.add(name); + } + return result; + } + + public Pair, Integer> getPagedTags(StoreRef storeRef, int fromTag, int pageSize) + { + ParameterCheck.mandatory("storeRef", storeRef); + ParameterCheck.mandatory("fromTag", fromTag); + ParameterCheck.mandatory("pageSize", pageSize); + + Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); + + final int totalCount = rootCategories.size(); + final int startIndex = Math.max(fromTag, 0); + final int endIndex = Math.min(fromTag + pageSize, totalCount); + List result = new ArrayList(pageSize); + int index = 0; + // paging for not sorted tag names + for (ChildAssociationRef rootCategory : rootCategories) + { + if (startIndex > index++) + { + continue; + } + String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); + result.add(name); + if (index == endIndex) + { + break; + } + } + return new Pair, Integer> (result, totalCount); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, java.lang.String) + */ + public List getTags(StoreRef storeRef, String filter) + { + ParameterCheck.mandatory("storeRef", storeRef); + + List result = null; + if (filter == null || filter.length() == 0) + { + result = getTags(storeRef); + } + else + { + Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE); + result = new ArrayList(rootCategories.size()); + for (ChildAssociationRef rootCategory : rootCategories) + { + String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); + if (name.contains(filter.toLowerCase()) == true) + { + result.add(name); + } + } + } + + return result; + } + + public Pair, Integer> getPagedTags(StoreRef storeRef, String filter, int fromTag, int pageSize) + { + ParameterCheck.mandatory("storeRef", storeRef); + ParameterCheck.mandatory("fromTag", fromTag); + ParameterCheck.mandatory("pageSize", pageSize); + + if (filter == null || filter.length() == 0) + { + return getPagedTags(storeRef, fromTag, pageSize); + } + else + { + Collection rootCategories = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, filter); + + final int totalCount = rootCategories.size(); + final int startIndex = Math.max(fromTag, 0); + final int endIndex = Math.min(fromTag + pageSize, totalCount); + List result = new ArrayList(pageSize); + int index = 0; + // paging for not sorted tag names + for (ChildAssociationRef rootCategory : rootCategories) + { + if (startIndex > index++) + { + continue; + } + String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME); + result.add(name); + if (index == endIndex) + { + break; + } + } + return new Pair, Integer> (result, totalCount); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#hasTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + public boolean hasTag(NodeRef nodeRef, String tag) + { + List tags = getTags(nodeRef); + return (tags.contains(tag.toLowerCase())); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#addTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + @SuppressWarnings("unchecked") + public NodeRef addTag(final NodeRef nodeRef, final String tagName) + { + NodeRef newTagNodeRef = null; + + if(tagName == null) + { + throw new IllegalArgumentException("Must provide a non-null tag"); + } + + updateTagBehaviour.disable(); + createTagBehaviour.disable(); + try + { + // Lower the case of the tag + String tag = tagName.toLowerCase(); + + // Get the tag node reference + newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag, true); + + List tagNodeRefs = new ArrayList(5); + if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == false) + { + // Add the aspect + nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGGABLE, null); + } + else + { + // Get the current tags + List currentTagNodes = (List)nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); + if (currentTagNodes != null) + { + tagNodeRefs = currentTagNodes; + } + } + + // Add the new tag (assuming it's not already been added + if (tagNodeRefs.contains(newTagNodeRef) == false) + { + tagNodeRefs.add(newTagNodeRef); + nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)tagNodeRefs); + queueTagUpdate(nodeRef, tag, true); + } + } + finally + { + updateTagBehaviour.enable(); + createTagBehaviour.enable(); + } + + return newTagNodeRef; + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#addTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) + */ + public List> addTags(NodeRef nodeRef, List tags) + { + List> ret = new ArrayList>(); + for (String tag : tags) + { + NodeRef tagNodeRef = addTag(nodeRef, tag); + ret.add(new Pair(tag, tagNodeRef)); + } + return ret; + } + + /** + * Gets the node reference for a given tag. + *

+ * Returns null if tag is not present. + * + * @param storeRef store reference + * @param tag tag + * @return NodeRef tag node reference or null not exist + */ + public NodeRef getTagNodeRef(StoreRef storeRef, String tag) + { + return getTagNodeRef(storeRef, tag, false); + } + + /** + * Gets the node reference for a given tag. + *

+ * Returns null if tag is not present and not created. + * + * @param storeRef store reference + * @param tag tag + * @param create create a node if one doesn't exist? + * @return NodeRef tag node reference or null not exist + */ + private NodeRef getTagNodeRef(StoreRef storeRef, String tag, boolean create) + { + for (String forbiddenSequence : FORBIDDEN_TAGS_SEQUENCES) + { + if (create && tag.contains(forbiddenSequence)) + { + throw new IllegalArgumentException("Tag name must not contain " + StringEscapeUtils.escapeJava(forbiddenSequence) + " char sequence"); + } + } + + NodeRef tagNodeRef = null; + Collection results = this.categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, tag, create); + if (!results.isEmpty()) + { + tagNodeRef = results.iterator().next().getChildRef(); + } + return tagNodeRef; + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#removeTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String) + */ + @SuppressWarnings("unchecked") + public void removeTag(NodeRef nodeRef, String tag) + { + updateTagBehaviour.disable(); + createTagBehaviour.disable(); + try + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + // Check for the taggable aspect + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) + { + // Get the tag node reference + NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag); + if (newTagNodeRef != null) + { + // Get the current tags + List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); + if (currentTagNodes != null && + currentTagNodes.size() != 0 && + currentTagNodes.contains(newTagNodeRef) == true) + { + currentTagNodes.remove(newTagNodeRef); + this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)currentTagNodes); + queueTagUpdate(nodeRef, tag, false); + } + } + } + } + finally + { + updateTagBehaviour.enable(); + createTagBehaviour.enable(); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#removeTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) + */ + public void removeTags(NodeRef nodeRef, List tags) + { + for (String tag : tags) + { + removeTag(nodeRef, tag); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.query.PagingRequest) + */ + @SuppressWarnings("unchecked") + // TODO canned query + public PagingResults> getTags(NodeRef nodeRef, PagingRequest pagingRequest) + { + // Check for the taggable aspect + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) + { + // Get the current tags + List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); + if (currentTagNodes != null) + { + final int totalItems = currentTagNodes.size(); + int skipCount = pagingRequest.getSkipCount(); + int maxItems = pagingRequest.getMaxItems(); + int end = maxItems == Integer.MAX_VALUE ? totalItems : skipCount + maxItems; + int size = (maxItems == Integer.MAX_VALUE ? totalItems : maxItems); + + final List> sortedTags = new ArrayList>(size); + // grab all tags and sort (assume fairly low number of tags) + for(NodeRef tagNode : currentTagNodes) + { + String tag = (String)this.nodeService.getProperty(tagNode, ContentModel.PROP_NAME); + sortedTags.add(new Pair(tagNode, tag)); + } + Collections.sort(sortedTags, new Comparator>() + { + @Override + public int compare(Pair o1, Pair o2) + { + String tag1 = o1.getSecond(); + String tag2 = o2.getSecond(); + return collator.compare(tag1, tag2); + } + }); + + final List> result = new ArrayList>(size); + Iterator> it = sortedTags.iterator(); + for(int count = 0; count < end && it.hasNext(); count++) + { + Pair tagPair = it.next(); + + if(count < skipCount) + { + continue; + } + + result.add(tagPair); + } + currentTagNodes = null; + final boolean hasMoreItems = end < totalItems; + + return new PagingResults>() + { + @Override + public List> getPage() + { + return result; + } + + @Override + public boolean hasMoreItems() + { + return hasMoreItems; + } + + @Override + public Pair getTotalResultCount() + { + Integer total = Integer.valueOf(totalItems); + return new Pair(total, total); + } + + @Override + public String getQueryExecutionId() + { + return null; + } + }; + } + } + + return new EmptyPagingResults>(); + } + + public PagingResults> getTags(StoreRef storeRef, PagingRequest pagingRequest) + { + return getTags(storeRef, pagingRequest, null, null); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, org.alfresco.query.PagingRequest) + */ + public PagingResults> getTags(StoreRef storeRef, PagingRequest pagingRequest, Collection exactNamesFilter, Collection alikeNamesFilter) + { + ParameterCheck.mandatory("storeRef", storeRef); + + PagingResults rootCategories = categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, pagingRequest, true, + exactNamesFilter, alikeNamesFilter); + + return mapPagingResult(rootCategories, + (childAssociation) -> new Pair<>(childAssociation.getChildRef(), childAssociation.getQName().getLocalName())); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef) + */ + @SuppressWarnings("unchecked") + public List getTags(NodeRef nodeRef) + { + List result = new ArrayList(10); + + // Check for the taggable aspect + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) + { + // Get the current tags + List currentTagNodes = (List)this.nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS); + if (currentTagNodes != null) + { + for (NodeRef currentTagNode : currentTagNodes) + { + String tag = (String)this.nodeService.getProperty(currentTagNode, ContentModel.PROP_NAME); + result.add(tag); + } + } + } + + return result; + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#setTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List) + */ + public void setTags(NodeRef nodeRef, List tags) + { + updateTagBehaviour.disable(); + createTagBehaviour.disable(); + try + { + List tagNodeRefs = new ArrayList(tags.size()); + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == false) + { + // Add the aspect + this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGGABLE, null); + } + + // Get the current list of tags + List oldTags = getTags(nodeRef); + + for (String tag : tags) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + // Get the tag node reference + NodeRef newTagNodeRef = getTagNodeRef(nodeRef.getStoreRef(), tag, true); + + if (tagNodeRefs.contains(newTagNodeRef) == false) + { + // Add to the list + tagNodeRefs.add(newTagNodeRef); + + // Trigger scope update + if (oldTags.contains(tag) == false) + { + queueTagUpdate(nodeRef, tag, true); + } + else + { + // Remove the tag from the old list + oldTags.remove(tag); + } + } + } + + // Remove the old tags from the tag scope + for (String oldTag : oldTags) + { + queueTagUpdate(nodeRef, oldTag, false); + } + + // Update category property + this.nodeService.setProperty(nodeRef, ContentModel.PROP_TAGS, (Serializable)tagNodeRefs); + } + finally + { + updateTagBehaviour.enable(); + createTagBehaviour.enable(); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#clearTags(org.alfresco.service.cmr.repository.NodeRef) + */ + public void clearTags(NodeRef nodeRef) + { + setTags(nodeRef, Collections.emptyList()); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#isTagScope(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean isTagScope(NodeRef nodeRef) + { + // Determines whether the node has the tag scope aspect + return this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE); + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#addTagScope(org.alfresco.service.cmr.repository.NodeRef) + */ + public void addTagScope(NodeRef nodeRef) + { + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == false) + { + // Add the tag scope aspect + this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE, null); + + // Refresh the tag scope + refreshTagScope(nodeRef, false); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#refreshTagScope(org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + public void refreshTagScope(NodeRef nodeRef, boolean async) + { + if (this.nodeService.exists(nodeRef) == true && + this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true) + { + Action action = this.actionService.createAction(RefreshTagScopeActionExecuter.NAME); + this.actionService.executeAction(action, nodeRef, false, async); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#removeTagScope(org.alfresco.service.cmr.repository.NodeRef) + */ + public void removeTagScope(NodeRef nodeRef) + { + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE) == true) + { + this.nodeService.removeAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#findTagScope(org.alfresco.service.cmr.repository.NodeRef) + */ + public TagScope findTagScope(NodeRef nodeRef) + { + TagScope tagScope = null; + + if (this.nodeService.exists(nodeRef) == true) + { + List tagScopeNodeRefs = new ArrayList(3); + getTagScopes(nodeRef, tagScopeNodeRefs, true); + if (tagScopeNodeRefs.size() != 0) + { + tagScope = new TagScopeImpl(tagScopeNodeRefs.get(0), getTagDetails(tagScopeNodeRefs.get(0))); + } + } + + return tagScope; + } + + /** + * Gets the tag details list for a given tag scope node reference + * + * @param nodeRef tag scope node reference + * @return List ordered list of tag details for the tag scope + */ + private List getTagDetails(NodeRef nodeRef) + { + List tagDetails = new ArrayList(13); + ContentReader reader = this.contentService.getReader(nodeRef, ContentModel.PROP_TAGSCOPE_CACHE); + if (reader != null) + { + tagDetails = TaggingServiceImpl.readTagDetails(reader.getContentInputStream()); + } + return tagDetails; + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#findAllTagScopes(org.alfresco.service.cmr.repository.NodeRef) + */ + public List findAllTagScopes(NodeRef nodeRef) + { + List result = null; + + if (this.nodeService.exists(nodeRef) == true) + { + List tagScopeNodeRefs = new ArrayList(3); + getTagScopes(nodeRef, tagScopeNodeRefs); + if (tagScopeNodeRefs.size() != 0) + { + result = new ArrayList(tagScopeNodeRefs.size()); + for (NodeRef tagScopeNodeRef : tagScopeNodeRefs) + { + result.add(new TagScopeImpl(tagScopeNodeRef, getTagDetails(tagScopeNodeRef))); + } + } + else + { + result = Collections.emptyList(); + } + } + + return result; + } + + /** + * Traverses up the node's primary parent placing ALL found tag scope's in a list. + *

+ * + * @param nodeRef node reference + * @param tagScopes list of tag scopes + */ + private void getTagScopes(NodeRef nodeRef, List tagScopes) + { + getTagScopes(nodeRef, tagScopes, false); + } + + /** + * Traverses up the node's primary parent placing found tag scope's in a list. + *

+ * If none are found then the list is empty. + * + * @param nodeRef node reference + * @param tagScopes list of tag scopes + * @param firstOnly true => only return first tag scope that is found + */ + private void getTagScopes(final NodeRef nodeRef, List tagScopes, boolean firstOnly) + { + Boolean hasAspect = AuthenticationUtil.runAs(new RunAsWork() + { + @Override + public Boolean doWork() throws Exception + { + return new Boolean(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE)); + } + }, AuthenticationUtil.getSystemUserName()); + + if (Boolean.TRUE.equals(hasAspect) == true) + { + tagScopes.add(nodeRef); + if (firstOnly) + { + return; + } + } + + NodeRef parent = AuthenticationUtil.runAs(new RunAsWork() + { + @Override + public NodeRef doWork() throws Exception + { + NodeRef result = null; + ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); + if (assoc != null) + { + result = assoc.getParentRef(); + } + return result; + } + }, AuthenticationUtil.getSystemUserName()); + + if (parent != null) + { + getTagScopes(parent, tagScopes, firstOnly); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String) + */ + public List findTaggedNodes(StoreRef storeRef, String tag) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + ResultSet resultSet= null; + + try + { + // Do the search for nodes + resultSet = this.searchService.query( + storeRef, + SearchService.LANGUAGE_LUCENE, + "+PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); + List nodeRefs = resultSet.getNodeRefs(); + return nodeRefs; + } + finally + { + if(resultSet != null) {resultSet.close();} + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String, org.alfresco.service.cmr.repository.NodeRef) + */ + public List findTaggedNodes(StoreRef storeRef, String tag, NodeRef nodeRef) + { + // Lower the case of the tag + tag = tag.toLowerCase(); + + // Get path + Path nodePath = this.nodeService.getPath(nodeRef); + String pathString = nodePath.toPrefixString(this.namespaceService); + ResultSet resultSet = null; + + try + { + // Do query + resultSet = this.searchService.query( + storeRef, + SearchService.LANGUAGE_LUCENE, + "+PATH:\"" + pathString + "//*\" +PATH:\"/cm:taggable/cm:" + ISO9075.encode(tag) + "/member\""); + List nodeRefs = resultSet.getNodeRefs(); + return nodeRefs; + } + finally + { + if(resultSet != null) {resultSet.close();} + } + } + + /** + * Helper method that takes an input stream and converts it into a list of tag details + * + * @param is input stream + * @return List list of tag details + */ + /*package*/ static List readTagDetails(InputStream is) + { + List result = new ArrayList(25); + BufferedReader reader = null; + try + { + reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String nextLine = reader.readLine(); + while (nextLine != null) + { + String[] values = nextLine.split("\\" + TAG_DETAILS_DELIMITER); + if(values.length == 1) + { + if(logger.isDebugEnabled()) + { + logger.debug("No count for tag "+values[0]); + } + } + else if (values.length > 1) + { + try + { + result.add(new TagDetailsImpl(values[0], Integer.parseInt(values[1]))); + if(values.length > 2) + { + if(logger.isDebugEnabled()) + { + logger.debug("Ignoring extra guff for tag: " + values[0]); + } + } + } + catch(NumberFormatException nfe) + { + if(logger.isDebugEnabled()) + { + logger.debug("Invalid tag count for " + values[0] + "<"+values[1]+">"); + } + } + } + + nextLine = reader.readLine(); + } + } + catch (Exception exception) + { + logger.warn("Unable to read tag details", exception); + } + finally + { + try { reader.close(); } catch (Exception e) {} + } + + return result; + } + + /** + * Helper method to convert a list of tag details into a string. + * + * @param tagDetails list of tag details + * @return String string of tag details + */ + /*package*/ static String tagDetailsToString(List tagDetails) + { + StringBuffer result = new StringBuffer(255); + + boolean bFirst = true; + for (TagDetails details : tagDetails) + { + if (bFirst == false) + { + result.append(NEXT_TAG_DELIMITER); + } + else + { + bFirst = false; + } + + result.append(details.getName()); + result.append(TAG_DETAILS_DELIMITER); + result.append(details.getCount()); + } + + return result.toString(); + } + + // ===== Methods Dealing with TagScope Updates ==== // + + public static final String TAG_UPDATES = "tagUpdates"; + + /** + * Triggers an async update of all the relevant tag scopes when a tag is + * added or removed from a node. + * Uses the audit service as a persisted queue to hold the list of changes, + * and triggers an sync action to work on the entries in the queue for us. + * This should avoid contention problems and race conditions. + * + * @param nodeRef node reference + * @param updates Map + */ + private void updateTagScope(NodeRef nodeRef, Map updates) + { + // First up, locate all the tag scopes for this node + // (Need to do a recursive search up to the root) + ArrayList tagScopeNodeRefs = new ArrayList(3); + getTagScopes(nodeRef, tagScopeNodeRefs); + + if(tagScopeNodeRefs.size() == 0) + { + if(logger.isDebugEnabled()) + { + logger.debug("No tag scopes found for " + nodeRef + " so no scope updates needed"); + } + return; + } + + // Turn from tag+yes/no into tag+1/-1 + // (Later we may roll things up better to be tag+#/-#) + HashMap changes = new HashMap(updates.size()); + for(String tag : updates.keySet()) + { + int val = -1; + if(updates.get(tag)) + val = 1; + changes.put(tag, val); + } + + // Next, queue the updates for each tag scope + for(NodeRef tagScopeNode : tagScopeNodeRefs) + { + Map auditValues = new HashMap(); + auditValues.put(TAGGING_AUDIT_KEY_TAGS, changes); + auditValues.put(TAGGING_AUDIT_KEY_NODEREF, tagScopeNode.toString()); + auditComponent.recordAuditValues(TAGGING_AUDIT_ROOT_PATH, auditValues); + } + if(logger.isDebugEnabled()) + { + logger.debug("Queueing async tag scope updates to tag scopes " + tagScopeNodeRefs + " of " + changes); + } + + // Finally, trigger the action to process the updates + // This will happen asynchronously + Action action = this.actionService.createAction(UpdateTagScopesActionExecuter.NAME); + action.setParameterValue(UpdateTagScopesActionExecuter.PARAM_TAG_SCOPES, tagScopeNodeRefs); + this.actionService.executeAction(action, null, false, true); + } + + /** + * Records the fact that the given tag for the given node will need to + * be added or removed from its parent tags scopes. + * {@link #updateTagScope(NodeRef, Map)} will schedule the update + * to occur, and an async action will do it. + */ + @SuppressWarnings("unchecked") + private void queueTagUpdate(NodeRef nodeRef, String tag, boolean add) + { + // Get the updates map + Map> updates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); + if (updates == null) + { + updates = new HashMap>(10); + AlfrescoTransactionSupport.bindResource(TAG_UPDATES, updates); + AlfrescoTransactionSupport.bindListener(this); + } + + // Add the details of the update to the map + Map nodeDetails = updates.get(nodeRef); + if (nodeDetails == null) + { + nodeDetails = new HashMap(10); + nodeDetails.put(tag, Boolean.valueOf(add)); + updates.put(nodeRef, nodeDetails); + } + else + { + Boolean currentValue = nodeDetails.get(tag); + if (currentValue == null) + { + nodeDetails.put(tag, Boolean.valueOf(add)); + updates.put(nodeRef, nodeDetails); + } + else if (currentValue.booleanValue() != add) + { + // If the boolean value is different then the tag had been added and removed or + // removed and then added in the same transaction. In both cases the net change is none. + // So remove the entry in the update map + nodeDetails.remove(tag); + } + // Otherwise do nothing because we have already noted the update + } + + } + + // ===== Transaction Listener Callback Methods ===== // + + /** + * @see org.alfresco.repo.transaction.TransactionListener#afterCommit() + */ + public void afterCommit() + { + + } + + /** + * @see org.alfresco.repo.transaction.TransactionListener#afterRollback() + */ + public void afterRollback() + { + } + + /** + * @see org.alfresco.repo.transaction.TransactionListener#beforeCommit(boolean) + */ + @SuppressWarnings("unchecked") + public void beforeCommit(boolean readOnly) + { + Map> updates = (Map>)AlfrescoTransactionSupport.getResource(TAG_UPDATES); + if (updates != null) + { + for (NodeRef nodeRef : updates.keySet()) + { + Map tagUpdates = updates.get(nodeRef); + if (tagUpdates != null && tagUpdates.size() != 0) + { + // Anything can happen during the transaction + if (!nodeServiceInternal.exists(nodeRef)) + { + continue; + } + updateTagScope(nodeRef, tagUpdates); + } + } + } + } + + /** + * @see org.alfresco.repo.transaction.TransactionListener#beforeCompletion() + */ + public void beforeCompletion() + { + } + + /** + * @see org.alfresco.repo.transaction.TransactionListener#flush() + */ + public void flush() + { + } + + public void afterCheckOut(NodeRef workingCopy) + { + if (this.nodeService.exists(workingCopy) == true && this.nodeService.hasAspect(workingCopy, ContentModel.ASPECT_TAGGABLE) == true + && this.nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)) + { + updateAllScopeTags(workingCopy, Boolean.FALSE); + } + } + + /** + * @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodesAndCountByTagName(StoreRef) + */ + @Override + public List> findTaggedNodesAndCountByTagName(StoreRef storeRef) + { + String queryTaggeble = "ASPECT:\"" + ContentModel.ASPECT_TAGGABLE + "\"" + "-ASPECT:\"" + ContentModel.ASPECT_WORKING_COPY + "\""; + SearchParameters sp = new SearchParameters(); + sp.setQuery(queryTaggeble); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.addStore(storeRef); + sp.addFieldFacet(new FieldFacet("TAG")); + + ResultSet resultSet = null; + try + { + // Do the search for nodes + resultSet = this.searchService.query(sp); + return resultSet.getFieldFacet("TAG"); + } + finally + { + if (resultSet != null) + { + resultSet.close(); + } + } + } + + @Experimental + @Override + public List> createTags(final StoreRef storeRef, final List tagNames) + { + updateTagBehaviour.disable(); + createTagBehaviour.disable(); + try + { + return tagNames.stream() + .map(String::toLowerCase) + .peek(tagName -> categoryService.getRootCategories(storeRef, ContentModel.ASPECT_TAGGABLE, tagName, false).stream() + .filter(association -> Objects.nonNull(association.getChildRef())) + .findAny() + .ifPresent(association -> { throw new DuplicateChildNodeNameException(association.getParentRef(), association.getTypeQName(), tagName, null); })) + .map(tagName -> new Pair<>(tagName, getTagNodeRef(storeRef, tagName, true))) + .collect(Collectors.toList()); + } + finally + { + updateTagBehaviour.enable(); + createTagBehaviour.enable(); + } + } + + private PagingResults mapPagingResult(final PagingResults pagingResults, final Function mapper) + { + return new PagingResults() + { + @Override + public List getPage() + { + return pagingResults.getPage().stream() + .map(mapper) + .collect(Collectors.toList()); + } + + @Override + public boolean hasMoreItems() + { + return pagingResults.hasMoreItems(); + } + + @Override + public Pair getTotalResultCount() + { + return pagingResults.getTotalResultCount(); + } + + @Override + public String getQueryExecutionId() + { + return pagingResults.getQueryExecutionId(); + } + }; + } +} diff --git a/repository/src/test/java/org/alfresco/repo/tagging/TaggingServiceImplUnitTest.java b/repository/src/test/java/org/alfresco/repo/tagging/TaggingServiceImplUnitTest.java index d0afd37558..51049dcf6c 100644 --- a/repository/src/test/java/org/alfresco/repo/tagging/TaggingServiceImplUnitTest.java +++ b/repository/src/test/java/org/alfresco/repo/tagging/TaggingServiceImplUnitTest.java @@ -25,6 +25,9 @@ */ package org.alfresco.repo.tagging; +import static org.alfresco.model.ContentModel.ASPECT_TAGGABLE; +import static org.alfresco.model.ContentModel.PROP_TAGS; +import static org.alfresco.repo.tagging.TaggingServiceImpl.TAG_UPDATES; import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -33,16 +36,26 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.stream.Collectors; -import org.alfresco.model.ContentModel; import org.alfresco.repo.policy.PolicyComponent; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.CategoryService; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchService; import org.alfresco.util.Pair; import org.junit.Before; import org.junit.Test; @@ -57,11 +70,20 @@ public class TaggingServiceImplUnitTest private static final String TAG_ID = "tag-node-id"; private static final String TAG_NAME = "tag-dummy-name"; private static final NodeRef TAG_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, TAG_ID); + private static final NodeRef CONTENT_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "content-id"); + @Mock + private NodeService nodeServiceMock; @Mock private CategoryService categoryServiceMock; @Mock private PolicyComponent policyComponentMock; + @Mock + private SearchService searchServiceMock; + @Mock + private ResultSet resultSetMock; + @Mock(extraInterfaces = List.class) + private Serializable currentTagsMock; @InjectMocks private TaggingServiceImpl taggingService; @@ -69,6 +91,7 @@ public class TaggingServiceImplUnitTest @Before public void setUp() throws Exception { + AlfrescoTransactionSupport.bindResource(TAG_UPDATES, new HashMap<>()); taggingService.init(); } @@ -82,8 +105,8 @@ public class TaggingServiceImplUnitTest //when final List> actualTagPairs = taggingService.createTags(STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME)); - then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, false); - then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, true); + then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false); + then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, true); then(categoryServiceMock).shouldHaveNoMoreInteractions(); List> expectedTagPairs = List.of(new Pair<>(TAG_NAME, TAG_NODE_REF)); assertThat(actualTagPairs) @@ -99,8 +122,57 @@ public class TaggingServiceImplUnitTest //when final Throwable actualException = catchThrowable(() -> taggingService.createTags(STORE_REF_WORKSPACE_SPACESSTORE, List.of(TAG_NAME))); - then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ContentModel.ASPECT_TAGGABLE, TAG_NAME, false); + then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false); then(categoryServiceMock).shouldHaveNoMoreInteractions(); assertThat(actualException).isInstanceOf(DuplicateChildNodeNameException.class); } + + @Test + @SuppressWarnings("unchecked") + public void testChangeTag() + { + final String newTagName = "new-tag-name"; + final NodeRef newTagNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, newTagName); + given(searchServiceMock.query(any(), any(String.class), any(String.class))).willReturn(resultSetMock); + given(resultSetMock.getNodeRefs()).willReturn(List.of(CONTENT_NODE_REF), Collections.emptyList()); + given(nodeServiceMock.hasAspect(CONTENT_NODE_REF, ASPECT_TAGGABLE)).willReturn(true); + given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false)).willReturn(childAssociationsOf(TAG_NODE_REF)); + given(nodeServiceMock.getProperty(CONTENT_NODE_REF, PROP_TAGS)).willReturn(currentTagsMock); + given(((List) currentTagsMock).size()).willReturn(1); + given(((List) currentTagsMock).contains(TAG_NODE_REF)).willReturn(true); + given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true)).willReturn(childAssociationsOf(newTagNodeRef)); + given(((List) currentTagsMock).contains(newTagNodeRef)).willReturn(false); + + //when + taggingService.changeTag(STORE_REF_WORKSPACE_SPACESSTORE, TAG_NAME, newTagName); + + then((List) currentTagsMock).should().remove(TAG_NODE_REF); + then((List) currentTagsMock).should().add(newTagNodeRef); + then(nodeServiceMock).should(times(2)).setProperty(CONTENT_NODE_REF, PROP_TAGS, currentTagsMock); + then(categoryServiceMock).should().deleteCategory(TAG_NODE_REF); + then(categoryServiceMock).should(times(2)).getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true); + } + + @Test + public void testChangeOrphanTag() + { + final String newTagName = "new-tag-name"; + given(searchServiceMock.query(any(), any(String.class), any(String.class))).willReturn(resultSetMock); + given(resultSetMock.getNodeRefs()).willReturn(Collections.emptyList()); + given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false)).willReturn(childAssociationsOf(TAG_NODE_REF)); + + //when + taggingService.changeTag(STORE_REF_WORKSPACE_SPACESSTORE, TAG_NAME, newTagName); + + then(nodeServiceMock).should(never()).setProperty(any(), any(), any()); + then(categoryServiceMock).should().deleteCategory(TAG_NODE_REF); + then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true); + } + + private static List childAssociationsOf(final NodeRef... childNodeRefs) + { + return Arrays.stream(childNodeRefs) + .map(childNodeRef -> new ChildAssociationRef(null, null, null, childNodeRef)) + .collect(Collectors.toList()); + } } \ No newline at end of file From c27a44d711293de0aa8acb530bbd4541e80f582d Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 24 Mar 2023 10:14:35 +0000 Subject: [PATCH 10/16] ACS-4863 Remove test for invalid URL. This test behaves differently against community and enterprise as the double slash is treated differently. --- .../alfresco/rest/tags/nodes/GetNodeTagsTests.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/nodes/GetNodeTagsTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/nodes/GetNodeTagsTests.java index abfcbc99e9..bab6668eb6 100644 --- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/nodes/GetNodeTagsTests.java +++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/tags/nodes/GetNodeTagsTests.java @@ -150,18 +150,6 @@ public class GetNodeTagsTests extends TagsDataPrep restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, nodeRef)); } - @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, - description = "Verify that if node id is empty returns status code 403") - @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION}) - public void emptyNodeIdTest() throws Exception - { - FileModel badDocument = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN); - badDocument.setNodeRef(""); - - restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(badDocument).getNodeTags(); - restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, "")); - } - @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify folder tags") @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION}) @@ -303,4 +291,4 @@ public class GetNodeTagsTests extends TagsDataPrep .and().field("skipCount").is("10000"); returnedCollection.assertThat().entriesListCountIs(0); } -} \ No newline at end of file +} From 0652cea2963a2ffea54277674929d252bafa08f0 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Fri, 24 Mar 2023 11:44:55 +0000 Subject: [PATCH 11/16] ACS-4863 Move new validation method to interface as a default implementation. --- remote-api/src/main/java/org/alfresco/rest/api/Nodes.java | 5 ++++- .../src/main/java/org/alfresco/rest/api/impl/NodesImpl.java | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java index 9a606ad049..a0f527b441 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/Nodes.java @@ -219,7 +219,10 @@ public interface Nodes * @throws InvalidArgumentException if the specified node id is not a valid format. * @throws EntityNotFoundException if the specified node was not found in the database. */ - NodeRef validateOrLookupNode(String nodeId); + default NodeRef validateOrLookupNode(String nodeId) + { + return validateOrLookupNode(nodeId, null); + } NodeRef validateOrLookupNode(String nodeId, String path); boolean nodeMatches(NodeRef nodeRef, Set expectedTypes, Set excludedTypes); diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java index ab1893d762..f255e61b63 100644 --- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -649,11 +649,6 @@ public class NodesImpl implements Nodes return nodeService.getPrimaryParent(nodeRef).getParentRef(); } - public NodeRef validateOrLookupNode(String nodeId) - { - return validateOrLookupNode(nodeId, null); - } - public NodeRef validateOrLookupNode(String nodeId, String path) { NodeRef parentNodeRef; From 95fb286c14edd887b7da73b58b87669fd871d8ed Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 12:17:14 +0000 Subject: [PATCH 12/16] [maven-release-plugin][skip ci] prepare release 20.117 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 98781b3f6b..f2d2c0de43 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.117-SNAPSHOT + 20.117 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index d0bd3817e3..2ec177f5d0 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.117-SNAPSHOT + 20.117 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 14345c810e..be00cf931b 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 3b39a4eaa7..42873fd846 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.117-SNAPSHOT + 20.117 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index d14798b0b4..701da6c4fb 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.117-SNAPSHOT + 20.117 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 1d6800ed5a..02d75e3bb8 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.117-SNAPSHOT + 20.117 diff --git a/amps/pom.xml b/amps/pom.xml index e7953bdc40..4e0d0ce033 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 0d6d28a04a..5184a76952 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.117-SNAPSHOT + 20.117 diff --git a/core/pom.xml b/core/pom.xml index 56fa775ee4..64f55a5d9b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/data-model/pom.xml b/data-model/pom.xml index 12777b0bcf..e16e0ae24c 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/mmt/pom.xml b/mmt/pom.xml index 174ad64649..a4e7f86d27 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 3c803b1e8d..8248df504e 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index b18c8b9949..4abd140826 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/pom.xml b/packaging/pom.xml index 07b56a4104..ceab1186ab 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 9f2a30111e..7365f8297b 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index c3bba31f34..b8b2a51313 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 466e9b97e3..a8afd53c94 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 2b3ecef6a9..5298c4ee4b 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index bc858b0b6c..e4d46ce9fb 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 098bfdcbac..19a8c02ccf 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117-SNAPSHOT + 20.117 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 333d8de3b5..bbfa9fd821 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117-SNAPSHOT + 20.117 diff --git a/pom.xml b/pom.xml index 7d68f64909..4f11996604 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.117-SNAPSHOT + 20.117 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 20.117 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 4a70fc01bc..401e20782a 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 diff --git a/repository/pom.xml b/repository/pom.xml index 39ee8438b0..ff7fdb63f3 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117-SNAPSHOT + 20.117 From bbdeb5ae970ae8f16fc7908188ee5caf2675b73d Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Fri, 24 Mar 2023 12:17:17 +0000 Subject: [PATCH 13/16] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index f2d2c0de43..04a01c86f6 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.117 + 20.118-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 2ec177f5d0..0b30b9910b 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.117 + 20.118-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index be00cf931b..976fdd5407 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 42873fd846..0fcb4ea40c 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.117 + 20.118-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 701da6c4fb..d874171609 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.117 + 20.118-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 02d75e3bb8..ef37502e19 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.117 + 20.118-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index 4e0d0ce033..1e8ee6fef3 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 5184a76952..3e6dd8c578 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.117 + 20.118-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 64f55a5d9b..564df89bbc 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index e16e0ae24c..7a25888573 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index a4e7f86d27..e66f6b792d 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 8248df504e..6032f0bf57 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index 4abd140826..c122b755b4 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index ceab1186ab..f5f7901ddb 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 7365f8297b..ddfc7dbde7 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index b8b2a51313..03f3fb8e9a 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index a8afd53c94..61de9b3b6f 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 5298c4ee4b..72e6061e3c 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index e4d46ce9fb..1774648d3a 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 19a8c02ccf..5f200b0b6c 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.117 + 20.118-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index bbfa9fd821..d680cd98fa 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.117 + 20.118-SNAPSHOT diff --git a/pom.xml b/pom.xml index 4f11996604..ecbd8d84bf 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.117 + 20.118-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 20.117 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 401e20782a..30af7de744 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index ff7fdb63f3..72b4fdbdc7 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.117 + 20.118-SNAPSHOT From 6942294780df958b7133ace3802d39cf69743e74 Mon Sep 17 00:00:00 2001 From: Alfresco CI User Date: Sun, 26 Mar 2023 00:03:13 +0000 Subject: [PATCH 14/16] [force] Force release for 2023-03-26. From 4053daaf1a35b98b9fa0b0179e6fda7003a25a54 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Sun, 26 Mar 2023 00:06:23 +0000 Subject: [PATCH 15/16] [maven-release-plugin][skip ci] prepare release 20.118 --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index 04a01c86f6..e391baac86 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.118-SNAPSHOT + 20.118 diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 0b30b9910b..2f89f8d0fb 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.118-SNAPSHOT + 20.118 diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index 976fdd5407..ab2767942f 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 0fcb4ea40c..4f97fd9d84 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.118-SNAPSHOT + 20.118 diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index d874171609..4b18be5701 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.118-SNAPSHOT + 20.118 diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index ef37502e19..23a6d0fda9 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.118-SNAPSHOT + 20.118 diff --git a/amps/pom.xml b/amps/pom.xml index 1e8ee6fef3..ce37ee35d3 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 3e6dd8c578..064ed81f79 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.118-SNAPSHOT + 20.118 diff --git a/core/pom.xml b/core/pom.xml index 564df89bbc..99c3cc9703 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/data-model/pom.xml b/data-model/pom.xml index 7a25888573..37abff147a 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/mmt/pom.xml b/mmt/pom.xml index e66f6b792d..44e046c3b3 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 6032f0bf57..118ebd9b51 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index c122b755b4..bc675d6692 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/pom.xml b/packaging/pom.xml index f5f7901ddb..103bb619c7 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index ddfc7dbde7..208a678af6 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index 03f3fb8e9a..a35d5b81b2 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index 61de9b3b6f..c8ee78319e 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 72e6061e3c..2d26e04d59 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 1774648d3a..0e882848be 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 5f200b0b6c..2877749fb5 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118-SNAPSHOT + 20.118 diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index d680cd98fa..3bc39372e0 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118-SNAPSHOT + 20.118 diff --git a/pom.xml b/pom.xml index ecbd8d84bf..34821dc579 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.118-SNAPSHOT + 20.118 pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - HEAD + 20.118 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 30af7de744..f636ab77ac 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 diff --git a/repository/pom.xml b/repository/pom.xml index 72b4fdbdc7..45e86e3b94 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118-SNAPSHOT + 20.118 From c0d1b332010c0e5c037eca7b7bad6d540c2e2959 Mon Sep 17 00:00:00 2001 From: alfresco-build <8039454+alfresco-build@users.noreply.github.com> Date: Sun, 26 Mar 2023 00:06:25 +0000 Subject: [PATCH 16/16] [maven-release-plugin][skip ci] prepare for next development iteration --- amps/ags/pom.xml | 2 +- amps/ags/rm-automation/pom.xml | 2 +- .../rm-automation/rm-automation-community-rest-api/pom.xml | 2 +- amps/ags/rm-community/pom.xml | 2 +- amps/ags/rm-community/rm-community-repo/pom.xml | 2 +- amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml | 2 +- amps/pom.xml | 2 +- amps/share-services/pom.xml | 2 +- core/pom.xml | 2 +- data-model/pom.xml | 2 +- mmt/pom.xml | 2 +- packaging/distribution/pom.xml | 2 +- packaging/docker-alfresco/pom.xml | 2 +- packaging/pom.xml | 2 +- packaging/tests/pom.xml | 2 +- packaging/tests/tas-cmis/pom.xml | 2 +- packaging/tests/tas-email/pom.xml | 2 +- packaging/tests/tas-integration/pom.xml | 2 +- packaging/tests/tas-restapi/pom.xml | 2 +- packaging/tests/tas-webdav/pom.xml | 2 +- packaging/war/pom.xml | 2 +- pom.xml | 4 ++-- remote-api/pom.xml | 2 +- repository/pom.xml | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) diff --git a/amps/ags/pom.xml b/amps/ags/pom.xml index e391baac86..87945c0a54 100644 --- a/amps/ags/pom.xml +++ b/amps/ags/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-amps - 20.118 + 20.119-SNAPSHOT diff --git a/amps/ags/rm-automation/pom.xml b/amps/ags/rm-automation/pom.xml index 2f89f8d0fb..9647cf1c24 100644 --- a/amps/ags/rm-automation/pom.xml +++ b/amps/ags/rm-automation/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.118 + 20.119-SNAPSHOT diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml index ab2767942f..43d90a7770 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-automation-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/amps/ags/rm-community/pom.xml b/amps/ags/rm-community/pom.xml index 4f97fd9d84..0fb4bb3335 100644 --- a/amps/ags/rm-community/pom.xml +++ b/amps/ags/rm-community/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-parent - 20.118 + 20.119-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-repo/pom.xml b/amps/ags/rm-community/rm-community-repo/pom.xml index 4b18be5701..42d22888b1 100644 --- a/amps/ags/rm-community/rm-community-repo/pom.xml +++ b/amps/ags/rm-community/rm-community-repo/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.118 + 20.119-SNAPSHOT diff --git a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml index 23a6d0fda9..7b11b90d0e 100644 --- a/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml +++ b/amps/ags/rm-community/rm-community-rest-api-explorer/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-governance-services-community-repo-parent - 20.118 + 20.119-SNAPSHOT diff --git a/amps/pom.xml b/amps/pom.xml index ce37ee35d3..1ab489790e 100644 --- a/amps/pom.xml +++ b/amps/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/amps/share-services/pom.xml b/amps/share-services/pom.xml index 064ed81f79..24c24c6051 100644 --- a/amps/share-services/pom.xml +++ b/amps/share-services/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-amps - 20.118 + 20.119-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 99c3cc9703..db1a275bd0 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/data-model/pom.xml b/data-model/pom.xml index 37abff147a..fcf75df5eb 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/mmt/pom.xml b/mmt/pom.xml index 44e046c3b3..649ec970eb 100644 --- a/mmt/pom.xml +++ b/mmt/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml index 118ebd9b51..a0b6cbbaf2 100644 --- a/packaging/distribution/pom.xml +++ b/packaging/distribution/pom.xml @@ -9,6 +9,6 @@ org.alfresco alfresco-community-repo-packaging - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml index bc675d6692..b9d95ff9bd 100644 --- a/packaging/docker-alfresco/pom.xml +++ b/packaging/docker-alfresco/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/pom.xml b/packaging/pom.xml index 103bb619c7..ce4a0a3b5c 100644 --- a/packaging/pom.xml +++ b/packaging/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml index 208a678af6..0c9530cfd0 100644 --- a/packaging/tests/pom.xml +++ b/packaging/tests/pom.xml @@ -6,7 +6,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml index a35d5b81b2..a18ffe24b8 100644 --- a/packaging/tests/tas-cmis/pom.xml +++ b/packaging/tests/tas-cmis/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-tests - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml index c8ee78319e..e1b8a49d93 100644 --- a/packaging/tests/tas-email/pom.xml +++ b/packaging/tests/tas-email/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml index 2d26e04d59..ec331927b7 100644 --- a/packaging/tests/tas-integration/pom.xml +++ b/packaging/tests/tas-integration/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/tas-restapi/pom.xml b/packaging/tests/tas-restapi/pom.xml index 0e882848be..117a98c99b 100644 --- a/packaging/tests/tas-restapi/pom.xml +++ b/packaging/tests/tas-restapi/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-community-repo-tests - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/tests/tas-webdav/pom.xml b/packaging/tests/tas-webdav/pom.xml index 2877749fb5..016cd3df01 100644 --- a/packaging/tests/tas-webdav/pom.xml +++ b/packaging/tests/tas-webdav/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-community-repo-tests - 20.118 + 20.119-SNAPSHOT diff --git a/packaging/war/pom.xml b/packaging/war/pom.xml index 3bc39372e0..efb5805f13 100644 --- a/packaging/war/pom.xml +++ b/packaging/war/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo-packaging - 20.118 + 20.119-SNAPSHOT diff --git a/pom.xml b/pom.xml index 34821dc579..daac9fff41 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 alfresco-community-repo - 20.118 + 20.119-SNAPSHOT pom Alfresco Community Repo Parent @@ -151,7 +151,7 @@ scm:git:https://github.com/Alfresco/alfresco-community-repo.git scm:git:https://github.com/Alfresco/alfresco-community-repo.git https://github.com/Alfresco/alfresco-community-repo - 20.118 + HEAD diff --git a/remote-api/pom.xml b/remote-api/pom.xml index f636ab77ac..5c3178510e 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT diff --git a/repository/pom.xml b/repository/pom.xml index 45e86e3b94..eec544fd8c 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -7,7 +7,7 @@ org.alfresco alfresco-community-repo - 20.118 + 20.119-SNAPSHOT