/**
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* 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.jbpm.services.task.impl;
import static org.kie.internal.query.QueryParameterIdentifiers.ASCENDING_VALUE;
import static org.kie.internal.query.QueryParameterIdentifiers.DESCENDING_VALUE;
import static org.kie.internal.query.QueryParameterIdentifiers.FILTER;
import static org.kie.internal.query.QueryParameterIdentifiers.FIRST_RESULT;
import static org.kie.internal.query.QueryParameterIdentifiers.MAX_RESULTS;
import static org.kie.internal.query.QueryParameterIdentifiers.ORDER_BY;
import static org.kie.internal.query.QueryParameterIdentifiers.ORDER_TYPE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import org.jbpm.query.jpa.data.QueryWhere;
import org.jbpm.services.task.utils.ClassUtil;
import org.kie.api.task.UserGroupCallback;
import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.Status;
import org.kie.api.task.model.Task;
import org.kie.api.task.model.TaskSummary;
import org.kie.internal.query.QueryContext;
import org.kie.internal.query.QueryFilter;
import org.kie.internal.task.api.TaskPersistenceContext;
import org.kie.internal.task.api.TaskQueryService;
import org.kie.internal.task.api.model.InternalTaskSummary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class TaskQueryServiceImpl implements TaskQueryService {
private static final Logger logger = LoggerFactory.getLogger(TaskQueryServiceImpl.class);
private TaskPersistenceContext persistenceContext;
private UserGroupCallback userGroupCallback;
protected List<?> adoptList(List<?> source, List<?> values) {
if (source == null || source.isEmpty()) {
List<Object> data = new ArrayList<Object>();
for (Object value : values) {
data.add(value);
}
return data;
}
return source;
}
protected void applyQueryFilter(Map<String, Object> params, QueryFilter queryFilter) {
if (queryFilter != null) {
applyQueryContext(params, queryFilter);
if (queryFilter.getFilterParams() != null && !queryFilter.getFilterParams().isEmpty()) {
params.put(FILTER, queryFilter.getFilterParams());
for(String key : queryFilter.getParams().keySet()){
params.put(key, queryFilter.getParams().get(key));
}
}
}
}
protected void applyQueryContext(Map<String, Object> params, QueryContext queryContext) {
if (queryContext != null) {
Integer offset = queryContext.getOffset();
if( offset != null && offset > 0 ) {
params.put(FIRST_RESULT, offset);
}
Integer count = queryContext.getCount();
if( count != null && count > 0 ) {
params.put(MAX_RESULTS, count);
}
if (queryContext.getOrderBy() != null && !queryContext.getOrderBy().isEmpty()) {
params.put(ORDER_BY, queryContext.getOrderBy());
if( queryContext.isAscending() != null ) {
if (queryContext.isAscending()) {
params.put(ORDER_TYPE, ASCENDING_VALUE);
} else {
params.put(ORDER_TYPE, DESCENDING_VALUE);
}
}
}
}
}
private static final List<Status> allActiveStatus = new ArrayList<Status>(){{
this.add(Status.Created);
this.add(Status.Ready);
this.add(Status.Reserved);
this.add(Status.InProgress);
this.add(Status.Suspended);
}};
public TaskQueryServiceImpl() {
}
public TaskQueryServiceImpl(TaskPersistenceContext persistenceContext, UserGroupCallback userGroupCallback) {
this.persistenceContext = persistenceContext;
this.userGroupCallback = userGroupCallback;
}
public void setPersistenceContext(TaskPersistenceContext persistenceContext) {
this.persistenceContext = persistenceContext;
}
public void setUserGroupCallback(UserGroupCallback userGroupCallback) {
this.userGroupCallback = userGroupCallback;
}
public List<TaskSummary> getTasksAssignedAsBusinessAdministrator(String userId, List<String> groupIds) {
return getTasksAssignedAsBusinessAdministratorByStatus(userId, groupIds, allActiveStatus);
}
public List<TaskSummary> getTasksAssignedAsExcludedOwner(String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsExcludedOwner",
persistenceContext.addParametersToMap("userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwner",
persistenceContext.addParametersToMap("userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds) {
if(groupIds == null || groupIds.isEmpty()){
return getTasksAssignedAsPotentialOwner(userId);
}
Map<String, Object> params = new HashMap<String, Object>();
params.put("userId", userId);
params.put("groupIds", groupIds);
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerWithGroups",
params,
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedByGroup(String groupId) {
if(groupId == null || groupId.isEmpty()){
return Collections.EMPTY_LIST;
}
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerByGroup",
persistenceContext.addParametersToMap("groupId", groupId ),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedByGroupsByExpirationDateOptional(List<String> groupIds, Date expirationDate) {
if(groupIds == null || groupIds.isEmpty()){
return Collections.EMPTY_LIST;
}
List<Object[]> tasksByGroups = (List<Object[]>)persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerByGroupsByExpirationDateOptional",
persistenceContext.addParametersToMap("groupIds", groupIds, "expirationDate", expirationDate),
ClassUtil.<List<Object[]>>castClass(List.class));
return collectTasksByPotentialOwners(tasksByGroups);
}
protected List<TaskSummary> collectTasksByPotentialOwners(List<Object[]> tasksByGroups) {
Set<Long> tasksIds = Collections.synchronizedSet(new HashSet<Long>());
Map<Long, List<String>> potentialOwners = Collections.synchronizedMap(new HashMap<Long, List<String>>());
for (Object o : tasksByGroups) {
Object[] get = (Object[]) o;
tasksIds.add((Long) get[0]);
if (potentialOwners.get((Long) get[0]) == null) {
potentialOwners.put((Long) get[0], new ArrayList<String>());
}
potentialOwners.get((Long) get[0]).add((String) get[1]);
}
if (!tasksIds.isEmpty()) {
List<TaskSummary> tasks = (List<TaskSummary>)persistenceContext.queryWithParametersInTransaction("TaskSummariesByIds",
persistenceContext.addParametersToMap("taskIds", tasksIds),
ClassUtil.<List<TaskSummary>>castClass(List.class));
for (TaskSummary ts : tasks) {
((InternalTaskSummary) ts).setPotentialOwners(potentialOwners.get(ts.getId()));
}
return tasks;
}
return new ArrayList<TaskSummary>();
}
public List<TaskSummary> getTasksAssignedByGroupsByExpirationDate(List<String> groupIds, Date expirationDate) {
if(groupIds == null || groupIds.isEmpty()){
return Collections.EMPTY_LIST;
}
List<Object[]> tasksByGroups = (List<Object[]>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerByGroupsByExpirationDate",
persistenceContext.addParametersToMap("groupIds", groupIds, "expirationDate", expirationDate),
ClassUtil.<List<Object[]>>castClass(List.class));
return collectTasksByPotentialOwners(tasksByGroups);
}
public List<TaskSummary> getTasksAssignedByGroups(List<String> groupIds) {
if(groupIds == null || groupIds.isEmpty()){
return Collections.EMPTY_LIST;
}
List<Object[]> tasksByGroups = (List<Object[]>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerByGroups",
persistenceContext.addParametersToMap("groupIds", groupIds),
ClassUtil.<List<Object[]>>castClass(List.class));
Set<Long> tasksIds = Collections.synchronizedSet(new HashSet<Long>());
Map<Long, List<String>> potentialOwners = Collections.synchronizedMap(new HashMap<Long, List<String>>());
for (Object o : tasksByGroups) {
Object[] get = (Object[]) o;
tasksIds.add((Long) get[0]);
if (potentialOwners.get((Long) get[0]) == null) {
potentialOwners.put((Long) get[0], new ArrayList<String>());
}
potentialOwners.get((Long) get[0]).add((String) get[1]);
}
if (!tasksIds.isEmpty()) {
List<TaskSummary> tasks = (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TaskSummariesByIds",
persistenceContext.addParametersToMap("taskIds", tasksIds),
ClassUtil.<List<TaskSummary>>castClass(List.class));
for (TaskSummary ts : tasks) {
((InternalTaskSummary) ts).setPotentialOwners(potentialOwners.get(ts.getId()));
}
return tasks;
}
return new ArrayList<TaskSummary>();
}
public Map<Long, List<OrganizationalEntity>> getPotentialOwnersForTaskIds(List<Long> taskIds){
List<Object[]> potentialOwners = persistenceContext.queryWithParametersInTransaction("GetPotentialOwnersForTaskIds",
persistenceContext.addParametersToMap("taskIds", taskIds),
ClassUtil.<List<Object[]>>castClass(List.class));
Map<Long, List<OrganizationalEntity>> potentialOwnersMap = new HashMap<Long, List<OrganizationalEntity>>();
Long currentTaskId = 0L;
for(Object[] item : potentialOwners){
Long taskId = (Long) item[0];
OrganizationalEntity potentialOwner = (OrganizationalEntity)item[1];
if(!Objects.equals(currentTaskId, taskId)){
currentTaskId = taskId;
}
if(potentialOwnersMap.get(currentTaskId) == null){
potentialOwnersMap.put(currentTaskId, new ArrayList<OrganizationalEntity>());
}
potentialOwnersMap.get(currentTaskId).add(potentialOwner);
}
return potentialOwnersMap;
}
public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, int firstResult, int maxResults) {
if(groupIds == null || groupIds.isEmpty()){
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwner",
persistenceContext.addParametersToMap("userId", userId,
"firstResult", firstResult, "maxResults", maxResults),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerWithGroups",
persistenceContext.addParametersToMap("userId", userId, "groupIds", groupIds,
"firstResult", firstResult, "maxResults", maxResults),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedAsRecipient(String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsRecipient",
persistenceContext.addParametersToMap("userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedAsTaskInitiator(String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsTaskInitiator",
persistenceContext.addParametersToMap("userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksAssignedAsTaskStakeholder(String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsTaskStakeholder",
persistenceContext.addParametersToMap("userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksOwned(String userId) {
return getTasksOwned(userId, null, null);
}
public List<TaskSummary> getTasksOwnedByStatus(String userId, List<Status> status) {
List<TaskSummary> taskOwned = getTasksOwned(userId, null, null);
if (!taskOwned.isEmpty()) {
Set<Long> tasksIds = new HashSet<Long>();
for (TaskSummary ts : taskOwned) {
tasksIds.add(ts.getId());
}
List<Object[]> tasksPotentialOwners = (List<Object[]>) persistenceContext.queryWithParametersInTransaction("TasksOwnedPotentialOwnersByTaskIds",
persistenceContext.addParametersToMap("taskIds", tasksIds),
ClassUtil.<List<Object[]>>castClass(List.class));
Map<Long, List<String>> potentialOwners = new HashMap<Long, List<String>>();
for (Object o : tasksPotentialOwners) {
Object[] get = (Object[]) o;
tasksIds.add((Long) get[0]);
if (potentialOwners.get((Long) get[0]) == null) {
potentialOwners.put((Long) get[0], new ArrayList<String>());
}
potentialOwners.get((Long) get[0]).add((String) get[1]);
}
for (TaskSummary ts : taskOwned) {
((InternalTaskSummary) ts).setPotentialOwners(potentialOwners.get(ts.getId()));
}
} else {
return new ArrayList<TaskSummary>(0);
}
return taskOwned;
}
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatus(String userId, List<Status> status) {
return getTasksAssignedAsPotentialOwner(userId, null, status, null);
}
public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, List<Status> status, QueryFilter filter) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("userId", userId);
params.put("status", adoptList(status, allActiveStatus));
params.put("groupIds", adoptList(groupIds, Collections.singletonList("")));
applyQueryFilter(params, filter);
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("NewTasksAssignedAsPotentialOwner",
params,
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getTasksOwned(String userId, List<Status> status, QueryFilter filter) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("userId", userId);
if(status == null){
status = new ArrayList<Status>();
status.add(Status.Reserved);
status.add(Status.InProgress);
}
params.put("status", status);
applyQueryFilter(params, filter);
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("NewTasksOwned",
params,
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getSubTasksAssignedAsPotentialOwner(long parentId, String userId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("SubTasksAssignedAsPotentialOwner",
persistenceContext.addParametersToMap("parentId", parentId, "userId", userId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public List<TaskSummary> getSubTasksByParent(long parentId) {
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("GetSubTasksByParentTaskId",
persistenceContext.addParametersToMap("parentId", parentId),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
public int getPendingSubTasksByParent(long parentId) {
return persistenceContext.queryWithParametersInTransaction("GetSubTasksByParentTaskId",
persistenceContext.addParametersToMap("parentId", parentId),
ClassUtil.<List<TaskSummary>>castClass(List.class)).size();
}
public Task getTaskInstanceById(long taskId) {
Task taskInstance = persistenceContext.findTask(taskId);
return taskInstance;
}
public Task getTaskByWorkItemId(long workItemId) {
List<Task> tasks = (List<Task>)persistenceContext.queryWithParametersInTransaction("TaskByWorkItemId",
persistenceContext.addParametersToMap("workItemId", workItemId,"maxResults", 1),
ClassUtil.<List<Task>>castClass(List.class));
if (tasks.isEmpty())
return null;
else
return (Task) (tasks.get(0));
}
@Override
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDate(String userId, List<String> groupIds,
List<Status> status, Date expirationDate) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("expirationDate", expirationDate);
return (List<TaskSummary>) getTasksAssignedAsPotentialOwner(userId, groupIds, status,
new QueryFilter("t.taskData.expirationTime = :expirationDate", params, "order by t.id", false));
}
@Override
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDateOptional(String userId, List<String> groupIds,
List<Status> status, Date expirationDate) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("expirationDate", expirationDate);
return (List<TaskSummary>) getTasksAssignedAsPotentialOwner(userId, groupIds, status,
new QueryFilter("(t.taskData.expirationTime = :expirationDate or t.taskData.expirationTime is null)", params, "order by t.id", false));
}
@Override
public List<TaskSummary> getTasksOwnedByExpirationDate(String userId, List<Status> status, Date expirationDate) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("expirationDate", expirationDate);
return (List<TaskSummary>) getTasksOwned(userId, status,
new QueryFilter( "t.taskData.expirationTime = :expirationDate", params, "order by t.id", false));
}
@Override
public List<TaskSummary> getTasksOwnedByExpirationDateOptional(String userId, List<Status> status, Date expirationDate) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("expirationDate", expirationDate);
return (List<TaskSummary>) getTasksOwned(userId, status,
new QueryFilter( "(t.taskData.expirationTime = :expirationDate or t.taskData.expirationTime is null)"
, params, "order by t.id", false));
}
@Override
public List<TaskSummary> getTasksOwnedByExpirationDateBeforeSpecifiedDate(String userId, List<Status> status, Date date) {
if(status == null || status.isEmpty()){
status = allActiveStatus;
}
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksOwnedWithParticularStatusByExpirationDateBeforeSpecifiedDate",
persistenceContext.addParametersToMap("userId", userId, "status", status, "date", date),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
@Override
public List<TaskSummary> getTasksByStatusByProcessInstanceId(long processInstanceId, List<Status> status) {
if(status == null || status.isEmpty()){
status = allActiveStatus;
}
List<TaskSummary> tasks = (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksByStatusByProcessId",
persistenceContext.addParametersToMap("processInstanceId", processInstanceId,
"status", status),
ClassUtil.<List<TaskSummary>>castClass(List.class));
return tasks;
}
@Override
public List<TaskSummary> getTasksByStatusByProcessInstanceIdByTaskName(long processInstanceId, List<Status> status, String taskName) {
if(status == null || status.isEmpty()){
status = allActiveStatus;
}
List<TaskSummary> tasks = (List<TaskSummary>)persistenceContext.queryWithParametersInTransaction("TasksByStatusByProcessIdByTaskName",
persistenceContext.addParametersToMap("processInstanceId", processInstanceId,
"status", status,
"taskName", taskName),
ClassUtil.<List<TaskSummary>>castClass(List.class));
return tasks;
}
@Override
public List<Long> getTasksByProcessInstanceId(long processInstanceId) {
List<Long> tasks = (List<Long>)persistenceContext.queryWithParametersInTransaction("TasksByProcessInstanceId",
persistenceContext.addParametersToMap("processInstanceId", processInstanceId),
ClassUtil.<List<Long>>castClass(List.class));
return tasks;
}
@Override
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDate(String userId, List<Status> status, Date expirationDate) {
if(status == null || status.isEmpty()){
status = allActiveStatus;
}
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerStatusByExpirationDate",
persistenceContext.addParametersToMap("userId", userId, "groupIds", "", "status", status, "expirationDate", expirationDate),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
@Override
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDateOptional(String userId, List<Status> status, Date expirationDate) {
if(status == null || status.isEmpty()){
status = allActiveStatus;
}
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsPotentialOwnerStatusByExpirationDateOptional",
persistenceContext.addParametersToMap("userId", userId, "groupIds", "", "status", status, "expirationDate", expirationDate),
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
@Override
public int getCompletedTaskByUserId(String userId) {
List<Status> statuses = new ArrayList<Status>();
statuses.add(Status.Completed);
List<TaskSummary> tasksCompleted = getTasksAssignedAsPotentialOwnerByStatus(userId, statuses);
return tasksCompleted.size();
}
@Override
public int getPendingTaskByUserId(String userId) {
List<TaskSummary> tasksAssigned = getTasksAssignedAsPotentialOwner(userId, null, null, null);
return tasksAssigned.size();
}
@Override
public List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatusByGroup(String userId, List<String> groupIds,
List<Status> status) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("userId", userId);
params.put("status", adoptList(status, allActiveStatus));
params.put("groupIds", adoptList(groupIds, Collections.singletonList("")));
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("QuickTasksAssignedAsPotentialOwnerWithGroupsByStatus",
params,
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
@Override
public List<TaskSummary> getTasksAssignedAsBusinessAdministratorByStatus(String userId, List<String> groupIds, List<Status> status) {
Map<String, Object> params = new HashMap<String, Object>();
params.put("userId", userId);
params.put("status", status);
params.put("groupIds", adoptList(groupIds, Collections.singletonList("")));
return (List<TaskSummary>) persistenceContext.queryWithParametersInTransaction("TasksAssignedAsBusinessAdministratorByStatus",params,
ClassUtil.<List<TaskSummary>>castClass(List.class));
}
@Override
public List<TaskSummary> query( String userId, Object queryObj ) {
QueryWhere queryWhere = (QueryWhere) queryObj;
return persistenceContext.doTaskSummaryCriteriaQuery(userId, userGroupCallback, (QueryWhere) queryWhere);
}
}