From beb0d2ec30cba0056ec472c0ba8e9138e1a3fc74 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Thu, 14 Feb 2013 01:42:19 +0000 Subject: [PATCH] RM-596: A records manager can create a rule that automatically files an unfiled record. * initial action implementation added * can handle relative name paths to find destination record folder * unit test * TODO .. expose in UI git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@46609 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-action-context.xml | 127 +++++------ .../action/impl/FileToAction.java | 113 ++++++++++ .../test/ActionTestSuite.java | 52 +++++ .../test/action/FileToActionTest.java | 209 ++++++++++++++++++ .../test/util/BaseRMTestCase.java | 9 +- 5 files changed, 443 insertions(+), 67 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ActionTestSuite.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/action/FileToActionTest.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml index 52d279b14c..842eac2465 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml @@ -60,9 +60,19 @@ - - + + + + + + + org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_ALLOW + org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW + org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW + + + @@ -92,7 +102,7 @@ - + @@ -117,7 +127,7 @@ - + @@ -152,32 +162,20 @@ - + - + - + - - - - org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW - org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW - - - - - - - + @@ -202,7 +200,7 @@ - + @@ -227,7 +225,7 @@ - + @@ -252,7 +250,7 @@ - + @@ -278,7 +276,7 @@ - + @@ -304,7 +302,7 @@ - + @@ -329,7 +327,7 @@ - + @@ -354,7 +352,7 @@ - + @@ -369,7 +367,7 @@ - + @@ -394,7 +392,7 @@ - + @@ -419,7 +417,7 @@ - + @@ -445,7 +443,7 @@ - + @@ -472,7 +470,7 @@ - + @@ -502,7 +500,7 @@ - + @@ -528,7 +526,7 @@ - + @@ -554,7 +552,7 @@ - + @@ -581,7 +579,7 @@ - + @@ -597,7 +595,7 @@ - + @@ -624,7 +622,7 @@ - + @@ -639,21 +637,18 @@ - - - - - - + + + + + - - - - + + @@ -677,26 +672,32 @@ - - - - + + - + - - - - - org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.execute=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction.*=RM_ALLOW - org.alfresco.repo.action.executer.ActionExecuter.*=RM_ALLOW - + + + + + + + + + + + + - - + + + + + + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java new file mode 100644 index 0000000000..ff4c318128 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/FileToAction.java @@ -0,0 +1,113 @@ +package org.alfresco.module.org_alfresco_module_rm.action.impl; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.model.FileNotFoundException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.springframework.util.StringUtils; + +/** + * File To action implementation. + * + * @author Roy Wetherall + * @since 2.1 + */ +public class FileToAction extends RMActionExecuterAbstractBase +{ + public static final String NAME = "fileTo"; + + public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder"; + public static final String PARAM_PATH = "path"; + + private FileFolderService fileFolderService; + + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + + /* + * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + protected void executeImpl(Action action, NodeRef actionedUponNodeRef) + { + if (recordService.isFiled(actionedUponNodeRef) == false) + { + // first look to see if the destination record folder has been specified + NodeRef recordFolder = (NodeRef)action.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER); + if (recordFolder == null) + { + // get the reference to the record folder based on the relative path + recordFolder = resolvePath(action, actionedUponNodeRef); + } + + if (recordFolder == null) + { + throw new AlfrescoRuntimeException("Unable to execute file to action, because the destination record folder could not be determined."); + } + + if (recordsManagementService.isRecordFolder(recordFolder) == true) + { + // TODO .. what if a record of the same name already exists in the destination record folder?? + try + { + fileFolderService.move(actionedUponNodeRef, recordFolder, null); + } + catch (FileNotFoundException fileNotFound) + { + throw new AlfrescoRuntimeException("Unable to execute file to action, because the move operation failed.", fileNotFound); + } + } + else + { + throw new AlfrescoRuntimeException("Unable to execute file to action, becuase the destination was not a record folder."); + } + } + else + { + throw new AlfrescoRuntimeException("Unable to execute file to action, because the actioned upon node is not an unfiled record."); + } + } + + private NodeRef resolvePath(Action action, NodeRef actionedUponNodeRef) + { + // TODO we could provide a parameter to override the file plan as the path context + + // the file plan node always provides the context + NodeRef context = recordsManagementService.getFilePlan(actionedUponNodeRef); + if (context == null) + { + throw new AlfrescoRuntimeException("Unable to execute file to action, because the path resolution context could not be found."); + } + + // assume by default the result is the context + NodeRef result = context; + + // look for the path parameter + String path = (String)action.getParameterValue(PARAM_PATH); + if (path != null && path.isEmpty() == false) + { + String[] pathValues = StringUtils.tokenizeToStringArray(path, "/", false, true); + try + { + FileInfo fileInfo = fileFolderService.resolveNamePath(context, new ArrayList(Arrays.asList(pathValues))); + result = fileInfo.getNodeRef(); + } + catch (FileNotFoundException fileNotFound) + { + // TODO .. handle this exception by possibly creating the missing record folder ??? + + throw new AlfrescoRuntimeException("Unable to execute file to action, because destination path could not be resolved."); + } + } + + return result; + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ActionTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ActionTestSuite.java new file mode 100644 index 0000000000..b4cd9a4797 --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/ActionTestSuite.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2011 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.alfresco.module.org_alfresco_module_rm.test.action.CreateRecordActionTest; +import org.alfresco.module.org_alfresco_module_rm.test.action.FileToActionTest; +import org.alfresco.module.org_alfresco_module_rm.test.action.HideRecordActionTest; +import org.alfresco.module.org_alfresco_module_rm.test.action.RejectActionTest; + + +/** + * RM test suite + * + * @author Roy Wetherall + * @since 2.1 + */ +public class ActionTestSuite extends TestSuite +{ + /** + * Creates the test suite + * + * @return the test suite + */ + public static Test suite() + { + TestSuite suite = new TestSuite(); + suite.addTestSuite(CreateRecordActionTest.class); + suite.addTestSuite(HideRecordActionTest.class); + suite.addTestSuite(RejectActionTest.class); + suite.addTestSuite(FileToActionTest.class); + return suite; + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/action/FileToActionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/action/FileToActionTest.java new file mode 100644 index 0000000000..a67e5b411b --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/action/FileToActionTest.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.test.action; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.action.impl.FileToAction; +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.service.cmr.action.ActionService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; + +/** + * FileTo action unit test + * + * @author Roy Wetherall + * @since 2.1 + */ +public class FileToActionTest extends BaseRMTestCase +{ + private static final String PATH = "rmcontainer/rmfolder"; + private static final String PATH2 = "/rmcontainer/rmfolder"; + + protected ActionService dmActionService; + + @Override + protected void initServices() + { + super.initServices(); + dmActionService = (ActionService) applicationContext.getBean("ActionService"); + } + + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + + @Override + protected boolean isUserTest() + { + return true; + } + + public void testFileToNodeRef() + { + doTestInTransaction(new Test() + { + public Void run() + { + // create record from document + recordService.createRecord(filePlan, dmDocument); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertFalse(recordService.isFiled(dmDocument)); + + // is the unfiled container the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(filePlanService.getUnfiledContainer(filePlan), parent); + + return null; + } + }, dmCollaborator); + + doTestInTransaction(new Test() + { + public Void run() + { + NodeRef unfiledContainer = filePlanService.getUnfiledContainer(filePlan); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(unfiledContainer, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmFolder, RMPermissionModel.FILING)); + + Capability capability = capabilityService.getCapability("FileToRecords"); + assertNotNull(capability); + assertEquals(AccessStatus.ALLOWED, capability.hasPermission(dmDocument)); + + // set parameters + Map params = new HashMap(1); + params.put(FileToAction.PARAM_DESTINATION_RECORD_FOLDER, rmFolder); + + // execute file-to action + actionService.executeRecordsManagementAction(dmDocument, FileToAction.NAME, params); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertTrue(recordService.isFiled(dmDocument)); + + // is the record folder the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(rmFolder, parent); + + return null; + } + }, rmAdminName); + + } + + public void testFileToPath() + { + doTestInTransaction(new Test() + { + public Void run() + { + // create record from document + recordService.createRecord(filePlan, dmDocument); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertFalse(recordService.isFiled(dmDocument)); + + // is the unfiled container the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(filePlanService.getUnfiledContainer(filePlan), parent); + + return null; + } + }, dmCollaborator); + + doTestInTransaction(new Test() + { + public Void run() + { + // set parameters + Map params = new HashMap(1); + params.put(FileToAction.PARAM_PATH, PATH); + + // execute file-to action + actionService.executeRecordsManagementAction(dmDocument, FileToAction.NAME, params); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertTrue(recordService.isFiled(dmDocument)); + + // is the record folder the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(rmFolder, parent); + + return null; + } + }, rmAdminName); + } + + public void testFileToPath2() + { + doTestInTransaction(new Test() + { + public Void run() + { + // create record from document + recordService.createRecord(filePlan, dmDocument); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertFalse(recordService.isFiled(dmDocument)); + + // is the unfiled container the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(filePlanService.getUnfiledContainer(filePlan), parent); + + return null; + } + }, dmCollaborator); + + doTestInTransaction(new Test() + { + public Void run() + { + // set parameters + Map params = new HashMap(1); + params.put(FileToAction.PARAM_PATH, PATH2); + + // execute file-to action + actionService.executeRecordsManagementAction(dmDocument, FileToAction.NAME, params); + + // check things have gone according to plan + assertTrue(recordService.isRecord(dmDocument)); + assertTrue(recordService.isFiled(dmDocument)); + + // is the record folder the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument).getParentRef(); + assertEquals(rmFolder, parent); + + return null; + } + }, rmAdminName); + } + +} 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 e58145370a..0d54bb5445 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 @@ -428,11 +428,11 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase // declare a record utils.declareRecord(recordDeclaredOne); utils.declareRecord(recordDeclaredTwo); - - // unfiled container - unfiledContainer = filePlanService.getUnfiledContainer(filePlan); - assertNotNull(unfiledContainer); } + + // unfiled container + unfiledContainer = filePlanService.getUnfiledContainer(filePlan); + assertNotNull(unfiledContainer); } }, AuthenticationUtil.getAdminUserName()); @@ -546,6 +546,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase { filePlanPermissionService.setPermission(filePlan, user, FILING); filePlanPermissionService.setPermission(rmContainer, user, FILING); + filePlanPermissionService.setPermission(unfiledContainer, user, FILING); } } }