This is the RM-specific parts of the refactor for classified renditions - see RM-2549.

This builds on the separate MetadataReferral services to link renditions to classified source nodes via a new classifiedRendition aspect which defines a new classifiedRendition assoc. The spring bean 'classifiedRenditionAssoc' defines that only the clf:classified aspect and its metadata will be linked.




git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/classified_renditions@111643 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Neil McErlean
2015-09-08 15:32:10 +00:00
parent cfcb18728c
commit 6443b39b72
9 changed files with 126 additions and 211 deletions

View File

@@ -125,6 +125,14 @@
<constructor-arg ref="classificationServiceDAO"/> <constructor-arg ref="classificationServiceDAO"/>
</bean> </bean>
<bean name="classifiedRenditionAssoc" parent="baseReferralAssoc">
<property name="assocType" value="clf:classifiedRendition" />
<property name="aspects">
<set>
<value>clf:classified</value>
</set>
</property>
</bean>
<!-- Security Clearance Service --> <!-- Security Clearance Service -->
@@ -187,6 +195,7 @@
<property name="securityClearanceService" ref="SecurityClearanceService"/> <property name="securityClearanceService" ref="SecurityClearanceService"/>
<property name="classificationServiceBootstrap" ref="classificationServiceBootstrap"/> <property name="classificationServiceBootstrap" ref="classificationServiceBootstrap"/>
<property name="freezeService" ref="FreezeService"/> <property name="freezeService" ref="FreezeService"/>
<property name="referredMetadataService" ref="ReferredMetadataService" />
</bean> </bean>
<bean id="ContentClassificationService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="ContentClassificationService" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -234,15 +243,15 @@
class="org.alfresco.module.org_alfresco_module_rm.model.clf.aspect.ClassifiedAspect" class="org.alfresco.module.org_alfresco_module_rm.model.clf.aspect.ClassifiedAspect"
parent="rm.baseBehaviour"> parent="rm.baseBehaviour">
<property name="classificationSchemeService" ref="ClassificationSchemeService" /> <property name="classificationSchemeService" ref="ClassificationSchemeService" />
<property name="referralAdminService" ref="ReferralAdminService" />
<property name="renditionService" ref="RenditionService" /> <property name="renditionService" ref="RenditionService" />
<property name="coreServicesExtras" ref="rm.coreServicesExtras" />
</bean> </bean>
<bean id="clf.classifiedRenditions" <bean id="clf.classifiedRenditions"
class="org.alfresco.module.org_alfresco_module_rm.model.clf.ClassifiedRenditions" class="org.alfresco.module.org_alfresco_module_rm.model.clf.ClassifiedRenditions"
parent="rm.baseBehaviour"> parent="rm.baseBehaviour">
<property name="contentClassificationService" ref="ContentClassificationService" /> <property name="contentClassificationService" ref="ContentClassificationService" />
<property name="referralAdminService" ref="ReferralAdminService" />
<property name="renditionService" ref="RenditionService" /> <property name="renditionService" ref="RenditionService" />
<property name="coreServicesExtras" ref="rm.coreServicesExtras" />
</bean> </bean>
</beans> </beans>

View File

@@ -38,11 +38,6 @@
type="org.alfresco.module.org_alfresco_module_rm.classification.ReclassificationValueConstraint" /> type="org.alfresco.module.org_alfresco_module_rm.classification.ReclassificationValueConstraint" />
</constraints> </constraints>
<!-- Types -->
<types>
</types>
<!-- Aspects --> <!-- Aspects -->
<aspects> <aspects>
<!-- Classified aspect --> <!-- Classified aspect -->
@@ -178,5 +173,21 @@
</property> </property>
</properties> </properties>
</aspect> </aspect>
<aspect name="clf:classifiedRendition">
<associations>
<association name="clf:classifiedRendition">
<source>
<mandatory>true</mandatory>
<many>true</many>
</source>
<target>
<class>cm:content</class>
<mandatory>true</mandatory>
<many>true</many>
</target>
</association>
</associations>
</aspect>
</aspects> </aspects>
</model> </model>

View File

