RM InPlace Prototype:

* permission mapping improvements ... allows filling and declaration of unfiled records
  * actions of 'records' in doc lib are shown as restricted rm list
  * "Record" banner is shown in doc lib if content is a record (this differs from the normal record view where the undeclared status is shown, this isn't relevant for a content user)
  * linked to many record folders indicator not shown unless it really is linked to many record folders
  


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/DEV/INPLACE@42374 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2012-10-05 06:03:21 +00:00
parent 6b54f8f9f8
commit 4e433635df
10 changed files with 304 additions and 161 deletions

View File

@@ -15,8 +15,7 @@
<!-- Create record action --> <!-- Create record action -->
<bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction"> <bean id="create-record" parent="action-executer" class="org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction">
<property name="recordsManagementService" ref="RecordsManagementService"/> <property name="recordsManagementService" ref="RecordsManagementService"/>
<property name="recordsManagementSecurityService" ref="RecordsManagementSecurityService" /> <property name="recordService" ref="RecordService" />
<property name="permissionService" ref="PermissionService" />
<property name="nodeService" ref="NodeService" /> <property name="nodeService" ref="NodeService" />
<property name="applicableTypes"> <property name="applicableTypes">
<list> <list>

View File

@@ -726,7 +726,6 @@
<property name="rma:dateFiled"> <property name="rma:dateFiled">
<title>Date Filed</title> <title>Date Filed</title>
<type>d:date</type> <type>d:date</type>
<mandatory>true</mandatory>
</property> </property>
<property name="rma:publicationDate"> <property name="rma:publicationDate">

View File

@@ -482,6 +482,7 @@
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.updateRole=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.updateRole=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.deleteRole=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.deleteRole=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.assignRoleToAuthority=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.assignRoleToAuthority=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.hasExtendedReaders=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.getExtendedReaders=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.getExtendedReaders=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.setExtendedReaders=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.setExtendedReaders=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.removeExtendedReaders=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService.removeExtendedReaders=RM_ALLOW
@@ -801,6 +802,8 @@
<property name="policyComponent" ref="policyComponent"/> <property name="policyComponent" ref="policyComponent"/>
<property name="dictionaryService" ref="DictionaryService"/> <property name="dictionaryService" ref="DictionaryService"/>
<property name="identifierService" ref="recordsManagementIdentifierService"/> <property name="identifierService" ref="recordsManagementIdentifierService"/>
<property name="permissionService" ref="PermissionService"/>
<property name="recordsManagementSecurityService" ref="RecordsManagementSecurityService"/>
</bean> </bean>
<bean id="RecordService" class="org.springframework.aop.framework.ProxyFactoryBean"> <bean id="RecordService" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -845,6 +848,7 @@
<![CDATA[ <![CDATA[
org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecordMetaDataAspects=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecordMetaDataAspects=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.record.RecordService.isDeclared=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.isDeclared=RM.Read.0
org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecordFromDocument=RM_ALLOW
org.alfresco.module.org_alfresco_module_rm.record.RecordService.*=RM_DENY org.alfresco.module.org_alfresco_module_rm.record.RecordService.*=RM_DENY
]]> ]]>
</value> </value>

View File

@@ -33,6 +33,7 @@ import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService;
import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.PolicyComponent;
@@ -284,7 +285,17 @@ public class RecordsManagementServiceImpl implements RecordsManagementService,
NodeRef thumbnail = childAssocRef.getChildRef(); NodeRef thumbnail = childAssocRef.getChildRef();
if (nodeService.exists(thumbnail) == true) if (nodeService.exists(thumbnail) == true)
{ {
// apply file plan component aspect to thumbnail
nodeService.addAspect(thumbnail, ASPECT_FILE_PLAN_COMPONENT, null); nodeService.addAspect(thumbnail, ASPECT_FILE_PLAN_COMPONENT, null);
// manage any extended readers
RecordsManagementSecurityService securityService = serviceRegistry.getRecordsManagementSecurityService();
NodeRef parent = childAssocRef.getParentRef();
Set<String> readers = securityService.getExtendedReaders(parent);
if (readers != null && readers.size() != 0)
{
securityService.setExtendedReaders(thumbnail, readers, false);
}
} }
} }

View File

