ACS-4025: Throw 400 error when ordering by tag count without including tag count (#1896)

* ACS-4025: change exception to throw 400 and add test
This commit is contained in:
George Evangelopoulos
2023-04-21 15:05:21 +01:00
committed by GitHub
parent dd05f3d338
commit 2c3845bf9d
3 changed files with 295 additions and 286 deletions

View File

@@ -2,6 +2,7 @@ package org.alfresco.rest.tags;
import static org.alfresco.utility.data.RandomData.getRandomName; import static org.alfresco.utility.data.RandomData.getRandomName;
import static org.alfresco.utility.report.log.Step.STEP; import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK; import static org.springframework.http.HttpStatus.OK;
import java.util.Set; import java.util.Set;
@@ -88,7 +89,7 @@ public class GetTagsTests extends TagsDataPrep
.withParams("include=count") .withParams("include=count")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.getEntries().stream() returnedCollection.getEntries().stream()
.filter(e -> e.onModel().getTag().equals(folderTagValue) || e.onModel().getTag().equals(documentTagValue)) .filter(e -> e.onModel().getTag().equals(folderTagValue) || e.onModel().getTag().equals(documentTagValue))
@@ -105,14 +106,13 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByCountDefaultOrderShouldBeAsc() public void testGetTags_withOrderByCountDefaultOrderShouldBeAsc()
{ {
STEP("Get tags and order results by count. Default sort order should be ascending"); STEP("Get tags and order results by count. Default sort order should be ascending");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("include=count&orderBy=count") .withParams("include=count&orderBy=count")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedAscBy("count"); returnedCollection.assertThat().entriesListIsSortedAscBy("count");
} }
@@ -122,14 +122,13 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByCountAsc() public void testGetTags_withOrderByCountAsc()
{ {
STEP("Get tags and order results by count in ascending order"); STEP("Get tags and order results by count in ascending order");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("include=count&orderBy=count ASC") .withParams("include=count&orderBy=count ASC")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedAscBy("count"); returnedCollection.assertThat().entriesListIsSortedAscBy("count");
} }
@@ -139,14 +138,13 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByCountDesc() public void testGetTags_withOrderByCountDesc()
{ {
STEP("Get tags and order results by count in descending order"); STEP("Get tags and order results by count in descending order");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("include=count&orderBy=count DESC") .withParams("include=count&orderBy=count DESC")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedDescBy("count"); returnedCollection.assertThat().entriesListIsSortedDescBy("count");
} }
@@ -156,14 +154,13 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByTagDefaultOrderShouldBeAsc() public void testGetTags_withOrderByTagDefaultOrderShouldBeAsc()
{ {
STEP("Get tags and order results by tag name. Default sort order should be ascending"); STEP("Get tags and order results by tag name. Default sort order should be ascending");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("orderBy=tag") .withParams("orderBy=tag")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedAscBy("tag"); returnedCollection.assertThat().entriesListIsSortedAscBy("tag");
} }
@@ -173,14 +170,13 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByTagAsc() public void testGetTags_withOrderByTagAsc()
{ {
STEP("Get tags and order results by tag name in ascending order"); STEP("Get tags and order results by tag name in ascending order");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("orderBy=tag ASC") .withParams("orderBy=tag ASC")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedAscBy("tag"); returnedCollection.assertThat().entriesListIsSortedAscBy("tag");
} }
@@ -190,17 +186,30 @@ public class GetTagsTests extends TagsDataPrep
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_withOrderByTagDesc() public void testGetTags_withOrderByTagDesc()
{ {
STEP("Get tags and order results by tag name in descending order"); STEP("Get tags and order results by tag name in descending order");
returnedCollection = restClient.authenticateUser(adminUserModel) returnedCollection = restClient.authenticateUser(adminUserModel)
.withParams("orderBy=tag DESC") .withParams("orderBy=tag DESC")
.withCoreAPI() .withCoreAPI()
.getTags(); .getTags();
restClient.assertStatusCodeIs(HttpStatus.OK); restClient.assertStatusCodeIs(OK);
returnedCollection.assertThat().entriesListIsSortedDescBy("tag"); returnedCollection.assertThat().entriesListIsSortedDescBy("tag");
} }
/**
* Ensure that we get a 400 error when we request to order by count without also including the tag count.
*/
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
public void testGetTags_orderByCountWithoutIncludeCount()
{
restClient.authenticateUser(adminUserModel)
.withParams("orderBy=count")
.withCoreAPI()
.getTags();
restClient.assertStatusCodeIs(BAD_REQUEST);
}
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Failed authentication get tags call returns status code 401 with Manager role") @TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Failed authentication get tags call returns status code 401 with Manager role")
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY }) @Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants") // @Bug(id="MNT-16904", description = "It fails only on environment with tenants")

