org.activiti.app.rest.runtime.AbstractTaskQueryResource.java Source code

Java tutorial

Introduction

Here is the source code for org.activiti.app.rest.runtime.AbstractTaskQueryResource.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.activiti.app.rest.runtime;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;

import org.activiti.app.model.common.ResultListDataRepresentation;
import org.activiti.app.model.idm.UserRepresentation;
import org.activiti.app.model.runtime.TaskRepresentation;
import org.activiti.app.security.SecurityUtils;
import org.activiti.app.service.api.UserCache;
import org.activiti.app.service.api.UserCache.CachedUser;
import org.activiti.app.service.exception.BadRequestException;
import org.activiti.app.service.runtime.PermissionService;
import org.activiti.editor.language.json.converter.util.CollectionUtils;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.TaskInfo;
import org.activiti.engine.task.TaskInfoQueryWrapper;
import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.util.ISO8601Utils;

public abstract class AbstractTaskQueryResource {

    private static final String SORT_CREATED_ASC = "created-asc";
    private static final String SORT_CREATED_DESC = "created-desc";
    private static final String SORT_DUE_ASC = "due-asc";
    private static final String SORT_DUE_DESC = "due-desc";

    private static final int DEFAULT_PAGE_SIZE = 25;

    @Inject
    protected RepositoryService repositoryService;

    @Inject
    protected TaskService taskService;

    @Inject
    protected RuntimeService runtimeService;

    @Inject
    protected HistoryService historyService;

    @Inject
    protected UserCache userCache;

    @Inject
    protected PermissionService permissionService;

    public ResultListDataRepresentation listTasks(ObjectNode requestNode) {

        if (requestNode == null) {
            throw new BadRequestException("No request found");
        }
        User currentUser = SecurityUtils.getCurrentUserObject();

        JsonNode stateNode = requestNode.get("state");
        TaskInfoQueryWrapper taskInfoQueryWrapper = null;
        if (stateNode != null && "completed".equals(stateNode.asText())) {
            HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
            historicTaskInstanceQuery.finished();
            taskInfoQueryWrapper = new TaskInfoQueryWrapper(historicTaskInstanceQuery);
        } else {
            taskInfoQueryWrapper = new TaskInfoQueryWrapper(taskService.createTaskQuery());
        }

        JsonNode deploymentKeyNode = requestNode.get("deploymentKey");
        if (deploymentKeyNode != null && deploymentKeyNode.isNull() == false) {
            List<Deployment> deployments = repositoryService.createDeploymentQuery()
                    .deploymentKey(deploymentKeyNode.asText()).list();
            List<String> deploymentIds = new ArrayList<String>(deployments.size());
            for (Deployment deployment : deployments) {
                deploymentIds.add(deployment.getId());
            }

            taskInfoQueryWrapper.getTaskInfoQuery().or().deploymentIdIn(deploymentIds)
                    .taskCategory(deploymentKeyNode.asText()).endOr();
        }

        JsonNode processInstanceIdNode = requestNode.get("processInstanceId");
        if (processInstanceIdNode != null && processInstanceIdNode.isNull() == false) {
            handleProcessInstanceFiltering(currentUser, taskInfoQueryWrapper, processInstanceIdNode);
        }

        JsonNode textNode = requestNode.get("text");
        if (textNode != null && textNode.isNull() == false) {
            handleTextFiltering(taskInfoQueryWrapper, textNode);
        }

        JsonNode assignmentNode = requestNode.get("assignment");
        if (assignmentNode != null && assignmentNode.isNull() == false) {
            handleAssignment(taskInfoQueryWrapper, assignmentNode, currentUser);
        }

        JsonNode processDefinitionNode = requestNode.get("processDefinitionId");
        if (processDefinitionNode != null && processDefinitionNode.isNull() == false) {
            handleProcessDefinition(taskInfoQueryWrapper, processDefinitionNode);
        }

        JsonNode dueBeforeNode = requestNode.get("dueBefore");
        if (dueBeforeNode != null && dueBeforeNode.isNull() == false) {
            handleDueBefore(taskInfoQueryWrapper, dueBeforeNode);
        }

        JsonNode dueAfterNode = requestNode.get("dueAfter");
        if (dueAfterNode != null && dueAfterNode.isNull() == false) {
            handleDueAfter(taskInfoQueryWrapper, dueAfterNode);
        }

        JsonNode sortNode = requestNode.get("sort");
        if (sortNode != null) {
            handleSorting(taskInfoQueryWrapper, sortNode);
        }

        int page = 0;
        JsonNode pageNode = requestNode.get("page");
        if (pageNode != null && !pageNode.isNull()) {
            page = pageNode.asInt(0);
        }

        int size = DEFAULT_PAGE_SIZE;
        JsonNode sizeNode = requestNode.get("size");
        if (sizeNode != null && !sizeNode.isNull()) {
            size = sizeNode.asInt(DEFAULT_PAGE_SIZE);
        }

        List<? extends TaskInfo> tasks = taskInfoQueryWrapper.getTaskInfoQuery().listPage(page * size, size);

        JsonNode includeProcessInstanceNode = requestNode.get("includeProcessInstance");
        // todo Once a ProcessInstanceInfo class has been implement use it instead rather than just the name
        Map<String, String> processInstancesNames = new HashMap<String, String>();
        if (includeProcessInstanceNode != null) {
            handleIncludeProcessInstance(taskInfoQueryWrapper, includeProcessInstanceNode, tasks,
                    processInstancesNames);
        }

        ResultListDataRepresentation result = new ResultListDataRepresentation(
                convertTaskInfoList(tasks, processInstancesNames));

        // In case we're not on the first page and the size exceeds the page size, we need to do an additional count for the total
        if (page != 0 || tasks.size() == size) {
            Long totalCount = taskInfoQueryWrapper.getTaskInfoQuery().count();
            result.setTotal(Long.valueOf(totalCount.intValue()));
            result.setStart(page * size);
        }

        return result;
    }

