diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml
index 1d8cd81110..b8c14a0773 100644
--- a/config/alfresco/action-services-context.xml
+++ b/config/alfresco/action-services-context.xml
@@ -157,6 +157,12 @@
+
+
+
+
+
+
diff --git a/config/alfresco/messages/action-config.properties b/config/alfresco/messages/action-config.properties
index b987bd25a9..38f04f8aca 100644
--- a/config/alfresco/messages/action-config.properties
+++ b/config/alfresco/messages/action-config.properties
@@ -23,6 +23,9 @@ compare-mime-type.description=The rule is applied to all items that have content
add-features.title=Add aspect to item
add-features.description=This will add an aspect to the matched item.
+remove-features.title=Remove an aspect from an item
+remove-features.description=This will remove an aspect from the matched item.
+
simple-workflow.title=Add simple workflow to item
simple-workflow.description=This will add a simple workflow to the matched item. This will allow the item to be moved to a different space for its next step in a workflow. You can also give a space for it to be moved to if you want a reject step.
diff --git a/source/java/org/alfresco/repo/action/ActionTestSuite.java b/source/java/org/alfresco/repo/action/ActionTestSuite.java
index a39f2fb910..c93d3ac216 100644
--- a/source/java/org/alfresco/repo/action/ActionTestSuite.java
+++ b/source/java/org/alfresco/repo/action/ActionTestSuite.java
@@ -25,6 +25,7 @@ import org.alfresco.repo.action.evaluator.HasAspectEvaluatorTest;
import org.alfresco.repo.action.evaluator.IsSubTypeEvaluatorTest;
import org.alfresco.repo.action.executer.AddFeaturesActionExecuterTest;
import org.alfresco.repo.action.executer.ContentMetadataExtracterTest;
+import org.alfresco.repo.action.executer.RemoveFeaturesActionExecuterTest;
import org.alfresco.repo.action.executer.SetPropertyValueActionExecuterTest;
import org.alfresco.repo.action.executer.SpecialiseTypeActionExecuterTest;
@@ -63,6 +64,7 @@ public class ActionTestSuite extends TestSuite
suite.addTestSuite(AddFeaturesActionExecuterTest.class);
suite.addTestSuite(ContentMetadataExtracterTest.class);
suite.addTestSuite(SpecialiseTypeActionExecuterTest.class);
+ suite.addTestSuite(RemoveFeaturesActionExecuterTest.class);
return suite;
}
diff --git a/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuter.java b/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuter.java
new file mode 100644
index 0000000000..1033a561b3
--- /dev/null
+++ b/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuter.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.action.executer;
+
+import java.util.List;
+
+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;
+
+/**
+ * Remove features action executor implementation.
+ *
+ * @author Roy Wetherall
+ */
+public class RemoveFeaturesActionExecuter extends ActionExecuterAbstractBase
+{
+ /**
+ * Action constants
+ */
+ public static final String NAME = "remove-features";
+ public static final String PARAM_ASPECT_NAME = "aspect-name";
+
+ /**
+ * The node service
+ */
+ private NodeService nodeService;
+
+ /**
+ * Set the node service
+ *
+ * @param nodeService the node service
+ */
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ /**
+ * @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.service.cmr.repository.NodeRef, NodeRef)
+ */
+ public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef)
+ {
+ if (this.nodeService.exists(actionedUponNodeRef) == true)
+ {
+ // Remove the aspect
+ QName aspectQName = (QName)ruleAction.getParameterValue(PARAM_ASPECT_NAME);
+ this.nodeService.removeAspect(actionedUponNodeRef, aspectQName);
+ }
+ }
+
+ /**
+ * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
+ */
+ @Override
+ protected void addParameterDefintions(List paramList)
+ {
+ paramList.add(new ParameterDefinitionImpl(PARAM_ASPECT_NAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASPECT_NAME)));
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuterTest.java b/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuterTest.java
new file mode 100644
index 0000000000..0d7ce950e0
--- /dev/null
+++ b/source/java/org/alfresco/repo/action/executer/RemoveFeaturesActionExecuterTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.action.executer;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.action.ActionImpl;
+import org.alfresco.repo.security.authentication.AuthenticationComponent;
+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.namespace.QName;
+import org.alfresco.util.BaseSpringTest;
+import org.alfresco.util.GUID;
+
+/**
+ * Remove features action execution test
+ *
+ * @author Roy Wetherall
+ */
+public class RemoveFeaturesActionExecuterTest extends BaseSpringTest
+{
+ /**
+ * The node service
+ */
+ private NodeService nodeService;
+
+ /**
+ * The store reference
+ */
+ private StoreRef testStoreRef;
+
+ /**
+ * The root node reference
+ */
+ private NodeRef rootNodeRef;
+
+ /**
+ * The test node reference
+ */
+ private NodeRef nodeRef;
+
+ /**
+ * The add features action executer
+ */
+ private RemoveFeaturesActionExecuter executer;
+
+ /**
+ * Id used to identify the test action created
+ */
+ private final static String ID = GUID.generate();
+
+ /**
+ * Called at the begining of all tests
+ */
+ @Override
+ protected void onSetUpInTransaction() throws Exception
+ {
+ this.nodeService = (NodeService)this.applicationContext.getBean("nodeService");
+
+ AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
+ authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
+
+ // Create the store and get the root node
+ this.testStoreRef = this.nodeService.createStore(
+ StoreRef.PROTOCOL_WORKSPACE, "Test_"
+ + System.currentTimeMillis());
+ this.rootNodeRef = this.nodeService.getRootNode(this.testStoreRef);
+
+ // Create the node used for tests
+ this.nodeRef = this.nodeService.createNode(
+ this.rootNodeRef,
+ ContentModel.ASSOC_CHILDREN,
+ QName.createQName("{test}testnode"),
+ ContentModel.TYPE_CONTENT).getChildRef();
+ this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_CLASSIFIABLE, null);
+
+ // Get the executer instance
+ this.executer = (RemoveFeaturesActionExecuter)this.applicationContext.getBean(RemoveFeaturesActionExecuter.NAME);
+ }
+
+ /**
+ * Test execution
+ */
+ public void testExecution()
+ {
+ // Check that the node has the classifiable aspect
+ assertTrue(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
+
+ // Execute the action
+ ActionImpl action = new ActionImpl(ID, RemoveFeaturesActionExecuter.NAME, null);
+ action.setParameterValue(RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_CLASSIFIABLE);
+ this.executer.execute(action, this.nodeRef);
+
+ // Check that the node now no longer has the classifiable aspect
+ assertFalse(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
+
+ // Now try and remove an aspect that is not present
+ ActionImpl action2 = new ActionImpl(ID, RemoveFeaturesActionExecuter.NAME, null);
+ action2.setParameterValue(RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
+ this.executer.execute(action2, this.nodeRef);
+ }
+}