View File

@@ -86,40 +86,40 @@ import org.apache.commons.collections.CollectionUtils;
*/ */
public class TagsImpl implements Tags public class TagsImpl implements Tags
{ {
public static final String PARAM_INCLUDE_COUNT = "count"; public static final String PARAM_INCLUDE_COUNT = "count";
private static final String PARAM_WHERE_TAG = "tag"; private static final String PARAM_WHERE_TAG = "tag";
static final String NOT_A_VALID_TAG = "An invalid parameter has been supplied"; static final String NOT_A_VALID_TAG = "An invalid parameter has been supplied";
static final String NO_PERMISSION_TO_MANAGE_A_TAG = "Current user does not have permission to manage a tag"; static final String NO_PERMISSION_TO_MANAGE_A_TAG = "Current user does not have permission to manage a tag";
private Nodes nodes; private Nodes nodes;
private NodeService nodeService; private NodeService nodeService;
private TaggingService taggingService; private TaggingService taggingService;
private TypeConstraint typeConstraint; private TypeConstraint typeConstraint;
private AuthorityService authorityService; private AuthorityService authorityService;
public void setTypeConstraint(TypeConstraint typeConstraint) public void setTypeConstraint(TypeConstraint typeConstraint)
{
this.typeConstraint = typeConstraint;
}
public void setNodes(Nodes nodes)
{ {
this.nodes = nodes; this.typeConstraint = typeConstraint;
} }
public void setNodeService(NodeService nodeService)
{ public void setNodes(Nodes nodes)
this.nodeService = nodeService; {
} this.nodes = nodes;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setTaggingService(TaggingService taggingService) public void setTaggingService(TaggingService taggingService)
{ {
this.taggingService = taggingService; this.taggingService = taggingService;
} }
public void setAuthorityService(AuthorityService authorityService) public void setAuthorityService(AuthorityService authorityService)
{ {
this.authorityService = authorityService; this.authorityService = authorityService;
} }
public List<Tag> addTags(String nodeId, final List<Tag> tags, final Parameters parameters) public List<Tag> addTags(String nodeId, final List<Tag> tags, final Parameters parameters)
{ {
@@ -134,15 +134,15 @@ public class TagsImpl implements Tags
{ {
List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues); List<Pair<String, NodeRef>> tagNodeRefs = taggingService.addTags(nodeRef, tagValues);
List<Tag> ret = new ArrayList<>(tags.size()); List<Tag> ret = new ArrayList<>(tags.size());
List<Pair<String, Integer>> tagsCountPairList = taggingService.findTaggedNodesAndCountByTagName(nodeRef.getStoreRef()); List<Pair<String, Integer>> tagsCountPairList = taggingService.findTaggedNodesAndCountByTagName(nodeRef.getStoreRef());
Map<String, Long> tagsCountMap = tagsCountPairList.stream().collect(Collectors.toMap(Pair::getFirst, pair -> Long.valueOf(pair.getSecond()))); Map<String, Long> tagsCountMap = tagsCountPairList.stream().collect(Collectors.toMap(Pair::getFirst, pair -> Long.valueOf(pair.getSecond())));
for (Pair<String, NodeRef> pair : tagNodeRefs) for (Pair<String, NodeRef> pair : tagNodeRefs)
{ {
Tag createdTag = new Tag(pair.getSecond(), pair.getFirst()); Tag createdTag = new Tag(pair.getSecond(), pair.getFirst());
if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT)) if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
{ {
createdTag.setCount(Optional.ofNullable(tagsCountMap.get(createdTag.getTag())).orElse(0L) + 1); createdTag.setCount(Optional.ofNullable(tagsCountMap.get(createdTag.getTag())).orElse(0L) + 1);
} }
ret.add(createdTag); ret.add(createdTag);
} }
return ret; return ret;
@@ -155,106 +155,106 @@ public class TagsImpl implements Tags
public void deleteTag(String nodeId, String tagId) public void deleteTag(String nodeId, String tagId)
{ {
NodeRef nodeRef = nodes.validateNode(nodeId); NodeRef nodeRef = nodes.validateNode(nodeId);
getTag(STORE_REF_WORKSPACE_SPACESSTORE, tagId, null); getTag(STORE_REF_WORKSPACE_SPACESSTORE, tagId, null);
NodeRef existingTagNodeRef = validateTag(tagId); NodeRef existingTagNodeRef = validateTag(tagId);
String tagValue = taggingService.getTagName(existingTagNodeRef); String tagValue = taggingService.getTagName(existingTagNodeRef);
taggingService.removeTag(nodeRef, tagValue); taggingService.removeTag(nodeRef, tagValue);
} }
@Override @Override
public void deleteTagById(StoreRef storeRef, String tagId) { public void deleteTagById(StoreRef storeRef, String tagId) {
verifyAdminAuthority(); verifyAdminAuthority();
NodeRef tagNodeRef = validateTag(storeRef, tagId); NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagValue = taggingService.getTagName(tagNodeRef); String tagValue = taggingService.getTagName(tagNodeRef);
taggingService.deleteTag(storeRef, tagValue); taggingService.deleteTag(storeRef, tagValue);
} }
@Override @Override
public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params) public CollectionWithPagingInfo<Tag> getTags(StoreRef storeRef, Parameters params)
{ {
Paging paging = params.getPaging(); Paging paging = params.getPaging();
Pair<String, Boolean> sorting = !params.getSorting().isEmpty() ? new Pair<>(params.getSorting().get(0).column, params.getSorting().get(0).asc) : null; Pair<String, Boolean> sorting = !params.getSorting().isEmpty() ? new Pair<>(params.getSorting().get(0).column, params.getSorting().get(0).asc) : null;
Map<Integer, Collection<String>> namesFilters = resolveTagNamesQuery(params.getQuery()); Map<Integer, Collection<String>> namesFilters = resolveTagNamesQuery(params.getQuery());
Map<NodeRef, Long> results = taggingService.getTags(storeRef, params.getInclude(), sorting, namesFilters.get(EQUALS), namesFilters.get(MATCHES)); Map<NodeRef, Long> results = taggingService.getTags(storeRef, params.getInclude(), sorting, namesFilters.get(EQUALS), namesFilters.get(MATCHES));
List<Tag> tagsList = results.entrySet().stream().map(entry -> new Tag(entry.getKey(), (String)nodeService.getProperty(entry.getKey(), ContentModel.PROP_NAME))).collect(Collectors.toList()); List<Tag> tagsList = results.entrySet().stream().map(entry -> new Tag(entry.getKey(), (String)nodeService.getProperty(entry.getKey(), ContentModel.PROP_NAME))).collect(Collectors.toList());
if (params.getInclude().contains(PARAM_INCLUDE_COUNT)) if (params.getInclude().contains(PARAM_INCLUDE_COUNT))
{ {
tagsList.forEach(tag -> tag.setCount(results.get(tag.getNodeRef()))); tagsList.forEach(tag -> tag.setCount(results.get(tag.getNodeRef())));
} }
ListBackedPagingResults listBackedPagingResults = new ListBackedPagingResults(tagsList, Util.getPagingRequest(params.getPaging())); ListBackedPagingResults listBackedPagingResults = new ListBackedPagingResults(tagsList, Util.getPagingRequest(params.getPaging()));
return CollectionWithPagingInfo.asPaged(paging, listBackedPagingResults.getPage(), listBackedPagingResults.hasMoreItems(), (Integer) listBackedPagingResults.getTotalResultCount().getFirst()); return CollectionWithPagingInfo.asPaged(paging, listBackedPagingResults.getPage(), listBackedPagingResults.hasMoreItems(), (Integer) listBackedPagingResults.getTotalResultCount().getFirst());
} }
public NodeRef validateTag(String tagId) public NodeRef validateTag(String tagId)
{ {
NodeRef tagNodeRef = nodes.validateNode(tagId); NodeRef tagNodeRef = nodes.validateNode(tagId);
return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef); return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef);
} }
public NodeRef validateTag(StoreRef storeRef, String tagId) public NodeRef validateTag(StoreRef storeRef, String tagId)
{ {
NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId); NodeRef tagNodeRef = nodes.validateNode(storeRef, tagId);
return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef); return checkTagRootAsNodePrimaryParent(tagId, tagNodeRef);
} }
/** /**
* Find the number of times the given tag is used (if requested). * Find the number of times the given tag is used (if requested).
* *
* @param storeRef The store the tag is in. * @param storeRef The store the tag is in.
* @param tagName The name of the tag. * @param tagName The name of the tag.
* @param parameters The request parameters object containing the includes parameter. * @param parameters The request parameters object containing the includes parameter.
* @return The number of times the tag is applied, or null if "count" wasn't in the include parameter. * @return The number of times the tag is applied, or null if "count" wasn't in the include parameter.
*/ */
private Long findCountIfRequested(StoreRef storeRef, String tagName, Parameters parameters) private Long findCountIfRequested(StoreRef storeRef, String tagName, Parameters parameters)
{ {
Long count = null; Long count = null;
if (parameters != null && parameters.getInclude() != null && parameters.getInclude().contains(PARAM_INCLUDE_COUNT)) if (parameters != null && parameters.getInclude() != null && parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
{ {
count = taggingService.findCountByTagName(storeRef, tagName); count = taggingService.findCountByTagName(storeRef, tagName);
} }
return count; return count;
} }
@Override @Override
public Tag changeTag(StoreRef storeRef, String tagId, Tag tag, Parameters parameters) public Tag changeTag(StoreRef storeRef, String tagId, Tag tag, Parameters parameters)
{ {
try try
{ {
NodeRef existingTagNodeRef = validateTag(storeRef, tagId); NodeRef existingTagNodeRef = validateTag(storeRef, tagId);
String existingTagName = taggingService.getTagName(existingTagNodeRef); String existingTagName = taggingService.getTagName(existingTagNodeRef);
Long count = findCountIfRequested(storeRef, existingTagName, parameters); Long count = findCountIfRequested(storeRef, existingTagName, parameters);
String newTagName = tag.getTag(); String newTagName = tag.getTag();
NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName); NodeRef newTagNodeRef = taggingService.changeTag(storeRef, existingTagName, newTagName);
return Tag.builder().nodeRef(newTagNodeRef).tag(newTagName).count(count).create(); return Tag.builder().nodeRef(newTagNodeRef).tag(newTagName).count(count).create();
} }
catch(NonExistentTagException e) catch(NonExistentTagException e)
{ {
throw new NotFoundException(e.getMessage()); throw new NotFoundException(e.getMessage());
} }
catch(TagExistsException e) catch(TagExistsException e)
{ {
throw new ConstraintViolatedException(e.getMessage()); throw new ConstraintViolatedException(e.getMessage());
} }
catch(TaggingException e) catch(TaggingException e)
{ {
throw new InvalidArgumentException(e.getMessage()); throw new InvalidArgumentException(e.getMessage());
} }
} }
@Override @Override
public Tag getTag(StoreRef storeRef, String tagId, Parameters parameters) public Tag getTag(StoreRef storeRef, String tagId, Parameters parameters)
{ {
NodeRef tagNodeRef = validateTag(storeRef, tagId); NodeRef tagNodeRef = validateTag(storeRef, tagId);
String tagName = taggingService.getTagName(tagNodeRef); String tagName = taggingService.getTagName(tagNodeRef);
Long count = findCountIfRequested(storeRef, tagName, parameters); Long count = findCountIfRequested(storeRef, tagName, parameters);
return Tag.builder().nodeRef(tagNodeRef).tag(tagName).count(count).create(); return Tag.builder().nodeRef(tagNodeRef).tag(tagName).count(count).create();
} }
@Override @Override
@@ -273,80 +273,80 @@ public class TagsImpl implements Tags
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 @Experimental
@Override @Override
public List<Tag> createTags(final StoreRef storeRef, final List<Tag> tags, final Parameters parameters) public List<Tag> createTags(final StoreRef storeRef, final List<Tag> tags, final Parameters parameters)
{ {
verifyAdminAuthority(); verifyAdminAuthority();
final List<String> tagNames = Optional.ofNullable(tags).orElse(Collections.emptyList()).stream() final List<String> tagNames = Optional.ofNullable(tags).orElse(Collections.emptyList()).stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.map(Tag::getTag) .map(Tag::getTag)
.distinct() .distinct()
.collect(toList()); .collect(toList());
if (CollectionUtils.isEmpty(tagNames)) if (CollectionUtils.isEmpty(tagNames))
{ {
throw new InvalidArgumentException(NOT_A_VALID_TAG); throw new InvalidArgumentException(NOT_A_VALID_TAG);
} }
return taggingService.createTags(storeRef, tagNames).stream() return taggingService.createTags(storeRef, tagNames).stream()
.map(pair -> Tag.builder().tag(pair.getFirst()).nodeRef(pair.getSecond()).create()) .map(pair -> Tag.builder().tag(pair.getFirst()).nodeRef(pair.getSecond()).create())
.peek(tag -> { .peek(tag -> {
if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT)) if (parameters.getInclude().contains(PARAM_INCLUDE_COUNT))
{ {
tag.setCount(0L); tag.setCount(0L);
} }
}).collect(toList()); }).collect(toList());
} }
private void verifyAdminAuthority() private void verifyAdminAuthority()
{ {
if (!authorityService.hasAdminAuthority()) if (!authorityService.hasAdminAuthority())
{ {
throw new PermissionDeniedException(NO_PERMISSION_TO_MANAGE_A_TAG); throw new PermissionDeniedException(NO_PERMISSION_TO_MANAGE_A_TAG);
} }
} }
/** /**
* Method resolves where query looking for clauses: EQUALS, IN or MATCHES. * Method resolves where query looking for clauses: EQUALS, IN or MATCHES.
* Expected values for EQUALS and IN will be merged under EQUALS clause. * Expected values for EQUALS and IN will be merged under EQUALS clause.
* @param namesQuery Where query with expected tag name(s). * @param namesQuery Where query with expected tag name(s).
* @return Map of expected exact and alike tag names. * @return Map of expected exact and alike tag names.
*/ */
private Map<Integer, Collection<String>> resolveTagNamesQuery(final Query namesQuery) private Map<Integer, Collection<String>> resolveTagNamesQuery(final Query namesQuery)
{ {
if (namesQuery == null || namesQuery == QueryImpl.EMPTY) if (namesQuery == null || namesQuery == QueryImpl.EMPTY)
{ {
return Collections.emptyMap(); return Collections.emptyMap();
} }
final Map<Integer, Collection<String>> properties = QueryHelper final Map<Integer, Collection<String>> properties = QueryHelper
.resolve(namesQuery) .resolve(namesQuery)
.usingOrOperator() .usingOrOperator()
.withoutNegations() .withoutNegations()
.getProperty(PARAM_WHERE_TAG) .getProperty(PARAM_WHERE_TAG)
.getExpectedValuesForAnyOf(EQUALS, IN, MATCHES) .getExpectedValuesForAnyOf(EQUALS, IN, MATCHES)
.skipNegated(); .skipNegated();
return properties.entrySet().stream() return properties.entrySet().stream()
.collect(Collectors.groupingBy((entry) -> { .collect(Collectors.groupingBy((entry) -> {
if (entry.getKey() == EQUALS || entry.getKey() == IN) if (entry.getKey() == EQUALS || entry.getKey() == IN)
{ {
return EQUALS; return EQUALS;
} }
else else
{ {
return MATCHES; return MATCHES;
} }
}, Collectors.flatMapping((entry) -> entry.getValue().stream().map(String::toLowerCase), Collectors.toCollection(HashSet::new)))); }, Collectors.flatMapping((entry) -> entry.getValue().stream().map(String::toLowerCase), Collectors.toCollection(HashSet::new))));
} }
private NodeRef checkTagRootAsNodePrimaryParent(String tagId, NodeRef tagNodeRef) private NodeRef checkTagRootAsNodePrimaryParent(String tagId, NodeRef tagNodeRef)
{ {
if ( tagNodeRef == null || !nodeService.getPrimaryParent(tagNodeRef).getParentRef().equals(TAG_ROOT_NODE_REF)) if ( tagNodeRef == null || !nodeService.getPrimaryParent(tagNodeRef).getParentRef().equals(TAG_ROOT_NODE_REF))
{ {
throw new EntityNotFoundException(tagId); throw new EntityNotFoundException(tagId);
} }
return tagNodeRef; return tagNodeRef;
} }
} }