    private void handleProcessInstanceFiltering(User currentUser, TaskInfoQueryWrapper taskInfoQueryWrapper,
            JsonNode processInstanceIdNode) {
        String processInstanceId = processInstanceIdNode.asText();
        taskInfoQueryWrapper.getTaskInfoQuery().processInstanceId(processInstanceId);
    }

    private void handleTextFiltering(TaskInfoQueryWrapper taskInfoQueryWrapper, JsonNode textNode) {
        String text = textNode.asText();

        // [4/9/2014] Used to be an or on description too, but doesnt work combined with the or query for an app.
        // (Would need a change in Activiti)
        taskInfoQueryWrapper.getTaskInfoQuery().taskNameLikeIgnoreCase("%" + text + "%");
    }

    private void handleAssignment(TaskInfoQueryWrapper taskInfoQueryWrapper, JsonNode assignmentNode,
            User currentUser) {
        String assignment = assignmentNode.asText();
        if (assignment.length() > 0) {
            String currentUserId = String.valueOf(currentUser.getId());
            if ("assignee".equals(assignment)) {
                taskInfoQueryWrapper.getTaskInfoQuery().taskAssignee(currentUserId);
            } else if ("candidate".equals(assignment)) {
                taskInfoQueryWrapper.getTaskInfoQuery().taskCandidateUser(currentUserId);
            } else if (assignment.startsWith("group_")) {
                String groupIdString = assignment.replace("group_", "");
                try {
                    Long.valueOf(groupIdString);
                } catch (NumberFormatException e) {
                    throw new BadRequestException("Invalid group id");
                }
                taskInfoQueryWrapper.getTaskInfoQuery().taskCandidateGroup(groupIdString);
            } else { // Default = involved
                taskInfoQueryWrapper.getTaskInfoQuery().taskInvolvedUser(currentUserId);
            }
        }
    }

    private void handleProcessDefinition(TaskInfoQueryWrapper taskInfoQueryWrapper,
            JsonNode processDefinitionIdNode) {
        String processDefinitionId = processDefinitionIdNode.asText();
        taskInfoQueryWrapper.getTaskInfoQuery().processDefinitionId(processDefinitionId);
    }

