diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties index dbb53e0559..96f6f06b8a 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/action-service.properties @@ -37,4 +37,6 @@ rm.action.event-not-undone=The event {0} can't be undone, because it's not defin rm.action.node-not-record-category=The disposition schedule could not be created, because the actioned upon node ({0}) was not a record category. rm.action.parameter-not-supplied=The parameter ''{0}'' has not been supplied. rm.action.delete-not-hold-type=The hold couldn't be deleted, because the node isn't of type {0}. (actionedUponNodeRef={1}) +rm.action.cast-to-rm-type=Can't upload a custom folder type to the records management file plan. rm.action.record-folder-create=Operation failed, because you can't place a record folder into another record folder. + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml index c59658b435..684289caa3 100755 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/patch/rm-patch-context.xml @@ -3,13 +3,22 @@ + + + + + classpath*:alfresco/module/org_alfresco_module_rm/version.properties + + + + - + diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties new file mode 100644 index 0000000000..cf2c7c2600 --- /dev/null +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/version.properties @@ -0,0 +1,3 @@ +# RM Schema number + +version.rm.schema=2501 diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java index 659b509aa9..522cd5d96e 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerType.java @@ -27,6 +27,7 @@ package org.alfresco.module.org_alfresco_module_rm.model.rma.type; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean; @@ -43,6 +44,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; +import org.springframework.extensions.surf.util.I18NUtil; /** * rma:recordsManagementContainer behaviour bean. @@ -69,6 +71,9 @@ public class RecordsManagementContainerType extends BaseBehaviourBean /** record folder service */ protected RecordFolderService recordFolderService; + /** I18N */ + private static final String MSG_CANNOT_CAST_TO_RM_TYPE = "rm.action.cast-to-rm-type"; + /** * @param identifierService identifier service */ @@ -151,6 +156,11 @@ public class RecordsManagementContainerType extends BaseBehaviourBean // This occurs if the RM folder has been created via IMap, WebDav, etc if (!nodeService.hasAspect(child, ASPECT_FILE_PLAN_COMPONENT)) { + // Throw exception if the type is not cm:folder + if (!ContentModel.TYPE_FOLDER.equals(childType)) + { + throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CANNOT_CAST_TO_RM_TYPE)); + } // check the type of the parent to determine what 'kind' of artifact to create NodeRef parent = childAssocRef.getParentRef(); QName parentType = nodeService.getType(parent); diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3450Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3450Test.java new file mode 100644 index 0000000000..6c325ab290 --- /dev/null +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3450Test.java @@ -0,0 +1,70 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.TestModel; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.util.GUID; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * Integration test for RM-3450 + * + * @author Roxana Lucanu + * @since 2.4.1 + */ +public class RM3450Test extends BaseRMTestCase +{ + + private static final String MSG_CANNOT_CAST_TO_RM_TYPE = "rm.action.cast-to-rm-type"; + + public void testRM3450() throws Exception + { + doTestInTransaction(new FailureTest + ( + I18NUtil.getMessage(MSG_CANNOT_CAST_TO_RM_TYPE), + AlfrescoRuntimeException.class + ) + { + @Override + public void run() throws Exception + { + transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Object execute() throws Exception + { + fileFolderService.create(unfiledContainer, GUID.generate(), TestModel.NOT_RM_FOLDER_TYPE).getNodeRef(); + return null; + } + }, false, true); + } + }, ADMIN_USER); + } + +} diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestModel.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestModel.java index 08b6854a56..15e7c45939 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestModel.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/TestModel.java @@ -40,4 +40,5 @@ public interface TestModel public static final QName ASPECT_RECORD_METADATA = QName.createQName(TEST_URI, "recordMetaData"); public static final QName PROPERTY_RECORD_METADATA = QName.createQName(TEST_URI, "recordMetaDataProperty"); + public static final QName NOT_RM_FOLDER_TYPE = QName.createQName(TEST_URI, "notRmFolderType"); } diff --git a/rm-community/rm-community-repo/test/resources/test-model.xml b/rm-community/rm-community-repo/test/resources/test-model.xml index 41869338d5..9eafa717a3 100644 --- a/rm-community/rm-community-repo/test/resources/test-model.xml +++ b/rm-community/rm-community-repo/test/resources/test-model.xml @@ -28,6 +28,9 @@ cm:content + + cm:folder + diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeUnitTest.java similarity index 95% rename from rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeTest.java rename to rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeUnitTest.java index 60ac81f490..4048585913 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeUnitTest.java @@ -46,7 +46,7 @@ import org.mockito.InjectMocks; * @author Mihai Cozma * @since 2.4 */ -public class HoldContainerTypeTest extends BaseUnitTest +public class HoldContainerTypeUnitTest extends BaseUnitTest { /** test object */ private @InjectMocks HoldContainerType holdContainerType; diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeUnitTest.java similarity index 73% rename from rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeTest.java rename to rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeUnitTest.java index 6f9fd8a661..5589f7a410 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordsManagementContainerTypeUnitTest.java @@ -26,16 +26,20 @@ */ package org.alfresco.module.org_alfresco_module_rm.model.rma.type; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; -import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.module.org_alfresco_module_rm.test.util.TestModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.junit.Test; import org.mockito.InjectMocks; /** @@ -43,10 +47,10 @@ import org.mockito.InjectMocks; * @author Ana Bozianu * @since 2.4 */ -public class RecordsManagementContainerTypeTest extends BaseUnitTest +public class RecordsManagementContainerTypeUnitTest extends BaseUnitTest { /** test object */ - private @InjectMocks RecordsManagementContainerType recordManagementContainerType; + private @InjectMocks RecordsManagementContainerType recordManagementContainerType; /** * Having the Unfilled Record container and a folder @@ -92,6 +96,28 @@ public class RecordsManagementContainerTypeTest extends BaseUnitTest /* Then the node type should not be changed to TYPE_RECORD_FOLDER */ verify(mockedNodeService, never()).setType(rmFolder, TYPE_RECORD_FOLDER); verify(mockedRecordFolderService, never()).setupRecordFolder(rmFolder); + } + + /** + * Trying to create a RM folder and its sub-types via SFDC, IMap, WebDav, etc + * Check that exception is thrown on creating child associations + */ + @Test + public void testRM3450() + { + NodeRef rmContainer = generateRMContainer(); + NodeRef nonRmFolder = generateNonRmFolderNode(); + + ChildAssociationRef childAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, rmContainer, TestModel.NOT_RM_FOLDER_TYPE, nonRmFolder); + try + { + recordManagementContainerType.onCreateChildAssociation(childAssoc, true); + fail("Expected to throw exception on create child association."); + } + catch (Throwable e) + { + assertTrue(e instanceof AlfrescoRuntimeException); + } } /** @@ -121,5 +147,20 @@ public class RecordsManagementContainerTypeTest extends BaseUnitTest when(mockedNodeService.hasAspect(rmFolder, ContentModel.ASPECT_HIDDEN)).thenReturn(hasHiddenAspect); when(mockedNodeService.hasAspect(rmFolder, ASPECT_FILE_PLAN_COMPONENT)).thenReturn(false); return rmFolder; + } + + /** + * Generates a folder node + * @return reference to the created folder + */ + private NodeRef generateNonRmFolderNode() + { + NodeRef nonRmFolder = generateNodeRef(); + when(mockedDictionaryService.isSubClass(TestModel.NOT_RM_FOLDER_TYPE, ContentModel.TYPE_FOLDER)).thenReturn(true); + when(mockedNodeService.getType(nonRmFolder)).thenReturn(TestModel.NOT_RM_FOLDER_TYPE); + when(mockedNodeService.exists(nonRmFolder)).thenReturn(true); + when(mockedNodeService.hasAspect(nonRmFolder, ContentModel.ASPECT_HIDDEN)).thenReturn(false); + when(mockedNodeService.hasAspect(nonRmFolder, ASPECT_FILE_PLAN_COMPONENT)).thenReturn(false); + return nonRmFolder; } } diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeUnitTest.java similarity index 94% rename from rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeTest.java rename to rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeUnitTest.java index 95fe49f052..69a7e20b2f 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeUnitTest.java @@ -40,7 +40,7 @@ import org.mockito.InjectMocks; * @author Mihai Cozma * @since 2.4 */ -public class TransferContainerTypeTest extends BaseUnitTest +public class TransferContainerTypeUnitTest extends BaseUnitTest { /** test object */ private @InjectMocks TransferContainerType transferContainerType;