diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/actionlet/FourEyeApproverActionletTest.java b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/actionlet/FourEyeApproverActionletTest.java
index c0c31662fbcc..5292b8465658 100644
--- a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/actionlet/FourEyeApproverActionletTest.java
+++ b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/actionlet/FourEyeApproverActionletTest.java
@@ -11,9 +11,7 @@
import com.dotcms.contenttype.transform.contenttype.StructureTransformer;
import com.dotcms.util.IntegrationTestInitService;
import com.dotmarketing.beans.Host;
-import com.dotmarketing.beans.Permission;
import com.dotmarketing.business.APILocator;
-import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.business.Role;
import com.dotmarketing.business.RoleAPI;
import com.dotmarketing.business.UserAPI;
@@ -27,205 +25,263 @@
import com.dotmarketing.portlets.workflows.business.BaseWorkflowIntegrationTest;
import com.dotmarketing.portlets.workflows.business.WorkflowAPI;
import com.dotmarketing.portlets.workflows.model.WorkflowActionClass;
-import com.dotmarketing.portlets.workflows.model.WorkflowActionClassParameter;
-import com.dotmarketing.portlets.workflows.model.WorkflowActionletParameter;
import com.dotmarketing.portlets.workflows.model.WorkflowProcessor;
import com.liferay.portal.model.User;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
+ * This class verifies the correct behavior of the {@link FourEyeApproverActionlet}, which requires
+ * a specific number of users to approve a content BEFORE it can be published. The workflow action
+ * that triggers this action should have the following actionlets in it:
+ *
+ * - Unlock Content.
+ * - '4 Eye' Approval.
+ * - Publish Content.
+ *
+ * This ensures that a contentlet will be correctly published after the required approvers have
+ * accepted the new content. This is how the Multiple Approver action works too.
+ *
* @author Jose Castro
* @version 4.3.0
* @since Jan 10, 2018
*/
public class FourEyeApproverActionletTest extends BaseWorkflowIntegrationTest {
- private static RoleAPI roleAPI;
private static WorkflowAPI workflowAPI;
private static ContentletAPI contentletAPI;
private static LanguageAPI languageAPI;
private static ContentTypeAPI contentTypeAPI;
private static UserAPI userAPI;
- private static Role publisherRole;
private static User systemUser;
-
private static CreateSchemeStepActionResult schemeStepActionResult = null;
private static ContentType type = null;
private static Contentlet contentlet = null;
+ private static User publisher1;
+ private static User publisher2;
@BeforeClass
public static void prepare() throws Exception {
// Setting up the web app environment
IntegrationTestInitService.getInstance().init();
-
systemUser = APILocator.systemUser();
- roleAPI = APILocator.getRoleAPI();
- publisherRole = roleAPI.findRoleByName("Publisher / Legal", null);
workflowAPI = APILocator.getWorkflowAPI();
contentTypeAPI = APILocator.getContentTypeAPI(systemUser);
contentletAPI = APILocator.getContentletAPI();
languageAPI = APILocator.getLanguageAPI();
userAPI = APILocator.getUserAPI();
+ final RoleAPI roleAPI = APILocator.getRoleAPI();
- final long sysTime = System.currentTimeMillis();
+ // Get the test role and two users from such a role
+ final Role publisherRole = roleAPI.findRoleByName("Publisher / Legal", null);
+ publisher1 = userAPI.getUsersByNameOrEmailOrUserID("chris@dotcms.com", 0, 1).get(0);
+ publisher2 = userAPI.getUsersByNameOrEmailOrUserID("daniel@dotcms.com", 0, 1).get(0);
- // creates the scheme and actions
+ // Create the scheme and actions. This method allows you to add just one sub-action
+ // in the beginning
+ final long sysTime = System.currentTimeMillis();
schemeStepActionResult = createSchemeStepActionActionlet
("itFourEyeApprovalScheme_" + sysTime, "step1", "action1",
CheckinContentActionlet.class);
-
- final List permissions = new ArrayList<>();
- Permission permission = new Permission(schemeStepActionResult.getAction().getId(), publisherRole.getId(), PermissionAPI.PERMISSION_USE);
- permissions.add(permission);
- workflowAPI.saveAction(schemeStepActionResult.getAction(), permissions);
-
- WorkflowActionClass wac = new WorkflowActionClass();
- wac.setActionId(schemeStepActionResult.getAction().getId());
- wac.setClazz(FourEyeApproverActionlet.class.getName());
- wac.setName(WorkFlowActionlet.class.cast(FourEyeApproverActionlet.class.newInstance()).getName());
- wac.setOrder(1);
- workflowAPI.saveActionClass(wac);
-
- wac = new WorkflowActionClass();
- wac.setActionId(schemeStepActionResult.getAction().getId());
- wac.setClazz(PublishContentActionlet.class.getName());
- wac.setName(WorkFlowActionlet.class.cast(PublishContentActionlet.class.newInstance()).getName());
- wac.setOrder(2);
- workflowAPI.saveActionClass(wac);
-
- List actionClasses = workflowAPI
- .findActionClasses(schemeStepActionResult.getAction());
-
- wac = actionClasses.get(1);
- WorkFlowActionlet actionlet = workflowAPI.findActionlet(wac.getClazz());
- List actionletParams = actionlet.getParameters();
-
- List newParams = new ArrayList<>();
- WorkflowActionClassParameter testParam = new WorkflowActionClassParameter();
- testParam.setActionClassId(wac.getId());
- testParam.setKey(actionletParams.get(0).getKey());
- testParam.setValue("chris@dotcms.com,daniel@dotcms.com");
- newParams.add(testParam);
-
- testParam = new WorkflowActionClassParameter();
- testParam.setActionClassId(wac.getId());
- testParam.setKey(actionletParams.get(1).getKey());
- testParam.setValue("2");
- newParams.add(testParam);
-
- testParam = new WorkflowActionClassParameter();
- testParam.setActionClassId(wac.getId());
- testParam.setKey(actionletParams.get(2).getKey());
- testParam.setValue("'4 Eye' Approval Required");
- newParams.add(testParam);
-
- testParam = new WorkflowActionClassParameter();
- testParam.setActionClassId(wac.getId());
- testParam.setKey(actionletParams.get(3).getKey());
- testParam.setValue("Please review this content.");
- newParams.add(testParam);
-
- workflowAPI.saveWorkflowActionClassParameters(newParams);
-
- //Map enteredParams = workflowAPI.findParamsForActionClass(wac);
-
- // creates the type to trigger the scheme
- createTestType();
-
- // associated the scheme to the type
+ // Set the role ID of the people who can use the action
+ addWhoCanUseToAction(schemeStepActionResult.getAction(),
+ Collections.singletonList(publisherRole.getId()));
+ // Add the remaining two sub-actions for this test
+ addActionletToAction(schemeStepActionResult.getAction().getId(),
+ FourEyeApproverActionlet.class, 1);
+ addActionletToAction(schemeStepActionResult.getAction().getId(),
+ PublishContentActionlet.class, 2);
+ // Add the required parameters to the '4-eyes' sub-action
+ final List actionletClasses = getActionletsFromAction(
+ schemeStepActionResult.getAction());
+ WorkflowActionClass workflowActionClass = actionletClasses.get(1);
+ addParameterValuesToActionlet(workflowActionClass,
+ Arrays.asList("chris@dotcms.com,daniel@dotcms.com", "2",
+ "'4 Eye' Approval Required", "Please review this content."));
+
+ // Create the content type to trigger the scheme
+ createTestContentType();
+
+ // Associate the scheme to the content type
workflowAPI.saveSchemesForStruct(new StructureTransformer(type).asStructure(),
- Arrays.asList(schemeStepActionResult.getScheme()));
+ Collections.singletonList(schemeStepActionResult.getScheme()));
}
/**
+ * Creates the test Content Type
+ *
* @throws DotDataException
* @throws DotSecurityException
*/
- private static void createTestType()
+ private static void createTestContentType()
throws DotDataException, DotSecurityException {
-
type = contentTypeAPI.save(
ContentTypeBuilder.builder(BaseContentType.CONTENT.immutableClass())
.expireDateVar(null).folder(FolderAPI.SYSTEM_FOLDER).host(Host.SYSTEM_HOST)
- .description("SaveContentActionletTest...")
- .name("SaveContentActionletTest").owner(APILocator.systemUser().toString())
- .variable("SaveContentActionletTest").build());
-
+ .description("Content Type for testing the 4-Eye Approval actionlet.")
+ .name("FourEyeActionletTest").owner(APILocator.systemUser().toString())
+ .variable("FourEyeActionletTest").build());
final List fields = new ArrayList<>(type.fields());
-
fields.add(FieldBuilder.builder(TextField.class).name("title").variable("title")
.contentTypeId(type.id()).dataType(DataTypes.TEXT).indexed(true).build());
fields.add(FieldBuilder.builder(TextField.class).name("txt").variable("txt")
.contentTypeId(type.id()).dataType(DataTypes.TEXT).indexed(true).build());
-
type = contentTypeAPI.save(type, fields);
}
@Test
- public void runActionlet() throws DotSecurityException, DotDataException, InterruptedException {
- User publisher1 = userAPI.getUsersByNameOrEmailOrUserID("chris@dotcms.com", 0, 2).get(0);
- User publisher2 = userAPI.getUsersByNameOrEmailOrUserID("daniel@dotcms.com", 0, 2).get(0);
+ public void contentApprovalWithTwoApprovers()
+ throws DotSecurityException, DotDataException {
+ // Create a contentlet first and save it
final long languageId = languageAPI.getDefaultLanguage().getId();
- Contentlet cont = new Contentlet();
+ final Contentlet cont = new Contentlet();
cont.setContentTypeId(type.id());
cont.setOwner(APILocator.systemUser().toString());
cont.setModDate(new Date());
cont.setLanguageId(languageId);
- cont.setStringProperty("title", "Test Save");
- cont.setStringProperty("txt", "Test Save Text");
+ cont.setStringProperty("title", "4-Eye Approval Test Title");
+ cont.setStringProperty("txt", "4-Eye Approval Test Text");
cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797");
cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d");
-
- // first save
final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false);
- boolean isLive = false;
+ Assert.assertFalse("The contentlet cannot be live, it has just been created.",
+ contentlet1.isLive());
- // triggering the save content action
+ // Set the appropriate workflow action to the contentlet
contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY,
schemeStepActionResult.getAction().getId());
contentlet1.setStringProperty("title", "Test Save");
contentlet1.setStringProperty("txt", "Test Save Text");
+ // Triggering the save content action
WorkflowProcessor processor =
workflowAPI.fireWorkflowPreCheckin(contentlet1, publisher1);
workflowAPI.fireWorkflowPostCheckin(processor);
- Thread.sleep(2000);
+ // The contentlet MUST NOT be live yet, it needs one more approval
final Contentlet contentlet2 = contentletAPI
.findContentletByIdentifier(contentlet1.getIdentifier(),
false, languageId, systemUser, false);
- isLive = contentlet2.isLive();
+ Assert.assertFalse("The contentlet cannot be live, it needs 1 more approver.",
+ contentlet2.isLive());
processor = workflowAPI.fireWorkflowPreCheckin(contentlet2, publisher2);
workflowAPI.fireWorkflowPostCheckin(processor);
- Thread.sleep(2000);
- Contentlet contentlet3 = contentletAPI
+ // The contentlet MUST be live now as it has been approved by another user
+ final Contentlet contentlet3 = contentletAPI
.findContentletByIdentifier(contentlet2.getIdentifier(),
false, languageId, systemUser, false);
- isLive = contentlet3.isLive();
+ Assert.assertTrue("The contentlet MUST be live, it has all the approvers.",
+ contentlet2.isLive());
- int counter = 0;
+ // Cleanup
contentlet = contentlet3;
+ contentletAPI.delete(contentlet3, systemUser, false);
+ }
+
+ @Test
+ public void contentApprovalWithOneApprover()
+ throws DotSecurityException, DotDataException, InterruptedException {
+ // Create a contentlet first and save it
+ final long languageId = languageAPI.getDefaultLanguage().getId();
+ final Contentlet cont = new Contentlet();
+ cont.setContentTypeId(type.id());
+ cont.setOwner(APILocator.systemUser().toString());
+ cont.setModDate(new Date());
+ cont.setLanguageId(languageId);
+ cont.setStringProperty("title", "4-Eye Approval Test Title");
+ cont.setStringProperty("txt", "4-Eye Approval Test Text");
+ cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797");
+ cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d");
+ final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false);
+ Assert.assertFalse("The contentlet cannot be live, it has just been created.",
+ contentlet1.isLive());
+
+ // Set the appropriate workflow action to the contentlet
+ contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY,
+ schemeStepActionResult.getAction().getId());
+ contentlet1.setStringProperty("title", "Test Save");
+ contentlet1.setStringProperty("txt", "Test Save Text");
+
+ // Triggering the save content action
+ WorkflowProcessor processor =
+ workflowAPI.fireWorkflowPreCheckin(contentlet1, publisher1);
+ workflowAPI.fireWorkflowPostCheckin(processor);
+
+ // The contentlet MUST NOT be live yet, it needs one more approval
+ final Contentlet contentlet2 = contentletAPI
+ .findContentletByIdentifier(contentlet1.getIdentifier(),
+ false, languageId, systemUser, false);
+ Assert.assertFalse("The contentlet cannot be live, it needs 1 more approver.",
+ contentlet2.isLive());
+
+ // Cleanup
+ contentletAPI.delete(contentlet2, systemUser, false);
+ }
+
+ @Test
+ public void unauthorizedUserTriggeringWorkflowAction()
+ throws DotSecurityException, DotDataException {
+ // Create a contentlet first and save it
+ final long languageId = languageAPI.getDefaultLanguage().getId();
+ final Contentlet cont = new Contentlet();
+ cont.setContentTypeId(type.id());
+ cont.setOwner(APILocator.systemUser().toString());
+ cont.setModDate(new Date());
+ cont.setLanguageId(languageId);
+ cont.setStringProperty("title", "4-Eye Approval Test Title");
+ cont.setStringProperty("txt", "4-Eye Approval Test Text");
+ cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797");
+ cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d");
+ final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false);
+ Assert.assertFalse("The contentlet cannot be live, it has just been created.",
+ contentlet1.isLive());
+
+ contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY,
+ schemeStepActionResult.getAction().getId());
+ contentlet1.setStringProperty("title", "Test Save");
+ contentlet1.setStringProperty("txt", "Test Save Text");
+
+ // Expect the correct 'user cannot read' exception
+ boolean isErrorExpected = false;
+ final String expectedErrorMsg = "User Joe Contributor : dotcms.org.2789 cannot read action action1";
+ try {
+ // Triggering the save content action with a non-authorized user
+ User incorrectUser = userAPI.getUsersByNameOrEmailOrUserID("joe@dotcms.com", 0, 1).get(0);
+ workflowAPI.fireWorkflowPreCheckin(contentlet1, incorrectUser);
+ } catch (Exception e) {
+ // Get the expected error message that validates if user can use the workflow action
+ final String errorMsg = e.getCause().getCause().getMessage();
+ isErrorExpected = expectedErrorMsg.equalsIgnoreCase(errorMsg);
+ }
+
+ // Cleanup
+ contentletAPI.delete(contentlet1, systemUser, false);
+
+ Assert.assertTrue(
+ "The root cause of the exception IS NOT the expected error. Please check this test.",
+ isErrorExpected);
}
/**
- * Remove the content type and workflows created
+ * Removes the test contentlet, workflow, and content type.
*/
@AfterClass
public static void cleanup()
throws DotDataException, DotSecurityException, AlreadyExistException {
try {
if (null != contentlet) {
- contentletAPI.delete(contentlet, APILocator.systemUser(), false);
+ contentletAPI.delete(contentlet, systemUser, false);
}
} finally {
try {
diff --git a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/BaseWorkflowIntegrationTest.java b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/BaseWorkflowIntegrationTest.java
index 57ebcf1fc2a2..8a47fbd54ffe 100644
--- a/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/BaseWorkflowIntegrationTest.java
+++ b/dotCMS/src/integration-test/java/com/dotmarketing/portlets/workflows/business/BaseWorkflowIntegrationTest.java
@@ -1,39 +1,52 @@
package com.dotmarketing.portlets.workflows.business;
import com.dotcms.IntegrationTestBase;
+import com.dotmarketing.beans.Permission;
import com.dotmarketing.business.APILocator;
+import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.exception.AlreadyExistException;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotSecurityException;
import com.dotmarketing.portlets.workflows.actionlet.WorkFlowActionlet;
import com.dotmarketing.portlets.workflows.model.WorkflowAction;
import com.dotmarketing.portlets.workflows.model.WorkflowActionClass;
+import com.dotmarketing.portlets.workflows.model.WorkflowActionClassParameter;
+import com.dotmarketing.portlets.workflows.model.WorkflowActionletParameter;
import com.dotmarketing.portlets.workflows.model.WorkflowScheme;
import com.dotmarketing.portlets.workflows.model.WorkflowStep;
import com.dotmarketing.util.Logger;
-
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-
+import java.util.Map;
+
+/**
+ * Utility class that provides useful methods to create and modify Workflows in dotCMS.
+ *
+ * @author Jonathan Sanchez
+ * @version 4.3.0
+ */
public class BaseWorkflowIntegrationTest extends IntegrationTestBase {
-
/**
* Creates a new scheme, with a new step, with a new action and action let.
* the new action will be associated to the step
+ *
* @param schemeName
* @param stepName
* @param actionName
* @param actionClass
+ *
* @return CreateSchemeStepActionResult: scheme, step, action
+ *
* @throws AlreadyExistException
* @throws DotDataException
*/
- protected static CreateSchemeStepActionResult createSchemeStepActionActionlet (final String schemeName,
- final String stepName,
- final String actionName,
- final Class actionClass) throws AlreadyExistException, DotDataException {
-
+ protected static CreateSchemeStepActionResult createSchemeStepActionActionlet(
+ final String schemeName,
+ final String stepName,
+ final String actionName,
+ final Class actionClass) throws AlreadyExistException, DotDataException {
final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
final WorkflowScheme scheme = new WorkflowScheme();
@@ -62,19 +75,21 @@ protected static CreateSchemeStepActionResult createSchemeStepActionActionlet (f
/**
* Create an action and actionlet associated to scheme and step
+ *
* @param schemeId
* @param stepId
* @param actionName
* @param actionClass
+ *
* @return CreateSchemeStepActionResult action and actionlet
+ *
* @throws AlreadyExistException
* @throws DotDataException
*/
- protected static CreateSchemeStepActionResult createActionActionlet (final String schemeId,
- final String stepId,
- final String actionName,
- final Class actionClass) throws AlreadyExistException, DotDataException {
-
+ protected static CreateSchemeStepActionResult createActionActionlet(final String schemeId,
+ final String stepId,
+ final String actionName,
+ final Class actionClass) throws AlreadyExistException, DotDataException {
final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
final WorkflowAction action = new WorkflowAction();
@@ -94,7 +109,8 @@ protected static CreateSchemeStepActionResult createActionActionlet (final Strin
workflowActionClass.setActionId(action.getId());
workflowActionClass.setClazz(actionClass.getName());
try {
- workflowActionClass.setName(WorkFlowActionlet.class.cast(actionClass.newInstance()).getName());
+ workflowActionClass
+ .setName(WorkFlowActionlet.class.cast(actionClass.newInstance()).getName());
workflowActionClass.setOrder(0);
workflowAPI.saveActionClass(workflowActionClass);
} catch (Exception e) {
@@ -108,23 +124,27 @@ protected static CreateSchemeStepActionResult createActionActionlet (final Strin
/**
* Deletes the scheme, the actions and steps
+ *
* @param scheme
+ *
* @throws DotSecurityException
* @throws DotDataException
* @throws AlreadyExistException
*/
- protected static void cleanScheme (final WorkflowScheme scheme) throws DotSecurityException, DotDataException, AlreadyExistException {
+ protected static void cleanScheme(final WorkflowScheme scheme)
+ throws DotSecurityException, DotDataException, AlreadyExistException {
final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
- final List schemeActions = workflowAPI.findActions(scheme, APILocator.systemUser());
+ final List schemeActions = workflowAPI
+ .findActions(scheme, APILocator.systemUser());
- for (final WorkflowAction action: schemeActions) {
+ for (final WorkflowAction action : schemeActions) {
workflowAPI.deleteAction(action);
}
final List workflowSteps = workflowAPI.findSteps(scheme);
- for (final WorkflowStep step: workflowSteps) {
+ for (final WorkflowStep step : workflowSteps) {
workflowAPI.deleteStep(step);
}
@@ -132,16 +152,108 @@ protected static void cleanScheme (final WorkflowScheme scheme) throws DotSecuri
workflowAPI.deleteScheme(scheme);
}
+ /**
+ * Adds the ID of one or more roles or users who can use the specified workflow action. In the
+ * UI, this method allows you to set the values for the 'Who Can Use' field.
+ *
+ * @param action The ID of the workflow action.
+ * @param roleIds The list of IDs of roles or users as they are in the 'cms_role' table.
+ *
+ * @throws AlreadyExistException
+ * @throws DotDataException
+ */
+ protected static void addWhoCanUseToAction(final WorkflowAction action,
+ final List roleIds)
+ throws AlreadyExistException, DotDataException {
+ final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
+ final List permissions = new ArrayList<>();
+ for (final String roleId : roleIds) {
+ Permission permission = new Permission(action.getId(), roleId,
+ PermissionAPI.PERMISSION_USE);
+ permissions.add(permission);
+ }
+ workflowAPI.saveAction(action, permissions);
+ }
+
+ /**
+ * Adds a specific actionlet (sub-action) to a workflow action in a given order.
+ *
+ * @param actionId The workflow action ID.
+ * @param actionletClass The actionlet class.
+ * @param order The zero-based order of the actionlet.
+ * @throws AlreadyExistException
+ * @throws DotDataException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ */
+ protected static void addActionletToAction(final String actionId, final Class actionletClass,
+ final int order)
+ throws AlreadyExistException, DotDataException, IllegalAccessException, InstantiationException {
+ final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
+ final WorkflowActionClass wac = new WorkflowActionClass();
+ wac.setActionId(actionId);
+ wac.setClazz(actionletClass.getName());
+ wac.setName(WorkFlowActionlet.class.cast(actionletClass.newInstance()).getName());
+ wac.setOrder(order);
+ workflowAPI.saveActionClass(wac);
+ }
+
+ /**
+ * Returns the actionlets that are associated to the specified workflow action.
+ *
+ * @param workflowAction The workflow action.
+ * @return The list of actionlet classes that will run when the specified action is executed.
+ * @throws DotDataException
+ */
+ protected static List getActionletsFromAction(final WorkflowAction workflowAction)
+ throws DotDataException {
+ final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
+ return workflowAPI.findActionClasses(workflowAction);
+ }
+
+ /**
+ * Some actionlets have fields where users can set parameters for them. This method allows you
+ * to set values for the parameters in a given actionlet.
+ *
+ * @param workflowActionletClass The actionlet class that will have the new parameters.
+ * @param paramValues
+ * @throws DotDataException
+ */
+ protected static void addParameterValuesToActionlet(final WorkflowActionClass workflowActionletClass,
+ final List paramValues) throws DotDataException {
+ final WorkflowAPI workflowAPI = APILocator.getWorkflowAPI();
+ final WorkFlowActionlet actionlet = workflowAPI.findActionlet(workflowActionletClass.getClazz());
+ final List actionletParams = actionlet.getParameters();
+ final List newParameters = new ArrayList<>();
+ for (int i = 0; i < paramValues.size(); i++) {
+ final WorkflowActionClassParameter actionletParam = new WorkflowActionClassParameter();
+ actionletParam.setActionClassId(workflowActionletClass.getId());
+ actionletParam.setKey(actionletParams.get(i).getKey());
+ actionletParam.setValue(paramValues.get(i));
+ newParameters.add(actionletParam);
+ }
+ workflowAPI.saveWorkflowActionClassParameters(newParameters);
+ }
+
+ /**
+ * This class represents a simple Workflow Scheme with its minimum parts:
+ *
+ * - A Workflow Scheme.
+ * - One Workflow Step.
+ * - One Workflow Action.
+ * - One Workflow Sub-Action.
+ *
+ */
public static final class CreateSchemeStepActionResult {
private final WorkflowScheme scheme;
- private final WorkflowStep step;
+ private final WorkflowStep step;
private final WorkflowAction action;
- private final WorkflowActionClass actionClass;
-
+ private final WorkflowActionClass actionClass;
public CreateSchemeStepActionResult(
- final WorkflowScheme scheme, final WorkflowStep step, final WorkflowAction action, final WorkflowActionClass actionClass) {
+ final WorkflowScheme scheme, final WorkflowStep step, final WorkflowAction action,
+ final WorkflowActionClass actionClass) {
this.scheme = scheme;
this.step = step;
this.action = action;
diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java
index 0cab8ec27874..18ac2491cc6f 100644
--- a/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java
+++ b/dotCMS/src/main/java/com/dotmarketing/portlets/workflows/business/WorkflowAPIImpl.java
@@ -32,6 +32,8 @@
import com.dotmarketing.portlets.workflows.actionlet.PushNowActionlet;
import com.dotmarketing.portlets.workflows.actionlet.PushPublishActionlet;
import com.dotmarketing.portlets.workflows.actionlet.ResetTaskActionlet;
+import com.dotmarketing.portlets.workflows.actionlet.SaveContentActionlet;
+import com.dotmarketing.portlets.workflows.actionlet.SaveContentAsDraftActionlet;
import com.dotmarketing.portlets.workflows.actionlet.SetValueActionlet;
import com.dotmarketing.portlets.workflows.actionlet.TranslationActionlet;
import com.dotmarketing.portlets.workflows.actionlet.TwitterActionlet;