    private void handleDueBefore(TaskInfoQueryWrapper taskInfoQueryWrapper, JsonNode dueBeforeNode) {
        String date = dueBeforeNode.asText();
        Date d = ISO8601Utils.parse(date);
        taskInfoQueryWrapper.getTaskInfoQuery().taskDueBefore(d);
    }

    private void handleDueAfter(TaskInfoQueryWrapper taskInfoQueryWrapper, JsonNode dueAfterNode) {
        String date = dueAfterNode.asText();
        Date d = ISO8601Utils.parse(date);
        taskInfoQueryWrapper.getTaskInfoQuery().taskDueAfter(d);
    }

    private void handleSorting(TaskInfoQueryWrapper taskInfoQueryWrapper, JsonNode sortNode) {
        String sort = sortNode.asText();

        if (SORT_CREATED_ASC.equals(sort)) {
            taskInfoQueryWrapper.getTaskInfoQuery().orderByTaskCreateTime().asc();
        } else if (SORT_CREATED_DESC.equals(sort)) {
            taskInfoQueryWrapper.getTaskInfoQuery().orderByTaskCreateTime().desc();
        } else if (SORT_DUE_ASC.equals(sort)) {
            taskInfoQueryWrapper.getTaskInfoQuery().orderByDueDateNullsLast().asc();
        } else if (SORT_DUE_DESC.equals(sort)) {
            taskInfoQueryWrapper.getTaskInfoQuery().orderByDueDateNullsLast().desc();
        } else {
            // Default
            taskInfoQueryWrapper.getTaskInfoQuery().orderByTaskCreateTime().desc();
        }
    }

    private void handleIncludeProcessInstance(TaskInfoQueryWrapper taskInfoQueryWrapper,
            JsonNode includeProcessInstanceNode, List<? extends TaskInfo> tasks,
            Map<String, String> processInstanceNames) {
        if (includeProcessInstanceNode.asBoolean() && CollectionUtils.isNotEmpty(tasks)) {
            Set<String> processInstanceIds = new HashSet<String>();
            for (TaskInfo task : tasks) {
                if (task.getProcessInstanceId() != null) {
                    processInstanceIds.add(task.getProcessInstanceId());
                }
            }
            if (CollectionUtils.isNotEmpty(processInstanceIds)) {
                if (taskInfoQueryWrapper.getTaskInfoQuery() instanceof HistoricTaskInstanceQuery) {
                    List<HistoricProcessInstance> processInstances = historyService
                            .createHistoricProcessInstanceQuery().processInstanceIds(processInstanceIds).list();
                    for (HistoricProcessInstance processInstance : processInstances) {
                        processInstanceNames.put(processInstance.getId(), processInstance.getName());
                    }
                } else {
                    List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery()
                            .processInstanceIds(processInstanceIds).list();
                    for (ProcessInstance processInstance : processInstances) {
                        processInstanceNames.put(processInstance.getId(), processInstance.getName());
                    }
                }
            }
        }
    }

    protected List<TaskRepresentation> convertTaskInfoList(List<? extends TaskInfo> tasks,
            Map<String, String> processInstanceNames) {
        List<TaskRepresentation> result = new ArrayList<TaskRepresentation>();
        if (CollectionUtils.isNotEmpty(tasks)) {
            for (TaskInfo task : tasks) {
                ProcessDefinitionEntity processDefinition = null;
                if (task.getProcessDefinitionId() != null) {
                    processDefinition = (ProcessDefinitionEntity) repositoryService
                            .getProcessDefinition(task.getProcessDefinitionId());
                }
                TaskRepresentation representation = new TaskRepresentation(task, processDefinition,
                        processInstanceNames.get(task.getProcessInstanceId()));

                if (StringUtils.isNotEmpty(task.getAssignee())) {
                    CachedUser cachedUser = userCache.getUser(task.getAssignee());
                    if (cachedUser != null && cachedUser.getUser() != null) {
                        User assignee = cachedUser.getUser();
                        representation.setAssignee(new UserRepresentation(assignee));
                    }
                }

                result.add(representation);
            }
        }
        return result;
    }
}