diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
index 96130f9e01..b0360da5ed 100644
--- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
+++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-model-context.xml
@@ -78,6 +78,12 @@
+
+
+
+
+
+
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerType.java
new file mode 100644
index 0000000000..c01f544991
--- /dev/null
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerType.java
@@ -0,0 +1,77 @@
+/*
+ * #%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.model.rma.type;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
+import org.alfresco.repo.node.NodeServicePolicies;
+import org.alfresco.repo.policy.annotation.Behaviour;
+import org.alfresco.repo.policy.annotation.BehaviourBean;
+import org.alfresco.repo.policy.annotation.BehaviourKind;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.springframework.extensions.surf.util.I18NUtil;
+
+/**
+ * rma:holdContainer behaviour bean
+ *
+ * @author Mihai Cozma
+ * @since 2.4
+ */
+@BehaviourBean(defaultType = "rma:holdContainer")
+public class HoldContainerType extends BaseBehaviourBean
+ implements NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnCreateNodePolicy
+{
+ private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
+
+ /**
+ * On every event
+ *
+ * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef,
+ * boolean)
+ */
+ @Override
+ @Behaviour(kind = BehaviourKind.ASSOCIATION)
+ public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
+ {
+
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
+ I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
+
+ }
+
+ @Override
+ public void onCreateNode(ChildAssociationRef childAssocRef)
+ {
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
+ I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
+
+ }
+}
diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerType.java
new file mode 100644
index 0000000000..a557cf2efe
--- /dev/null
+++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerType.java
@@ -0,0 +1,75 @@
+/*
+ * #%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.model.rma.type;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
+import org.alfresco.repo.node.NodeServicePolicies;
+import org.alfresco.repo.policy.annotation.Behaviour;
+import org.alfresco.repo.policy.annotation.BehaviourBean;
+import org.alfresco.repo.policy.annotation.BehaviourKind;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.springframework.extensions.surf.util.I18NUtil;
+
+/**
+ * rma:transferContainer behaviour bean
+ *
+ * @author Mihai Cozma
+ * @since 2.4
+ */
+@BehaviourBean(defaultType = "rma:transferContainer")
+public class TransferContainerType extends BaseBehaviourBean
+ implements NodeServicePolicies.OnCreateChildAssociationPolicy, NodeServicePolicies.OnCreateNodePolicy
+{
+ private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
+
+ /**
+ * On every event
+ *
+ * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef,
+ * boolean)
+ */
+ @Override
+ @Behaviour(kind = BehaviourKind.ASSOCIATION)
+ public void onCreateChildAssociation(ChildAssociationRef childAssocRef, boolean bNew)
+ {
+ // ensure not content to be added in Holdsfolder
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
+ I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
+ }
+
+ @Override
+ public void onCreateNode(ChildAssociationRef childAssocRef)
+ {
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ if (instanceOf(nodeRef, ContentModel.TYPE_CONTENT) == true) { throw new AlfrescoRuntimeException(
+ I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER)); }
+ }
+}
diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3341Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3341Test.java
new file mode 100644
index 0000000000..fdf38a09f2
--- /dev/null
+++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM3341Test.java
@@ -0,0 +1,122 @@
+/*
+ * #%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.model.ContentModel;
+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.model.FileInfo;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.AccessStatus;
+import org.springframework.extensions.surf.util.I18NUtil;
+
+/**
+ * Unit test for RM-3341 .. can copy to hold and transfer folder
+ *
+ * @since 2.4
+ */
+public class RM3341Test extends BaseRMTestCase
+{
+
+ private final static String MSG_ERROR_ADD_CONTENT_CONTAINER = "rm.service.error-add-content-container";
+
+ public void testCopyingContentsInHoldandTransfer() throws Exception
+ {
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run()
+ {
+ NodeRef holdContainer = filePlanService.getHoldContainer(filePlan);
+ assertNotNull(holdContainer);
+ NodeRef transferContainer = filePlanService.getTransferContainer(filePlan);
+ assertNotNull(transferContainer);
+
+ assertEquals(AccessStatus.ALLOWED,
+ permissionService.hasPermission(holdContainer, RMPermissionModel.FILING));
+ assertEquals(AccessStatus.ALLOWED,
+ permissionService.hasPermission(transferContainer, RMPermissionModel.FILING));
+
+ return null;
+ }
+ }, ADMIN_USER);
+
+ doTestInTransaction(new Test()
+ {
+ @Override
+
+ public Void run()
+ {
+
+ NodeRef holdContainer = filePlanService.getHoldContainer(filePlan);
+ assertNotNull(holdContainer);
+
+ try
+ {
+ FileInfo copyInfo = fileFolderService.create(holdContainer, "test file", ContentModel.TYPE_CONTENT);
+ fail("This should have thrown an exception");
+ }
+ catch (AlfrescoRuntimeException e)
+ {
+ // ("Content can't be added to a record container. Use record folders to file content.")
+ assertEquals(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER), e.getMsgId());
+ }
+ return null;
+ }
+
+ });
+ doTestInTransaction(new Test()
+ {
+ @Override
+
+ public Void run()
+ {
+
+ NodeRef transferContainer = filePlanService.getTransferContainer(filePlan);
+ assertNotNull(transferContainer);
+
+ try
+ {
+
+ fileFolderService.create(transferContainer, "test content", ContentModel.TYPE_CONTENT);
+
+ fail("This should have thrown an exception");
+
+ }
+ catch (AlfrescoRuntimeException e)
+ {
+ // ("Content can't be added to a record container. Use record folders to file content.")
+ assertEquals(I18NUtil.getMessage(MSG_ERROR_ADD_CONTENT_CONTAINER), e.getMsgId());
+ }
+ return null;
+ }
+
+ });
+ }
+}
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/HoldContainerTypeTest.java
new file mode 100644
index 0000000000..60ac81f490
--- /dev/null
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/HoldContainerTypeTest.java
@@ -0,0 +1,87 @@
+/*
+ * #%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.model.rma.type;
+
+import static org.mockito.Mockito.doReturn;
+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.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+
+/**
+ * Unit test for HoldContainerTypeTest
+ *
+ * @author Mihai Cozma
+ * @since 2.4
+ */
+public class HoldContainerTypeTest extends BaseUnitTest
+{
+ /** test object */
+ private @InjectMocks HoldContainerType holdContainerType;
+
+ /**
+ * Having the Unfilled Record container and a folder having the aspect ASPECT_HIDDEN When adding a child association
+ * between the folder and the container Then the folder type shouldn't be renamed
+ */
+ @Test (expected = AlfrescoRuntimeException.class)
+ public void testAddContentToHoldContainer()
+ {
+
+ NodeRef holdContainer = createHoldContainer();
+
+ /*
+ * When adding a child association between the folder and the container
+ */
+ NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT);
+ ChildAssociationRef childAssoc = new ChildAssociationRef( ContentModel.TYPE_CONTENT, holdContainer,
+ ContentModel.TYPE_CONTENT, record);
+
+ holdContainerType.onCreateChildAssociation(childAssoc, true);
+
+ }
+
+ /**
+ * Generates a record management container
+ *
+ * @return reference to the generated container
+ */
+ private NodeRef createHoldContainer()
+ {
+ NodeRef holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER, true);
+
+ return holdContainer;
+ }
+
+}
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/TransferContainerTypeTest.java
new file mode 100644
index 0000000000..95fe49f052
--- /dev/null
+++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/TransferContainerTypeTest.java
@@ -0,0 +1,81 @@
+/*
+ * #%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.model.rma.type;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.model.ContentModel;
+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 org.mockito.InjectMocks;
+
+/**
+ * Unit test for TransferContainerTypeTest
+ *
+ * @author Mihai Cozma
+ * @since 2.4
+ */
+public class TransferContainerTypeTest extends BaseUnitTest
+{
+ /** test object */
+ private @InjectMocks TransferContainerType transferContainerType;
+
+ /**
+ * Having the Unfilled Record container and a folder having the aspect ASPECT_HIDDEN When adding a child association
+ * between the folder and the container Then the folder type shouldn't be renamed
+ */
+ @Test(expected = AlfrescoRuntimeException.class)
+ public void testAddContentToTransferContainerTest()
+ {
+
+ NodeRef transferContainer = createTransferContainer();
+
+ /*
+ * When adding a child association between the folder and the container
+ */
+ NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT);
+ ChildAssociationRef childAssoc = new ChildAssociationRef(ContentModel.TYPE_CONTENT, transferContainer,
+ ContentModel.TYPE_CONTENT, record);
+
+ transferContainerType.onCreateChildAssociation(childAssoc, true);
+
+ }
+
+ /**
+ * Generates a record management container
+ *
+ * @return reference to the generated container
+ */
+ private NodeRef createTransferContainer()
+ {
+ NodeRef holdContainer = generateNodeRef(TYPE_TRANSFER, true);
+
+ return holdContainer;
+ }
+
+}