@@ -19,23 +19,18 @@
package org.alfresco.module.org_alfresco_module_rm.action.dm; package org.alfresco.module.org_alfresco_module_rm.action.dm;
import java.util.List; import java.util.List;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
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;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
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.cmr.security.PermissionService;
import org.alfresco.service.namespace.RegexQNamePattern;
/** /**
* Creates a new record from an existing content object. * Creates a new record from an existing content object.
@@ -47,29 +42,31 @@ import org.alfresco.service.namespace.RegexQNamePattern;
public class CreateRecordAction extends ActionExecuterAbstractBase public class CreateRecordAction extends ActionExecuterAbstractBase
implements RecordsManagementModel implements RecordsManagementModel
{ {
/** Action name */
public static final String NAME = "create-record"; public static final String NAME = "create-record";
/** Records management service */
private RecordsManagementService recordsManagementService; private RecordsManagementService recordsManagementService;
private RecordsManagementSecurityService recordsManagementSecurityService; /** Record service */
private RecordService recordService;
private PermissionService permissionService;
private NodeService nodeService; private NodeService nodeService;
/**
* @param recordsManagementService records management service
*/
public void setRecordsManagementService(RecordsManagementService recordsManagementService) public void setRecordsManagementService(RecordsManagementService recordsManagementService)
{ {
this.recordsManagementService = recordsManagementService; this.recordsManagementService = recordsManagementService;
} }
public void setRecordsManagementSecurityService(RecordsManagementSecurityService recordsManagementSecurityService) /**
* @param recordService record service
*/
public void setRecordService(RecordService recordService)
{ {
this.recordsManagementSecurityService = recordsManagementSecurityService; this.recordService = recordService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
} }
public void setNodeService(NodeService nodeService) public void setNodeService(NodeService nodeService)
@@ -77,43 +74,31 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
this.nodeService = nodeService; this.nodeService = nodeService;
} }
/**
* @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
*/
@Override @Override
protected void executeImpl(Action action, final NodeRef actionedUponNodeRef) protected void executeImpl(Action action, final NodeRef actionedUponNodeRef)
{
// skip everything if the actioned upon node reference is already a record
if (nodeService.hasAspect(actionedUponNodeRef, ASPECT_RECORD) == false)
{ {
// TODO we should use the file plan passed as a parameter // TODO we should use the file plan passed as a parameter
// grab the file plan // grab the file plan
List<NodeRef> filePlans = recordsManagementService.getFilePlans(); List<NodeRef> filePlans = recordsManagementService.getFilePlans();
if (filePlans.size() == 1) if (filePlans.size() == 1)
{ {
// TODO parameterise the action with the file plan
final NodeRef filePlan = filePlans.get(0); final NodeRef filePlan = filePlans.get(0);
// run record creation as system
AuthenticationUtil.runAsSystem(new RunAsWork<Void>() AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{ {
@Override @Override
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
// get the documents readers // create record from existing document
Long aclId = nodeService.getNodeAclId(actionedUponNodeRef); recordService.createRecordFromDocument(filePlan, actionedUponNodeRef);
Set<String> readers = permissionService.getReaders(aclId);
// get the documents primary parent assoc
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(actionedUponNodeRef);
/// get the new record container for the file plan
NodeRef newRecordContainer = getNewRecordContainer(filePlan);
if (newRecordContainer == null)
{
throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found.");
}
// move the document into the file plan
nodeService.moveNode(actionedUponNodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName());
// maintain the original primary location
nodeService.addChild(parentAssoc.getParentRef(), actionedUponNodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName());
// set the readers
recordsManagementSecurityService.setExtendedReaders(actionedUponNodeRef, readers);
return null; return null;
} }
@@ -124,17 +109,11 @@ public class CreateRecordAction extends ActionExecuterAbstractBase
throw new AlfrescoRuntimeException("Unable to find file plan."); throw new AlfrescoRuntimeException("Unable to find file plan.");
} }
} }
private NodeRef getNewRecordContainer(NodeRef filePlan)
{
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ASSOC_UNFILED_RECORDS, RegexQNamePattern.MATCH_ALL);
if (assocs.size() != 1)
{
throw new AlfrescoRuntimeException("Error getting the new record container, because the container cannot be indentified.");
}
return assocs.get(0).getChildRef();
} }
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override @Override
protected void addParameterDefinitions(List<ParameterDefinition> params) protected void addParameterDefinitions(List<ParameterDefinition> params)
{ {

View File

@@ -22,19 +22,39 @@ import java.util.List;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.jscript.app.BaseEvaluator; import org.alfresco.module.org_alfresco_module_rm.jscript.app.BaseEvaluator;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
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.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
/** /**
* Determines whether a node has multiple parents within a file plan
*
* @author Roy Wetherall * @author Roy Wetherall
*/ */
public class MultiParentEvaluator extends BaseEvaluator public class MultiParentEvaluator extends BaseEvaluator
{ {
@Override @Override
protected boolean evaluateImpl(NodeRef nodeRef) protected boolean evaluateImpl(final NodeRef nodeRef)
{
return AuthenticationUtil.runAsSystem(new RunAsWork<Boolean>()
{
@Override
public Boolean doWork() throws Exception
{ {
List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); List<ChildAssociationRef> parents = nodeService.getParentAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
return (parents.size() > 1); int count = 0;
for (ChildAssociationRef parent : parents)
{
if (nodeService.hasAspect(parent.getParentRef(), ASPECT_FILE_PLAN_COMPONENT) == true)
{
count++;
}
}
return (count > 1);
}
});
} }
} }

View File

@@ -47,6 +47,14 @@ public interface RecordService
*/ */
boolean isDeclared(NodeRef nodeRef); boolean isDeclared(NodeRef nodeRef);
/**
* Create a new record from an existing document.
*
* @param filePlan
* @param document
*/
void createRecordFromDocument(NodeRef filePlan, NodeRef document);
// TODO boolean isRecordFiled(NodeRef record); // TODO boolean isRecordFiled(NodeRef record);
// TODO boolean isRecordClassified(NodeRef record); // TODO boolean isRecordClassified(NodeRef record);

View File

@@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.record;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
@@ -27,20 +28,20 @@ import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService;
import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
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.NamespaceService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
/** /**
* Record service implementation
*
* @author Roy Wetherall * @author Roy Wetherall
* @since 2.1 * @since 2.1
*/ */
@@ -56,6 +57,10 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel
private PolicyComponent policyComponent; private PolicyComponent policyComponent;
private PermissionService permissionService;
private RecordsManagementSecurityService recordsManagementSecurityService;
/** List of available record meta-data aspects */ /** List of available record meta-data aspects */
private Set<QName> recordMetaDataAspects; private Set<QName> recordMetaDataAspects;
@@ -84,41 +89,51 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel
this.policyComponent = policyComponent; this.policyComponent = policyComponent;
} }
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setRecordsManagementSecurityService(RecordsManagementSecurityService recordsManagementSecurityService)
{
this.recordsManagementSecurityService = recordsManagementSecurityService;
}
public void init() public void init()
{ {
policyComponent.bindAssociationBehaviour( // policyComponent.bindAssociationBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"), // QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateChildAssociation"),
TYPE_UNFILED_RECORD_CONTAINER, // TYPE_UNFILED_RECORD_CONTAINER,
ContentModel.ASSOC_CONTAINS, // ContentModel.ASSOC_CONTAINS,
new JavaBehaviour(this, "onCreateNewRecord", NotificationFrequency.TRANSACTION_COMMIT)); // new JavaBehaviour(this, "onCreateNewRecord", NotificationFrequency.TRANSACTION_COMMIT));
} }
public void onCreateNewRecord(final ChildAssociationRef childAssocRef, boolean bNew) // public void onCreateNewRecord(final ChildAssociationRef childAssocRef, boolean bNew)
{ // {
AuthenticationUtil.runAsSystem(new RunAsWork<Void>() // AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{ // {
@Override // @Override
public Void doWork() throws Exception // public Void doWork() throws Exception
{ // {
NodeRef nodeRef = childAssocRef.getChildRef(); // NodeRef nodeRef = childAssocRef.getChildRef();
if (nodeService.exists(nodeRef) == true) // if (nodeService.exists(nodeRef) == true)
{ // {
QName type = nodeService.getType(nodeRef); // QName type = nodeService.getType(nodeRef);
if (ContentModel.TYPE_CONTENT.equals(type) == true || // if (ContentModel.TYPE_CONTENT.equals(type) == true ||
dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) == true) // dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) == true)
{ // {
makeRecord(nodeRef); // makeRecord(nodeRef);
} // }
else // else
{ // {
throw new AlfrescoRuntimeException("Only content can be created as a record."); // throw new AlfrescoRuntimeException("Only content can be created as a record.");
} // }
} // }
//
return null; // return null;
} // }
}); // });
} // }
/** /**
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects() * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects()
@@ -153,47 +168,39 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel
return (nodeService.hasAspect(record, ASPECT_DECLARED_RECORD)); return (nodeService.hasAspect(record, ASPECT_DECLARED_RECORD));
} }
/** @Override
* @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getNewRecordContainer(org.alfresco.service.cmr.repository.NodeRef) public void createRecordFromDocument(NodeRef filePlan, NodeRef document)
*/ {
// public NodeRef getNewRecordContainer(NodeRef filePlan) // skip everything if the document is already a record
// { if (nodeService.hasAspect(document, ASPECT_RECORD) == false)
// NodeRef result = null; {
// // get the documents readers
// if (recordsManagementService.isFilePlan(filePlan) == true) Long aclId = nodeService.getNodeAclId(document);
// { Set<String> readers = permissionService.getReaders(aclId);
// List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ASSOC_NEW_RECORDS, RegexQNamePattern.MATCH_ALL);
// if (assocs.size() != 1)
// {
// throw new AlfrescoRuntimeException("Error getting the new record container, because the container cannot be indentified.");
// }
// result = assocs.get(0).getChildRef();
// }
//
// return result;
// }
// @Override // get the documents primary parent assoc
// public NodeRef createRecord(NodeRef filePlan, NodeRef document) ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(document);
// {
// // get the documents primary parent assoc /// get the new record container for the file plan
// ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(document); NodeRef newRecordContainer = getNewRecordContainer(filePlan);
// if (newRecordContainer == null)
// /// get the new record container for the file plan {
// NodeRef newRecordContainer = getNewRecordContainer(filePlan); throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found.");
// if (newRecordContainer == null) }
// {
// throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); // move the document into the file plan
// } nodeService.moveNode(document, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName());
//
// // move the document into the file plan // maintain the original primary location
// nodeService.moveNode(document, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName()); nodeService.addChild(parentAssoc.getParentRef(), document, parentAssoc.getTypeQName(), parentAssoc.getQName());
//
// // maintain the original primary location // make the document a record
// nodeService.addChild(parentAssoc.getParentRef(), document, parentAssoc.getTypeQName(), parentAssoc.getQName()); makeRecord(document);
//
// return document; // set the readers
// } recordsManagementSecurityService.setExtendedReaders(document, readers);
}
}
/** /**
* *
@@ -207,4 +214,19 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel
nodeService.setProperty(document, PROP_IDENTIFIER, recordId); nodeService.setProperty(document, PROP_IDENTIFIER, recordId);
} }
/**
*
* @param filePlan
* @return
*/
private NodeRef getNewRecordContainer(NodeRef filePlan)
{
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(filePlan, ASSOC_UNFILED_RECORDS, RegexQNamePattern.MATCH_ALL);
if (assocs.size() != 1)
{
throw new AlfrescoRuntimeException("Error getting the new record container, because the container cannot be indentified.");
}
return assocs.get(0).getChildRef();
}
} }

