From da22f3c3c47bf65c90679e143e3e3f6cf1ed7ec9 Mon Sep 17 00:00:00 2001 From: Sara Aspery Date: Fri, 10 May 2019 14:47:38 +0100 Subject: [PATCH 1/6] RM-6792 Oliver strings and fix closed folder and tests --- .../org_alfresco_module_rm/action-context.xml | 3 + .../messages/actions.properties | 3 +- .../action/dm/CreateRecordAction.java | 159 +++++++++++++++++- .../record/RecordService.java | 25 +++ .../record/RecordServiceImpl.java | 53 +++++- .../legacy/action/CreateRecordActionTest.java | 47 +++++- .../test/util/BaseRMTestCase.java | 5 + .../record/RecordServiceImplUnitTest.java | 108 ++++++++++++ .../test/util/BaseUnitTest.java | 4 + 9 files changed, 398 insertions(+), 9 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml index d1dda0a2e9..c80360da50 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml @@ -16,6 +16,9 @@ + + + {http://www.alfresco.org/model/content/1.0}content diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties index 3b4c93b3d4..e2d43aa52b 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties @@ -48,9 +48,10 @@ isRecordType.description=Records have a specified record type # # Declare As Record create-record.title=Declare as Record -create-record.description=Declares file as a record +create-record.description=Declares file as a record and optionally files it create-record.file-plan.display-label=File Plan create-record.hide-record.display-label=Hide Record +create-record.path.display-label=Destination Record Folder Path # Declare As Version Record declare-as-version-record.title=Declare Version as Record declare-as-version-record.description=Declares this version of the file as a record diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java index 2869b9c755..bd60827fcc 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java @@ -27,16 +27,27 @@ package org.alfresco.module.org_alfresco_module_rm.action.dm; +import java.util.Arrays; import java.util.List; +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase; +import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; +import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +import org.springframework.util.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Creates a new record from an existing content object. @@ -48,16 +59,53 @@ import org.alfresco.service.cmr.repository.NodeRef; public class CreateRecordAction extends AuditableActionExecuterAbstractBase implements RecordsManagementModel { + /** Logger */ + private static final Log LOGGER = LogFactory.getLog(CreateRecordAction.class); + /** Action name */ public static final String NAME = "create-record"; /** Parameter names */ public static final String PARAM_FILE_PLAN = "file-plan"; public static final String PARAM_HIDE_RECORD = "hide-record"; + public static final String PARAM_PATH = "path"; + + /** Node service */ + private NodeService nodeService; + + /** File plan service */ + private FilePlanService filePlanService; + + /** Authentication util */ + private AuthenticationUtil authenticationUtil; /** Record service */ private RecordService recordService; + /** + * @param nodeService node service + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @param filePlanService file plan service + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + + /** + * @param authenticationUtil authentication util + */ + public void setAuthenticationUtil(AuthenticationUtil authenticationUtil) + { + this.authenticationUtil = authenticationUtil; + } + /** * @param recordService record service */ @@ -74,6 +122,14 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase { NodeRef filePlan = (NodeRef) action.getParameterValue(PARAM_FILE_PLAN); + // resolve destination record folder if path supplied + NodeRef destinationRecordFolder = null; + String pathParameter = (String) action.getParameterValue(PARAM_PATH); + if (pathParameter != null && !pathParameter.isEmpty()) + { + destinationRecordFolder = resolvePath(filePlan, pathParameter); + } + // indicate whether the record should be hidden or not (default not) boolean hideRecord = false; Boolean hideRecordValue = ((Boolean) action.getParameterValue(PARAM_HIDE_RECORD)); @@ -85,7 +141,12 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase synchronized (this) { // create record from existing document - recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord); + recordService.createRecord(filePlan, actionedUponNodeRef, destinationRecordFolder, !hideRecord); + + if (destinationRecordFolder != null) + { + recordService.file(actionedUponNodeRef); + } } } @@ -97,6 +158,102 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase { // NOTE: commented out for now so that it doesn't appear in the UI ... enable later when multi-file plan support is added //params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN))); + params.add(new ParameterDefinitionImpl(PARAM_PATH, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_PATH))); params.add(new ParameterDefinitionImpl(PARAM_HIDE_RECORD, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_HIDE_RECORD))); } + + /** + * Helper method to get the target record folder node reference from the action path parameter + * + * @param filePlan The filePlan containing the path + * @param pathParameter The path + * @return The NodeRef of the resolved path + */ + private NodeRef resolvePath(NodeRef filePlan, final String pathParameter) + { + NodeRef destinationFolder; + + if (filePlan == null) + { + filePlan = getDefaultFilePlan(); + } + + final String[] pathElementsArray = StringUtils.tokenizeToStringArray(pathParameter, "/", false, true); + if ((pathElementsArray != null) && (pathElementsArray.length > 0)) + { + destinationFolder = resolvePath(filePlan, Arrays.asList(pathElementsArray)); + + // destination must be a record folder + QName nodeType = nodeService.getType(destinationFolder); + if (!nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER)) + { + throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is not a record folder."); + } + } + else + { + throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be found."); + } + return destinationFolder; + } + + /** + * Helper method to recursively get the next path element node reference from the action path parameter + * + * @param parent The parent of the path elements + * @param pathElements The path elements still to be resolved + * @return The NodeRef of the resolved path element + */ + private NodeRef resolvePath(NodeRef parent, List pathElements) + { + NodeRef nodeRef; + String childName = pathElements.get(0); + + nodeRef = nodeService.getChildByName(parent, ContentModel.ASSOC_CONTAINS, childName); + + if (nodeRef == null) + { + throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be resolved."); + } + else + { + QName nodeType = nodeService.getType(nodeRef); + if (nodeType.equals(RecordsManagementModel.TYPE_HOLD_CONTAINER) || + nodeType.equals(RecordsManagementModel.TYPE_TRANSFER_CONTAINER) || + nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER)) + { + throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is invalid."); + } + } + if (pathElements.size() > 1) + { + nodeRef = resolvePath(nodeRef, pathElements.subList(1, pathElements.size())); + } + return nodeRef; + } + + /** + * Helper method to get the default RM filePlan + * + * @return The NodeRef of the default RM filePlan + */ + private NodeRef getDefaultFilePlan() + { + NodeRef filePlan = authenticationUtil.runAsSystem(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork() + { + @Override + public NodeRef doWork() + { + return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); + } + }); + + // if the file plan is still null, raise an exception + if (filePlan == null) + { + LOGGER.debug("Unable to execute " + NAME + " action, because the fileplan path could not be determined. Make sure at least one file plan has been created."); + throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the fileplan path could not be determined."); + } + return filePlan; + } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java index fd1209762d..d5a249f107 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java @@ -159,6 +159,31 @@ public interface RecordService */ boolean isDeclared(NodeRef nodeRef); + /** + * Creates a new record from an existing node and files it into the specified location. + *

+ * Note that the node reference of the record will be the same as the original + * document. + * + * @param filePlan The filePlan in which the record should be placed. filePlan can be null in this case the default RM site will be used. + * @param nodeRef The node from which the record will be created + * @param locationNodeRef The container in which the record will be created + * @param isLinked indicates if the newly created record is linked to it's original location or not. + */ + void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef, final boolean isLinked); + + /** + * Creates a new record from an existing node and files it into the specified location. + *

+ * Note that the node reference of the record will be the same as the original + * document. + * + * @param filePlan The filePlan in which the record should be placed. filePlan can be null in this case the default RM site will be used. + * @param nodeRef The node from which the record will be created + * @param locationNodeRef The container in which the record will be created + */ + void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef); + /** * Creates a new unfiled record from an existing node. *

diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index fc0c2615d2..031caf5a9c 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -812,7 +812,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects(org.alfresco.service.cmr.repository.NodeRef) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetadataAspects(org.alfresco.service.cmr.repository.NodeRef) */ @Override public Set getRecordMetadataAspects(NodeRef nodeRef) @@ -861,8 +861,27 @@ public class RecordServiceImpl extends BaseBehaviourBean */ @Override public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked) + { + createRecord(filePlan, nodeRef, null, isLinked); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef) + { + createRecord(filePlan, nodeRef, destinationNodeRef, true); + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + @Override + public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef, final boolean isLinked) { // filePlan can be null. In this case the default RM site will be used. + // locationNodeRef can be null. In this case the unfiled record container will be used ParameterCheck.mandatory("nodeRef", nodeRef); ParameterCheck.mandatory("isLinked", isLinked); @@ -882,11 +901,33 @@ public class RecordServiceImpl extends BaseBehaviourBean ruleService.disableRuleType("outbound"); try { - // get the new record container for the file plan - NodeRef newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan); + NodeRef newRecordContainer = destinationNodeRef; + // if optional location not specified, use the unfiledContainer if (newRecordContainer == null) { - throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); + // get the new record container for the file plan + newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan); + if (newRecordContainer == null) + { + throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); + } + + } + // if optional location supplied, check that it is a valid record folder + else + { + QName nodeType = nodeService.getType(newRecordContainer); + if(!(nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) || + nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER))) + { + throw new AlfrescoRuntimeException("Unable to create record, because container is not a valid type for new record."); + } + + Boolean isClosed = (Boolean) nodeService.getProperty(newRecordContainer, PROP_IS_CLOSED); + if (isClosed != null && isClosed) + { + throw new AlfrescoRuntimeException("Unable to create record, because container is closed."); + } } // get the documents readers and writers @@ -1202,7 +1243,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createNewRecord(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecordFromContent(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader) */ @Override public NodeRef createRecordFromContent(NodeRef parent, String name, QName type, Map properties, ContentReader reader) @@ -1322,7 +1363,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.disposableitem.RecordService#isFiled(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 boolean isFiled(final NodeRef nodeRef) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java index 0afe5d76f5..16450b107d 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java @@ -31,6 +31,7 @@ import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; 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.Action; +import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; /** @@ -52,6 +53,13 @@ public class CreateRecordActionTest extends BaseRMTestCase return true; } + /** + * Test create record action + * + * Given a collaboration site document + * When the create record action is executed for that document + * Then a record is created for it + */ public void testCreateRecordAction() { doTestInTransaction(new Test() @@ -75,8 +83,45 @@ public class CreateRecordActionTest extends BaseRMTestCase assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS)); - }; + } }, dmCollaborator); } + + /** + * Test create record action with optional location + * + * Given a collaboration site document + * When the create record action with optional record location is executed for that document + * Then a record is created for it and filed in the specified location + */ + public void testCreateRecordActionWithLocation() + { + doTestInTransaction(new Test() + { + public Void run() + { + assertFalse(recordService.isRecord(dmDocument1)); + + Action action = actionService.createAction(CreateRecordAction.NAME); + action.setParameterValue(CreateRecordAction.PARAM_HIDE_RECORD, false); + action.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan); + action.setParameterValue(CreateRecordAction.PARAM_PATH, "rmContainer/rmFolder"); + actionService.executeAction(action, dmDocument1); + + return null; + } + + public void test(Void result) throws Exception + { + assertTrue(recordService.isRecord(dmDocument1)); + assertTrue(recordService.isFiled(dmDocument1)); + + // is the record folder the primary parent of the filed record + NodeRef parent = nodeService.getPrimaryParent(dmDocument1).getParentRef(); + assertEquals(rmFolder, parent); + } + }, + ADMIN_USER); + } } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 4eeb564b49..a47d89dc5f 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -123,6 +123,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase /** test data */ protected String NAME_DM_DOCUMENT = "collabDocument.txt"; + protected String NAME_DM_DOCUMENT1 = "collabDocument1.txt"; /** admin user */ protected static final String ADMIN_USER = "admin"; @@ -273,7 +274,9 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected SiteInfo collaborationSite; protected NodeRef documentLibrary; protected NodeRef dmFolder; + protected NodeRef dmFolder1; protected NodeRef dmDocument; + protected NodeRef dmDocument1; /** collaboration site users */ protected String dmConsumer; @@ -786,6 +789,8 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase // create a folder and documents dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef(); dmDocument = fileFolderService.create(dmFolder, NAME_DM_DOCUMENT, ContentModel.TYPE_CONTENT).getNodeRef(); + dmFolder1 = fileFolderService.create(documentLibrary, "collabFolder1", ContentModel.TYPE_FOLDER).getNodeRef(); + dmDocument1 = fileFolderService.create(dmFolder1, NAME_DM_DOCUMENT1, ContentModel.TYPE_CONTENT).getNodeRef(); dmConsumer = GUID.generate(); dmConsumerNodeRef = createPerson(dmConsumer); diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index a2bf96b29d..c38b5cf2e1 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -45,12 +45,15 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.repo.policy.Behaviour; import org.alfresco.service.cmr.repository.ChildAssociationRef; 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.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.apache.commons.collections.CollectionUtils; @@ -69,6 +72,9 @@ public class RecordServiceImplUnitTest extends BaseUnitTest { private NodeRef nonStandardFilePlanComponent; private NodeRef nonStandardFilePlan; + private NodeRef dmNodeRef; + private NodeRef unfiledRecordFolder; + private ChildAssociationRef parentAssoc; private static QName TYPE_MY_FILE_PLAN = generateQName(); private static QName ASPECT_FOR_FILE_PLAN = generateQName(); @@ -84,6 +90,9 @@ public class RecordServiceImplUnitTest extends BaseUnitTest nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY); nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN); + dmNodeRef = generateNodeRef(TYPE_CONTENT); + unfiledRecordFolder = generateNodeRef(TYPE_UNFILED_RECORD_FOLDER); + parentAssoc = mock(ChildAssociationRef.class); // set-up node service when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan); @@ -462,4 +471,103 @@ public class RecordServiceImplUnitTest extends BaseUnitTest // verify verify(values, never()).add(nodeRef); } + + /** + * Given a file that is not yet a record + * When I create the record without specifying a location + * Then the record is created in the unfiled record folder + */ + @Test + public void createRecordIntoUnfiledRecordFolder() + { + mocksForRecordCreation(); + + // create the record + recordService.createRecord(nonStandardFilePlan, dmNodeRef); + + // verify record was created in unfiled record container + verify(mockedNodeService, times(1)).moveNode( + dmNodeRef, + unfiledRecordFolder, + ContentModel.ASSOC_CONTAINS, + parentAssoc.getQName()); + } + + /** + * Given a file that is not yet a record + * When I create the record specifying the unfiled record folder + * Then the record is created in the unfiled record folder + */ + @Test + public void createRecordIntoSpecifiedUnfiledRecordFolder() + { + mocksForRecordCreation(); + + // create the record + recordService.createRecord(nonStandardFilePlan, dmNodeRef, unfiledRecordFolder); + + // verify record was created in specified record folder + verify(mockedNodeService, times(1)).moveNode( + dmNodeRef, + unfiledRecordFolder, + ContentModel.ASSOC_CONTAINS, + parentAssoc.getQName()); + } + + /** + * Given a file that is not yet a record + * When I create the record specifying a location + * Then the record is created in the specified record folder + */ + @Test + public void createRecordIntoSpecifiedRecordFolder() + { + mocksForRecordCreation(); + + // create the record + recordService.createRecord(nonStandardFilePlan, dmNodeRef, recordFolder); + + // verify record was created in specified record folder + verify(mockedNodeService, times(1)).moveNode( + dmNodeRef, + recordFolder, + ContentModel.ASSOC_CONTAINS, + parentAssoc.getQName()); + } + + /** + * Given a file that is not yet a record + * When I create the record specifying an invalid location + * Then an exception is thrown + */ + @Test(expected=AlfrescoRuntimeException.class) + public void createRecordIntoInvalidRecordFolder() + { + mocksForRecordCreation(); + NodeRef recordCategory = generateNodeRef(TYPE_RECORD_CATEGORY); + + // create the record + recordService.createRecord(nonStandardFilePlan, dmNodeRef, recordCategory); + } + + /* Helper method to set up the mocks for record creation */ + private void mocksForRecordCreation() + { + when(mockedNodeService.getPrimaryParent(dmNodeRef)) + .thenReturn(parentAssoc); + when(parentAssoc.getQName()).thenReturn(generateQName()); + + // mocks for sanity checks on node and fileplan + when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED); + when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true); + when(mockedFilePlanService.isFilePlan(nonStandardFilePlan)).thenReturn(true); + + // mocks for policies + doNothing().when(recordService).invokeBeforeRecordDeclaration(dmNodeRef); + doNothing().when(recordService).invokeOnRecordDeclaration(dmNodeRef); + + when(mockedFilePlanService.getUnfiledContainer(nonStandardFilePlan)).thenReturn(unfiledRecordFolder); + + when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null); + } } diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java index be68a337d2..b4ab37fed1 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java @@ -72,10 +72,12 @@ import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNamePattern; @@ -122,6 +124,8 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel @Mock(name="copyService") protected CopyService mockedCopyService; @Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService; @Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService; + @Mock(name="ruleService") protected RuleService mockedRuleService; + @Mock(name="versionService") protected VersionService mockedVersionService; /** rm service mocks */ @Mock(name="filePlanService") protected FilePlanService mockedFilePlanService; From 8186baf452cb5e245212203670305dc1c3ce1dbb Mon Sep 17 00:00:00 2001 From: Sara Aspery Date: Fri, 10 May 2019 15:44:32 +0100 Subject: [PATCH 2/6] Revert "RM-6792 Oliver strings and fix closed folder and tests" This reverts commit da22f3c3c47bf65c90679e143e3e3f6cf1ed7ec9 --- .../org_alfresco_module_rm/action-context.xml | 3 - .../messages/actions.properties | 3 +- .../action/dm/CreateRecordAction.java | 159 +----------------- .../record/RecordService.java | 25 --- .../record/RecordServiceImpl.java | 53 +----- .../legacy/action/CreateRecordActionTest.java | 47 +----- .../test/util/BaseRMTestCase.java | 5 - .../record/RecordServiceImplUnitTest.java | 108 ------------ .../test/util/BaseUnitTest.java | 4 - 9 files changed, 9 insertions(+), 398 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml index c80360da50..d1dda0a2e9 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/action-context.xml @@ -16,9 +16,6 @@ - - - {http://www.alfresco.org/model/content/1.0}content diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties index e2d43aa52b..3b4c93b3d4 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/actions.properties @@ -48,10 +48,9 @@ isRecordType.description=Records have a specified record type # # Declare As Record create-record.title=Declare as Record -create-record.description=Declares file as a record and optionally files it +create-record.description=Declares file as a record create-record.file-plan.display-label=File Plan create-record.hide-record.display-label=Hide Record -create-record.path.display-label=Destination Record Folder Path # Declare As Version Record declare-as-version-record.title=Declare Version as Record declare-as-version-record.description=Declares this version of the file as a record diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java index bd60827fcc..2869b9c755 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/action/dm/CreateRecordAction.java @@ -27,27 +27,16 @@ package org.alfresco.module.org_alfresco_module_rm.action.dm; -import java.util.Arrays; import java.util.List; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.AuditableActionExecuterAbstractBase; -import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; -import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.namespace.QName; - -import org.springframework.util.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * Creates a new record from an existing content object. @@ -59,53 +48,16 @@ import org.apache.commons.logging.LogFactory; public class CreateRecordAction extends AuditableActionExecuterAbstractBase implements RecordsManagementModel { - /** Logger */ - private static final Log LOGGER = LogFactory.getLog(CreateRecordAction.class); - /** Action name */ public static final String NAME = "create-record"; /** Parameter names */ public static final String PARAM_FILE_PLAN = "file-plan"; public static final String PARAM_HIDE_RECORD = "hide-record"; - public static final String PARAM_PATH = "path"; - - /** Node service */ - private NodeService nodeService; - - /** File plan service */ - private FilePlanService filePlanService; - - /** Authentication util */ - private AuthenticationUtil authenticationUtil; /** Record service */ private RecordService recordService; - /** - * @param nodeService node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * @param filePlanService file plan service - */ - public void setFilePlanService(FilePlanService filePlanService) - { - this.filePlanService = filePlanService; - } - - /** - * @param authenticationUtil authentication util - */ - public void setAuthenticationUtil(AuthenticationUtil authenticationUtil) - { - this.authenticationUtil = authenticationUtil; - } - /** * @param recordService record service */ @@ -122,14 +74,6 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase { NodeRef filePlan = (NodeRef) action.getParameterValue(PARAM_FILE_PLAN); - // resolve destination record folder if path supplied - NodeRef destinationRecordFolder = null; - String pathParameter = (String) action.getParameterValue(PARAM_PATH); - if (pathParameter != null && !pathParameter.isEmpty()) - { - destinationRecordFolder = resolvePath(filePlan, pathParameter); - } - // indicate whether the record should be hidden or not (default not) boolean hideRecord = false; Boolean hideRecordValue = ((Boolean) action.getParameterValue(PARAM_HIDE_RECORD)); @@ -141,12 +85,7 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase synchronized (this) { // create record from existing document - recordService.createRecord(filePlan, actionedUponNodeRef, destinationRecordFolder, !hideRecord); - - if (destinationRecordFolder != null) - { - recordService.file(actionedUponNodeRef); - } + recordService.createRecord(filePlan, actionedUponNodeRef, !hideRecord); } } @@ -158,102 +97,6 @@ public class CreateRecordAction extends AuditableActionExecuterAbstractBase { // NOTE: commented out for now so that it doesn't appear in the UI ... enable later when multi-file plan support is added //params.add(new ParameterDefinitionImpl(PARAM_FILE_PLAN, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_FILE_PLAN))); - params.add(new ParameterDefinitionImpl(PARAM_PATH, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_PATH))); params.add(new ParameterDefinitionImpl(PARAM_HIDE_RECORD, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_HIDE_RECORD))); } - - /** - * Helper method to get the target record folder node reference from the action path parameter - * - * @param filePlan The filePlan containing the path - * @param pathParameter The path - * @return The NodeRef of the resolved path - */ - private NodeRef resolvePath(NodeRef filePlan, final String pathParameter) - { - NodeRef destinationFolder; - - if (filePlan == null) - { - filePlan = getDefaultFilePlan(); - } - - final String[] pathElementsArray = StringUtils.tokenizeToStringArray(pathParameter, "/", false, true); - if ((pathElementsArray != null) && (pathElementsArray.length > 0)) - { - destinationFolder = resolvePath(filePlan, Arrays.asList(pathElementsArray)); - - // destination must be a record folder - QName nodeType = nodeService.getType(destinationFolder); - if (!nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER)) - { - throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is not a record folder."); - } - } - else - { - throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be found."); - } - return destinationFolder; - } - - /** - * Helper method to recursively get the next path element node reference from the action path parameter - * - * @param parent The parent of the path elements - * @param pathElements The path elements still to be resolved - * @return The NodeRef of the resolved path element - */ - private NodeRef resolvePath(NodeRef parent, List pathElements) - { - NodeRef nodeRef; - String childName = pathElements.get(0); - - nodeRef = nodeService.getChildByName(parent, ContentModel.ASSOC_CONTAINS, childName); - - if (nodeRef == null) - { - throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path could not be resolved."); - } - else - { - QName nodeType = nodeService.getType(nodeRef); - if (nodeType.equals(RecordsManagementModel.TYPE_HOLD_CONTAINER) || - nodeType.equals(RecordsManagementModel.TYPE_TRANSFER_CONTAINER) || - nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER)) - { - throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the destination path is invalid."); - } - } - if (pathElements.size() > 1) - { - nodeRef = resolvePath(nodeRef, pathElements.subList(1, pathElements.size())); - } - return nodeRef; - } - - /** - * Helper method to get the default RM filePlan - * - * @return The NodeRef of the default RM filePlan - */ - private NodeRef getDefaultFilePlan() - { - NodeRef filePlan = authenticationUtil.runAsSystem(new org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork() - { - @Override - public NodeRef doWork() - { - return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); - } - }); - - // if the file plan is still null, raise an exception - if (filePlan == null) - { - LOGGER.debug("Unable to execute " + NAME + " action, because the fileplan path could not be determined. Make sure at least one file plan has been created."); - throw new AlfrescoRuntimeException("Unable to execute " + NAME + " action, because the fileplan path could not be determined."); - } - return filePlan; - } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java index d5a249f107..fd1209762d 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordService.java @@ -159,31 +159,6 @@ public interface RecordService */ boolean isDeclared(NodeRef nodeRef); - /** - * Creates a new record from an existing node and files it into the specified location. - *

- * Note that the node reference of the record will be the same as the original - * document. - * - * @param filePlan The filePlan in which the record should be placed. filePlan can be null in this case the default RM site will be used. - * @param nodeRef The node from which the record will be created - * @param locationNodeRef The container in which the record will be created - * @param isLinked indicates if the newly created record is linked to it's original location or not. - */ - void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef, final boolean isLinked); - - /** - * Creates a new record from an existing node and files it into the specified location. - *

- * Note that the node reference of the record will be the same as the original - * document. - * - * @param filePlan The filePlan in which the record should be placed. filePlan can be null in this case the default RM site will be used. - * @param nodeRef The node from which the record will be created - * @param locationNodeRef The container in which the record will be created - */ - void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef locationNodeRef); - /** * Creates a new unfiled record from an existing node. *

diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index 031caf5a9c..fc0c2615d2 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -812,7 +812,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetadataAspects(org.alfresco.service.cmr.repository.NodeRef) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#getRecordMetaDataAspects(org.alfresco.service.cmr.repository.NodeRef) */ @Override public Set getRecordMetadataAspects(NodeRef nodeRef) @@ -861,27 +861,8 @@ public class RecordServiceImpl extends BaseBehaviourBean */ @Override public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final boolean isLinked) - { - createRecord(filePlan, nodeRef, null, isLinked); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef) - { - createRecord(filePlan, nodeRef, destinationNodeRef, true); - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecord(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, boolean) - */ - @Override - public void createRecord(final NodeRef filePlan, final NodeRef nodeRef, final NodeRef destinationNodeRef, final boolean isLinked) { // filePlan can be null. In this case the default RM site will be used. - // locationNodeRef can be null. In this case the unfiled record container will be used ParameterCheck.mandatory("nodeRef", nodeRef); ParameterCheck.mandatory("isLinked", isLinked); @@ -901,33 +882,11 @@ public class RecordServiceImpl extends BaseBehaviourBean ruleService.disableRuleType("outbound"); try { - NodeRef newRecordContainer = destinationNodeRef; - // if optional location not specified, use the unfiledContainer + // get the new record container for the file plan + NodeRef newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan); if (newRecordContainer == null) { - // get the new record container for the file plan - newRecordContainer = filePlanService.getUnfiledContainer(checkedFilePlan); - if (newRecordContainer == null) - { - throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); - } - - } - // if optional location supplied, check that it is a valid record folder - else - { - QName nodeType = nodeService.getType(newRecordContainer); - if(!(nodeType.equals(RecordsManagementModel.TYPE_RECORD_FOLDER) || - nodeType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER))) - { - throw new AlfrescoRuntimeException("Unable to create record, because container is not a valid type for new record."); - } - - Boolean isClosed = (Boolean) nodeService.getProperty(newRecordContainer, PROP_IS_CLOSED); - if (isClosed != null && isClosed) - { - throw new AlfrescoRuntimeException("Unable to create record, because container is closed."); - } + throw new AlfrescoRuntimeException("Unable to create record, because new record container could not be found."); } // get the documents readers and writers @@ -1243,7 +1202,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createRecordFromContent(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader) + * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#createNewRecord(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, org.alfresco.service.namespace.QName, java.util.Map, org.alfresco.service.cmr.repository.ContentReader) */ @Override public NodeRef createRecordFromContent(NodeRef parent, String name, QName type, Map properties, ContentReader reader) @@ -1363,7 +1322,7 @@ public class RecordServiceImpl extends BaseBehaviourBean } /** - * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isFiled(org.alfresco.service.cmr.repository.NodeRef) + * @see org.alfresco.module.org_alfresco_module_rm.disposableitem.RecordService#isFiled(org.alfresco.service.cmr.repository.NodeRef) */ @Override public boolean isFiled(final NodeRef nodeRef) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java index 16450b107d..0afe5d76f5 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/action/CreateRecordActionTest.java @@ -31,7 +31,6 @@ import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; 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.Action; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; /** @@ -53,13 +52,6 @@ public class CreateRecordActionTest extends BaseRMTestCase return true; } - /** - * Test create record action - * - * Given a collaboration site document - * When the create record action is executed for that document - * Then a record is created for it - */ public void testCreateRecordAction() { doTestInTransaction(new Test() @@ -83,45 +75,8 @@ public class CreateRecordActionTest extends BaseRMTestCase assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(dmDocument, RMPermissionModel.READ_RECORDS)); assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS)); - } + }; }, dmCollaborator); } - - /** - * Test create record action with optional location - * - * Given a collaboration site document - * When the create record action with optional record location is executed for that document - * Then a record is created for it and filed in the specified location - */ - public void testCreateRecordActionWithLocation() - { - doTestInTransaction(new Test() - { - public Void run() - { - assertFalse(recordService.isRecord(dmDocument1)); - - Action action = actionService.createAction(CreateRecordAction.NAME); - action.setParameterValue(CreateRecordAction.PARAM_HIDE_RECORD, false); - action.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan); - action.setParameterValue(CreateRecordAction.PARAM_PATH, "rmContainer/rmFolder"); - actionService.executeAction(action, dmDocument1); - - return null; - } - - public void test(Void result) throws Exception - { - assertTrue(recordService.isRecord(dmDocument1)); - assertTrue(recordService.isFiled(dmDocument1)); - - // is the record folder the primary parent of the filed record - NodeRef parent = nodeService.getPrimaryParent(dmDocument1).getParentRef(); - assertEquals(rmFolder, parent); - } - }, - ADMIN_USER); - } } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index a47d89dc5f..4eeb564b49 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -123,7 +123,6 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase /** test data */ protected String NAME_DM_DOCUMENT = "collabDocument.txt"; - protected String NAME_DM_DOCUMENT1 = "collabDocument1.txt"; /** admin user */ protected static final String ADMIN_USER = "admin"; @@ -274,9 +273,7 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected SiteInfo collaborationSite; protected NodeRef documentLibrary; protected NodeRef dmFolder; - protected NodeRef dmFolder1; protected NodeRef dmDocument; - protected NodeRef dmDocument1; /** collaboration site users */ protected String dmConsumer; @@ -789,8 +786,6 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase // create a folder and documents dmFolder = fileFolderService.create(documentLibrary, "collabFolder", ContentModel.TYPE_FOLDER).getNodeRef(); dmDocument = fileFolderService.create(dmFolder, NAME_DM_DOCUMENT, ContentModel.TYPE_CONTENT).getNodeRef(); - dmFolder1 = fileFolderService.create(documentLibrary, "collabFolder1", ContentModel.TYPE_FOLDER).getNodeRef(); - dmDocument1 = fileFolderService.create(dmFolder1, NAME_DM_DOCUMENT1, ContentModel.TYPE_CONTENT).getNodeRef(); dmConsumer = GUID.generate(); dmConsumerNodeRef = createPerson(dmConsumer); diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index c38b5cf2e1..a2bf96b29d 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -45,15 +45,12 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; import org.alfresco.repo.policy.Behaviour; import org.alfresco.service.cmr.repository.ChildAssociationRef; 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.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.apache.commons.collections.CollectionUtils; @@ -72,9 +69,6 @@ public class RecordServiceImplUnitTest extends BaseUnitTest { private NodeRef nonStandardFilePlanComponent; private NodeRef nonStandardFilePlan; - private NodeRef dmNodeRef; - private NodeRef unfiledRecordFolder; - private ChildAssociationRef parentAssoc; private static QName TYPE_MY_FILE_PLAN = generateQName(); private static QName ASPECT_FOR_FILE_PLAN = generateQName(); @@ -90,9 +84,6 @@ public class RecordServiceImplUnitTest extends BaseUnitTest nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY); nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN); - dmNodeRef = generateNodeRef(TYPE_CONTENT); - unfiledRecordFolder = generateNodeRef(TYPE_UNFILED_RECORD_FOLDER); - parentAssoc = mock(ChildAssociationRef.class); // set-up node service when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan); @@ -471,103 +462,4 @@ public class RecordServiceImplUnitTest extends BaseUnitTest // verify verify(values, never()).add(nodeRef); } - - /** - * Given a file that is not yet a record - * When I create the record without specifying a location - * Then the record is created in the unfiled record folder - */ - @Test - public void createRecordIntoUnfiledRecordFolder() - { - mocksForRecordCreation(); - - // create the record - recordService.createRecord(nonStandardFilePlan, dmNodeRef); - - // verify record was created in unfiled record container - verify(mockedNodeService, times(1)).moveNode( - dmNodeRef, - unfiledRecordFolder, - ContentModel.ASSOC_CONTAINS, - parentAssoc.getQName()); - } - - /** - * Given a file that is not yet a record - * When I create the record specifying the unfiled record folder - * Then the record is created in the unfiled record folder - */ - @Test - public void createRecordIntoSpecifiedUnfiledRecordFolder() - { - mocksForRecordCreation(); - - // create the record - recordService.createRecord(nonStandardFilePlan, dmNodeRef, unfiledRecordFolder); - - // verify record was created in specified record folder - verify(mockedNodeService, times(1)).moveNode( - dmNodeRef, - unfiledRecordFolder, - ContentModel.ASSOC_CONTAINS, - parentAssoc.getQName()); - } - - /** - * Given a file that is not yet a record - * When I create the record specifying a location - * Then the record is created in the specified record folder - */ - @Test - public void createRecordIntoSpecifiedRecordFolder() - { - mocksForRecordCreation(); - - // create the record - recordService.createRecord(nonStandardFilePlan, dmNodeRef, recordFolder); - - // verify record was created in specified record folder - verify(mockedNodeService, times(1)).moveNode( - dmNodeRef, - recordFolder, - ContentModel.ASSOC_CONTAINS, - parentAssoc.getQName()); - } - - /** - * Given a file that is not yet a record - * When I create the record specifying an invalid location - * Then an exception is thrown - */ - @Test(expected=AlfrescoRuntimeException.class) - public void createRecordIntoInvalidRecordFolder() - { - mocksForRecordCreation(); - NodeRef recordCategory = generateNodeRef(TYPE_RECORD_CATEGORY); - - // create the record - recordService.createRecord(nonStandardFilePlan, dmNodeRef, recordCategory); - } - - /* Helper method to set up the mocks for record creation */ - private void mocksForRecordCreation() - { - when(mockedNodeService.getPrimaryParent(dmNodeRef)) - .thenReturn(parentAssoc); - when(parentAssoc.getQName()).thenReturn(generateQName()); - - // mocks for sanity checks on node and fileplan - when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED); - when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true); - when(mockedFilePlanService.isFilePlan(nonStandardFilePlan)).thenReturn(true); - - // mocks for policies - doNothing().when(recordService).invokeBeforeRecordDeclaration(dmNodeRef); - doNothing().when(recordService).invokeOnRecordDeclaration(dmNodeRef); - - when(mockedFilePlanService.getUnfiledContainer(nonStandardFilePlan)).thenReturn(unfiledRecordFolder); - - when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null); - } } diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java index b4ab37fed1..be68a337d2 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java @@ -72,12 +72,10 @@ import org.alfresco.service.cmr.repository.CopyService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.OwnableService; import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.version.VersionService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QNamePattern; @@ -124,8 +122,6 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel @Mock(name="copyService") protected CopyService mockedCopyService; @Mock(name="fileFolderService") protected FileFolderService mockedFileFolderService; @Mock(name="modelSecurityService") protected ModelSecurityService mockedModelSecurityService; - @Mock(name="ruleService") protected RuleService mockedRuleService; - @Mock(name="versionService") protected VersionService mockedVersionService; /** rm service mocks */ @Mock(name="filePlanService") protected FilePlanService mockedFilePlanService; From c412db13d5050ea713475406cc88b63dde70302b Mon Sep 17 00:00:00 2001 From: cagache Date: Thu, 27 Sep 2018 12:40:04 +0300 Subject: [PATCH 3/6] Back-port fix from MNT-19967 --- .../disposition/DispositionServiceImpl.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index d3cd3cb49d..32f68c1bb5 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -348,9 +348,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl return ds; } - - - /** * This method returns a NodeRef * Gets the disposition instructions @@ -383,7 +380,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl NodeRef result = getAssociatedDispositionScheduleImpl(parent); if (result == null) { - return null; + return getOriginDispositionSchedule(parent); } return new DispositionScheduleImpl(serviceRegistry, nodeService, result); } From bf4ed09b0959acb37de95edeb721ee136c2e44e8 Mon Sep 17 00:00:00 2001 From: alfresco-build Date: Mon, 8 Jul 2019 16:39:17 +0100 Subject: [PATCH 4/6] [maven-release-plugin] prepare release V2.5.3.2 --- pom.xml | 4 ++-- rm-automation/pom.xml | 2 +- rm-community/pom.xml | 2 +- rm-community/rm-community-repo/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 94bb3279db..63dd6f6deb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm pom - 2.5.3.2-SNAPSHOT + 2.5.3.2 Alfresco Records Management @@ -24,7 +24,7 @@ scm:git:https://git.alfresco.com/records-management/records-management.git scm:git:https://git.alfresco.com/records-management/records-management.git https://git.alfresco.com/records-management/records-management - V2.5.3 + V2.5.3.2 diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index ed4b09801c..001d2f6edd 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.3.2-SNAPSHOT + 2.5.3.2 diff --git a/rm-community/pom.xml b/rm-community/pom.xml index de97020bf4..06d71f1b26 100644 --- a/rm-community/pom.xml +++ b/rm-community/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.3.2-SNAPSHOT + 2.5.3.2 diff --git a/rm-community/rm-community-repo/pom.xml b/rm-community/rm-community-repo/pom.xml index a93c2573b9..25fbb20356 100644 --- a/rm-community/rm-community-repo/pom.xml +++ b/rm-community/rm-community-repo/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-rm-community - 2.5.3.2-SNAPSHOT + 2.5.3.2 From 249675acc7d63f4d0aab24fec7d0816c0ca5f856 Mon Sep 17 00:00:00 2001 From: alfresco-build Date: Mon, 8 Jul 2019 16:39:21 +0100 Subject: [PATCH 5/6] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- rm-automation/pom.xml | 2 +- rm-community/pom.xml | 2 +- rm-community/rm-community-repo/pom.xml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 63dd6f6deb..4797d209c1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm pom - 2.5.3.2 + 2.5.3.3-SNAPSHOT Alfresco Records Management @@ -24,7 +24,7 @@ scm:git:https://git.alfresco.com/records-management/records-management.git scm:git:https://git.alfresco.com/records-management/records-management.git https://git.alfresco.com/records-management/records-management - V2.5.3.2 + V2.5.3 diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 001d2f6edd..c61d666c8e 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.3.2 + 2.5.3.3-SNAPSHOT diff --git a/rm-community/pom.xml b/rm-community/pom.xml index 06d71f1b26..73c9631e3e 100644 --- a/rm-community/pom.xml +++ b/rm-community/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.3.2 + 2.5.3.3-SNAPSHOT diff --git a/rm-community/rm-community-repo/pom.xml b/rm-community/rm-community-repo/pom.xml index 25fbb20356..7e79f8c07f 100644 --- a/rm-community/rm-community-repo/pom.xml +++ b/rm-community/rm-community-repo/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-rm-community - 2.5.3.2 + 2.5.3.3-SNAPSHOT From 726dcc2e02f88dcb4b64bad1eac45c255413e661 Mon Sep 17 00:00:00 2001 From: rlucanu Date: Tue, 9 Jul 2019 12:12:28 +0300 Subject: [PATCH 6/6] Revert "Record only merge of version change." This reverts commit eab3137a7c4b834de73a1c2b2b25ca15ddf0911c, reversing changes made to 249675acc7d63f4d0aab24fec7d0816c0ca5f856. --- pom.xml | 4 +-- rm-automation/pom.xml | 2 +- rm-community/pom.xml | 2 +- rm-community/rm-community-repo/pom.xml | 2 +- .../capability/RMAfterInvocationProvider.java | 2 -- .../disposition/DispositionScheduleImpl.java | 28 +++++-------------- .../disposition/DispositionServiceImpl.java | 5 +--- 7 files changed, 13 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index 2bb16c3e43..4797d209c1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm pom - 2.5.5-SNAPSHOT + 2.5.3.3-SNAPSHOT Alfresco Records Management @@ -24,7 +24,7 @@ scm:git:https://git.alfresco.com/records-management/records-management.git scm:git:https://git.alfresco.com/records-management/records-management.git https://git.alfresco.com/records-management/records-management - HEAD + V2.5.3 diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 21a954745a..c61d666c8e 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.5-SNAPSHOT + 2.5.3.3-SNAPSHOT diff --git a/rm-community/pom.xml b/rm-community/pom.xml index 53f27e0007..73c9631e3e 100644 --- a/rm-community/pom.xml +++ b/rm-community/pom.xml @@ -8,7 +8,7 @@ org.alfresco alfresco-rm - 2.5.5-SNAPSHOT + 2.5.3.3-SNAPSHOT diff --git a/rm-community/rm-community-repo/pom.xml b/rm-community/rm-community-repo/pom.xml index 776105b476..7e79f8c07f 100644 --- a/rm-community/rm-community-repo/pom.xml +++ b/rm-community/rm-community-repo/pom.xml @@ -9,7 +9,7 @@ org.alfresco alfresco-rm-community - 2.5.5-SNAPSHOT + 2.5.3.3-SNAPSHOT diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java index 85a64b7c01..8ed963c752 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMAfterInvocationProvider.java @@ -485,7 +485,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon returnedObject.getResultSetMetaData().getLimitedBy(), PermissionEvaluationMode.EAGER, returnedObject.getResultSetMetaData().getSearchParameters())); - filteringResultSet.setNumberFound(returnedObject.getNumberFound()); return filteringResultSet; } else @@ -499,7 +498,6 @@ public class RMAfterInvocationProvider extends RMSecurityCommon returnedObject.getResultSetMetaData().getLimitedBy(), PermissionEvaluationMode.EAGER, returnedObject.getResultSetMetaData().getSearchParameters())); - filteringResultSet.setNumberFound(returnedObject.getNumberFound()); return filteringResultSet; } } diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionScheduleImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionScheduleImpl.java index eec7f3db4e..5ab334b6a9 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionScheduleImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionScheduleImpl.java @@ -35,7 +35,6 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -52,10 +51,7 @@ public class DispositionScheduleImpl implements DispositionSchedule, private NodeService nodeService; private RecordsManagementServiceRegistry services; private NodeRef dispositionDefinitionNodeRef; - /** authentication helper */ - private AuthenticationUtil authenticationUtil; - - + private List actions; private Map actionsById; @@ -65,11 +61,6 @@ public class DispositionScheduleImpl implements DispositionSchedule, /** Map of disposition definitions by disposition action name */ private Map actionsByDispositionActionName; - - public void setAuthenticationUtil(AuthenticationUtil authenticationUtil) - { - this.authenticationUtil = authenticationUtil; - } public DispositionScheduleImpl(RecordsManagementServiceRegistry services, NodeService nodeService, NodeRef nodeRef) { @@ -109,18 +100,13 @@ public class DispositionScheduleImpl implements DispositionSchedule, */ public boolean isRecordLevelDisposition() { - return authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() + boolean result = false; + Boolean value = (Boolean)this.nodeService.getProperty(this.dispositionDefinitionNodeRef, PROP_RECORD_LEVEL_DISPOSITION); + if (value != null) { - public Boolean doWork() throws Exception - { - Boolean value = (Boolean)nodeService.getProperty(dispositionDefinitionNodeRef, PROP_RECORD_LEVEL_DISPOSITION); - if (value != null) - { - return value.booleanValue(); - } - return null; - } - }); + result = value.booleanValue(); + } + return result; } /** diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index d3cd3cb49d..32f68c1bb5 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -348,9 +348,6 @@ public class DispositionServiceImpl extends ServiceBaseImpl return ds; } - - - /** * This method returns a NodeRef * Gets the disposition instructions @@ -383,7 +380,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl NodeRef result = getAssociatedDispositionScheduleImpl(parent); if (result == null) { - return null; + return getOriginDispositionSchedule(parent); } return new DispositionScheduleImpl(serviceRegistry, nodeService, result); }