getExemptionCategories()
+ {
+ return exemptionCategories;
+ }
+
+ /**
+ * Get a ExemptionCategory
using its id.
+ *
+ * @param id The id of an exemption category.
+ * @return The exemption category.
+ * @throws ExemptionCategoryIdNotFound If the exemption category cannot be found.
+ */
+ public ExemptionCategory findCategoryById(String id) throws ExemptionCategoryIdNotFound
+ {
+ for (ExemptionCategory exemptionCategory : exemptionCategories)
+ {
+ if (exemptionCategory.getId().equals(id))
+ {
+ return exemptionCategory;
+ }
+ }
+ throw new ExemptionCategoryIdNotFound(id);
+ }
+}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/model/ClassifiedContentModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/model/ClassifiedContentModel.java
index a8c6996e3b..f3b3f0265a 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/model/ClassifiedContentModel.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/model/ClassifiedContentModel.java
@@ -38,6 +38,7 @@ public interface ClassifiedContentModel
Serializable[] LEVELS_KEY = new String[] { "org.alfresco", "module.org_alfresco_module_rm", "classification.levels" };
Serializable[] REASONS_KEY = new String[] { "org.alfresco", "module.org_alfresco_module_rm", "classification.reasons" };
+ Serializable[] EXEMPTION_CATEGORIES_KEY = new String[] { "org.alfresco", "module.org_alfresco_module_rm", "classification.exemptionCategories" };
/** Classified aspect */
QName ASPECT_CLASSIFIED = QName.createQName(CLF_URI, "classified");
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/ClassificationReasonsTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/ClassificationReasonsTest.java
index b46e327a04..042836848b 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/ClassificationReasonsTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/classification/ClassificationReasonsTest.java
@@ -22,7 +22,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.classificati
import java.util.List;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationReason;
-import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeServiceImpl;
+import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceBootstrap;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
/**
@@ -39,7 +39,7 @@ public class ClassificationReasonsTest extends BaseRMTestCase
*
* Note that this test requires a clean db, as otherwise the classification scheme service will use the persisted
* classification reasons in preference to those given on the classpath (see the logic in
- * {@link ClassificationSchemeServiceImpl#initConfiguredClassificationReasons()}).
+ * {@link ClassificationServiceBootstrap#initConfiguredClassificationReasons()}).
*/
public void testLoadBootstrappedClassificationReasons() throws Exception
{
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceBootstrapUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceBootstrapUnitTest.java
index f1e7dfa3c2..882848ccf6 100644
--- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceBootstrapUnitTest.java
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceBootstrapUnitTest.java
@@ -73,6 +73,9 @@ public class ClassificationServiceBootstrapUnitTest
new ClassificationReason("id2", "label2"));
private static final List ALTERNATIVE_CLASSIFICATION_REASONS = asList(new ClassificationReason("id8", "label8"),
new ClassificationReason("id9", "label9"));
+ private static final List EXEMPTION_CATEGORIES = asList(new ExemptionCategory("id1", "label1"),
+ new ExemptionCategory("id2", "label2"));
+ private static final List CHANGED_EXEMPTION_CATEGORIES = asList(new ExemptionCategory("id3", "label3"));
/**
* A convenience method for turning lists of level id Strings into lists
@@ -103,6 +106,7 @@ public class ClassificationServiceBootstrapUnitTest
@Mock ClassificationServiceDAO mockClassificationServiceDAO;
@Mock AttributeService mockAttributeService;
@Mock AuthenticationUtil mockAuthenticationUtil;
+ @Mock ExemptionCategoryManager mockExemptionCategoryManager;
@Mock ClearanceLevelManager mockClearanceLevelManager;
/** Using a mock appender in the class logger so that we can verify some of the logging requirements. */
@Mock Appender mockAppender;
@@ -113,7 +117,8 @@ public class ClassificationServiceBootstrapUnitTest
{
MockitoAnnotations.initMocks(this);
MockAuthenticationUtilHelper.setup(mockAuthenticationUtil);
- // This seems to be necessary because the ClearanceLevelManager isn't a constructor argument.
+ // This seems to be necessary because the POJO managers aren't constructor arguments.
+ classificationServiceBootstrap.setExemptionCategoryManager(mockExemptionCategoryManager);
classificationServiceBootstrap.setClearanceLevelManager(mockClearanceLevelManager);
}
@@ -224,6 +229,80 @@ public class ClassificationServiceBootstrapUnitTest
classificationServiceBootstrap.initConfiguredClassificationReasons();
}
+ @Test
+ public void testInitConfiguredExemptionCategories_firstLoad()
+ {
+ when(mockAttributeService.getAttribute(anyString(), anyString(), anyString()))
+ .thenReturn((Serializable) null);
+ when(mockClassificationServiceDAO.getConfiguredExemptionCategories()).thenReturn(EXEMPTION_CATEGORIES);
+
+ classificationServiceBootstrap.initConfiguredExemptionCategories();
+
+ verify(mockExemptionCategoryManager).setExemptionCategories(EXEMPTION_CATEGORIES);
+ }
+
+ @Test
+ public void testInitConfiguredExemptionCategories_secondLoad()
+ {
+ when(mockAttributeService.getAttribute(anyString(), anyString(), anyString()))
+ .thenReturn((Serializable) EXEMPTION_CATEGORIES);
+ when(mockClassificationServiceDAO.getConfiguredExemptionCategories()).thenReturn(EXEMPTION_CATEGORIES);
+
+ classificationServiceBootstrap.initConfiguredExemptionCategories();
+
+ verify(mockExemptionCategoryManager).setExemptionCategories(EXEMPTION_CATEGORIES);
+ }
+
+ /**
+ * Check that if the exemption categories supplied on the classpath differ from those already persisted then a
+ * warning is logged and no change is made to the persisted categories.
+ *
+ * This test uses the underlying log4j implementation to insert a mock Appender, and tests this for the warning
+ * message. If the underlying logging framework is changed then this unit test will fail, and it may not be possible
+ * to/worth fixing.
+ */
+ @Test
+ public void testInitConfiguredExemptionCategories_changedCategories()
+ {
+ when(mockAttributeService.getAttribute(anyString(), anyString(), anyString()))
+ .thenReturn((Serializable) EXEMPTION_CATEGORIES);
+ when(mockClassificationServiceDAO.getConfiguredExemptionCategories()).thenReturn(CHANGED_EXEMPTION_CATEGORIES);
+
+ // Put the mock Appender into the log4j logger and allow warning messages to be received.
+ org.apache.log4j.Logger log4jLogger = org.apache.log4j.Logger.getLogger(ClassificationServiceBootstrap.class);
+ log4jLogger.addAppender(mockAppender);
+ Level normalLevel = log4jLogger.getLevel();
+ log4jLogger.setLevel(Level.WARN);
+
+ // Call the method under test.
+ classificationServiceBootstrap.initConfiguredExemptionCategories();
+
+ // Reset the logging level for other tests.
+ log4jLogger.setLevel(normalLevel);
+
+ // Check the persisted values weren't changed.
+ verify(mockAttributeService, never()).setAttribute(any(Serializable.class),
+ anyString(), anyString(), anyString());
+
+ // Check that the warning message was logged.
+ verify(mockAppender).doAppend(loggingEventCaptor.capture());
+ List loggingEvents = loggingEventCaptor.getAllValues();
+ Stream messages = loggingEvents.stream()
+ .map(LoggingEvent::getRenderedMessage);
+ String expectedMessage = "Exemption categories configured in classpath do not match those stored in Alfresco. Alfresco will use the unchanged values stored in the database.";
+ assertTrue("Warning message not found in log.", messages.anyMatch(message -> expectedMessage.equals(message)));
+ }
+
+ @Test(expected = MissingConfiguration.class)
+ public void testInitConfiguredExemptionCategories_noCategoriesFound()
+ {
+ when(mockAttributeService.getAttribute(anyString(), anyString(), anyString()))
+ .thenReturn((Serializable) null);
+ when(mockClassificationServiceDAO.getConfiguredReasons()).thenReturn(null);
+
+ classificationServiceBootstrap.initConfiguredExemptionCategories();
+ }
+
/**
* Check that the initialise method creates a clearance level corresponding to each classification level and that
* the display label for the lowest clearance level is "No Clearance" (rather than "Unclassified").
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ExemptionCategoryManagerUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ExemptionCategoryManagerUnitTest.java
new file mode 100644
index 0000000000..b85eda4811
--- /dev/null
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ExemptionCategoryManagerUnitTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * 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 .
+ */
+package org.alfresco.module.org_alfresco_module_rm.classification;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.ExemptionCategoryIdNotFound;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for the {@link ExemptionCategoryManager}.
+ *
+ * @author tpage
+ */
+public class ExemptionCategoryManagerUnitTest
+{
+ private static final ExemptionCategory CATEGORY_1 = new ExemptionCategory("id1", "displayLabelKey1");
+ private static final ExemptionCategory CATEGORY_2 = new ExemptionCategory("id2", "displayLabelKey2");
+ private static final ExemptionCategory CATEGORY_3 = new ExemptionCategory("id3", "displayLabelKey3");
+ private static final List CATEGORIES = Arrays.asList(CATEGORY_1, CATEGORY_2, CATEGORY_3);
+
+ private ExemptionCategoryManager exemptionCategoryManager;
+
+ @Before public void setup()
+ {
+ exemptionCategoryManager = new ExemptionCategoryManager();
+ exemptionCategoryManager.setExemptionCategories(CATEGORIES);
+ }
+
+ @Test public void findClassificationById_found()
+ {
+ ExemptionCategory actual = exemptionCategoryManager.findCategoryById("id2");
+ assertEquals(CATEGORY_2, actual);
+ }
+
+ @Test(expected = ExemptionCategoryIdNotFound.class) public void findClassificationById_notFound()
+ {
+ exemptionCategoryManager.findCategoryById("id_unknown");
+ }
+}