From 8b784834bc9cfde8aadb4be599df9ead695547b6 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 6 Dec 2012 08:38:18 +0000 Subject: [PATCH] RM-557: Unfiled records service API * fleshed out unit tests for record service * fixed up a couple of issues when creating records * unfiled record API integrated into the Record Service * investigated moving filling API from actions into service (roughed out API) * updated create record action git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@44403 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-service-context.xml | 7 +- .../action/RMActionExecuterAbstractBase.java | 23 - .../action/dm/CreateRecordAction.java | 72 ++- .../jscript/app/JSONConversionComponent.java | 2 +- .../model/RecordsManagementModel.java | 1 - .../record/RecordService.java | 42 +- .../record/RecordServiceImpl.java | 165 +++++-- ...tImpl.java => CreateRecordActionTest.java} | 27 +- .../test/service/FreezeServiceImplTest.java | 29 +- .../test/service/RecordServiceImplTest.java | 423 ++++++++++++++---- .../test/util/BaseRMTestCase.java | 51 ++- 11 files changed, 576 insertions(+), 266 deletions(-) rename rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/{RecordServiceTestImpl.java => CreateRecordActionTest.java} (87%) diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 1d871e0a1c..2977a419c1 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -973,6 +973,7 @@ + @@ -1018,8 +1019,10 @@ org.alfresco.module.org_alfresco_module_rm.record.RecordService.getRecordMetaDataAspects=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.record.RecordService.isRecord=RM_ALLOW 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.getUnfiledRecordContainer=RM_ALLOW + org.alfresco.module.org_alfresco_module_rm.record.RecordService.isFiled=RM.Read.0 + org.alfresco.module.org_alfresco_module_rm.record.RecordService.createRecord=RM_ALLOW + org.alfresco.module.org_alfresco_module_rm.record.RecordService.fileRecord=RM.WRITE.0.1 + org.alfresco.module.org_alfresco_module_rm.record.RecordService.getUnfiledContainer=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.record.RecordService.*=RM_DENY ]]> diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java index f2802c6fa9..f3b6a56988 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/RMActionExecuterAbstractBase.java @@ -250,24 +250,6 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra this.recordService = recordService; } - /** - * Register with a single capability - * @param capability - */ - // public void setCapability(AbstractCapability capability) - // { - // capabilities.add(capability); - // } - - /** - * Register with several capabilities - * @param capabilities - */ - // public void setCapabilities(Collection capabilities) - // { - // this.capabilities.addAll(capabilities); - // } - public void setRecordsManagementAdminService(RecordsManagementAdminService recordsManagementAdminService) { this.recordsManagementAdminService = recordsManagementAdminService; @@ -296,11 +278,6 @@ public abstract class RMActionExecuterAbstractBase extends ActionExecuterAbstra PropertyCheck.mandatory(this, "recordsManagementService", recordsManagementService); PropertyCheck.mandatory(this, "recordsManagementAdminService", recordsManagementAdminService); PropertyCheck.mandatory(this, "recordsManagementEventService", recordsManagementEventService); - - // for(AbstractCapability capability : capabilities) - // { - // capability.registerAction(this); - // } } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java index 51e86cdb60..e405fa0034 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java @@ -27,8 +27,6 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -114,48 +112,38 @@ public class CreateRecordAction extends ActionExecuterAbstractBase } else { - // run record creation as system - AuthenticationUtil.runAsSystem(new RunAsWork() + NodeRef filePlan = (NodeRef)action.getParameterValue(PARAM_FILE_PLAN); + if (filePlan == null) { - @Override - public Void doWork() throws Exception - { - NodeRef filePlan = (NodeRef)action.getParameterValue(PARAM_FILE_PLAN); - if (filePlan == null) - { - List filePlans = recordsManagementService.getFilePlans(); - if (filePlans.size() == 1) - { - filePlan = filePlans.get(0); - } - else - { - if (logger.isDebugEnabled() == true) - { - logger.debug("Can not create record, because the default file plan can not be determined."); - } - throw new AlfrescoRuntimeException("Can not create record, because the default file plan can not be determined."); - } - } - else - { - // verify that the provided file plan is actually a file plan - if (recordsManagementService.isFilePlan(filePlan) == false) - { - if (logger.isDebugEnabled() == true) - { - logger.debug("Can not create record, because the provided file plan node reference is not a file plan."); - } - throw new AlfrescoRuntimeException("Can not create record, because the provided file plan node reference is not a file plan."); - } - } - - // create record from existing document - recordService.createRecordFromDocument(filePlan, actionedUponNodeRef); - - return null; + List filePlans = recordsManagementService.getFilePlans(); + if (filePlans.size() == 1) + { + filePlan = filePlans.get(0); } - }); + else + { + if (logger.isDebugEnabled() == true) + { + logger.debug("Can not create record, because the default file plan can not be determined."); + } + throw new AlfrescoRuntimeException("Can not create record, because the default file plan can not be determined."); + } + } + else + { + // verify that the provided file plan is actually a file plan + if (recordsManagementService.isFilePlan(filePlan) == false) + { + if (logger.isDebugEnabled() == true) + { + logger.debug("Can not create record, because the provided file plan node reference is not a file plan."); + } + throw new AlfrescoRuntimeException("Can not create record, because the provided file plan node reference is not a file plan."); + } + } + + // create record from existing document + recordService.createRecord(filePlan, actionedUponNodeRef); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java index 92c8b5627b..c94320cf3c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/jscript/app/JSONConversionComponent.java @@ -145,7 +145,7 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC rmNodeValues.put("filePlan", filePlan.toString()); // Unfiled container node reference - NodeRef unfiledRecordContainer = recordService.getUnfiledRecordContainer(filePlan); + NodeRef unfiledRecordContainer = recordService.getUnfiledContainer(filePlan); rmNodeValues.put("unfiledRecordContainer", unfiledRecordContainer.toString()); rmNodeValues.put("properties", propertiesToJSON(unfiledRecordContainer, useShortQName)); QName type = fileFolderService.getFileInfo(unfiledRecordContainer).getType(); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index a547203692..e8e3111ea2 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -231,5 +231,4 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel // Extended readers aspect public static final QName ASPECT_EXTENDED_READERS = QName.createQName(RM_URI, "extendedReaders"); public static final QName PROP_READERS = QName.createQName(RM_URI, "readers"); - } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java index 7fda6b96b3..2a5d076d35 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java @@ -54,32 +54,36 @@ public interface RecordService * @return boolean true if record is declared, false otherwise */ boolean isDeclared(NodeRef nodeRef); - + /** - * Creates a new record from an existing document. + * Indicates whether the record is filed or not * - * @param filePlan The filePlan in which the record should be placed - * @param document The document from which the record will be created + * @param nodeRef record + * @return boolean true if filed, false otherwise */ - void createRecordFromDocument(NodeRef filePlan, NodeRef document); - + boolean isFiled(NodeRef nodeRef); + /** - * Gets the unfiled record container for the given file plan + * Gets the unfiled root container for the given file plan * * @param filePlan The filePlan for which the unfiled record container should be retrieved * @return NodeRef The nodeRef of the container object */ - public NodeRef getUnfiledRecordContainer(NodeRef filePlan); + public NodeRef getUnfiledContainer(NodeRef filePlan); - // TODO boolean isRecordFiled(NodeRef record); - - // TODO boolean isRecordClassified(NodeRef record); - - // TODO NodeRef getNewRecordContainer(NodeRef filePlan); - - // TODO NodeRef createRecord(NodeRef filePlan, NodeRef document); - - // TODO NodeRef createAndFileRecord(NodeRef recordFolder, NodeRef document); - - // TODO void fileRecord(NodeRef recordFolder, NodeRef record); + /** + * Creates a new unfiled record from an existing node. + * + * @param filePlan The filePlan in which the record should be placed + * @param nodeRef The node from which the record will be created + */ + void createRecord(NodeRef filePlan, NodeRef nodeRef); + + /** + * Files an unfiled record. + * + * @param record record + * @param recordFolder record folder + */ + void fileRecord(NodeRef record, NodeRef recordFolder); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index f05a9951d9..b2f9ae0421 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -25,14 +25,19 @@ import java.util.Set; 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.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; 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.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; @@ -60,6 +65,9 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel /** Extended security service */ private ExtendedSecurityService extendedSecurityService; + + /** Records management service */ + private RecordsManagementService recordsManagementService; /** List of available record meta-data aspects */ private Set recordMetaDataAspects; @@ -104,9 +112,20 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel this.extendedSecurityService = extendedSecurityService; } + /** + * @param recordsManagementService records management service + */ + public void setRecordsManagementService(RecordsManagementService recordsManagementService) + { + this.recordsManagementService = recordsManagementService; + } + + /** + * Init method + */ public void init() { - + // TODO } /** @@ -156,52 +175,39 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel return nodeService.hasAspect(record, ASPECT_DECLARED_RECORD); } - + /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecordFromDocument(org.alfresco.service.cmr.repository.NodeRef, - * org.alfresco.service.cmr.repository.NodeRef) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isFiled(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public void createRecordFromDocument(NodeRef filePlan, NodeRef document) + public boolean isFiled(NodeRef nodeRef) { - ParameterCheck.mandatory("filePlan", filePlan); - ParameterCheck.mandatory("document", document); - - // skip everything if the document is already a record - if (nodeService.hasAspect(document, ASPECT_RECORD) == false) + ParameterCheck.mandatory("nodeRef", nodeRef); + + boolean result = false; + + if (isRecord(nodeRef) == true) { - // get the new record container for the file plan - NodeRef newRecordContainer = getUnfiledRecordContainer(filePlan); - if (newRecordContainer == null) { throw new AlfrescoRuntimeException( - "Unable to create record, because new record container could not be found."); } - - // get the documents primary parent assoc - ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(document); - - // move the document into the file plan - nodeService.moveNode(document, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName()); - - // maintain the original primary location - nodeService.addChild(parentAssoc.getParentRef(), document, parentAssoc.getTypeQName(), parentAssoc - .getQName()); - - // make the document a record - makeRecord(document); - - // get the documents readers - Long aclId = nodeService.getNodeAclId(document); - Set readers = permissionService.getReaders(aclId); - - // set the readers - extendedSecurityService.setExtendedReaders(document, readers); + ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(nodeRef); + if (childAssocRef != null) + { + NodeRef parent = childAssocRef.getParentRef(); + if (parent != null && + recordsManagementService.isRecordFolder(parent) == true) + { + result = true; + } + } } + + return result; } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getUnfiledRecordContainer(org.alfresco.service.cmr.repository.NodeRef) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getUnfiledRootContainer(org.alfresco.service.cmr.repository.NodeRef) */ @Override - public NodeRef getUnfiledRecordContainer(NodeRef filePlan) + public NodeRef getUnfiledContainer(NodeRef filePlan) { ParameterCheck.mandatory("filePlan", filePlan); @@ -213,6 +219,93 @@ public class RecordServiceImpl implements RecordService, RecordsManagementModel return assocs.get(0).getChildRef(); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, + * org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void createRecord(final NodeRef filePlan, final NodeRef nodeRef) + { + ParameterCheck.mandatory("filePlan", filePlan); + ParameterCheck.mandatory("document", nodeRef); + + if (nodeService.hasAspect(nodeRef, ASPECT_RECORD) == false) + { + // first we do a sanity check to ensure that the user has at least write permissions on the document + if (permissionService.hasPermission(nodeRef, PermissionService.WRITE) != AccessStatus.ALLOWED) + { + throw new AccessDeniedException("Can not create record from document, because the user " + + AuthenticationUtil.getFullyAuthenticatedUser() + + " does not have Write permissions on the doucment " + + nodeRef.toString()); + } + + // do the work of creating the record as the system user + AuthenticationUtil.runAsSystem(new RunAsWork() + { + + @Override + public Void doWork() throws Exception + { + // get the new record container for the file plan + NodeRef newRecordContainer = getUnfiledContainer(filePlan); + if (newRecordContainer == null) + { + throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); + } + + // get the documents readers + Long aclId = nodeService.getNodeAclId(nodeRef); + Set readers = permissionService.getReaders(aclId); + + // get the documents primary parent assoc + ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeRef); + + // move the document into the file plan + nodeService.moveNode(nodeRef, newRecordContainer, ContentModel.ASSOC_CONTAINS, parentAssoc.getQName()); + + // maintain the original primary location + nodeService.addChild(parentAssoc.getParentRef(), nodeRef, parentAssoc.getTypeQName(), parentAssoc.getQName()); + + // make the document a record + makeRecord(nodeRef); + + // set the readers + extendedSecurityService.setExtendedReaders(nodeRef, readers); + + return null; + } + }); + } + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#fileRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void fileRecord(NodeRef record, NodeRef recordFolder) + { + // check if this is a record + if (isRecord(record) == false) + { + // TODO .. should we make this a record? + throw new UnsupportedOperationException("Currently unable to file something that isn't already a record"); + } + + if (isFiled(record) == false) + { + // TODO .. refactor the existing code to file a record here ... this will include moving the code that + // currently manages the properties of the disposition lifecycle aspect into the disposition service + throw new UnsupportedOperationException("Currently unsuported."); + } + else + { + // TODO .. figure out how we 'refile' a currently filed record + throw new UnsupportedOperationException("Currently unable to file an already filed record."); + } + + } + /** * Helper Methods */ diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceTestImpl.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CreateRecordActionTest.java similarity index 87% rename from rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceTestImpl.java rename to rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CreateRecordActionTest.java index bdc61b4b6e..47ee86d8e4 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceTestImpl.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CreateRecordActionTest.java @@ -20,7 +20,6 @@ package org.alfresco.module.org_alfresco_module_rm.test.service; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; -import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; @@ -42,7 +41,7 @@ import org.alfresco.util.GUID; * * @author Roy Wetherall */ -public class RecordServiceTestImpl extends BaseRMTestCase +public class CreateRecordActionTest extends BaseRMTestCase { protected static final String COLLABORATION_SITE_ID = "collab-site-id"; @@ -107,6 +106,8 @@ public class RecordServiceTestImpl extends BaseRMTestCase // create a folder and documents dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef(); dmDocument = fileFolderService.create(dmFolder, "collabDocument.txt", ContentModel.TYPE_CONTENT).getNodeRef(); + + } @Override @@ -146,27 +147,9 @@ public class RecordServiceTestImpl extends BaseRMTestCase assertEquals(AccessStatus.ALLOWED, dmPermissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS)); assertEquals(AccessStatus.ALLOWED, dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS)); - assertTrue(recordService.isRecord(dmDocument)); - - // - Capability createCapability = capabilityService.getCapability("Create"); - assertNotNull(createCapability); - createCapability.evaluate(dmDocument); - - - + assertTrue(recordService.isRecord(dmDocument)); }; }, dmUserName); - - doTestInTransaction(new Test() - { - public Void run() - { - - return null; - } - }); - } - + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java index 63fbd927e3..a17c05421e 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/FreezeServiceImplTest.java @@ -35,32 +35,11 @@ import org.alfresco.service.cmr.repository.NodeRef; */ public class FreezeServiceImplTest extends BaseRMTestCase { - /** First Record */ - private NodeRef recordOne; - - /** Second Record */ - private NodeRef recordTwo; - - /** Third Record */ - private NodeRef recordThree; - - /** Fourth Record */ - private NodeRef recordFour; - - /** - * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#setupTestDataImpl() - */ @Override - protected void setupTestDataImpl() - { - super.setupTestDataImpl(); - - // create test records - recordOne = utils.createRecord(rmFolder, "one.txt"); - recordTwo = utils.createRecord(rmFolder, "two.txt"); - recordThree = utils.createRecord(rmFolder, "three.txt"); - recordFour = utils.createRecord(rmFolder, "four.txt"); - } + protected boolean isRecordTest() + { + return true; + } /** * Test freeze service methods diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceImplTest.java index 481d485c85..bbea845ca4 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/RecordServiceImplTest.java @@ -22,115 +22,350 @@ import java.util.Arrays; import java.util.List; import java.util.Set; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.permissions.AccessDeniedException; +import org.alfresco.repo.site.SiteModel; +import org.alfresco.repo.site.SiteServiceImpl; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.site.SiteInfo; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; +import org.alfresco.service.cmr.tagging.TaggingService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; +/** + * Records Service Implementation Test + * + * @author Roy Wetherall + * @author Tuna Askoy + * @since 2.1 + */ public class RecordServiceImplTest extends BaseRMTestCase { + protected static final String COLLABORATION_SITE_ID = "collab-site-id"; - /** - * @see RecordService#getRecordMetaDataAspects() - */ - public void testGetRecordMetaDataAspects() throws Exception - { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - Set aspects = recordService.getRecordMetaDataAspects(); - assertNotNull(aspects); - assertEquals(5, aspects.size()); - assertTrue(aspects.containsAll(getAspectList())); + protected ActionService dmActionService; - return null; - } + protected TaggingService taggingService; - /** - * Helper method for getting a list of record meta data aspects - * - * @return Record meta data aspects as list - */ - private List getAspectList() - { - QName[] aspects = new QName[] + protected PermissionService dmPermissionService; + + protected ExtendedSecurityService extendedSecurityService; + + // collaboration site artifacts + protected SiteInfo collaborationSite; + protected NodeRef documentLibrary; + protected NodeRef dmFolder; + protected NodeRef dmDocument; + + // dm users + protected String dmConsumer; + protected NodeRef dmConsumerNodeRef; + protected String dmCollaborator; + protected NodeRef dmCollaboratorNodeRef; + + @Override + protected void initServices() + { + super.initServices(); + + dmActionService = (ActionService) applicationContext.getBean("ActionService"); + taggingService = (TaggingService) applicationContext.getBean("TaggingService"); + dmPermissionService = (PermissionService) applicationContext.getBean("PermissionService"); + extendedSecurityService = (ExtendedSecurityService) applicationContext.getBean("ExtendedSecurityService"); + } + + /** + * This is a user test + * + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isUserTest() + */ + @Override + protected boolean isUserTest() + { + return true; + } + + /** + * This is a record test + * + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isRecordTest() + */ + @Override + protected boolean isRecordTest() + { + return true; + } + + /** + * Setup the collaboration site test data + */ + @Override + protected void setupTestData() + { + super.setupTestData(); + + doTestInTransaction(new Test() + { + public Void run() { - DOD5015Model.ASPECT_DIGITAL_PHOTOGRAPH_RECORD, - DOD5015Model.ASPECT_PDF_RECORD, - DOD5015Model.ASPECT_WEB_RECORD, - DOD5015Model.ASPECT_SCANNED_RECORD, - ASPECT_RECORD_META_DATA - }; + setupCollaborationSiteTestDataImpl(); + return null; + } + }, AuthenticationUtil.getSystemUserName()); + } - return Arrays.asList(aspects); - } - }); - } + protected void setupCollaborationSiteTestDataImpl() + { + // create collaboration site + collaborationSite = siteService.createSite("preset", COLLABORATION_SITE_ID, "title", "description", SiteVisibility.PRIVATE); + documentLibrary = SiteServiceImpl.getSiteContainer( + COLLABORATION_SITE_ID, + SiteService.DOCUMENT_LIBRARY, + true, + siteService, + transactionService, + taggingService); - /** - * @see RecordService#isRecord(org.alfresco.service.cmr.repository.NodeRef) - */ - public void testIsRecord() throws Exception - { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - // FIXME - return null; - } - }); - } + assertNotNull("Collaboration site document library component was not successfully created.", documentLibrary); - /** - * @see RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) - */ - public void testIsDeclared() throws Exception - { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - // FIXME - return null; - } - }); - } + // create a folder and documents + dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef(); + dmDocument = fileFolderService.create(dmFolder, "collabDocument.txt", ContentModel.TYPE_CONTENT).getNodeRef(); - /** - * @see RecordService#createRecordFromDocument(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) - */ - public void testCreateRecordFromDocument() throws Exception - { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - // FIXME - return null; - } - }); - } + } - /** - * @see RecordService#getUnfiledRecordContainer(org.alfresco.service.cmr.repository.NodeRef) - */ - public void testGetUnfiledRecordContainer() throws Exception - { - doTestInTransaction(new Test() - { - @Override - public Void run() - { - // FIXME - return null; - } - }); - } + @Override + protected void setupTestUsersImpl(NodeRef filePlan) + { + super.setupTestUsersImpl(filePlan); + dmConsumer = GUID.generate(); + dmConsumerNodeRef = createPerson(dmConsumer); + siteService.setMembership(COLLABORATION_SITE_ID, dmConsumer, SiteModel.SITE_CONSUMER); + + dmCollaborator = GUID.generate(); + dmCollaboratorNodeRef = createPerson(dmCollaborator); + siteService.setMembership(COLLABORATION_SITE_ID, dmCollaborator, SiteModel.SITE_COLLABORATOR); + } + + @Override + protected void tearDownImpl() + { + super.tearDownImpl(); + siteService.deleteSite(COLLABORATION_SITE_ID); + } + + /** + * @see RecordService#getRecordMetaDataAspects() + */ + public void testGetRecordMetaDataAspects() throws Exception + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + Set aspects = recordService.getRecordMetaDataAspects(); + assertNotNull(aspects); + assertEquals(5, aspects.size()); + assertTrue(aspects.containsAll(getAspectList())); + + return null; + } + + /** + * Helper method for getting a list of record meta data aspects + * + * @return Record meta data aspects as list + */ + private List getAspectList() + { + QName[] aspects = new QName[] + { + DOD5015Model.ASPECT_DIGITAL_PHOTOGRAPH_RECORD, + DOD5015Model.ASPECT_PDF_RECORD, + DOD5015Model.ASPECT_WEB_RECORD, + DOD5015Model.ASPECT_SCANNED_RECORD, + ASPECT_RECORD_META_DATA + }; + + return Arrays.asList(aspects); + } + }); + } + + /** + * @see RecordService#isRecord(org.alfresco.service.cmr.repository.NodeRef) + */ + public void testIsRecord() throws Exception + { + doTestInTransaction(new VoidTest() + { + @Override + public void runImpl() + { + assertFalse(recordService.isRecord(filePlan)); + assertFalse(recordService.isRecord(rmContainer)); + assertFalse(recordService.isRecord(rmFolder)); + assertTrue(recordService.isRecord(recordOne)); + assertTrue(recordService.isRecord(recordDeclaredOne)); + } + }); + } + + /** + * @see RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) + */ + public void testIsDeclared() throws Exception + { + doTestInTransaction(new VoidTest() + { + @Override + public void runImpl() + { + assertFalse(recordService.isRecord(filePlan)); + assertFalse(recordService.isRecord(rmContainer)); + assertFalse(recordService.isRecord(rmFolder)); + assertTrue(recordService.isRecord(recordOne)); + assertTrue(recordService.isRecord(recordDeclaredOne)); + } + }); + } + + public void testUnfiled() throws Exception + { + doTestInTransaction(new VoidTest() + { + @Override + public void runImpl() + { + assertFalse(recordService.isFiled(filePlan)); + assertFalse(recordService.isFiled(rmContainer)); + assertFalse(recordService.isFiled(rmFolder)); + assertTrue(recordService.isFiled(recordOne)); + assertTrue(recordService.isFiled(recordDeclaredOne)); + } + }); + } + + /** + * @see RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + public void testCreateRecord() throws Exception + { + // show that users without WRITE can not create a record from a document + doTestInTransaction(new FailureTest + ( + "Can not create a record from a document if you do not have WRITE permissions.", + AccessDeniedException.class + ) + { + public void run() throws Exception + { + recordService.createRecord(filePlan, dmDocument); + } + }, dmConsumer); + + // create record from document + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertFalse(recordService.isRecord(dmDocument)); + assertFalse(extendedSecurityService.hasExtendedReaders(dmDocument)); + + checkPermissions(READ_RECORDS, + AccessStatus.DENIED, // file plan + AccessStatus.DENIED, // unfiled container + AccessStatus.DENIED, // record category + AccessStatus.DENIED, // record folder + AccessStatus.DENIED); // doc/record + + assertEquals(AccessStatus.DENIED, + dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS)); + + checkPermissions(FILING, + AccessStatus.DENIED, // file plan + AccessStatus.DENIED, // unfiled container + AccessStatus.DENIED, // record category + AccessStatus.DENIED, // record folder + AccessStatus.DENIED); // doc/record + + recordService.createRecord(filePlan, dmDocument); + + checkPermissions(READ_RECORDS, + AccessStatus.ALLOWED, // file plan + AccessStatus.ALLOWED, // unfiled container + AccessStatus.DENIED, // record category + AccessStatus.DENIED, // record folder + AccessStatus.ALLOWED); // doc/record + + assertEquals(AccessStatus.ALLOWED, + dmPermissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS)); + + checkPermissions(FILING, + AccessStatus.DENIED, // file plan + AccessStatus.DENIED, // unfiled container + AccessStatus.DENIED, // record category + AccessStatus.DENIED, // record folder + AccessStatus.DENIED); // doc/record + + assertTrue(recordService.isRecord(dmDocument)); + assertTrue(extendedSecurityService.hasExtendedReaders(dmDocument)); + assertFalse(recordService.isFiled(dmDocument)); + + return null; + } + }, dmCollaborator); + + + + } + + private void checkPermissions(String permission, AccessStatus filePlanExpected, + AccessStatus unfiledExpected, + AccessStatus recordCatExpected, + AccessStatus recordFolderExpected, + AccessStatus recordExpected) + { + assertEquals(filePlanExpected, + dmPermissionService.hasPermission(filePlan, permission)); + assertEquals(unfiledExpected, + dmPermissionService.hasPermission(unfiledContainer, permission)); + assertEquals(recordCatExpected, + dmPermissionService.hasPermission(rmContainer, permission)); + assertEquals(recordFolderExpected, + dmPermissionService.hasPermission(rmFolder, permission)); + assertEquals(recordExpected, + dmPermissionService.hasPermission(dmDocument, permission)); + } + + /** + * @see RecordService#getUnfiledContainer(org.alfresco.service.cmr.repository.NodeRef) + */ + public void testGetUnfiledContainer() throws Exception + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertNotNull(recordService.getUnfiledContainer(filePlan)); + + return null; + } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index f5010c0cb7..851175cd5d 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -133,6 +133,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected NodeRef rmContainer; protected DispositionSchedule dispositionSchedule; protected NodeRef rmFolder; + protected NodeRef unfiledContainer; /** multi-hierarchy test data * @@ -204,6 +205,15 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected NodeRef recordsManagerPerson; protected NodeRef rmAdminPerson; + /** test records */ + protected NodeRef recordOne; + protected NodeRef recordTwo; + protected NodeRef recordThree; + protected NodeRef recordFour; + protected NodeRef recordFive; + protected NodeRef recordDeclaredOne; + protected NodeRef recordDeclaredTwo; + /** * Indicates whether this is a multi-hierarchy test or not. If it is then the multi-hierarchy record * taxonomy test data is loaded. @@ -215,13 +225,20 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase /** * Indicates whether the test users should be created or not. - * @return */ protected boolean isUserTest() { return false; } + /** + * Indicates whether the test records should be created or not. + */ + protected boolean isRecordTest() + { + return false; + } + /** * Indicates whether the test users should have filling on the file plan structure * by default or not. @@ -346,8 +363,29 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase public Void run() { setupTestDataImpl(); + + if (isRecordTest() == true) + { + setupTestRecords(); + } + return null; } + + @Override + public void test(Void result) throws Exception + { + if (isRecordTest() == true) + { + // declare a record + utils.declareRecord(recordDeclaredOne); + utils.declareRecord(recordDeclaredTwo); + + // unfiled container + unfiledContainer = recordService.getUnfiledContainer(filePlan); + assertNotNull(unfiledContainer); + } + } }, AuthenticationUtil.getSystemUserName()); } @@ -389,6 +427,17 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase assertNotNull("Could not create rm folder", rmFolder); } + protected void setupTestRecords() + { + recordOne = utils.createRecord(rmFolder, "one.txt"); + recordTwo = utils.createRecord(rmFolder, "two.txt"); + recordThree = utils.createRecord(rmFolder, "three.txt"); + recordFour = utils.createRecord(rmFolder, "four.txt"); + recordFive = utils.createRecord(rmFolder, "five.txt"); + recordDeclaredOne = utils.createRecord(rmFolder, "declaredOne.txt"); + recordDeclaredTwo = utils.createRecord(rmFolder, "declaredTwo.txt"); + } + protected void setupTestUsers(final NodeRef filePlan) { retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback()