diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml
index 7a7c92e6a4..10212b6e9d 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-patch-context.xml
@@ -63,5 +63,18 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java
new file mode 100644
index 0000000000..c77de708dc
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/patch/RMv21CapabilityPatch.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.module.org_alfresco_module_rm.patch;
+
+import java.util.List;
+import java.util.Set;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService;
+import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
+import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
+import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
+import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
+import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService;
+import org.alfresco.module.org_alfresco_module_rm.role.Role;
+import org.alfresco.repo.module.AbstractModuleComponent;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.BeanNameAware;
+
+/**
+ * RM v2.1 patch to updated modified capabilities.
+ *
+ * @author Roy Wetherall
+ * @since 2.1
+ */
+public class RMv21CapabilityPatch extends AbstractModuleComponent
+ implements BeanNameAware, RecordsManagementModel, DOD5015Model
+{
+ /** Logger */
+ private static Log logger = LogFactory.getLog(RMv21CapabilityPatch.class);
+
+ /** Records management service */
+ private RecordsManagementService recordsManagementService;
+
+ /** File plan role service */
+ private FilePlanRoleService filePlanRoleService;
+
+ /** Capability service */
+ private CapabilityService capabilityService;
+
+ /**
+ * @param recordsManagementService records management service
+ */
+ public void setRecordsManagementService(RecordsManagementService recordsManagementService)
+ {
+ this.recordsManagementService = recordsManagementService;
+ }
+
+ /**
+ * @param filePlanRoleService file plan role service
+ */
+ public void setFilePlanRoleService(FilePlanRoleService filePlanRoleService)
+ {
+ this.filePlanRoleService = filePlanRoleService;
+ }
+
+ /**
+ * @param capabilityService capability service
+ */
+ public void setCapabilityService(CapabilityService capabilityService)
+ {
+ this.capabilityService = capabilityService;
+ }
+
+ /**
+ * @see org.alfresco.repo.module.AbstractModuleComponent#executeInternal()
+ */
+ @Override
+ protected void executeInternal() throws Throwable
+ {
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug("RM module: RMv21CapabilityPatch executing ...");
+ }
+
+ List filePlans = recordsManagementService.getFilePlans();
+
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug(" ... updating " + filePlans.size() + " file plans");
+ }
+
+ for (NodeRef filePlan : filePlans)
+ {
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug(" ... updating file plan " + filePlan.toString());
+ }
+
+ // add new capabilities
+ addCapability(filePlan,
+ "CreateRecords",
+ FilePlanRoleService.ROLE_ADMIN,
+ FilePlanRoleService.ROLE_POWER_USER,
+ FilePlanRoleService.ROLE_RECORDS_MANAGER,
+ FilePlanRoleService.ROLE_SECURITY_OFFICER);
+
+ }
+
+ if (logger.isDebugEnabled() == true)
+ {
+ logger.debug(" ... complete");
+ }
+ }
+
+ /**
+ * Adds a new capability to the specified roles.
+ *
+ * @param filePlan file plan
+ * @param capabilityName capability name
+ * @param roles roles
+ */
+ private void addCapability(NodeRef filePlan, String capabilityName, String ... roles)
+ {
+ Capability capability = capabilityService.getCapability(capabilityName);
+ if (capability == null)
+ {
+ throw new AlfrescoRuntimeException("Unable to bootstrap RMv21 capabilities, because capability " + capabilityName + " does not exist.");
+ }
+
+ for (String roleName : roles)
+ {
+ Role role = filePlanRoleService.getRole(filePlan, roleName);
+ if (role != null)
+ {
+ Set capabilities = role.getCapabilities();
+ capabilities.add(capability);
+ filePlanRoleService.updateRole(filePlan, role.getName(), role.getDisplayLabel(), capabilities);
+ }
+ }
+ }
+
+}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java
index ff9c072143..afb260d62a 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleService.java
@@ -31,6 +31,13 @@ import org.alfresco.service.cmr.repository.NodeRef;
*/
public interface FilePlanRoleService
{
+ /** Default role names */
+ public static final String ROLE_USER = "User";
+ public static final String ROLE_POWER_USER = "PowerUser";
+ public static final String ROLE_SECURITY_OFFICER = "SecurityOfficer";
+ public static final String ROLE_RECORDS_MANAGER = "RecordsManager";
+ public static final String ROLE_ADMIN = "Administrator";
+
/**
* Returns the name of the container group for all roles of a specified file
* plan.