diff --git a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
index 79257be1f5..29eb3bc8a2 100644
--- a/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
+++ b/packaging/tests/tas-restapi/src/test/java/org/alfresco/rest/rules/GetRuleSetsTests.java
@@ -132,6 +132,23 @@ public class GetRuleSetsTests extends RestTest
ruleSets.assertThat().entriesListCountIs(1);
}
+ /** Check we can get the reason that a rule set is included in the list. */
+ @Test (groups = { TestGroup.REST_API, TestGroup.RULES })
+ public void getRuleSetsAndInclusionType()
+ {
+ STEP("Get the rule sets and inclusion type");
+ RestRuleSetModelsCollection ruleSets = restClient.authenticateUser(user).withCoreAPI()
+ .usingNode(ruleFolder)
+ .usingParams("include=inclusionType")
+ .getListOfRuleSets();
+
+ restClient.assertStatusCodeIs(OK);
+ ruleSets.getEntries().get(0).onModel()
+ .assertThat().field("inclusionType").is("owned")
+ .assertThat().field("id").is(ruleSetId);
+ ruleSets.assertThat().entriesListCountIs(1);
+ }
+
/** Check we can get a rule set by its id. */
@Test (groups = { TestGroup.REST_API, TestGroup.RULES, TestGroup.SANITY })
public void getRuleSetById()
diff --git a/pom.xml b/pom.xml
index c933c9132a..3c63bab9f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,7 +120,7 @@
2.7.4
3.0.49
5.1.1
- 1.103
+ 1.104
1.31
1.8
1.6
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
index 32296098ff..3e7d10bf38 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetLoader.java
@@ -25,10 +25,15 @@
*/
package org.alfresco.rest.api.impl.rules;
+import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
+import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
+import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
+
import java.util.List;
import org.alfresco.rest.api.model.rules.RuleSet;
import org.alfresco.service.Experimental;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -36,6 +41,8 @@ import org.alfresco.service.cmr.repository.NodeService;
@Experimental
public class RuleSetLoader
{
+ protected static final String OWNING_FOLDER = "owningFolder";
+ protected static final String INCLUSION_TYPE = "inclusionType";
private NodeService nodeService;
/**
@@ -45,15 +52,33 @@ public class RuleSetLoader
* @param includes A list of fields to include.
* @return The rule set object.
*/
- protected RuleSet loadRuleSet(NodeRef ruleSetNodeRef, List includes)
+ protected RuleSet loadRuleSet(NodeRef ruleSetNodeRef, NodeRef folderNodeRef, List includes)
{
String ruleSetId = ruleSetNodeRef.getId();
RuleSet ruleSet = RuleSet.of(ruleSetId);
- if (includes != null && includes.contains("owningFolder"))
+ if (includes != null)
{
NodeRef parentRef = nodeService.getPrimaryParent(ruleSetNodeRef).getParentRef();
- ruleSet.setOwningFolder(parentRef);
+ if (includes.contains(OWNING_FOLDER))
+ {
+ ruleSet.setOwningFolder(parentRef);
+ }
+ if (includes.contains(INCLUSION_TYPE))
+ {
+ // In the case that a rule set applies to the given folder for multiple reasons then priority is given to owned, then linked, then inherited.
+ if (parentRef.equals(folderNodeRef))
+ {
+ ruleSet.setInclusionType(OWNED);
+ }
+ else
+ {
+ boolean linked = nodeService.getParentAssocs(ruleSetNodeRef)
+ .stream().map(ChildAssociationRef::getParentRef)
+ .anyMatch(folderNodeRef::equals);
+ ruleSet.setInclusionType(linked ? LINKED : INHERITED);
+ }
+ }
}
return ruleSet;
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java
index 89dfcb57e6..e8b181e3e2 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/rules/RuleSetsImpl.java
@@ -54,7 +54,8 @@ public class RuleSetsImpl implements RuleSets
NodeRef ruleSetNode = ruleService.getRuleSetNode(folderNode);
List ruleSets = Optional.ofNullable(ruleSetNode)
- .map(nodeRef -> ruleSetLoader.loadRuleSet(nodeRef, includes)).stream().collect(toList());
+ .map(nodeRef -> ruleSetLoader.loadRuleSet(nodeRef, folderNode, includes))
+ .stream().collect(toList());
return ListPage.of(ruleSets, paging);
}
@@ -65,7 +66,7 @@ public class RuleSetsImpl implements RuleSets
NodeRef folderNode = validator.validateFolderNode(folderNodeId, false);
NodeRef ruleSetNode = validator.validateRuleSetNode(ruleSetId, folderNode);
- return ruleSetLoader.loadRuleSet(ruleSetNode, includes);
+ return ruleSetLoader.loadRuleSet(ruleSetNode, folderNode, includes);
}
public void setRuleSetLoader(RuleSetLoader ruleSetLoader)
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java
new file mode 100644
index 0000000000..687cde0f4d
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/InclusionType.java
@@ -0,0 +1,59 @@
+/*
+ * #%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.rules;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import org.alfresco.service.Experimental;
+
+/** The reason why a rule set applies to a folder. */
+@Experimental
+public enum InclusionType
+{
+ OWNED, INHERITED, LINKED;
+
+ /**
+ * Load an InclusionType from a given string (case insensitively).
+ *
+ * @param inclusionType The given string.
+ * @return The inclusion type.
+ */
+ public static InclusionType from(String inclusionType)
+ {
+ return InclusionType.valueOf(inclusionType.toUpperCase());
+ }
+
+ /**
+ * The lower case version of the inclusion type.
+ *
+ * @return A lowercase string.
+ */
+ @JsonValue
+ public String toString()
+ {
+ return super.toString().toLowerCase();
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
index 343c2bc13e..df1984673f 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/rules/RuleSet.java
@@ -27,7 +27,9 @@
package org.alfresco.rest.api.model.rules;
import java.util.Objects;
+import java.util.StringJoiner;
+import org.alfresco.rest.api.People;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -38,6 +40,7 @@ public class RuleSet
private String id;
private NodeRef owningFolder;
+ private InclusionType inclusionType;
public static RuleSet of(String id)
{
@@ -74,10 +77,26 @@ public class RuleSet
this.owningFolder = owningFolder;
}
+ public InclusionType getInclusionType()
+ {
+ return inclusionType;
+ }
+
+ public void setInclusionType(InclusionType inclusionType)
+ {
+ this.inclusionType = inclusionType;
+ }
+
@Override
public String toString()
{
- return "RuleSet{" + "id='" + id + '\'' + '}';
+ return "RuleSet{"
+ + new StringJoiner(", ")
+ .add("id='" + id + "'")
+ .add("owningFolder='" + owningFolder + "'")
+ .add("inclusionType='" + inclusionType + "'")
+ .toString()
+ + '}';
}
@Override
@@ -89,13 +108,14 @@ public class RuleSet
return false;
RuleSet ruleSet = (RuleSet) o;
return Objects.equals(id, ruleSet.id)
- && Objects.equals(owningFolder, ruleSet.owningFolder);
+ && Objects.equals(owningFolder, ruleSet.owningFolder)
+ && inclusionType == ruleSet.inclusionType;
}
@Override
public int hashCode()
{
- return Objects.hash(id, owningFolder);
+ return Objects.hash(id, owningFolder, inclusionType);
}
public static Builder builder()
@@ -107,6 +127,7 @@ public class RuleSet
{
private String id;
private NodeRef owningFolder;
+ private InclusionType inclusionType;
public Builder id(String id)
{
@@ -120,11 +141,18 @@ public class RuleSet
return this;
}
+ public Builder inclusionType(InclusionType inclusionType)
+ {
+ this.inclusionType = inclusionType;
+ return this;
+ }
+
public RuleSet create()
{
final RuleSet ruleSet = new RuleSet();
ruleSet.setId(id);
ruleSet.setOwningFolder(owningFolder);
+ ruleSet.setInclusionType(inclusionType);
return ruleSet;
}
}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
index 54299b261e..29a0fd92c5 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetLoaderTest.java
@@ -25,18 +25,22 @@
*/
package org.alfresco.rest.api.impl.rules;
+import static org.alfresco.rest.api.impl.rules.RuleSetLoader.INCLUSION_TYPE;
+import static org.alfresco.rest.api.impl.rules.RuleSetLoader.OWNING_FOLDER;
+import static org.alfresco.rest.api.model.rules.InclusionType.INHERITED;
+import static org.alfresco.rest.api.model.rules.InclusionType.LINKED;
+import static org.alfresco.rest.api.model.rules.InclusionType.OWNED;
+import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
import static org.mockito.BDDMockito.given;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.rest.api.model.rules.RuleSet;
-import org.alfresco.rest.framework.resource.parameters.Paging;
import org.alfresco.service.Experimental;
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;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -51,8 +55,11 @@ public class RuleSetLoaderTest extends TestCase
{
private static final String FOLDER_ID = "dummy-folder-id";
private static final String RULE_SET_ID = "dummy-rule-set-id";
- private static final NodeRef FOLDER_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID);
- private static final NodeRef RULE_SET_NODE = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
+ private static final NodeRef FOLDER_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, FOLDER_ID);
+ private static final NodeRef RULE_SET_NODE = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, RULE_SET_ID);
+ private static final String LINKING_FOLDER_ID = "linking-folder";
+ private static final NodeRef LINKING_FOLDER = new NodeRef(STORE_REF_WORKSPACE_SPACESSTORE, LINKING_FOLDER_ID);
+ private static final NodeRef INHERITING_FOLDER = new NodeRef("inheriting://folder/");
@InjectMocks
private RuleSetLoader ruleSetLoader;
@@ -60,6 +67,8 @@ public class RuleSetLoaderTest extends TestCase
private NodeService nodeServiceMock;
@Mock
private ChildAssociationRef ruleSetAssociationMock;
+ @Mock
+ private ChildAssociationRef linkAssociationMock;
@Before
@Override
@@ -67,13 +76,16 @@ public class RuleSetLoaderTest extends TestCase
{
given(ruleSetAssociationMock.getParentRef()).willReturn(FOLDER_NODE);
given(nodeServiceMock.getPrimaryParent(RULE_SET_NODE)).willReturn(ruleSetAssociationMock);
+
+ given(linkAssociationMock.getParentRef()).willReturn(LINKING_FOLDER);
+ given(nodeServiceMock.getParentAssocs(RULE_SET_NODE)).willReturn(List.of(ruleSetAssociationMock, linkAssociationMock));
}
@Test
public void testLoadRuleSet_noIncludes()
{
// Call the method under test.
- RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, null);
+ RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, null);
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).create();
assertEquals(expected, actual);
@@ -83,9 +95,39 @@ public class RuleSetLoaderTest extends TestCase
public void testLoadRuleSet_includeOwningFolder()
{
// Call the method under test.
- RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, List.of("owningFolder"));
+ RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(OWNING_FOLDER));
RuleSet expected = RuleSet.builder().id(RULE_SET_ID).owningFolder(FOLDER_NODE).create();
assertEquals(expected, actual);
}
+
+ @Test
+ public void testLoadRuleSet_includeInclusionType()
+ {
+ // Call the method under test.
+ RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, List.of(INCLUSION_TYPE));
+
+ RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(OWNED).create();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testLoadRuleSet_linkedInclusionType()
+ {
+ // Call the method under test.
+ RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, LINKING_FOLDER, List.of(INCLUSION_TYPE));
+
+ RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(LINKED).create();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testLoadRuleSet_inheritedInclusionType()
+ {
+ // Call the method under test.
+ RuleSet actual = ruleSetLoader.loadRuleSet(RULE_SET_NODE, INHERITING_FOLDER, List.of(INCLUSION_TYPE));
+
+ RuleSet expected = RuleSet.builder().id(RULE_SET_ID).inclusionType(INHERITED).create();
+ assertEquals(expected, actual);
+ }
}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java
index bb2fba99a4..1ef53083ec 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/rules/RuleSetsImplTest.java
@@ -87,7 +87,7 @@ public class RuleSetsImplTest extends TestCase
given(nodeValidatorMock.validateRuleSetNode(RULE_SET_ID, FOLDER_NODE)).willReturn(RULE_SET_NODE);
given(ruleServiceMock.getRuleSetNode(FOLDER_NODE)).willReturn(RULE_SET_NODE);
- given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE, INCLUDES)).willReturn(ruleSetMock);
+ given(ruleSetLoaderMock.loadRuleSet(RULE_SET_NODE, FOLDER_NODE, INCLUDES)).willReturn(ruleSetMock);
}
@Test