View File

@@ -154,16 +154,30 @@ public interface RecordsManagementSecurityService
void deletePermission(NodeRef nodeRef, String authority, String permission); void deletePermission(NodeRef nodeRef, String authority, String permission);
/** /**
* Indicates whether the node has any extended readers set or not.
* *
* @param nodeRef * @param nodeRef node reference
* @return * @return boolean true if the node has extended readers set, false otherwise
* @since 2.1
*/
boolean hasExtendedReaders(NodeRef nodeRef);
/**
* Gets the set authorities that are extended readers for the given node.
*
* @param nodeRef node reference
* @return {@link Set}<{@link String}> extended readers
* @since 2.1
*/ */
Set<String> getExtendedReaders(NodeRef nodeRef); Set<String> getExtendedReaders(NodeRef nodeRef);
/** /**
* Set the authorities that are extended readers on the node. Applies extended readers to
* file plan parent hierarchy.
* *
* @param nodeRef * @param nodeRef node reference
* @param readers * @param readers extended readers
* @since 2.1
*/ */
void setExtendedReaders(NodeRef nodeRef, Set<String> readers); void setExtendedReaders(NodeRef nodeRef, Set<String> readers);
@@ -171,12 +185,23 @@ public interface RecordsManagementSecurityService
* *
* @param nodeRef * @param nodeRef
* @param readers * @param readers
* @param applyToParents
* @since 2.1
*/
void setExtendedReaders(NodeRef nodeRef, Set<String> readers, boolean applyToParents);
/**
*
* @param nodeRef
* @param readers
* @since 2.1
*/ */
void removeExtendedReaders(NodeRef nodeRef, Set<String> readers); void removeExtendedReaders(NodeRef nodeRef, Set<String> readers);
/** /**
* *
* @param nodeRef * @param nodeRef
* @since 2.1
*/ */
void removeAllExtendedReaders(NodeRef nodeRef); void removeAllExtendedReaders(NodeRef nodeRef);
} }