@@ -23,11 +23,6 @@ import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.c
import static org.alfresco.util.ParameterCheck.mandatory; import static org.alfresco.util.ParameterCheck.mandatory;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.QuickShareModel; import org.alfresco.model.QuickShareModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.InvalidNode; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.InvalidNode;
@@ -35,6 +30,7 @@ import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationE
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.ReasonIdNotFound; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.ReasonIdNotFound;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService;
import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
@@ -43,6 +39,11 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/** /**
* A service to handle the classification of content. * A service to handle the classification of content.
* *
@@ -57,12 +58,17 @@ public class ContentClassificationServiceImpl extends ServiceBaseImpl
private SecurityClearanceService securityClearanceService; private SecurityClearanceService securityClearanceService;
private ClassificationServiceBootstrap classificationServiceBootstrap; private ClassificationServiceBootstrap classificationServiceBootstrap;
private FreezeService freezeService; private FreezeService freezeService;
private ReferredMetadataService referredMetadataService;
public void setLevelManager(ClassificationLevelManager levelManager) { this.levelManager = levelManager; } public void setLevelManager(ClassificationLevelManager levelManager) { this.levelManager = levelManager; }
public void setReasonManager(ClassificationReasonManager reasonManager) { this.reasonManager = reasonManager; } public void setReasonManager(ClassificationReasonManager reasonManager) { this.reasonManager = reasonManager; }
public void setSecurityClearanceService(SecurityClearanceService securityClearanceService) { this.securityClearanceService = securityClearanceService; } public void setSecurityClearanceService(SecurityClearanceService securityClearanceService) { this.securityClearanceService = securityClearanceService; }
public void setClassificationServiceBootstrap(ClassificationServiceBootstrap classificationServiceBootstrap) { this.classificationServiceBootstrap = classificationServiceBootstrap; } public void setClassificationServiceBootstrap(ClassificationServiceBootstrap classificationServiceBootstrap) { this.classificationServiceBootstrap = classificationServiceBootstrap; }
public void setFreezeService(FreezeService service) { this.freezeService = service; } public void setFreezeService(FreezeService service) { this.freezeService = service; }
public void setReferredMetadataService(ReferredMetadataService service)
{
this.referredMetadataService = service;
}
public void init() public void init()
{ {
@@ -80,16 +86,24 @@ public class ContentClassificationServiceImpl extends ServiceBaseImpl
{ {
public ClassificationLevel doWork() throws Exception public ClassificationLevel doWork() throws Exception
{ {
// by default everything is unclassified final String classificationId;
ClassificationLevel result = ClassificationLevelManager.UNCLASSIFIED;
if (nodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED)) if (nodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED))
{ {
String classificationId = (String)nodeService.getProperty(nodeRef, PROP_CURRENT_CLASSIFICATION); classificationId = (String)nodeService.getProperty(nodeRef, PROP_CURRENT_CLASSIFICATION);
result = levelManager.findLevelById(classificationId); }
else if (referredMetadataService.isReferringMetadata(nodeRef, ASPECT_CLASSIFIED))
{
classificationId = (String) referredMetadataService.getReferredProperty(nodeRef, PROP_CURRENT_CLASSIFICATION);
// Note that this property value could be null/missing.
}
else
{
classificationId = null;
} }
return result; // by default everything is unclassified
return classificationId == null ? ClassificationLevelManager.UNCLASSIFIED : levelManager.findLevelById(classificationId);
} }
}); });
}; };
@@ -231,12 +245,19 @@ public class ContentClassificationServiceImpl extends ServiceBaseImpl
mandatory("nodeRef", nodeRef); mandatory("nodeRef", nodeRef);
boolean isClassified = false; boolean isClassified = false;
String currentClassification = (String) nodeService.getProperty(nodeRef, PROP_CURRENT_CLASSIFICATION);
if (nodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED) && final String currentClassification;
!(UNCLASSIFIED_ID).equals(currentClassification)) if (nodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED))
{ {
isClassified = true; currentClassification = (String) nodeService.getProperty(nodeRef, PROP_CURRENT_CLASSIFICATION);
isClassified = currentClassification != null && ! UNCLASSIFIED_ID.equals(currentClassification);
}
else if (referredMetadataService.isReferringMetadata(nodeRef, ASPECT_CLASSIFIED))
{
currentClassification = (String) referredMetadataService.getReferredProperty(nodeRef, PROP_CURRENT_CLASSIFICATION);
// This could be a null/missing property.
isClassified = currentClassification != null && ! UNCLASSIFIED_ID.equals(currentClassification);
} }
return isClassified; return isClassified;

View File

@@ -62,4 +62,8 @@ public interface ClassifiedContentModel
/** Security Clearance aspect. */ /** Security Clearance aspect. */
QName ASPECT_SECURITY_CLEARANCE = QName.createQName(CLF_URI, "securityClearance"); QName ASPECT_SECURITY_CLEARANCE = QName.createQName(CLF_URI, "securityClearance");
QName PROP_CLEARANCE_LEVEL = QName.createQName(CLF_URI, "clearanceLevel"); QName PROP_CLEARANCE_LEVEL = QName.createQName(CLF_URI, "clearanceLevel");
/** Classified Rendition aspect. */
QName ASPECT_CLASSIFIED_RENDITION = QName.createQName(CLF_URI, "classifiedRendition");
QName ASSOC_CLASSIFIED_RENDITION = QName.createQName(CLF_URI, "classifiedRendition");
} }

