Initial implementation of RM-2238, RM-2288, RM-2289 & RM-2290. Classification Abbreviations and tests.

In fact, this is pretty much done. Still to do: Unclassified Abbreviation.

New class ClassificationLevelValidation which contains the various validation checks for level abbreviations. Unit tests for same. This new class is used by ClassificationServiceBootstrap.
Added a new exception type just so that we have somewhere to store any illegal characters in a level abbreviation.
Had to change the classification level IDs to “TS”, “S” & “C” as “Confidential” has a length > 10. I’d been thinking of doing this is a separate commit but the additional validation requires that we do it now.
Minor fallout in test code due to ID changes.



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@105641 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Neil McErlean
2015-06-05 15:58:10 +00:00
parent 9b61610016
commit f8c417d0d0
6 changed files with 245 additions and 16 deletions

View File

@@ -21,6 +21,9 @@ package org.alfresco.module.org_alfresco_module_rm.classification;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.NodeRef;
import java.util.Collections;
import java.util.List;
/**
* Generic class for any runtime exception to do with classified records.
*
@@ -54,6 +57,22 @@ public class ClassificationException extends AlfrescoRuntimeException
public IllegalConfiguration(String msgId) { super(msgId); }
}
/** Represents a fatal error due to illegal {@link ClassificationLevel#getId() classification level ID} configuration.
* The configuration was understood by the server, but was rejected as illegal. */
public static class IllegalAbbreviationChars extends IllegalConfiguration
{
/** serial version uid */
private static final long serialVersionUID = 98787676565465454L;
private final List<Character> illegalChars;
public IllegalAbbreviationChars(String msgId, List<Character> illegalChars)
{
super(msgId);
this.illegalChars = illegalChars;
}
public List<Character> getIllegalChars() { return Collections.unmodifiableList(illegalChars); }
}
/** Represents a fatal error due to malformed configuration.
* The configuration could not be understood by the server. */
public static class MalformedConfiguration extends ClassificationException

View File

@@ -0,0 +1,104 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.module.org_alfresco_module_rm.classification;
import static java.util.Arrays.asList;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.IllegalAbbreviationChars;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.IllegalConfiguration;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingConfiguration;
import java.util.ArrayList;
import java.util.List;
/**
* This class is responsible for validating {@link ClassificationLevel}s.
*
* @author Neil Mc Erlean
* @since 3.0
*/
public class ClassificationLevelValidation
{
/** The maximum number of chatacters allowed in a {@link ClassificationLevel#getId() level ID}. */
private static final int ABBREVIATION_LENGTH_LIMIT = 10;
/**
* Illegal characters in a {@link ClassificationLevel#getId() level ID}.
* Equals to Alfresco's disallowed filename characters.
*/
// See <constraint name="cm:filename" type="REGEX"> in contentModel.xml
static final List<Character> ILLEGAL_ABBREVIATION_CHARS = asList('"', '*', '\\', '>', '<', '?', '/', ':', '|');
/**
* Validates the provided {@link ClassificationLevel}.
* @param level the level to validate.
* @throws MissingConfiguration if the level abbreviation is missing.
* @throws IllegalConfiguration if the level abbreviation violates the standard restrictions.
* @throws IllegalAbbreviationChars if the level abbreviation contains illegal characters.
*/
void validateLevel(ClassificationLevel level)
{
final String levelId = level.getId();
if (levelId == null || levelId.equals(""))
{
throw new MissingConfiguration("Classification level ID is missing.");
}
else if (levelId.length() > ABBREVIATION_LENGTH_LIMIT)
{
throw new IllegalConfiguration("Illegal classification level abbreviation. Length " +
levelId.length() + " > " + ABBREVIATION_LENGTH_LIMIT);
}
else if (!getIllegalAbbreviationChars(levelId).isEmpty())
{
throw new IllegalAbbreviationChars("Illegal character(s) in level abbreviation",
getIllegalAbbreviationChars(levelId));
}
}
/**
* Validates the provided {@link ClassificationLevel}s as a whole and individually.
* @param levels the levels to validate.
* @throws MissingConfiguration if the levels or any of their abbreviations are missing.
* @throws IllegalConfiguration if any of the level abbreviations violate the standard restrictions.
* @throws IllegalAbbreviationChars if the level abbreviation contains illegal characters.
*/
public void validateLevels(List<ClassificationLevel> levels)
{
if (levels == null || levels.isEmpty())
{
throw new MissingConfiguration("Classification level configuration is missing.");
}
for (ClassificationLevel level : levels)
{
validateLevel(level);
}
}
private List<Character> getIllegalAbbreviationChars(String s)
{
final List<Character> result = new ArrayList<>();
for (Character c : ILLEGAL_ABBREVIATION_CHARS)
{
if (s.contains(c.toString())) result.add(c);
}
return result;
}
}

View File

@@ -56,6 +56,7 @@ public class ClassificationServiceBootstrap extends AbstractLifecycleBean implem
/** The clearance levels currently configured in this server. */
private ClearanceLevelManager clearanceLevelManager = new ClearanceLevelManager();
private ClassificationServiceDAO classificationServiceDAO;
private final ClassificationLevelValidation levelValidation = new ClassificationLevelValidation();
public ClassificationServiceBootstrap(AuthenticationUtil authUtil,
TransactionService txService,
@@ -113,11 +114,9 @@ public class ClassificationServiceBootstrap extends AbstractLifecycleBean implem
LOGGER.debug("Persisted classification levels: {}", loggableStatusOf(allPersistedLevels));
LOGGER.debug("Classpath classification levels: {}", loggableStatusOf(configurationLevels));
if (configurationLevels == null || configurationLevels.isEmpty())
{
throw new MissingConfiguration("Classification level configuration is missing.");
}
else if (!configurationLevels.equals(allPersistedLevels))
levelValidation.validateLevels(configurationLevels);
if (!configurationLevels.equals(allPersistedLevels))
{
attributeService.setAttribute((Serializable) configurationLevels, LEVELS_KEY);
this.classificationLevelManager.setClassificationLevels(configurationLevels);