View File

@@ -31,6 +31,7 @@ import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
@@ -42,6 +43,7 @@ import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
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.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;
@@ -70,7 +72,8 @@ import org.springframework.context.ApplicationContextAware;
*/ */
public class RecordsManagementSecurityServiceImpl implements RecordsManagementSecurityService, public class RecordsManagementSecurityServiceImpl implements RecordsManagementSecurityService,
RecordsManagementModel, RecordsManagementModel,
ApplicationContextAware ApplicationContextAware,
NodeServicePolicies.OnMoveNodePolicy
{ {
/** Capability service */ /** Capability service */
@@ -206,6 +209,11 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
NodeServicePolicies.OnCreateNodePolicy.QNAME, NodeServicePolicies.OnCreateNodePolicy.QNAME,
TYPE_RECORD_FOLDER, TYPE_RECORD_FOLDER,
new JavaBehaviour(this, "onCreateRecordFolder", NotificationFrequency.TRANSACTION_COMMIT)); new JavaBehaviour(this, "onCreateRecordFolder", NotificationFrequency.TRANSACTION_COMMIT));
policyComponent.bindClassBehaviour(
NodeServicePolicies.OnMoveNodePolicy.QNAME,
ASPECT_RECORD,
new JavaBehaviour(this, "onMoveNode", NotificationFrequency.TRANSACTION_COMMIT));
} }
/** /**
@@ -980,6 +988,24 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
} }
/**
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#hasExtendedReaders(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean hasExtendedReaders(NodeRef nodeRef)
{
boolean result = false;
Set<String> extendedReaders = getExtendedReaders(nodeRef);
if (extendedReaders != null && extendedReaders.size() != 0)
{
result = true;
}
return result;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#getExtendedReaders(org.alfresco.service.cmr.repository.NodeRef)
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public Set<String> getExtendedReaders(NodeRef nodeRef) public Set<String> getExtendedReaders(NodeRef nodeRef)
@@ -999,9 +1025,18 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
/** /**
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#setExtendedReaders(org.alfresco.service.cmr.repository.NodeRef, java.util.Set) * @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#setExtendedReaders(org.alfresco.service.cmr.repository.NodeRef, java.util.Set)
*/ */
@SuppressWarnings("unchecked")
@Override @Override
public void setExtendedReaders(NodeRef nodeRef, Set<String> readers) public void setExtendedReaders(NodeRef nodeRef, Set<String> readers)
{
setExtendedReaders(nodeRef, readers, true);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#setExtendedReaders(org.alfresco.service.cmr.repository.NodeRef, java.util.Set, boolean)
*/
@SuppressWarnings("unchecked")
@Override
public void setExtendedReaders(NodeRef nodeRef, java.util.Set<String> readers, boolean applyToParents)
{ {
ParameterCheck.mandatory("nodeRef", nodeRef); ParameterCheck.mandatory("nodeRef", nodeRef);
ParameterCheck.mandatory("readers", readers); ParameterCheck.mandatory("readers", readers);
@@ -1044,6 +1079,19 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
// set the readers property (this will in turn apply the aspect if required) // set the readers property (this will in turn apply the aspect if required)
nodeService.setProperty(nodeRef, PROP_READERS, (Serializable)readersMap); nodeService.setProperty(nodeRef, PROP_READERS, (Serializable)readersMap);
// apply the readers to any renditions of the content
if (recordsManagementService.isRecord(nodeRef) == true)
{
List<ChildAssociationRef> assocs = nodeService.getChildAssocs(nodeRef, RenditionModel.ASSOC_RENDITION, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef assoc : assocs)
{
NodeRef child = assoc.getChildRef();
setExtendedReaders(child, readers, false);
}
}
if (applyToParents == true)
{
// apply the extended readers up the file plan primary hierarchy // apply the extended readers up the file plan primary hierarchy
NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef();
if (parent != null && if (parent != null &&
@@ -1053,6 +1101,7 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
} }
} }
} }
}
@Override @Override
public void removeExtendedReaders(NodeRef nodeRef, Set<String> readers) public void removeExtendedReaders(NodeRef nodeRef, Set<String> readers)
@@ -1069,5 +1118,32 @@ public class RecordsManagementSecurityServiceImpl implements RecordsManagementSe
{ {
// TODO Auto-generated method stub // TODO Auto-generated method stub
}
@Override
public void onMoveNode(final ChildAssociationRef origAssoc, final ChildAssociationRef newAssoc)
{
// TODO temp solution for demo
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
{
@Override
public Void doWork() throws Exception
{
NodeRef record = newAssoc.getChildRef();
NodeRef parent = newAssoc.getParentRef();
Set<String> readers = getExtendedReaders(record);
if (readers != null && readers.size() != 0)
{
setExtendedReaders(parent, readers);
}
return null;
}});
} }
} }