diff --git a/core/src/main/java/org/alfresco/query/ListBackedPagingResults.java b/core/src/main/java/org/alfresco/query/ListBackedPagingResults.java index a2833cc67d..0158b0bdc7 100644 --- a/core/src/main/java/org/alfresco/query/ListBackedPagingResults.java +++ b/core/src/main/java/org/alfresco/query/ListBackedPagingResults.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2011 Alfresco Software Limited. + * Copyright (C) 2005-2022 Alfresco Software Limited. * * This file is part of Alfresco * @@ -16,6 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ + package org.alfresco.query; import java.util.Collections; @@ -55,7 +56,7 @@ public class ListBackedPagingResults implements PagingResults } this.results = Collections.unmodifiableList( - list.subList(start, end)); + list.subList(Math.min(start, end), end)); this.size = list.size(); this.hasMore = ! (list.size() == end); } diff --git a/pom.xml b/pom.xml index 76fd32f91f..5a33843434 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,7 @@ 8.31 1.70 4.6.1 + 3.23.1 20220320 2.9.0 2.11.0 @@ -755,6 +756,11 @@ mockito-core ${dependency.mockito-core.version} + + org.assertj + assertj-core + ${dependency.assertj.version} + org.apache.commons commons-dbcp2 diff --git a/remote-api/pom.xml b/remote-api/pom.xml index 8531e63c47..f6dabc2ea5 100644 --- a/remote-api/pom.xml +++ b/remote-api/pom.xml @@ -87,6 +87,11 @@ mockito-core test + + org.assertj + assertj-core + test + org.springframework spring-test diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Rules.java b/remote-api/src/main/java/org/alfresco/rest/api/Rules.java new file mode 100644 index 0000000000..87a3e98d73 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/Rules.java @@ -0,0 +1,50 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api; + +import org.alfresco.rest.api.model.Rule; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.service.Experimental; + +/** + * Folder node rules API. + * + */ +@Experimental +public interface Rules +{ + /** + * Get rules for node's and rule set's IDs + * + * @param folderNodeId node ID + * @param ruleSetId rule set ID + * @param paging {@link Paging} information + * @return {@link CollectionWithPagingInfo} containing a list page of folder rules + */ + CollectionWithPagingInfo getRules(String folderNodeId, String ruleSetId, Paging paging); +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java new file mode 100644 index 0000000000..8eaf7cba0c --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/RulesImpl.java @@ -0,0 +1,129 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.impl; + +import org.alfresco.model.ContentModel; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.Rules; +import org.alfresco.rest.api.model.Rule; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.ListPage; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.QName; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Experimental +public class RulesImpl implements Rules +{ + + private static final String DEFAULT_RULE_SET_ID = "-default-"; + + private Nodes nodes; + + private PermissionService permissionService; + + private RuleService ruleService; + + @Override + public CollectionWithPagingInfo getRules(final String folderNodeId, final String ruleSetId, final Paging paging) + { + final NodeRef folderNodeRef = validateNode(folderNodeId, ContentModel.TYPE_FOLDER); + + if (isNotDefaultId(ruleSetId)) { + final NodeRef ruleSetNodeRef = validateNode(ruleSetId, ContentModel.TYPE_SYSTEM_FOLDER, "rule set"); + + if (!ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderNodeRef)) { + throw new InvalidArgumentException("Rule set is not associated with folder node!"); + } + } + + final List rules = ruleService.getRules(folderNodeRef).stream() + .map(Rule::from) + .collect(Collectors.toList()); + + return ListPage.of(rules, paging); + } + + public void setNodes(Nodes nodes) + { + this.nodes = nodes; + } + + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + public void setRuleService(RuleService ruleService) + { + this.ruleService = ruleService; + } + + private NodeRef validateNode(final String nodeId, final QName namespaceType) + { + return validateNode(nodeId, namespaceType, null); + } + + /** + * Validates if node exists, user have permission to read from it and is of a given type. + * + * @param nodeId - node ID + * @param expectedType - expected type + * @param expectedTypeName - expected type local name + * @return node reference + */ + private NodeRef validateNode(final String nodeId, final QName expectedType, final String expectedTypeName) + { + final NodeRef nodeRef = nodes.validateNode(nodeId); + + if (permissionService.hasReadPermission(nodeRef) != AccessStatus.ALLOWED) { + throw new PermissionDeniedException("Cannot read from this node!"); + } + + final Set expectedTypes = Set.of(expectedType); + if (!nodes.nodeMatches(nodeRef, expectedTypes, null)) { + final String expectedTypeLocalName = (expectedTypeName != null)? expectedTypeName : expectedType.getLocalName(); + throw new InvalidArgumentException(String.format("NodeId of a %s is expected!", expectedTypeLocalName)); + } + + return nodeRef; + } + + private static boolean isNotDefaultId(final String ruleSetId) { + return !DEFAULT_RULE_SET_ID.equals(ruleSetId); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/Rule.java b/remote-api/src/main/java/org/alfresco/rest/api/model/Rule.java new file mode 100644 index 0000000000..13812bcafd --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/model/Rule.java @@ -0,0 +1,70 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.model; + +import org.alfresco.rest.framework.resource.UniqueId; +import org.alfresco.service.Experimental; + +@Experimental +public class Rule +{ + private String id; + private String name; + + public static Rule from(final org.alfresco.service.cmr.rule.Rule ruleModel) { + if (ruleModel == null) { + return null; + } + + final Rule rule = new Rule(); + rule.id = ruleModel.getNodeRef().getId(); + rule.name = ruleModel.getTitle(); + + return rule; + } + + @UniqueId + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRuleSetsRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRuleSetsRelation.java new file mode 100644 index 0000000000..4a3d3163f9 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRuleSetsRelation.java @@ -0,0 +1,40 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.nodes; + +import org.alfresco.rest.framework.resource.RelationshipResource; +import org.alfresco.service.Experimental; + +/** + * Folder node rule sets. + * + */ +@Experimental +@RelationshipResource(name = "rule-sets", entityResource = NodesEntityResource.class, title = "Folder node rule sets") +public class NodeRuleSetsRelation +{ +} diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRulesRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRulesRelation.java new file mode 100644 index 0000000000..3cb37dbf21 --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeRulesRelation.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.nodes; + +import org.alfresco.rest.api.Rules; +import org.alfresco.rest.api.model.Rule; +import org.alfresco.rest.framework.WebApiDescription; +import org.alfresco.rest.framework.resource.RelationshipResource; +import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.service.Experimental; +import org.alfresco.util.PropertyCheck; +import org.springframework.beans.factory.InitializingBean; + +import javax.servlet.http.HttpServletResponse; + +/** + * Folder node's rules. + * + */ +@Experimental +@RelationshipResource(name = "rules", entityResource = NodeRuleSetsRelation.class, title = "Folder node rules") +public class NodeRulesRelation implements RelationshipResourceAction.Read, InitializingBean +{ + + private Rules rules; + + @Override + public void afterPropertiesSet() throws Exception + { + PropertyCheck.mandatory(this, "rules", this.rules); + } + + /** + * List folder node rules for given node's and rule set's IDs as a page. + * + * - GET /nodes/{folderNodeId}/rulesets/{ruleSetId}/rules + * + * @param folderNodeId - entity resource context for this relationship + * @param parameters - will never be null. Contains i.a. paging information and ruleSetId (relationshipId) + * @return a paged list of folder rules + */ + @WebApiDescription( + title = "Get folder node rules", + description = "Returns a paged list of folder rules for given node's and rule set's ID", + successStatus = HttpServletResponse.SC_OK + ) + @Override + public CollectionWithPagingInfo readAll(String folderNodeId, Parameters parameters) + { + final String ruleSetId = parameters.getRelationshipId(); + + return rules.getRules(folderNodeId, ruleSetId, parameters.getPaging()); + } + + public void setRules(Rules rules) + { + this.rules = rules; + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ArrayListPage.java b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ArrayListPage.java new file mode 100644 index 0000000000..76e518186d --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ArrayListPage.java @@ -0,0 +1,123 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.framework.resource.parameters; + +import org.alfresco.rest.api.search.context.SearchContext; +import org.alfresco.service.Experimental; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Experimental +public class ArrayListPage extends ArrayList implements ListPage +{ + private final Paging paging; + private final int totalItems; + private final boolean hasMore; + + public ArrayListPage(final List list) + { + super(list != null ? list : Collections.emptyList()); + this.paging = null; + this.totalItems = this.size(); + this.hasMore = false; + } + + public ArrayListPage(final List list, final Paging paging) + { + super(sublistFrom(list, paging)); + this.paging = paging; + if (list != null) + { + this.totalItems = list.size(); + if (paging != null) + { + final int start = paging.getSkipCount(); + final int end = (paging.getMaxItems() == 0) ? list.size() : Math.min(list.size(), start + paging.getMaxItems()); + this.hasMore = !(list.size() == end); + } else { + this.hasMore = false; + } + } else { + this.totalItems = 0; + this.hasMore = false; + } + } + + @Override + public Paging getPaging() + { + return paging; + } + + @Override + public Integer getTotalItems() + { + return totalItems; + } + + @Override + public boolean hasMoreItems() + { + return hasMore; + } + + @Override + public String getQueryExecutionId() + { + return null; + } + + @Override + public Object getSourceEntity() + { + return null; + } + + @Override + public SearchContext getContext() + { + return null; + } + + private static List sublistFrom(final List list, final Paging paging) + { + if (list == null) + { + return Collections.emptyList(); + } + if (paging == null) + { + return list; + } + + final int start = paging.getSkipCount(); + final int end = (paging.getMaxItems() == 0)? list.size() : Math.min(list.size(), start + paging.getMaxItems()); + return list.subList(Math.min(start, end), end); + } +} diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/CollectionWithPagingInfo.java b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/CollectionWithPagingInfo.java index cff6072f6e..b303e9fa08 100644 --- a/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/CollectionWithPagingInfo.java +++ b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/CollectionWithPagingInfo.java @@ -2,7 +2,7 @@ * #%L * Alfresco Remote API * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -43,7 +43,7 @@ import java.util.Collections; * * @author Gethin James. */ -public class CollectionWithPagingInfo implements SerializablePagedCollection +public class CollectionWithPagingInfo implements SerializablePagedCollection { private final Collection collection; @@ -80,6 +80,18 @@ public class CollectionWithPagingInfo implements SerializablePagedCollection this.context = context; } + /** + * Constructs a new CollectionWithPagingInfo from a {@link SerializablePagedCollection} instance. + * + * @param pagedCollection - a collection with paging information + * @return CollectionWithPagingInfo + */ + public static CollectionWithPagingInfo from(SerializablePagedCollection pagedCollection) + { + return new CollectionWithPagingInfo<>(pagedCollection.getCollection(), pagedCollection.getPaging(), pagedCollection.hasMoreItems(), pagedCollection.getTotalItems(), + pagedCollection.getSourceEntity(), pagedCollection.getContext()); + } + /** * Constructs a new CollectionWithPagingInfo. * It automatically sets the total items based on the collection size and diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ListPage.java b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ListPage.java new file mode 100644 index 0000000000..8b0d99534c --- /dev/null +++ b/remote-api/src/main/java/org/alfresco/rest/framework/resource/parameters/ListPage.java @@ -0,0 +1,80 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.framework.resource.parameters; + +import org.alfresco.query.PagingResults; +import org.alfresco.rest.framework.resource.SerializablePagedCollection; +import org.alfresco.service.Experimental; +import org.alfresco.util.Pair; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * List page with paging information. + * + * + * @param - list element type + */ +@Experimental +public interface ListPage extends List, PagingResults, SerializablePagedCollection +{ + + default List getPage() + { + return this; + } + + default Pair getTotalResultCount() + { + return new Pair<>(this.getTotalItems(), this.getTotalItems()); + } + + default Collection getCollection() + { + return this; + } + + /** + * Builds a collection with paging information. + * + * @param list - the list that needs to be paged + * @param paging - paging request info + * @return list page in {@link CollectionWithPagingInfo} + * @param - list element type + */ + static CollectionWithPagingInfo of(final List list, final Paging paging) + { + if (list == null) + { + return CollectionWithPagingInfo.asPaged(paging, Collections.emptyList()); + } + + return CollectionWithPagingInfo.from(new ArrayListPage<>(list, paging)); + } +} diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml index 11bc9ac49b..a8a1efd97a 100644 --- a/remote-api/src/main/resources/alfresco/public-rest-context.xml +++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml @@ -850,6 +850,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java b/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java index badb4c25f4..ddd6508f0f 100644 --- a/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java +++ b/remote-api/src/test/java/org/alfresco/AppContextExtraTestSuite.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2017 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -49,6 +49,8 @@ import org.junit.runners.Suite; org.alfresco.repo.webdav.WebDAVHelperTest.class, org.alfresco.repo.webdav.WebDAVLockServiceImplTest.class, org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class, + org.alfresco.rest.api.impl.RulesImplTest.class, + org.alfresco.rest.api.nodes.NodeRulesRelationTest.class, org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class, org.alfresco.rest.api.search.ResultMapperTests.class, org.alfresco.rest.api.search.SearchApiWebscriptTests.class, @@ -56,6 +58,7 @@ import org.junit.runners.Suite; org.alfresco.rest.api.search.SearchQuerySerializerTests.class, org.alfresco.rest.api.search.StoreMapperTests.class, org.alfresco.rest.api.tests.ModulePackageTest.class, + org.alfresco.rest.framework.resource.parameters.ArrayListPageTest.class, org.alfresco.rest.framework.tests.core.InspectorTests.class, org.alfresco.rest.framework.tests.core.JsonJacksonTests.class, org.alfresco.rest.framework.tests.core.ParamsExtractorTests.class, diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java new file mode 100644 index 0000000000..52e70fe181 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/RulesImplTest.java @@ -0,0 +1,193 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.impl; + +import junit.framework.TestCase; +import org.alfresco.rest.api.Nodes; +import org.alfresco.rest.api.model.Rule; +import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; +import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException; +import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.service.Experimental; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class RulesImplTest extends TestCase +{ + + private static final String FOLDER_NODE_ID = "dummy-node-id"; + private static final String RULE_SET_ID = "dummy-rule-set-id"; + private static final NodeRef folderNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_NODE_ID); + private static final NodeRef ruleSetNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID); + + @Mock + private Nodes nodes; + + @Mock + private PermissionService permissionService; + + @Mock + private RuleService ruleService; + + @InjectMocks + private RulesImpl rules; + + @Before + @Override + public void setUp() throws Exception + { + MockitoAnnotations.openMocks(this); + + given(nodes.validateNode(eq(FOLDER_NODE_ID))).willReturn(folderNodeRef); + given(nodes.validateNode(eq(RULE_SET_ID))).willReturn(ruleSetNodeRef); + given(nodes.nodeMatches(any(), any(), any())).willReturn(true); + given(permissionService.hasReadPermission(any())).willReturn(AccessStatus.ALLOWED); + } + + @Test + public void testGetRules() + { + final Paging paging = Paging.DEFAULT; + given(ruleService.isRuleSetAssociatedWithFolder(any(), any())).willReturn(true); + + // when + final CollectionWithPagingInfo rulesPage = rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging); + + then(nodes).should().validateNode(eq(FOLDER_NODE_ID)); + then(nodes).should().validateNode(eq(RULE_SET_ID)); + then(nodes).should().nodeMatches(eq(folderNodeRef), any(), isNull()); + then(nodes).should().nodeMatches(eq(ruleSetNodeRef), any(), isNull()); + then(nodes).shouldHaveNoMoreInteractions(); + then(permissionService).should().hasReadPermission(eq(folderNodeRef)); + then(permissionService).should().hasReadPermission(eq(ruleSetNodeRef)); + then(permissionService).shouldHaveNoMoreInteractions(); + then(ruleService).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef)); + then(ruleService).should().getRules(eq(folderNodeRef)); + then(ruleService).shouldHaveNoMoreInteractions(); + assertThat(rulesPage) + .isNotNull() + .extracting(CollectionWithPagingInfo::getCollection) + .isNotNull(); + } + + @Test + public void testGetRulesForDefaultRuleSet() + { + final String defaultRuleSetId = "-default-"; + final Paging paging = Paging.DEFAULT; + + // when + final CollectionWithPagingInfo rulesPage = rules.getRules(FOLDER_NODE_ID, defaultRuleSetId, paging); + + then(nodes).should().validateNode(eq(FOLDER_NODE_ID)); + then(nodes).should().nodeMatches(eq(folderNodeRef), any(), isNull()); + then(nodes).shouldHaveNoMoreInteractions(); + then(permissionService).should().hasReadPermission(eq(folderNodeRef)); + then(permissionService).shouldHaveNoMoreInteractions(); + then(ruleService).should().getRules(eq(folderNodeRef)); + then(ruleService).shouldHaveNoMoreInteractions(); + assertThat(rulesPage) + .isNotNull() + .extracting(CollectionWithPagingInfo::getCollection) + .isNotNull(); + } + + @Test + public void testGetRulesForNotExistingFolderNode() + { + final Paging paging = Paging.DEFAULT; + given(nodes.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(false); + + // when + assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy( + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging)); + + then(ruleService).shouldHaveNoInteractions(); + } + + @Test + public void testGetRulesForNotExistingRuleSetNode() + { + final Paging paging = Paging.DEFAULT; + given(nodes.nodeMatches(eq(folderNodeRef), any(), any())).willReturn(true); + given(nodes.nodeMatches(eq(ruleSetNodeRef), any(), any())).willReturn(false); + + // when + assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy( + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging)); + + then(ruleService).shouldHaveNoInteractions(); + } + + @Test + public void testGetRulesForNotAssociatedRuleSetToFolder() + { + final Paging paging = Paging.DEFAULT; + given(ruleService.isRuleSetAssociatedWithFolder(any(), any())).willReturn(false); + + // when + assertThatExceptionOfType(InvalidArgumentException.class).isThrownBy( + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging)); + + then(ruleService).should().isRuleSetAssociatedWithFolder(eq(ruleSetNodeRef), eq(folderNodeRef)); + then(ruleService).shouldHaveNoMoreInteractions(); + } + + @Test + public void testGetRulesWithoutReadPermission() + { + final Paging paging = Paging.DEFAULT; + given(permissionService.hasReadPermission(any())).willReturn(AccessStatus.DENIED); + + // when + assertThatExceptionOfType(PermissionDeniedException.class).isThrownBy( + () -> rules.getRules(FOLDER_NODE_ID, RULE_SET_ID, paging)); + + then(ruleService).shouldHaveNoInteractions(); + } +} \ No newline at end of file diff --git a/remote-api/src/test/java/org/alfresco/rest/api/nodes/NodeRulesRelationTest.java b/remote-api/src/test/java/org/alfresco/rest/api/nodes/NodeRulesRelationTest.java new file mode 100644 index 0000000000..0c776ad7d5 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/api/nodes/NodeRulesRelationTest.java @@ -0,0 +1,80 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.api.nodes; + +import junit.framework.TestCase; +import org.alfresco.rest.api.Rules; +import org.alfresco.rest.framework.resource.parameters.Paging; +import org.alfresco.rest.framework.resource.parameters.Parameters; +import org.alfresco.rest.framework.resource.parameters.Params; +import org.alfresco.service.Experimental; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.then; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class NodeRulesRelationTest extends TestCase +{ + + private static final String FOLDER_NODE_ID = "dummy-node-id"; + private static final String RULE_SET_ID = "dummy-rule-set-id"; + + @Mock + private Rules rules; + + @InjectMocks + private NodeRulesRelation nodeRulesRelation; + + @Override + @Before + public void setUp() throws Exception + { + MockitoAnnotations.openMocks(this); + } + + @Test + public void testReadAll() + { + final Paging paging = Paging.DEFAULT; + final Params.RecognizedParams params = new Params.RecognizedParams(null, paging, null, null, null, null, null, null, false); + final Parameters parameters = Params.valueOf(FOLDER_NODE_ID, RULE_SET_ID, params, null, null); + + // when + nodeRulesRelation.readAll(FOLDER_NODE_ID, parameters); + + then(rules).should().getRules(eq(FOLDER_NODE_ID), eq(RULE_SET_ID), eq(paging)); + then(rules).shouldHaveNoMoreInteractions(); + } +} \ No newline at end of file diff --git a/remote-api/src/test/java/org/alfresco/rest/framework/resource/parameters/ArrayListPageTest.java b/remote-api/src/test/java/org/alfresco/rest/framework/resource/parameters/ArrayListPageTest.java new file mode 100644 index 0000000000..df9a88dad2 --- /dev/null +++ b/remote-api/src/test/java/org/alfresco/rest/framework/resource/parameters/ArrayListPageTest.java @@ -0,0 +1,198 @@ +/* + * #%L + * Alfresco Remote API + * %% + * Copyright (C) 2005 - 2022 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.rest.framework.resource.parameters; + +import junit.framework.TestCase; +import org.alfresco.rest.framework.resource.SerializablePagedCollection; +import org.alfresco.service.Experimental; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +@Experimental +@RunWith(MockitoJUnitRunner.class) +public class ArrayListPageTest extends TestCase +{ + + private List getPageFormats() { + return List.of( + new PageFormat(10, 0), + new PageFormat(10, 10), + new PageFormat(110, 20) + ); + } + + @Test + public void testCreatePage() + { + final List pageFormats = getPageFormats(); + for (PageFormat pageFormat : pageFormats) + { + final int pageSize = pageFormat.size; + final int offset = pageFormat.offset; + final List list = randomListOf(offset,100, Object.class); + final Paging paging = Paging.valueOf(offset, pageSize); + + // when + final SerializablePagedCollection page = new ArrayListPage<>(list, paging); + + assertThat(page) + .isNotNull() + .extracting(SerializablePagedCollection::getCollection) + .isNotNull() + .isEqualTo(list.subList(offset, Math.min(offset + pageSize, list.size()))) + .extracting(Collection::size) + .isEqualTo(Math.min(pageSize, list.size() - offset)); + assertThat(page.getTotalItems()) + .isEqualTo(list.size()); + assertThat(page.hasMoreItems()) + .isEqualTo(list.size() - offset > pageSize); + assertThat(page.getPaging()) + .isNotNull(); + } + } + + @Test + public void testCreatePageWithoutPaging() + { + final List list = randomListOf(0,100, Object.class); + + // when + final SerializablePagedCollection page = new ArrayListPage<>(list); + + assertThat(page) + .isNotNull() + .extracting(SerializablePagedCollection::getCollection) + .isNotNull() + .isEqualTo(list) + .extracting(Collection::size) + .isEqualTo(list.size()); + assertThat(page.getTotalItems()) + .isEqualTo(list.size()); + assertThat(page.hasMoreItems()) + .isFalse(); + assertThat(page.getPaging()) + .isNull(); + } + + @Test + public void testCreatePageForBiggerOffsetThanListSize() + { + final int offset = 10; + final List list = createListOf(8, Object.class); + final Paging paging = Paging.valueOf(offset, 5); + + // when + final SerializablePagedCollection page = new ArrayListPage<>(list, paging); + + assertThat(page) + .isNotNull() + .extracting(SerializablePagedCollection::getCollection) + .isNotNull() + .extracting(Collection::isEmpty) + .isEqualTo(true); + assertThat(page.getTotalItems()) + .isEqualTo(list.size()); + assertThat(page.hasMoreItems()) + .isFalse(); + } + + @Test + public void testCreatePageForNullList() + { + // when + final SerializablePagedCollection page = new ArrayListPage<>(null, Paging.DEFAULT); + + assertThat(page) + .isNotNull() + .extracting(SerializablePagedCollection::getCollection) + .isNotNull() + .extracting(Collection::isEmpty) + .isEqualTo(true); + assertThat(page.getTotalItems()) + .isEqualTo(0); + assertThat(page.hasMoreItems()) + .isFalse(); + } + + @Test + public void testCreatePageForNullPaging() + { + final List list = createListOf(18, Object.class); + + // when + final SerializablePagedCollection page = new ArrayListPage<>(list, null); + + assertThat(page) + .isNotNull() + .extracting(SerializablePagedCollection::getCollection) + .isNotNull() + .extracting(Collection::size) + .isEqualTo(list.size()); + assertThat(page.getTotalItems()) + .isEqualTo(list.size()); + assertThat(page.hasMoreItems()) + .isFalse(); + assertThat(page.getPaging()) + .isNull(); + } + + private static List randomListOf(final int minSize, final int maxSize, final Class clazz) { + return createListOf(new Random().nextInt((maxSize - minSize) + 1) + minSize, clazz); + } + + private static List createListOf(final int size, final Class clazz) { + final List list = new ArrayList<>(); + for (int i = 0; i < size; i++) { + list.add(mock(clazz)); + } + Collections.shuffle(list); + + return list; + } + + private static final class PageFormat + { + private final int size; + private final int offset; + + public PageFormat(int size, int offset) + { + this.size = size; + this.offset = offset; + } + } +} \ No newline at end of file diff --git a/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java b/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java index 220a0167d4..7cc3e777f8 100644 --- a/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/rule/RuleServiceImpl.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -25,15 +25,6 @@ */ package org.alfresco.repo.rule; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ActionImpl; import org.alfresco.repo.action.ActionModel; @@ -66,12 +57,22 @@ import org.alfresco.service.cmr.rule.RuleType; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.GUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.extensions.surf.util.ParameterCheck; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * Rule service implementation. *

@@ -1611,4 +1612,15 @@ public class RuleServiceImpl } return result; } + + @Override + public boolean isRuleSetAssociatedWithFolder(final NodeRef ruleSetNodeRef, final NodeRef folderNodeRef) { + return findAssociatedParents(ruleSetNodeRef, RuleModel.ASSOC_RULE_FOLDER).stream() + .map(ChildAssociationRef::getParentRef) + .anyMatch(folderNodeRef::equals); + } + + private List findAssociatedParents(final NodeRef nodeRef, final QNamePattern pattern) { + return runtimeNodeService.getParentAssocs(nodeRef, pattern, pattern); + } } diff --git a/repository/src/main/java/org/alfresco/service/cmr/rule/Rule.java b/repository/src/main/java/org/alfresco/service/cmr/rule/Rule.java index 43631e3614..db8d3f5cd2 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/rule/Rule.java +++ b/repository/src/main/java/org/alfresco/service/cmr/rule/Rule.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2022 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.service.cmr.rule; import java.io.Serializable; @@ -70,7 +70,7 @@ public class Rule implements Serializable /** * The associated action */ - private Action action; + private Action action; /** * Indicates whether the rule should execute the action asynchronously or not diff --git a/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java b/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java index 9367052f36..175c2e2347 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java +++ b/repository/src/main/java/org/alfresco/service/cmr/rule/RuleService.java @@ -1,28 +1,28 @@ -/* - * #%L - * Alfresco Repository - * %% - * Copyright (C) 2005 - 2016 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% - */ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2022 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.service.cmr.rule; import java.util.List; @@ -329,4 +329,14 @@ public interface RuleService */ @Auditable(parameters = {"nodeRef"}) public List getLinkedFromRuleNodes(NodeRef nodeRef); + + /** + * Check if rule set's associated parent is equal to folder node. + * + * @param ruleSetNodeRef - node reference of a rule set + * @param folderNodeRef - node reference of a folder + * @return true if rule set is associated with folder + */ + @Auditable(parameters = {"nodeRef"}) + boolean isRuleSetAssociatedWithFolder(NodeRef ruleSetNodeRef, NodeRef folderNodeRef); } diff --git a/repository/src/test/java/org/alfresco/repo/rule/RuleLinkTest.java b/repository/src/test/java/org/alfresco/repo/rule/RuleLinkTest.java index 1e4f492cf2..b1db17102d 100644 --- a/repository/src/test/java/org/alfresco/repo/rule/RuleLinkTest.java +++ b/repository/src/test/java/org/alfresco/repo/rule/RuleLinkTest.java @@ -2,7 +2,7 @@ * #%L * Alfresco Repository * %% - * Copyright (C) 2005 - 2016 Alfresco Software Limited + * Copyright (C) 2005 - 2022 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of @@ -25,12 +25,6 @@ */ package org.alfresco.repo.rule; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator; @@ -41,6 +35,7 @@ import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionCondition; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -56,6 +51,12 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.springframework.transaction.annotation.Transactional; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Parameter definition implementation unit test. * @@ -350,7 +351,41 @@ public class RuleLinkTest extends BaseSpringTest assertTrue(nodeService.hasAspect(folderThree, RuleModel.ASPECT_RULES)); assertEquals(rules1, rules3); } - + + @Test + public void testIsRuleSetAssociatedWithFolder() + { + final Rule rule = createTestRule(false, "luke"); + this.ruleService.saveRule(folderOne, rule); + final NodeRef ruleSetNodeRef = nodeService.getChildAssocs(folderOne, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER).stream() + .filter(ChildAssociationRef::isPrimary) + .map(ChildAssociationRef::getChildRef) + .findFirst() + .orElse(null); + + // when + final boolean associated = ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderOne); + + assertTrue(associated); + } + + @Test + public void testIsRuleSetNotAssociatedWithFolder() + { + final Rule rule = createTestRule(false, "luke"); + this.ruleService.saveRule(folderTwo , rule); + final NodeRef ruleSetNodeRef = nodeService.getChildAssocs(folderTwo, RuleModel.ASSOC_RULE_FOLDER, RuleModel.ASSOC_RULE_FOLDER).stream() + .filter(ChildAssociationRef::isPrimary) + .map(ChildAssociationRef::getChildRef) + .findFirst() + .orElse(null); + + // when + final boolean associated = ruleService.isRuleSetAssociatedWithFolder(ruleSetNodeRef, folderOne); + + assertFalse(associated); + } + protected Rule createTestRule(boolean isAppliedToChildren, String title) { // Rule properties