org.flowable.cmmn.editor.json.converter.HumanTaskJsonConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.flowable.cmmn.editor.json.converter.HumanTaskJsonConverter.java

Source

/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * 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.flowable.cmmn.editor.json.converter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.flowable.cmmn.editor.json.converter.CmmnJsonConverter.CmmnModelIdHelper;
import org.flowable.cmmn.editor.json.converter.util.CollectionUtils;
import org.flowable.cmmn.editor.json.model.CmmnModelInfo;
import org.flowable.cmmn.model.BaseElement;
import org.flowable.cmmn.model.CaseElement;
import org.flowable.cmmn.model.CmmnModel;
import org.flowable.cmmn.model.ExtensionElement;
import org.flowable.cmmn.model.HumanTask;
import org.flowable.cmmn.model.PlanItem;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * @author Tijs Rademakers
 */
public class HumanTaskJsonConverter extends BaseCmmnJsonConverter
        implements FormAwareConverter, FormKeyAwareConverter {

    protected Map<String, String> formMap;
    protected Map<String, CmmnModelInfo> formKeyMap;

    public static void fillTypes(Map<String, Class<? extends BaseCmmnJsonConverter>> convertersToCmmnMap,
            Map<Class<? extends BaseElement>, Class<? extends BaseCmmnJsonConverter>> convertersToJsonMap) {

        fillJsonTypes(convertersToCmmnMap);
        fillCmmnTypes(convertersToJsonMap);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseCmmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put(STENCIL_TASK_HUMAN, HumanTaskJsonConverter.class);
    }

    public static void fillCmmnTypes(
            Map<Class<? extends BaseElement>, Class<? extends BaseCmmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(HumanTask.class, HumanTaskJsonConverter.class);
    }

    @Override
    protected String getStencilId(BaseElement baseElement) {
        return STENCIL_TASK_HUMAN;
    }

    @Override
    protected void convertElementToJson(ObjectNode elementNode, ObjectNode propertiesNode,
            ActivityProcessor processor, BaseElement baseElement, CmmnModel cmmnModel) {
        PlanItem planItem = (PlanItem) baseElement;
        HumanTask humanTask = (HumanTask) planItem.getPlanItemDefinition();
        String assignee = humanTask.getAssignee();

        if (StringUtils.isNotEmpty(assignee) || CollectionUtils.isNotEmpty(humanTask.getCandidateUsers())
                || CollectionUtils.isNotEmpty(humanTask.getCandidateGroups())) {

            ObjectNode assignmentNode = objectMapper.createObjectNode();
            ObjectNode assignmentValuesNode = objectMapper.createObjectNode();

            List<ExtensionElement> idmAssigneeList = humanTask.getExtensionElements().get("flowable-idm-assignee");
            if (CollectionUtils.isNotEmpty(idmAssigneeList)
                    || CollectionUtils
                            .isNotEmpty(humanTask.getExtensionElements().get("flowable-idm-candidate-user"))
                    || CollectionUtils
                            .isNotEmpty(humanTask.getExtensionElements().get("flowable-idm-candidate-group"))) {

                assignmentValuesNode.put("type", "idm");
                ObjectNode idmNode = objectMapper.createObjectNode();
                assignmentValuesNode.set("idm", idmNode);

                List<ExtensionElement> canCompleteList = humanTask.getExtensionElements()
                        .get("initiator-can-complete");
                if (CollectionUtils.isNotEmpty(canCompleteList)) {
                    assignmentValuesNode.put("initiatorCanCompleteTask",
                            Boolean.valueOf(canCompleteList.get(0).getElementText()));
                }

                if (StringUtils.isNotEmpty(humanTask.getAssignee())) {
                    ObjectNode assigneeNode = objectMapper.createObjectNode();
                    assigneeNode.put("id", humanTask.getAssignee());
                    idmNode.set("assignee", assigneeNode);
                    idmNode.put("type", "user");

                    fillProperty("email", "assignee-info-email", assigneeNode, humanTask);
                    fillProperty("firstName", "assignee-info-firstname", assigneeNode, humanTask);
                    fillProperty("lastName", "assignee-info-lastname", assigneeNode, humanTask);
                }

                List<ExtensionElement> idmCandidateUserList = humanTask.getExtensionElements()
                        .get("flowable-idm-candidate-user");
                if (CollectionUtils.isNotEmpty(humanTask.getCandidateUsers())
                        && CollectionUtils.isNotEmpty(idmCandidateUserList)) {

                    List<String> candidateUserIds = new ArrayList<>();

                    if (humanTask.getCandidateUsers().size() == 1) {
                        idmNode.put("type", "users");

                        String candidateUsersString = humanTask.getCandidateUsers().get(0);
                        String[] candidateUserArray = candidateUsersString.split(",");
                        for (String candidate : candidateUserArray) {
                            candidateUserIds.add(candidate.trim());
                        }

                    } else {
                        candidateUserIds.addAll(humanTask.getCandidateUsers());
                    }

                    if (candidateUserIds.size() > 0) {
                        ArrayNode candidateUsersNode = objectMapper.createArrayNode();
                        idmNode.set("candidateUsers", candidateUsersNode);
                        idmNode.put("type", "users");
                        for (String candidateUser : humanTask.getCandidateUsers()) {
                            ObjectNode candidateUserNode = objectMapper.createObjectNode();
                            candidateUserNode.put("id", candidateUser);
                            candidateUsersNode.add(candidateUserNode);

                            fillProperty("email", "user-info-email-" + candidateUser, candidateUserNode, humanTask);
                            fillProperty("firstName", "user-info-firstname-" + candidateUser, candidateUserNode,
                                    humanTask);
                            fillProperty("lastName", "user-info-lastname-" + candidateUser, candidateUserNode,
                                    humanTask);
                        }
                    }
                }

                List<ExtensionElement> idmCandidateGroupList = humanTask.getExtensionElements()
                        .get("flowable-idm-candidate-group");
                if (CollectionUtils.isNotEmpty(humanTask.getCandidateGroups())
                        && CollectionUtils.isNotEmpty(idmCandidateGroupList)) {

                    List<String> candidateGroupIds = new ArrayList<>();

                    if (humanTask.getCandidateGroups().size() == 1) {
                        idmNode.put("type", "groups");

                        String candidateGroupsString = humanTask.getCandidateGroups().get(0);
                        String[] candidateGroupArray = candidateGroupsString.split(",");
                        for (String candidate : candidateGroupArray) {
                            candidateGroupIds.add(candidate.trim());
                        }

                    } else {
                        candidateGroupIds.addAll(humanTask.getCandidateGroups());
                    }

                    if (candidateGroupIds.size() > 0) {
                        ArrayNode candidateGroupsNode = objectMapper.createArrayNode();
                        idmNode.set("candidateGroups", candidateGroupsNode);
                        idmNode.put("type", "groups");
                        for (String candidateGroup : humanTask.getCandidateGroups()) {
                            ObjectNode candidateGroupNode = objectMapper.createObjectNode();
                            candidateGroupNode.put("id", candidateGroup);
                            candidateGroupsNode.add(candidateGroupNode);

                            fillProperty("name", "group-info-name-" + candidateGroup, candidateGroupNode,
                                    humanTask);
                        }
                    }
                }

            } else {
                assignmentValuesNode.put("type", "static");

                if (StringUtils.isNotEmpty(assignee)) {
                    assignmentValuesNode.put(PROPERTY_USERTASK_ASSIGNEE, assignee);
                }

                if (CollectionUtils.isNotEmpty(humanTask.getCandidateUsers())) {
                    ArrayNode candidateArrayNode = objectMapper.createArrayNode();
                    for (String candidateUser : humanTask.getCandidateUsers()) {
                        ObjectNode candidateNode = objectMapper.createObjectNode();
                        candidateNode.put("value", candidateUser);
                        candidateArrayNode.add(candidateNode);
                    }
                    assignmentValuesNode.set(PROPERTY_USERTASK_CANDIDATE_USERS, candidateArrayNode);
                }

                if (CollectionUtils.isNotEmpty(humanTask.getCandidateGroups())) {
                    ArrayNode candidateArrayNode = objectMapper.createArrayNode();
                    for (String candidateGroup : humanTask.getCandidateGroups()) {
                        ObjectNode candidateNode = objectMapper.createObjectNode();
                        candidateNode.put("value", candidateGroup);
                        candidateArrayNode.add(candidateNode);
                    }
                    assignmentValuesNode.set(PROPERTY_USERTASK_CANDIDATE_GROUPS, candidateArrayNode);
                }
            }

            assignmentNode.set("assignment", assignmentValuesNode);
            propertiesNode.set(PROPERTY_USERTASK_ASSIGNMENT, assignmentNode);
        }

        if (humanTask.getPriority() != null) {
            setPropertyValue(PROPERTY_USERTASK_PRIORITY, humanTask.getPriority(), propertiesNode);
        }

        if (StringUtils.isNotEmpty(humanTask.getFormKey())) {
            if (formKeyMap != null && formKeyMap.containsKey(humanTask.getFormKey())) {
                ObjectNode formRefNode = objectMapper.createObjectNode();
                CmmnModelInfo modelInfo = formKeyMap.get(humanTask.getFormKey());
                formRefNode.put("id", modelInfo.getId());
                formRefNode.put("name", modelInfo.getName());
                formRefNode.put("key", modelInfo.getKey());
                propertiesNode.set(PROPERTY_FORM_REFERENCE, formRefNode);

            } else {
                setPropertyValue(PROPERTY_FORMKEY, humanTask.getFormKey(), propertiesNode);
            }
        }

        setPropertyValue(PROPERTY_USERTASK_DUEDATE, humanTask.getDueDate(), propertiesNode);
        setPropertyValue(PROPERTY_USERTASK_CATEGORY, humanTask.getCategory(), propertiesNode);
    }

    protected int getExtensionElementValueAsInt(String name, HumanTask humanTask) {
        int intValue = 0;
        String value = getExtensionElementValue(name, humanTask);
        if (value != null && NumberUtils.isNumber(value)) {
            intValue = Integer.valueOf(value);
        }
        return intValue;
    }

    protected String getExtensionElementValue(String name, HumanTask humanTask) {
        String value = "";
        if (CollectionUtils.isNotEmpty(humanTask.getExtensionElements().get(name))) {
            ExtensionElement extensionElement = humanTask.getExtensionElements().get(name).get(0);
            value = extensionElement.getElementText();
        }
        return value;
    }

    @Override
    protected CaseElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode,
            ActivityProcessor processor, BaseElement parentElement, Map<String, JsonNode> shapeMap,
            CmmnModel cmmnModel, CmmnModelIdHelper cmmnModelIdHelper) {

        HumanTask task = new HumanTask();

        task.setPriority(getPropertyValueAsString(PROPERTY_USERTASK_PRIORITY, elementNode));
        String formKey = getPropertyValueAsString(PROPERTY_FORMKEY, elementNode);
        if (StringUtils.isNotEmpty(formKey)) {
            task.setFormKey(formKey);
        } else {
            JsonNode formReferenceNode = getProperty(PROPERTY_FORM_REFERENCE, elementNode);
            if (formReferenceNode != null && formReferenceNode.get("id") != null) {

                if (formMap != null && formMap.containsKey(formReferenceNode.get("id").asText())) {
                    task.setFormKey(formMap.get(formReferenceNode.get("id").asText()));
                }
            }
        }

        task.setDueDate(getPropertyValueAsString(PROPERTY_USERTASK_DUEDATE, elementNode));
        task.setCategory(getPropertyValueAsString(PROPERTY_USERTASK_CATEGORY, elementNode));

        JsonNode assignmentNode = getProperty(PROPERTY_USERTASK_ASSIGNMENT, elementNode);
        if (assignmentNode != null) {
            JsonNode assignmentDefNode = assignmentNode.get("assignment");
            if (assignmentDefNode != null) {

                JsonNode typeNode = assignmentDefNode.get("type");
                JsonNode canCompleteTaskNode = assignmentDefNode.get("initiatorCanCompleteTask");
                if (typeNode == null || "static".equalsIgnoreCase(typeNode.asText())) {
                    JsonNode assigneeNode = assignmentDefNode.get(PROPERTY_USERTASK_ASSIGNEE);
                    if (assigneeNode != null && !assigneeNode.isNull()) {
                        task.setAssignee(assigneeNode.asText());
                    }

                    task.setCandidateUsers(getValueAsList(PROPERTY_USERTASK_CANDIDATE_USERS, assignmentDefNode));
                    task.setCandidateGroups(getValueAsList(PROPERTY_USERTASK_CANDIDATE_GROUPS, assignmentDefNode));

                    if (StringUtils.isNotEmpty(task.getAssignee())) {

                        if (canCompleteTaskNode != null && !canCompleteTaskNode.isNull()) {
                            addInitiatorCanCompleteExtensionElement(Boolean.valueOf(canCompleteTaskNode.asText()),
                                    task);
                        } else {
                            addInitiatorCanCompleteExtensionElement(false, task);
                        }

                    } else if (StringUtils.isNotEmpty(task.getAssignee())) {
                        addInitiatorCanCompleteExtensionElement(true, task);
                    }

                } else if ("idm".equalsIgnoreCase(typeNode.asText())) {
                    JsonNode idmDefNode = assignmentDefNode.get("idm");
                    if (idmDefNode != null && idmDefNode.has("type")) {
                        JsonNode idmTypeNode = idmDefNode.get("type");
                        if (idmTypeNode != null && "user".equalsIgnoreCase(idmTypeNode.asText())
                                && idmDefNode.has("assignee")) {

                            fillAssigneeInfo(idmDefNode, canCompleteTaskNode, task);

                        } else if (idmTypeNode != null && "users".equalsIgnoreCase(idmTypeNode.asText())
                                && idmDefNode.has("candidateUsers")) {

                            fillCandidateUsers(idmDefNode, canCompleteTaskNode, task);

                        } else if (idmTypeNode != null && "groups".equalsIgnoreCase(idmTypeNode.asText())
                                && idmDefNode.has("candidateGroups")) {

                            fillCandidateGroups(idmDefNode, canCompleteTaskNode, task);

                        } else {
                            task.setAssignee("${" + cmmnModel.getPrimaryCase().getInitiatorVariableName() + "}");
                            addExtensionElement("flowable-idm-initiator", String.valueOf(true), task);
                        }
                    }
                }
            }
        }

        return task;
    }

    protected void fillAssigneeInfo(JsonNode idmDefNode, JsonNode canCompleteTaskNode, HumanTask task) {
        JsonNode assigneeNode = idmDefNode.get("assignee");
        if (assigneeNode != null && !assigneeNode.isNull()) {
            JsonNode idNode = assigneeNode.get("id");
            JsonNode emailNode = assigneeNode.get("email");
            if (idNode != null && !idNode.isNull() && StringUtils.isNotEmpty(idNode.asText())) {
                task.setAssignee(idNode.asText());
                addExtensionElement("flowable-idm-assignee", String.valueOf(true), task);
                addExtensionElement("assignee-info-email", emailNode, task);
                addExtensionElement("assignee-info-firstname", assigneeNode.get("firstName"), task);
                addExtensionElement("assignee-info-lastname", assigneeNode.get("lastName"), task);
            }
        }

        if (canCompleteTaskNode != null && !canCompleteTaskNode.isNull()) {
            addInitiatorCanCompleteExtensionElement(Boolean.valueOf(canCompleteTaskNode.asText()), task);
        } else {
            addInitiatorCanCompleteExtensionElement(false, task);
        }
    }

    protected void fillCandidateUsers(JsonNode idmDefNode, JsonNode canCompleteTaskNode, HumanTask task) {
        List<String> candidateUsers = new ArrayList<>();
        JsonNode candidateUsersNode = idmDefNode.get("candidateUsers");
        if (candidateUsersNode != null && candidateUsersNode.isArray()) {
            List<String> emails = new ArrayList<>();
            for (JsonNode userNode : candidateUsersNode) {
                if (userNode != null && !userNode.isNull()) {
                    JsonNode idNode = userNode.get("id");
                    JsonNode emailNode = userNode.get("email");
                    if (idNode != null && !idNode.isNull() && StringUtils.isNotEmpty(idNode.asText())) {
                        String id = idNode.asText();
                        candidateUsers.add(id);

                        addExtensionElement("user-info-email-" + id, emailNode, task);
                        addExtensionElement("user-info-firstname-" + id, userNode.get("firstName"), task);
                        addExtensionElement("user-info-lastname-" + id, userNode.get("lastName"), task);

                    } else if (emailNode != null && !emailNode.isNull()
                            && StringUtils.isNotEmpty(emailNode.asText())) {
                        String email = emailNode.asText();
                        candidateUsers.add(email);
                        emails.add(email);
                    }
                }
            }

            if (emails.size() > 0) {
                // Email extension element
                addExtensionElement("flowable-candidate-users-emails", StringUtils.join(emails, ","), task);
            }

            if (candidateUsers.size() > 0) {
                addExtensionElement("flowable-idm-candidate-user", String.valueOf(true), task);
                if (canCompleteTaskNode != null && !canCompleteTaskNode.isNull()) {
                    addInitiatorCanCompleteExtensionElement(Boolean.valueOf(canCompleteTaskNode.asText()), task);
                } else {
                    addInitiatorCanCompleteExtensionElement(false, task);
                }
            }
        }

        if (candidateUsers.size() > 0) {
            task.setCandidateUsers(candidateUsers);
        }
    }

    protected void fillCandidateGroups(JsonNode idmDefNode, JsonNode canCompleteTaskNode, HumanTask task) {
        List<String> candidateGroups = new ArrayList<>();
        JsonNode candidateGroupsNode = idmDefNode.get("candidateGroups");
        if (candidateGroupsNode != null && candidateGroupsNode.isArray()) {
            for (JsonNode groupNode : candidateGroupsNode) {
                if (groupNode != null && !groupNode.isNull()) {
                    JsonNode idNode = groupNode.get("id");
                    JsonNode nameNode = groupNode.get("name");
                    if (idNode != null && !idNode.isNull() && StringUtils.isNotEmpty(idNode.asText())) {
                        String id = idNode.asText();
                        candidateGroups.add(id);

                        addExtensionElement("group-info-name-" + id, nameNode, task);
                    }
                }
            }
        }

        if (candidateGroups.size() > 0) {
            task.setCandidateGroups(candidateGroups);
            addExtensionElement("flowable-idm-candidate-group", String.valueOf(true), task);

            if (canCompleteTaskNode != null && !canCompleteTaskNode.isNull()) {
                addInitiatorCanCompleteExtensionElement(Boolean.valueOf(canCompleteTaskNode.asText()), task);
            } else {
                addInitiatorCanCompleteExtensionElement(false, task);
            }
        }
    }

    protected void addInitiatorCanCompleteExtensionElement(boolean canCompleteTask, HumanTask task) {
        addExtensionElement("initiator-can-complete", String.valueOf(canCompleteTask), task);
    }

    protected void addExtensionElement(String name, JsonNode elementNode, HumanTask task) {
        if (elementNode != null && !elementNode.isNull() && StringUtils.isNotEmpty(elementNode.asText())) {
            addExtensionElement(name, elementNode.asText(), task);
        }
    }

    protected void addExtensionElement(String name, String elementText, HumanTask task) {
        ExtensionElement extensionElement = new ExtensionElement();
        extensionElement.setNamespace(NAMESPACE);
        extensionElement.setNamespacePrefix("modeler");
        extensionElement.setName(name);
        extensionElement.setElementText(elementText);
        task.addExtensionElement(extensionElement);
    }

    protected void fillProperty(String propertyName, String extensionElementName, ObjectNode elementNode,
            HumanTask task) {
        List<ExtensionElement> extensionElementList = task.getExtensionElements().get(extensionElementName);
        if (CollectionUtils.isNotEmpty(extensionElementList)) {
            elementNode.put(propertyName, extensionElementList.get(0).getElementText());
        }
    }

    @Override
    public void setFormMap(Map<String, String> formMap) {
        this.formMap = formMap;
    }

    @Override
    public void setFormKeyMap(Map<String, CmmnModelInfo> formKeyMap) {
        this.formKeyMap = formKeyMap;
    }
}