View File

@@ -126,7 +126,7 @@ public class TaggingServiceImpl implements TaggingService,
private static Log logger = LogFactory.getLog(TaggingServiceImpl.class); private static Log logger = LogFactory.getLog(TaggingServiceImpl.class);
private static Collator collator = Collator.getInstance(); private static Collator collator = Collator.getInstance();
private NodeService nodeService; private NodeService nodeService;
private NodeService nodeServiceInternal; private NodeService nodeServiceInternal;
@@ -503,7 +503,7 @@ public class TaggingServiceImpl implements TaggingService,
// Lower the case of the tag // Lower the case of the tag
tag = tag.toLowerCase(); tag = tag.toLowerCase();
return getTagNodeRef(storeRef, tag, true); return getTagNodeRef(storeRef, tag, true);
} }
/** /**
@@ -532,33 +532,33 @@ public class TaggingServiceImpl implements TaggingService,
public NodeRef changeTag(StoreRef storeRef, String existingTag, String newTag) public NodeRef changeTag(StoreRef storeRef, String existingTag, String newTag)
{ {
if (existingTag == null) if (existingTag == null)
{ {
throw new TaggingException("Existing tag cannot be null"); throw new TaggingException("Existing tag cannot be null");
} }
if (newTag == null || StringUtils.isBlank(newTag)) if (newTag == null || StringUtils.isBlank(newTag))
{ {
throw new TaggingException("New tag cannot be blank"); throw new TaggingException("New tag cannot be blank");
} }
existingTag = existingTag.toLowerCase(); existingTag = existingTag.toLowerCase();
newTag = newTag.toLowerCase(); newTag = newTag.toLowerCase();
if (existingTag.equals(newTag)) if (existingTag.equals(newTag))
{ {
throw new TaggingException("New and existing tags are the same"); throw new TaggingException("New and existing tags are the same");
} }
if (getTagNodeRef(storeRef, existingTag) == null) if (getTagNodeRef(storeRef, existingTag) == null)
{ {
throw new NonExistentTagException("Tag " + existingTag + " not found"); throw new NonExistentTagException("Tag " + existingTag + " not found");
} }
if (getTagNodeRef(storeRef, newTag) != null) if (getTagNodeRef(storeRef, newTag) != null)
{ {
throw new TagExistsException("Tag " + newTag + " already exists"); throw new TagExistsException("Tag " + newTag + " already exists");
} }
NodeRef tagNodeRef = getTagNodeRef(storeRef, existingTag); NodeRef tagNodeRef = getTagNodeRef(storeRef, existingTag);
nodeService.setProperty(tagNodeRef, PROP_NAME, newTag); nodeService.setProperty(tagNodeRef, PROP_NAME, newTag);
@@ -718,12 +718,12 @@ public class TaggingServiceImpl implements TaggingService,
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public NodeRef addTag(final NodeRef nodeRef, final String tagName) public NodeRef addTag(final NodeRef nodeRef, final String tagName)
{ {
NodeRef newTagNodeRef = null; NodeRef newTagNodeRef = null;
if(tagName == null) if(tagName == null)
{ {
throw new IllegalArgumentException("Must provide a non-null tag"); throw new IllegalArgumentException("Must provide a non-null tag");
} }
updateTagBehaviour.disable(); updateTagBehaviour.disable();
createTagBehaviour.disable(); createTagBehaviour.disable();
@@ -773,7 +773,7 @@ public class TaggingServiceImpl implements TaggingService,
*/ */
public List<Pair<String, NodeRef>> addTags(NodeRef nodeRef, List<String> tags) public List<Pair<String, NodeRef>> addTags(NodeRef nodeRef, List<String> tags)
{ {
List<Pair<String, NodeRef>> ret = new ArrayList<Pair<String, NodeRef>>(); List<Pair<String, NodeRef>> ret = new ArrayList<Pair<String, NodeRef>>();
for (String tag : tags) for (String tag : tags)
{ {
NodeRef tagNodeRef = addTag(nodeRef, tag); NodeRef tagNodeRef = addTag(nodeRef, tag);
@@ -894,36 +894,36 @@ public class TaggingServiceImpl implements TaggingService,
int skipCount = pagingRequest.getSkipCount(); int skipCount = pagingRequest.getSkipCount();
int maxItems = pagingRequest.getMaxItems(); int maxItems = pagingRequest.getMaxItems();
int end = maxItems == Integer.MAX_VALUE ? totalItems : skipCount + maxItems; int end = maxItems == Integer.MAX_VALUE ? totalItems : skipCount + maxItems;
int size = (maxItems == Integer.MAX_VALUE ? totalItems : maxItems); int size = (maxItems == Integer.MAX_VALUE ? totalItems : maxItems);
final List<Pair<NodeRef, String>> sortedTags = new ArrayList<Pair<NodeRef, String>>(size); final List<Pair<NodeRef, String>> sortedTags = new ArrayList<Pair<NodeRef, String>>(size);
// grab all tags and sort (assume fairly low number of tags) // grab all tags and sort (assume fairly low number of tags)
for(NodeRef tagNode : currentTagNodes) for(NodeRef tagNode : currentTagNodes)
{ {
String tag = (String)this.nodeService.getProperty(tagNode, PROP_NAME); String tag = (String)this.nodeService.getProperty(tagNode, PROP_NAME);
sortedTags.add(new Pair<NodeRef, String>(tagNode, tag)); sortedTags.add(new Pair<NodeRef, String>(tagNode, tag));
} }
Collections.sort(sortedTags, new Comparator<Pair<NodeRef, String>>() Collections.sort(sortedTags, new Comparator<Pair<NodeRef, String>>()
{ {
@Override @Override
public int compare(Pair<NodeRef, String> o1, Pair<NodeRef, String> o2) public int compare(Pair<NodeRef, String> o1, Pair<NodeRef, String> o2)
{ {
String tag1 = o1.getSecond(); String tag1 = o1.getSecond();
String tag2 = o2.getSecond(); String tag2 = o2.getSecond();
return collator.compare(tag1, tag2); return collator.compare(tag1, tag2);
} }
}); });
final List<Pair<NodeRef, String>> result = new ArrayList<Pair<NodeRef, String>>(size); final List<Pair<NodeRef, String>> result = new ArrayList<Pair<NodeRef, String>>(size);
Iterator<Pair<NodeRef, String>> it = sortedTags.iterator(); Iterator<Pair<NodeRef, String>> it = sortedTags.iterator();
for(int count = 0; count < end && it.hasNext(); count++) for(int count = 0; count < end && it.hasNext(); count++)
{ {
Pair<NodeRef, String> tagPair = it.next(); Pair<NodeRef, String> tagPair = it.next();
if(count < skipCount) if(count < skipCount)
{ {
continue; continue;
} }
result.add(tagPair); result.add(tagPair);
} }
@@ -932,30 +932,30 @@ public class TaggingServiceImpl implements TaggingService,
return new PagingResults<Pair<NodeRef, String>>() return new PagingResults<Pair<NodeRef, String>>()
{ {
@Override @Override
public List<Pair<NodeRef, String>> getPage() public List<Pair<NodeRef, String>> getPage()
{ {
return result; return result;
} }
@Override @Override
public boolean hasMoreItems() public boolean hasMoreItems()
{ {
return hasMoreItems; return hasMoreItems;
} }
@Override @Override
public Pair<Integer, Integer> getTotalResultCount() public Pair<Integer, Integer> getTotalResultCount()
{ {
Integer total = Integer.valueOf(totalItems); Integer total = Integer.valueOf(totalItems);
return new Pair<Integer, Integer>(total, total); return new Pair<Integer, Integer>(total, total);
} }
@Override @Override
public String getQueryExecutionId() public String getQueryExecutionId()
{ {
return null; return null;
} }
}; };
} }
} }
@@ -1028,7 +1028,7 @@ public class TaggingServiceImpl implements TaggingService,
{ {
if (tagsByCountMap.isEmpty()) if (tagsByCountMap.isEmpty())
{ {
throw new QueryException("Tag count should be included when ordering by count"); throw new IllegalArgumentException("Tag count should be included when ordering by count");
} }
if (!sorting.getSecond()) if (!sorting.getSecond())
@@ -1289,14 +1289,14 @@ public class TaggingServiceImpl implements TaggingService,
*/ */
private void getTagScopes(final NodeRef nodeRef, List<NodeRef> tagScopes, boolean firstOnly) private void getTagScopes(final NodeRef nodeRef, List<NodeRef> tagScopes, boolean firstOnly)
{ {
Boolean hasAspect = AuthenticationUtil.runAs(new RunAsWork<Boolean>() Boolean hasAspect = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
{ {
@Override @Override
public Boolean doWork() throws Exception public Boolean doWork() throws Exception
{ {
return new Boolean(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE)); return new Boolean(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGSCOPE));
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
if (Boolean.TRUE.equals(hasAspect) == true) if (Boolean.TRUE.equals(hasAspect) == true)
{ {
@@ -1308,23 +1308,23 @@ public class TaggingServiceImpl implements TaggingService,
} }
NodeRef parent = AuthenticationUtil.runAs(new RunAsWork<NodeRef>() NodeRef parent = AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
{ {
@Override @Override
public NodeRef doWork() throws Exception public NodeRef doWork() throws Exception
{ {
NodeRef result = null; NodeRef result = null;
ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef);
if (assoc != null) if (assoc != null)
{ {
result = assoc.getParentRef(); result = assoc.getParentRef();
} }
return result; return result;
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
if (parent != null) if (parent != null)
{ {
getTagScopes(parent, tagScopes, firstOnly); getTagScopes(parent, tagScopes, firstOnly);
} }
} }