diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml
index 0c0b5d7cba..b7e06015fb 100644
--- a/config/alfresco/action-services-context.xml
+++ b/config/alfresco/action-services-context.xml
@@ -462,6 +462,24 @@
+
+
+ false
+
+
+
+
+
+
+
+
+
+ {http://www.alfresco.org/model/content/1.0}content
+ {http://www.alfresco.org/model/content/1.0}folder
+
+
+
+
diff --git a/config/alfresco/messages/action-config.properties b/config/alfresco/messages/action-config.properties
index 9dc4a78c36..6033b6382e 100644
--- a/config/alfresco/messages/action-config.properties
+++ b/config/alfresco/messages/action-config.properties
@@ -135,6 +135,9 @@ check-out.destination-folder.display-label=Destination folder
check-out.assoc-type.display-label=Association type
check-out.assoc-name.display-label=Association name
+take-ownership.title=Take ownership
+take-ownership.description=This will take ownership of matched content.
+
set-property-value.title=Set property value
set-property-value.description=This will set the value of a property to a given value.
set-property-value.property.display-label=Property
diff --git a/source/java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuter.java b/source/java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuter.java
new file mode 100644
index 0000000000..ad4407700f
--- /dev/null
+++ b/source/java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005-2014 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.repo.action.executer;
+
+import java.util.List;
+
+import org.alfresco.service.cmr.action.Action;
+import org.alfresco.service.cmr.action.ParameterDefinition;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.security.OwnableService;
+
+/**
+ * Take Ownership action executor
+ *
+ * @author Neil Mc Erlean
+ * @since 5.0
+ */
+public class TakeOwnershipActionExecuter extends ActionExecuterAbstractBase
+{
+ public static final String NAME = "take-ownership";
+
+ private NodeService nodeService;
+ private OwnableService ownableService;
+
+ public void setNodeService (NodeService service) { this.nodeService = service; }
+ public void setOwnableService(OwnableService service) { this.ownableService = service; }
+
+ @Override protected void addParameterDefinitions(List paramList)
+ {
+ // Intentionally empty. There are no parameters for this action.
+ }
+
+ public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef)
+ {
+ if (nodeService.exists(actionedUponNodeRef) && isApplicableType(actionedUponNodeRef))
+ {
+ ownableService.takeOwnership(actionedUponNodeRef);
+ }
+ }
+}
diff --git a/source/test-java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuterTest.java b/source/test-java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuterTest.java
new file mode 100644
index 0000000000..20b10c298e
--- /dev/null
+++ b/source/test-java/org/alfresco/repo/action/executer/TakeOwnershipActionExecuterTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2005-2014 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.repo.action.executer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.action.ActionImpl;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.OwnableService;
+import org.alfresco.service.cmr.site.SiteVisibility;
+import org.alfresco.test_category.OwnJVMTestsCategory;
+import org.alfresco.util.GUID;
+import org.alfresco.util.test.junitrules.AlfrescoPerson;
+import org.alfresco.util.test.junitrules.ApplicationContextInit;
+import org.alfresco.util.test.junitrules.RunAsFullyAuthenticatedRule;
+import org.alfresco.util.test.junitrules.TemporaryNodes;
+import org.alfresco.util.test.junitrules.TemporarySites;
+import org.alfresco.util.test.junitrules.TemporarySites.TestSiteAndMemberInfo;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.RuleChain;
+
+/** Tests for {@link TakeOwnershipActionExecuter}. */
+@Category(OwnJVMTestsCategory.class)
+public class TakeOwnershipActionExecuterTest
+{
+ // Rule to initialise the default Alfresco spring configuration
+ public static ApplicationContextInit APP_CONTEXT_INIT = new ApplicationContextInit();
+
+ public static final String USER_ONE_NAME = "UserOne";
+ public static final String USER_TWO_NAME = "UserTwo";
+
+ // Rules to create 2 test users.
+ public static AlfrescoPerson TEST_USER1 = new AlfrescoPerson(APP_CONTEXT_INIT, USER_ONE_NAME);
+
+ // Rules to manage test sites & nodes reused across all the test methods
+ public static TemporarySites TEMP_SITES = new TemporarySites(APP_CONTEXT_INIT);
+ public static TemporaryNodes TEMP_NODES = new TemporaryNodes(APP_CONTEXT_INIT);
+
+ // Tie them together in a static Rule Chain
+ @ClassRule public static RuleChain STATIC_RULE_CHAIN = RuleChain.outerRule(APP_CONTEXT_INIT)
+ .around(TEST_USER1)
+ .around(TEMP_NODES)
+ .around(TEMP_SITES);
+
+ // A rule to allow individual test methods all to be run as "UserOne".
+ // Some test methods need to switch user during execution which they are free to do.
+ @Rule public RunAsFullyAuthenticatedRule runAsRule = new RunAsFullyAuthenticatedRule(TEST_USER1);
+
+ private static OwnableService OWNABLE_SERVICE;
+ private static RetryingTransactionHelper TRANSACTION_HELPER;
+
+ private static TestSiteAndMemberInfo SITE_INFO;
+ private static NodeRef TEST_DOC;
+
+ @BeforeClass public static void initStaticData() throws Exception
+ {
+ OWNABLE_SERVICE = APP_CONTEXT_INIT.getApplicationContext().getBean("OwnableService", OwnableService.class);
+ TRANSACTION_HELPER = APP_CONTEXT_INIT.getApplicationContext().getBean("retryingTransactionHelper", RetryingTransactionHelper.class);
+
+ // One user creates a site.
+ final String siteShortName = GUID.generate();
+ SITE_INFO = TEMP_SITES.createTestSiteWithUserPerRole(siteShortName,
+ "sitePreset",
+ SiteVisibility.PUBLIC,
+ TEST_USER1.getUsername());
+ // A site contributor creates a document in it.
+ TEST_DOC = TEMP_NODES.createNode(SITE_INFO.doclib, "userOnesDoc", ContentModel.TYPE_CONTENT, SITE_INFO.siteContributor);
+ }
+
+ @Test public void siteOwnerCanTakeOwnershipOfNodeViaAnAction() throws Exception
+ {
+ TRANSACTION_HELPER.doInTransaction(new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ // Initially the site contributor is the owner of a document (node).
+ assertEquals("Wrong owner at test start.", SITE_INFO.siteContributor, OWNABLE_SERVICE.getOwner(TEST_DOC));
+
+ // Then the site owner (user 1) takes ownership of the document.
+ // See e.g. https://docs.alfresco.com/4.1/concepts/cuh-user-roles-permissions.html
+ // for details on who has permission to take ownership.
+ assertEquals(TEST_USER1.getUsername(), AuthenticationUtil.getRunAsUser());
+
+ TakeOwnershipActionExecuter executor = APP_CONTEXT_INIT.getApplicationContext().
+ getBean(TakeOwnershipActionExecuter.NAME,
+ TakeOwnershipActionExecuter.class);
+ final String actionId = GUID.generate();
+ ActionImpl action = new ActionImpl(null, actionId, TakeOwnershipActionExecuter.NAME, null);
+
+ executor.execute(action, TEST_DOC);
+
+ // Now the node should be owned by User 1.
+ assertEquals("Wrong owner at test end.", TEST_USER1.getUsername(), OWNABLE_SERVICE.getOwner(TEST_DOC));
+
+ return null;
+ }
+ });
+ }
+}
+