View File

@@ -20,21 +20,22 @@ package org.alfresco.module.org_alfresco_module_rm.model.clf;
import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService; import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService;
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.Behaviour;
import org.alfresco.repo.policy.annotation.BehaviourBean; import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.rendition.RenditionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
/** /**
* Behaviour bean for classified rendition nodes. * Behaviour bean for classified rendition nodes.
* *
* @since 3.0.a * @since 2.4.a
*/ */
@BehaviourBean @BehaviourBean
( (
@@ -45,7 +46,7 @@ public class ClassifiedRenditions extends BaseBehaviourBean
ClassifiedContentModel ClassifiedContentModel
{ {
private ContentClassificationService contentClassificationService; private ContentClassificationService contentClassificationService;
private CoreServicesExtras servicesExtras; private ReferralAdminService referralAdminService;
private RenditionService renditionService; private RenditionService renditionService;
public void setContentClassificationService(ContentClassificationService service) public void setContentClassificationService(ContentClassificationService service)
@@ -53,9 +54,9 @@ public class ClassifiedRenditions extends BaseBehaviourBean
this.contentClassificationService = service; this.contentClassificationService = service;
} }
public void setCoreServicesExtras(CoreServicesExtras extras) public void setReferralAdminService(ReferralAdminService service)
{ {
this.servicesExtras = extras; this.referralAdminService = service;
} }
public void setRenditionService(RenditionService service) public void setRenditionService(RenditionService service)
@@ -74,16 +75,19 @@ public class ClassifiedRenditions extends BaseBehaviourBean
) )
public void onAddAspect(final NodeRef renditionNodeRef, final QName aspectTypeQName) public void onAddAspect(final NodeRef renditionNodeRef, final QName aspectTypeQName)
{ {
// When a rendition is created, set up a metadata link of its classification to the source node.
authenticationUtil.runAs(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork<Void>() authenticationUtil.runAs(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork<Void>()
{ {
public Void doWork() public Void doWork()
{ {
final NodeRef sourceNode = renditionService.getSourceNode(renditionNodeRef).getParentRef(); final ChildAssociationRef chAssRef = renditionService.getSourceNode(renditionNodeRef);
if (contentClassificationService.isClassified(sourceNode)) final NodeRef sourceNode = chAssRef.getParentRef();
if (contentClassificationService.isClassified(sourceNode) &&
referralAdminService.getAttachedReferralFrom(renditionNodeRef, ASPECT_CLASSIFIED) != null)
{ {
// All renditions should be given the same classification as their source node referralAdminService.attachReferrer(renditionNodeRef, sourceNode, ASSOC_CLASSIFIED_RENDITION);
servicesExtras.copyAspect(sourceNode, renditionNodeRef, ASPECT_CLASSIFIED);
} }
return null; return null;
} }
}, authenticationUtil.getSystemUserName()); }, authenticationUtil.getSystemUserName());

View File

@@ -20,17 +20,13 @@ package org.alfresco.module.org_alfresco_module_rm.model.clf.aspect;
import static org.alfresco.module.org_alfresco_module_rm.util.RMCollectionUtils.diffKey; import static org.alfresco.module.org_alfresco_module_rm.util.RMCollectionUtils.diffKey;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingDowngradeInstructions; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingDowngradeInstructions;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationLevel; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationLevel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService.Reclassification; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService.Reclassification;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService;
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
import org.alfresco.module.org_alfresco_module_rm.util.RMCollectionUtils.Difference; import org.alfresco.module.org_alfresco_module_rm.util.RMCollectionUtils.Difference;
import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
@@ -44,10 +40,15 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
/** /**
* clf:classification behaviour bean * clf:classification behaviour bean
* *
* @since 3.0.a * @since 2.4.a
*/ */
@BehaviourBean @BehaviourBean
( (
@@ -58,31 +59,27 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
ClassifiedContentModel ClassifiedContentModel
{ {
private ClassificationSchemeService classificationSchemeService; private ClassificationSchemeService classificationSchemeService;
private ReferralAdminService referralAdminService;
private RenditionService renditionService; private RenditionService renditionService;
private CoreServicesExtras servicesExtras;
public void setClassificationSchemeService(ClassificationSchemeService service) public void setClassificationSchemeService(ClassificationSchemeService service)
{ {
this.classificationSchemeService = service; this.classificationSchemeService = service;
} }
public void setReferralAdminService(ReferralAdminService service)
{
this.referralAdminService = service;
}
public void setRenditionService(RenditionService service) public void setRenditionService(RenditionService service)
{ {
this.renditionService = service; this.renditionService = service;
} }
public void setCoreServicesExtras(CoreServicesExtras extras)
{
this.servicesExtras = extras;
}
/** /**
* Behaviour associated with updating the classified aspect properties. * Behaviour associated with updating the classified aspect properties.
* <p> * <p>
* Ensures that on reclassification of content (in other words a change in the value of the
* {@link ClassifiedContentModel#PROP_CURRENT_CLASSIFICATION clf:currentClassification} property)
* that various metadata are correctly updated as a side-effect.
* <p>
* Validates the consistency of the properties. * Validates the consistency of the properties.
*/ */
@Override @Override
@@ -91,7 +88,7 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
kind = BehaviourKind.CLASS, kind = BehaviourKind.CLASS,
notificationFrequency = NotificationFrequency.EVERY_EVENT notificationFrequency = NotificationFrequency.EVERY_EVENT
) )
public void onUpdateProperties(final NodeRef nodeRef, public void onUpdateProperties(final NodeRef classifiedNode,
final Map<QName, Serializable> before, final Map<QName, Serializable> before,
final Map<QName, Serializable> after) final Map<QName, Serializable> after)
{ {
@@ -101,7 +98,7 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
{ {
final Difference classificationChange = diffKey(before, after, PROP_CURRENT_CLASSIFICATION); final Difference classificationChange = diffKey(before, after, PROP_CURRENT_CLASSIFICATION);
if (classificationChange == Difference.CHANGED && nodeService.hasAspect(nodeRef, ASPECT_CLASSIFIED)) if (classificationChange == Difference.CHANGED && nodeService.hasAspect(classifiedNode, ASPECT_CLASSIFIED))
{ {
final String oldValue = (String)before.get(PROP_CURRENT_CLASSIFICATION); final String oldValue = (String)before.get(PROP_CURRENT_CLASSIFICATION);
final String newValue = (String)after.get(PROP_CURRENT_CLASSIFICATION); final String newValue = (String)after.get(PROP_CURRENT_CLASSIFICATION);
@@ -113,14 +110,12 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
if (reclassification != null) if (reclassification != null)
{ {
nodeService.setProperty(nodeRef, PROP_LAST_RECLASSIFICATION_ACTION, reclassification.toModelString()); nodeService.setProperty(classifiedNode, PROP_LAST_RECLASSIFICATION_ACTION, reclassification.toModelString());
nodeService.setProperty(nodeRef, PROP_LAST_RECLASSIFY_AT, new Date()); nodeService.setProperty(classifiedNode, PROP_LAST_RECLASSIFY_AT, new Date());
} }
} }
checkConsistencyOfProperties(nodeRef); checkConsistencyOfProperties(classifiedNode);
copyClassifiedPropertiesToRenditions(nodeRef);
return null; return null;
} }
@@ -136,33 +131,33 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
@Behaviour @Behaviour
( (
kind = BehaviourKind.CLASS, kind = BehaviourKind.CLASS,
notificationFrequency = NotificationFrequency.EVERY_EVENT notificationFrequency = NotificationFrequency.FIRST_EVENT
) )
public void onAddAspect(final NodeRef nodeRef, final QName aspectTypeQName) public void onAddAspect(final NodeRef classifiedNode, final QName aspectTypeQName)
{ {
AuthenticationUtil.runAs(new RunAsWork<Void>() AuthenticationUtil.runAs(new RunAsWork<Void>()
{ {
public Void doWork() public Void doWork()
{ {
checkConsistencyOfProperties(nodeRef); checkConsistencyOfProperties(classifiedNode);
copyClassifiedPropertiesToRenditions(nodeRef); // If this node has any renditions, we must ensure that they inherit the classification
// from their source node.
final List<ChildAssociationRef> renditions = renditionService.getRenditions(classifiedNode);
for (ChildAssociationRef chAssRef : renditions)
{
final NodeRef renditionNode = chAssRef.getChildRef();
if (referralAdminService.getAttachedReferralFrom(renditionNode, ASPECT_CLASSIFIED_RENDITION) == null)
{
referralAdminService.attachReferrer(renditionNode, classifiedNode, ASSOC_CLASSIFIED_RENDITION);
}
}
return null; return null;
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
} }
private void copyClassifiedPropertiesToRenditions(NodeRef nodeRef)
{
// All renditions should be given the same classification as their source node
for (final ChildAssociationRef chAssRef : renditionService.getRenditions(nodeRef))
{
final NodeRef renditionNode = chAssRef.getChildRef();
servicesExtras.copyAspect(nodeRef, renditionNode, ASPECT_CLASSIFIED);
}
}
/** /**
* Check the consistency of the classification properties and throw an exception if they are invalid. * Check the consistency of the classification properties and throw an exception if they are invalid.
* *

View File

@@ -45,6 +45,7 @@ import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationE
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.LevelIdNotFound; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.LevelIdNotFound;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService;
import org.alfresco.module.org_alfresco_module_rm.test.util.MockAuthenticationUtilHelper; import org.alfresco.module.org_alfresco_module_rm.test.util.MockAuthenticationUtilHelper;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
@@ -80,6 +81,7 @@ public class ContentClassificationServiceImplUnitTest implements ClassifiedConte
@Mock FreezeService mockFreezeService; @Mock FreezeService mockFreezeService;
@Mock SecurityClearanceService mockSecurityClearanceService; @Mock SecurityClearanceService mockSecurityClearanceService;
@Mock AuthenticationUtil mockAuthenticationUtil; @Mock AuthenticationUtil mockAuthenticationUtil;
@Mock ReferredMetadataService mockReferredMetadataService;
@Mock ClassificationAspectProperties mockPropertiesDTO; @Mock ClassificationAspectProperties mockPropertiesDTO;
@Captor ArgumentCaptor<Map<QName, Serializable>> propertiesCaptor; @Captor ArgumentCaptor<Map<QName, Serializable>> propertiesCaptor;

View File

@@ -1,95 +0,0 @@
/*
* 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.model.clf;
import static java.util.Arrays.asList;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.model.clf.aspect.ClassifiedAspect;
import org.alfresco.module.org_alfresco_module_rm.test.util.MockAuthenticationUtilHelper;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
import org.alfresco.service.cmr.rendition.RenditionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
/**
* Unit tests for {@link ClassifiedRenditions}.
*
* @since 3.0.a
*/
public class ClassifiedRenditionsUnitTest implements ClassifiedContentModel
{
private static final NodeRef SOURCE_NODE = new NodeRef("node://ref/");
private static final NodeRef RENDITION_1 = new NodeRef("node://rendition1/");
private static final NodeRef RENDITION_2 = new NodeRef("node://rendition2/");
@InjectMocks ClassifiedAspect classifiedAspect;
@Mock AuthenticationUtil mockAuthenticationUtil;
@Mock ContentClassificationService mockContentClassificationService;
@Mock CoreServicesExtras mockCoreServicesExtras;
@Mock NodeService mockNodeService;
@Mock RenditionService mockRenditionService;
@Before
public void setUp()
{
initMocks(this);
MockAuthenticationUtilHelper.setup(mockAuthenticationUtil);
}
@Test public void newRenditionOfClassifiedNodeShouldItselfBeClassified()
{
when(mockRenditionService.getRenditions(SOURCE_NODE))
.thenReturn(asList(rendition(SOURCE_NODE, RENDITION_1), rendition(SOURCE_NODE, RENDITION_2)));
when(mockRenditionService.getSourceNode(RENDITION_1)).thenReturn(rendition(SOURCE_NODE, RENDITION_1));
when(mockRenditionService.getSourceNode(RENDITION_2)).thenReturn(rendition(SOURCE_NODE, RENDITION_2));
when(mockContentClassificationService.isClassified(SOURCE_NODE)).thenReturn(true);
final ClassifiedRenditions behaviour = new ClassifiedRenditions();
behaviour.setAuthenticationUtil(mockAuthenticationUtil);
behaviour.setContentClassificationService(mockContentClassificationService);
behaviour.setCoreServicesExtras(mockCoreServicesExtras);
behaviour.setNodeService(mockNodeService);
behaviour.setRenditionService(mockRenditionService);
behaviour.onAddAspect(RENDITION_2, RenditionModel.ASPECT_RENDITION);
verify(mockCoreServicesExtras).copyAspect(SOURCE_NODE, RENDITION_2, ClassifiedContentModel.ASPECT_CLASSIFIED);
}
/** Creates a test Rendition ChildAssociationRef. */
private ChildAssociationRef rendition(NodeRef source, NodeRef rendition)
{
return new ChildAssociationRef(RenditionModel.ASSOC_RENDITION, source, RenditionModel.ASSOC_RENDITION, rendition);
}
}

View File

@@ -19,52 +19,46 @@
package org.alfresco.module.org_alfresco_module_rm.model.clf.aspect; package org.alfresco.module.org_alfresco_module_rm.model.clf.aspect;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks; import static org.mockito.MockitoAnnotations.initMocks;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.model.RenditionModel; import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingDowngradeInstructions; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingDowngradeInstructions;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationLevel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService;
import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras; import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.rendition.RenditionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import java.util.Date;
/** /**
* Unit tests for the {@link ClassifiedAspect}. * Unit tests for the {@link ClassifiedAspect}.
* *
* @author Tom Page * @author Tom Page
* @since 3.0.a * @author Neil Mc Erlean
* @since 2.4.a
*/ */
public class ClassifiedAspectUnitTest implements ClassifiedContentModel public class ClassifiedAspectUnitTest implements ClassifiedContentModel
{ {
private static final NodeRef NODE_REF = new NodeRef("node://Ref/"); private static final NodeRef NODE_REF = new NodeRef("node://Ref/");
private static final NodeRef RENDITION_1 = new NodeRef("node://rendition1/"); private static final NodeRef RENDITION_1 = new NodeRef("node://rendition1/");
private static final NodeRef RENDITION_2 = new NodeRef("node://rendition2/"); private static final NodeRef RENDITION_2 = new NodeRef("node://rendition2/");
private static final ClassificationLevel TOP_SECRET = new ClassificationLevel("Top Secret", "Top Secret");
private static final ClassificationLevel SECRET = new ClassificationLevel("Secret", "Secret");
@InjectMocks ClassifiedAspect classifiedAspect; @InjectMocks ClassifiedAspect classifiedAspect;
@Mock ClassificationSchemeService mockClassificationSchemeService; @Mock ClassificationSchemeService mockClassificationSchemeService;
@Mock CoreServicesExtras mockCoreServicesExtras; @Mock CoreServicesExtras mockCoreServicesExtras;
@Mock NodeService mockNodeService; @Mock NodeService mockNodeService;
@Mock RenditionService mockRenditionService; @Mock RenditionService mockRenditionService;
@Mock ReferralAdminService mockReferralAdminService;
@Before @Before
public void setUp() public void setUp()
@@ -135,50 +129,20 @@ public class ClassifiedAspectUnitTest implements ClassifiedContentModel
classifiedAspect.checkConsistencyOfProperties(NODE_REF); classifiedAspect.checkConsistencyOfProperties(NODE_REF);
} }
/** Check that when a node is classified, its renditions are also classified. */ @Test public void newlyClassifiedNodeShouldLinkItsMetadataToAllRenditions()
@Test public void classificationOfNodeShouldClassifyRenditions()
{ {
for (NodeRef n : asList(NODE_REF, RENDITION_1, RENDITION_2)) when(mockRenditionService.getRenditions(NODE_REF))
{
when(mockNodeService.hasAspect(n, ASPECT_CLASSIFIED)).thenReturn(true);
}
when(mockClassificationSchemeService.getClassificationLevelById(eq("Top Secret"))).thenReturn(TOP_SECRET);
when(mockClassificationSchemeService.getClassificationLevelById(eq("Secret"))).thenReturn(SECRET);
when(mockClassificationSchemeService.getReclassification(any(), any())).thenReturn(ClassificationSchemeService.Reclassification.DOWNGRADE);
when(mockRenditionService.getRenditions(eq(NODE_REF)))
.thenReturn(asList(rendition(NODE_REF, RENDITION_1), rendition(NODE_REF, RENDITION_2))); .thenReturn(asList(rendition(NODE_REF, RENDITION_1), rendition(NODE_REF, RENDITION_2)));
for (final NodeRef rendition : asList(RENDITION_1, RENDITION_2))
{
when(mockRenditionService.getSourceNode(rendition)).thenReturn(rendition(NODE_REF, rendition));
}
classifiedAspect.onAddAspect(NODE_REF, ASPECT_CLASSIFIED); classifiedAspect.onAddAspect(NODE_REF, ASPECT_CLASSIFIED);
for (NodeRef rendition : asList(RENDITION_1, RENDITION_2)) for (NodeRef rendition : asList(RENDITION_1, RENDITION_2))
{ {
verify(mockCoreServicesExtras).copyAspect(NODE_REF, rendition, ClassifiedContentModel.ASPECT_CLASSIFIED); verify(mockReferralAdminService).attachReferrer(rendition, NODE_REF, ASSOC_CLASSIFIED_RENDITION);
}
}
@Test public void reclassificationOfNodeShouldReclassifyRenditions()
{
for (NodeRef n : asList(NODE_REF, RENDITION_1, RENDITION_2))
{
when(mockNodeService.hasAspect(n, ASPECT_CLASSIFIED)).thenReturn(true);
}
when(mockClassificationSchemeService.getClassificationLevelById("Top Secret")).thenReturn(TOP_SECRET);
when(mockClassificationSchemeService.getClassificationLevelById("Secret")).thenReturn(SECRET);
when(mockClassificationSchemeService.getReclassification(any(), any())).thenReturn(ClassificationSchemeService.Reclassification.DOWNGRADE);
when(mockRenditionService.getRenditions(eq(NODE_REF)))
.thenReturn(asList(rendition(NODE_REF, RENDITION_1), rendition(NODE_REF, RENDITION_2)));
Map<QName, Serializable> oldProps = new HashMap<>();
oldProps.put(PROP_CLASSIFIED_BY, "userone");
oldProps.put(PROP_CURRENT_CLASSIFICATION, "Top Secret");
Map<QName, Serializable> newProps = new HashMap<>(oldProps);
newProps.put(PROP_CURRENT_CLASSIFICATION, "Secret");
classifiedAspect.onUpdateProperties(NODE_REF, oldProps, newProps);
for (NodeRef rendition : asList(RENDITION_1, RENDITION_2))
{
verify(mockCoreServicesExtras).copyAspect(NODE_REF, rendition, ClassifiedContentModel.ASPECT_CLASSIFIED);
} }
} }