/* * 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.runtime.manager.impl.task; import org.drools.core.command.impl.CommandBasedStatefulKnowledgeSession; import org.drools.persistence.PersistableRunner; import org.kie.api.command.Command; import org.kie.api.runtime.KieSession; import org.kie.api.task.TaskLifeCycleEventListener; import org.kie.api.task.model.Attachment; import org.kie.api.task.model.Comment; import org.kie.api.task.model.Content; import org.kie.api.task.model.Group; import org.kie.api.task.model.I18NText; 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.api.task.model.User; import org.kie.internal.query.QueryFilter; import org.kie.internal.task.api.ContentMarshallerContext; import org.kie.internal.task.api.EventService; import org.kie.internal.task.api.InternalTaskService; import org.kie.internal.task.api.UserInfo; import org.kie.internal.task.api.model.ContentData; import org.kie.internal.task.api.model.FaultData; import org.kie.internal.task.api.model.SubTasksStrategy; import org.kie.internal.task.api.model.TaskDef; import org.kie.internal.task.api.model.TaskEvent; import org.kie.internal.task.query.TaskSummaryQueryBuilder; import java.lang.reflect.InvocationHandler; import java.util.Date; import java.util.List; import java.util.Map; /** * Fully synchronized <code>TaskService</code> implementation used by the <code>SingletonRuntimeManager</code>. * Synchronization is done on <code>CommandService</code> of the <code>KieSession</code> to ensure correctness * until transaction completion. * * TODO: use the java {@link InvocationHandler}/proxy mechanism to make this class *much* shorter.. */ // TODO: use the Ink public class SynchronizedTaskService implements InternalTaskService, EventService<TaskLifeCycleEventListener> { private Object ksession; private InternalTaskService taskService; public SynchronizedTaskService(KieSession ksession, InternalTaskService taskService) { if (ksession instanceof CommandBasedStatefulKnowledgeSession) { this.ksession = (PersistableRunner) ((CommandBasedStatefulKnowledgeSession) ksession).getRunner(); } else { this.ksession = ksession; } this.taskService = taskService; } @Override public void activate(long taskId, String userId) { synchronized (ksession) { taskService.activate(taskId, userId); } } @Override public void addGroup(Group group) { synchronized (ksession) { taskService.addGroup(group); } } @Override public void addUser(User user) { synchronized (ksession) { taskService.addUser(user); } } @Override public int archiveTasks(List<TaskSummary> tasks) { synchronized (ksession) { return taskService.archiveTasks(tasks); } } @Override public void claim(long taskId, String userId) { synchronized (ksession) { taskService.claim(taskId, userId); } } @Override public void claimNextAvailable(String userId, String language) { synchronized (ksession) { taskService.claimNextAvailable(userId, language); } } @Override public void complete(long taskId, String userId, Map<String, Object> data) { synchronized (ksession) { taskService.complete(taskId, userId, data); } } @Override public void delegate(long taskId, String userId, String targetUserId) { synchronized (ksession) { taskService.delegate(taskId, userId, targetUserId); } } @Override public void deleteFault(long taskId, String userId) { synchronized (ksession) { taskService.deleteFault(taskId, userId); } } @Override public void deleteOutput(long taskId, String userId) { synchronized (ksession) { taskService.deleteOutput(taskId, userId); } } @Override public void deployTaskDef(TaskDef def) { synchronized (ksession) { taskService.deployTaskDef(def); } } @Override public void exit(long taskId, String userId) { synchronized (ksession) { taskService.exit(taskId, userId); } } @Override public void fail(long taskId, String userId, Map<String, Object> faultData) { synchronized (ksession) { taskService.fail(taskId, userId, faultData); } } @Override public void forward(long taskId, String userId, String targetEntityId) { synchronized (ksession) { taskService.forward(taskId, userId, targetEntityId); } } @Override public List<TaskSummary> getActiveTasks() { synchronized (ksession) { return taskService.getActiveTasks(); } } @Override public List<TaskSummary> getActiveTasks(Date since) { synchronized (ksession) { return taskService.getActiveTasks(since); } } @Override public List<TaskDef> getAllTaskDef(String filter) { synchronized (ksession) { return taskService.getAllTaskDef(filter); } } @Override public List<TaskSummary> getArchivedTasks() { synchronized (ksession) { return taskService.getArchivedTasks(); } } @Override public List<TaskSummary> getCompletedTasks() { synchronized (ksession) { return taskService.getCompletedTasks(); } } @Override public List<TaskSummary> getCompletedTasks(Date since) { synchronized (ksession) { return taskService.getCompletedTasks(since); } } @Override public List<TaskSummary> getCompletedTasksByProcessId(Long processId) { synchronized (ksession) { return taskService.getCompletedTasksByProcessId(processId); } } @Override public Group getGroupById(String groupId) { synchronized (ksession) { return taskService.getGroupById(groupId); } } @Override public List<Group> getGroups() { synchronized (ksession) { return taskService.getGroups(); } } @Override public List<TaskSummary> getSubTasksAssignedAsPotentialOwner(long parentId, String userId) { synchronized (ksession) { return taskService.getSubTasksAssignedAsPotentialOwner(parentId, userId); } } @Override public List<TaskSummary> getSubTasksByParent(long parentId) { synchronized (ksession) { return taskService.getSubTasksByParent(parentId); } } @Override public int getPendingSubTasksByParent(long parentId) { synchronized (ksession) { return taskService.getPendingSubTasksByParent(parentId); } } @Override public Task getTaskByWorkItemId(long workItemId) { synchronized (ksession) { return taskService.getTaskByWorkItemId(workItemId); } } @Override public TaskDef getTaskDefById(String id) { synchronized (ksession) { return taskService.getTaskDefById(id); } } @Override public Task getTaskById(long taskId) { synchronized (ksession) { return taskService.getTaskById(taskId); } } @Override public List<TaskSummary> getTasksAssignedAsBusinessAdministrator( String userId, String language) { synchronized (ksession) { return taskService.getTasksAssignedAsBusinessAdministrator(userId, language); } } @Override public List<TaskSummary> getTasksAssignedAsExcludedOwner(String userId) { synchronized (ksession) { return taskService.getTasksAssignedAsExcludedOwner(userId); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwner(userId, groupIds); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, String language, int firstResult, int maxResults) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwner(userId, groupIds, language, firstResult, maxResults); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, String language) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwner(userId, language); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatus( String userId, List<Status> status, String language) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwnerByStatus(userId, status, language); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatusByGroup( String userId, List<String> groupIds, List<Status> status) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwnerByStatusByGroup(userId, groupIds, status); } } @Override public List<TaskSummary> getTasksAssignedAsRecipient(String userId) { synchronized (ksession) { return taskService.getTasksAssignedAsRecipient(userId); } } @Override public List<TaskSummary> getTasksAssignedAsTaskInitiator(String userId) { synchronized (ksession) { return taskService.getTasksAssignedAsTaskInitiator(userId); } } @Override public List<TaskSummary> getTasksAssignedAsTaskStakeholder(String userId) { synchronized (ksession) { return taskService.getTasksAssignedAsTaskStakeholder(userId); } } @Override public List<TaskSummary> getTasksOwned(String userId, String language) { synchronized (ksession) { return taskService.getTasksOwned(userId, language); } } @Override public List<TaskSummary> getTasksOwnedByStatus(String userId, List<Status> status, String language) { synchronized (ksession) { return taskService.getTasksOwnedByStatus(userId, status, language); } } @Override public List<TaskSummary> getTasksOwnedByExpirationDate(String userId, List<Status> statuses, Date expirationDate) { synchronized (ksession) { return taskService.getTasksOwnedByExpirationDate(userId, statuses, expirationDate); } } @Override public List<TaskSummary> getTasksOwnedByExpirationDateOptional( String userId, List<Status> statuses, Date expirationDate) { synchronized (ksession) { return taskService.getTasksOwnedByExpirationDateOptional(userId, statuses, expirationDate); } } @Override public List<TaskSummary> getTasksOwnedByExpirationDateBeforeSpecifiedDate(String userId, List<Status> status, Date date) { synchronized (ksession) { return taskService.getTasksOwnedByExpirationDateBeforeSpecifiedDate(userId, status, date); } } @Override public List<TaskSummary> getTasksByStatusByProcessInstanceId( long processInstanceId, List<Status> status, String language) { synchronized (ksession) { return taskService.getTasksByStatusByProcessInstanceId(processInstanceId, status, language); } } @Override public List<TaskSummary> getTasksByStatusByProcessInstanceIdByTaskName( long processInstanceId, List<Status> status, String taskName) { synchronized (ksession) { return taskService.getTasksByStatusByProcessInstanceIdByTaskName(processInstanceId, status, taskName); } } @Override public List<Long> getTasksByProcessInstanceId(long processInstanceId) { synchronized (ksession) { return taskService.getTasksByProcessInstanceId(processInstanceId); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwnerByProcessId( String userId, String processId ) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwnerByProcessId(userId, processId); } } @Override public User getUserById(String userId) { synchronized (ksession) { return taskService.getUserById(userId); } } @Override public List<User> getUsers() { synchronized (ksession) { return taskService.getUsers(); } } @Override public long addTask(Task task, Map<String, Object> params) { synchronized (ksession) { return taskService.addTask(task, params); } } @Override public long addTask(Task task, ContentData data) { synchronized (ksession) { return taskService.addTask(task, data); } } @Override public void release(long taskId, String userId) { synchronized (ksession) { taskService.release(taskId, userId); } } @Override public void remove(long taskId, String userId) { synchronized (ksession) { taskService.remove(taskId, userId); } } @Override public void removeGroup(String groupId) { synchronized (ksession) { taskService.removeGroup(groupId); } } @Override public int removeTasks(List<TaskSummary> tasks) { synchronized (ksession) { return taskService.removeTasks(tasks); } } @Override public void removeUser(String userId) { synchronized (ksession) { taskService.removeUser(userId); } } @Override public void resume(long taskId, String userId) { synchronized (ksession) { taskService.resume(taskId, userId); } } @Override public void setFault(long taskId, String userId, FaultData fault) { synchronized (ksession) { taskService.setFault(taskId, userId, fault); } } @Override public void setOutput(long taskId, String userId, Object outputContentData) { synchronized (ksession) { taskService.setOutput(taskId, userId, outputContentData); } } @Override public void setPriority(long taskId, int priority) { synchronized (ksession) { taskService.setPriority(taskId, priority); } } @Override public void setTaskNames(long taskId, List<I18NText> taskNames) { synchronized (ksession) { taskService.setTaskNames(taskId, taskNames); } } @Override public void skip(long taskId, String userId) { synchronized (ksession) { taskService.skip(taskId, userId); } } @Override public void start(long taskId, String userId) { synchronized (ksession) { taskService.start(taskId, userId); } } @Override public void stop(long taskId, String userId) { synchronized (ksession) { taskService.stop(taskId, userId); } } @Override public void suspend(long taskId, String userId) { synchronized (ksession) { taskService.suspend(taskId, userId); } } @Override public void undeployTaskDef(String id) { synchronized (ksession) { taskService.undeployTaskDef(id); } } @Override public List<TaskEvent> getTaskEventsById(long taskId) { synchronized (ksession) { return taskService.getTaskEventsById(taskId); } } @Override public UserInfo getUserInfo() { synchronized (ksession) { return taskService.getUserInfo(); } } @Override public void setUserInfo(UserInfo userInfo) { synchronized (ksession) { taskService.setUserInfo(userInfo); } } @Override public void addUsersAndGroups(Map<String, User> users, Map<String, Group> groups) { synchronized (ksession) { taskService.addUsersAndGroups(users, groups); } } @Override public void nominate(long taskId, String userId, List<OrganizationalEntity> potentialOwners) { synchronized (ksession) { taskService.nominate(taskId, userId, potentialOwners); } } @Override public int removeAllTasks() { synchronized (ksession) { return taskService.removeAllTasks(); } } @Override public long addContent(long taskId, Content content) { synchronized (ksession) { return taskService.addContent(taskId, content); } } @Override public long addContent(long taskId, Map<String, Object> params) { synchronized (ksession) { return taskService.addContent(taskId, params); } } @Override public void deleteContent(long taskId, long contentId) { synchronized (ksession) { taskService.deleteContent(taskId, contentId); } } @Override public List<Content> getAllContentByTaskId(long taskId) { synchronized (ksession) { return taskService.getAllContentByTaskId(taskId); } } @Override public Content getContentById(long contentId) { synchronized (ksession) { return taskService.getContentById(contentId); } } @Override public long addAttachment(long taskId, Attachment attachment, Content content) { synchronized (ksession) { return taskService.addAttachment(taskId, attachment, content); } } @Override public void deleteAttachment(long taskId, long attachmentId) { synchronized (ksession) { taskService.deleteAttachment(taskId, attachmentId); } } @Override public List<Attachment> getAllAttachmentsByTaskId(long taskId) { synchronized (ksession) { return taskService.getAllAttachmentsByTaskId(taskId); } } @Override public Attachment getAttachmentById(long attachId) { synchronized (ksession) { return taskService.getAttachmentById(attachId); } } @Override public void removeTaskEventsById(long taskId) { synchronized (ksession) { taskService.removeTaskEventsById(taskId); } } @Override public OrganizationalEntity getOrganizationalEntityById(String entityId) { synchronized (ksession) { return taskService.getOrganizationalEntityById(entityId); } } @Override public void setExpirationDate(long taskId, Date date) { synchronized (ksession) { taskService.setExpirationDate(taskId, date); } } @Override public void setDescriptions(long taskId, List<I18NText> descriptions) { synchronized (ksession) { taskService.setDescriptions(taskId, descriptions); } } @Override public void setSkipable(long taskId, boolean skipable) { synchronized (ksession) { taskService.setSkipable(taskId, skipable); } } @Override public void setSubTaskStrategy(long taskId, SubTasksStrategy strategy) { synchronized (ksession) { taskService.setSubTaskStrategy(taskId, strategy); } } @Override public int getPriority(long taskId) { synchronized (ksession) { return taskService.getPriority(taskId); } } @Override public Date getExpirationDate(long taskId) { synchronized (ksession) { return taskService.getExpirationDate(taskId); } } @Override public List<I18NText> getDescriptions(long taskId) { synchronized (ksession) { return taskService.getDescriptions(taskId); } } @Override public boolean isSkipable(long taskId) { synchronized (ksession) { return taskService.isSkipable(taskId); } } @Override public SubTasksStrategy getSubTaskStrategy(long taskId) { synchronized (ksession) { return taskService.getSubTaskStrategy(taskId); } } @Override public Task getTaskInstanceById(long taskId) { synchronized (ksession) { return taskService.getTaskInstanceById(taskId); } } @Override public int getCompletedTaskByUserId(String userId) { synchronized (ksession) { return taskService.getCompletedTaskByUserId(userId); } } @Override public int getPendingTaskByUserId(String userId) { synchronized (ksession) { return taskService.getPendingTaskByUserId(userId); } } @Override public List<TaskSummary> getTasksAssignedByGroup(String groupId) { synchronized (ksession) { return taskService.getTasksAssignedByGroup(groupId); } } @Override public List<TaskSummary> getTasksAssignedByGroups(List<String> groupIds) { synchronized (ksession) { return taskService.getTasksAssignedByGroups(groupIds); } } @Override public Long addComment(long taskId, Comment comment) { synchronized (ksession) { return taskService.addComment(taskId, comment); } } @Override public Long addComment( long taskId, String addedByUserId, String commentText ) { synchronized (ksession) { return taskService.addComment(taskId, addedByUserId, commentText); } } @Override public void deleteComment(long taskId, long commentId) { synchronized (ksession) { taskService.deleteComment(taskId, commentId); } } @Override public List<Comment> getAllCommentsByTaskId(long taskId) { synchronized (ksession) { return taskService.getAllCommentsByTaskId(taskId); } } @Override public Comment getCommentById(long commentId) { synchronized (ksession) { return taskService.getCommentById(commentId); } } @Override public Map<String, Object> getTaskContent(long taskId) { synchronized (ksession) { return taskService.getTaskContent(taskId); } } @SuppressWarnings("unchecked") @Override public void registerTaskEventListener(TaskLifeCycleEventListener taskLifecycleEventListener) { synchronized (ksession) { ((EventService<TaskLifeCycleEventListener>)taskService).registerTaskEventListener(taskLifecycleEventListener); } } @SuppressWarnings("unchecked") @Override public List<TaskLifeCycleEventListener> getTaskEventListeners() { synchronized (ksession) { return ((EventService<TaskLifeCycleEventListener>) taskService).getTaskEventListeners(); } } @SuppressWarnings("unchecked") @Override public void clearTaskEventListeners() { synchronized (ksession) { ((EventService<TaskLifeCycleEventListener>) taskService).clearTaskEventListeners(); } } @SuppressWarnings("unchecked") @Override public void removeTaskEventListener(TaskLifeCycleEventListener listener) { synchronized (ksession) { ((EventService<TaskLifeCycleEventListener>) taskService).removeTaskEventListener(listener); } } @Override public <T> T execute(Command<T> command) { synchronized (ksession) { return taskService.execute(command); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDate(String userId, List<Status> statuses, Date expirationDate) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwnerByExpirationDate(userId, statuses, expirationDate); } } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDateOptional(String userId, List<Status> statuses, Date expirationDate) { synchronized (ksession) { return taskService.getTasksAssignedAsPotentialOwnerByExpirationDateOptional(userId, statuses, expirationDate); } } @Override public Map<Long, List<OrganizationalEntity>> getPotentialOwnersForTaskIds(List<Long> taskIds) { synchronized (ksession) { return taskService.getPotentialOwnersForTaskIds(taskIds); } } @Override public void addMarshallerContext(String ownerId, ContentMarshallerContext context) { synchronized (ksession) { if (taskService != null) { taskService.addMarshallerContext(ownerId, context); } } } @Override public void removeMarshallerContext(String ownerId) { synchronized (ksession) { if (taskService != null) { taskService.removeMarshallerContext(ownerId); } } } @Override public ContentMarshallerContext getMarshallerContext(Task task) { synchronized (ksession) { if (taskService != null) { return taskService.getMarshallerContext(task); } return null; } } @Override public List<TaskSummary> getTasksOwned(String userId, List<Status> status, QueryFilter filter) { return taskService.getTasksOwned(userId, status, filter); } @Override public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, List<Status> status, QueryFilter filter) { return taskService.getTasksAssignedAsPotentialOwner(userId, groupIds, status, filter); } @Override public TaskSummaryQueryBuilder taskSummaryQuery( String userId ) { return taskService.taskSummaryQuery(userId); } @Override public List<TaskSummary> getTasksAssignedAsBusinessAdministratorByStatus( String userId, String language, List<Status> statuses ) { synchronized( ksession ) { return taskService.getTasksAssignedAsBusinessAdministratorByStatus(userId, language, statuses); } } @Override public void executeReminderForTask( long taskId, String initiator ) { synchronized( ksession ) { taskService.executeReminderForTask(taskId, initiator); } } @Override public long setDocumentContentFromUser( long taskId, String userId, byte[] byteContent ) { synchronized( ksession ) { return taskService.setDocumentContentFromUser(taskId, userId, byteContent); } } @Override public long addOutputContentFromUser( long taskId, String userId, Map<String, Object> params ) { synchronized( ksession ) { return taskService.addOutputContentFromUser(taskId, userId, params); } } @Override public Content getContentByIdForUser( long contentId, String userId ) { synchronized( ksession ) { return taskService.getContentByIdForUser(contentId, userId); } } @Override public Map<String, Object> getOutputContentMapForUser( long taskId, String userId ) { synchronized( ksession ) { return taskService.getOutputContentMapForUser(taskId, userId); } } }