TaskManagerImpl.java 15.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.taskmanagement.Filter
 *  com.adobe.granite.taskmanagement.Task
 *  com.adobe.granite.taskmanagement.TaskAction
 *  com.adobe.granite.taskmanagement.TaskManager
 *  com.adobe.granite.taskmanagement.TaskManagerException
 *  com.adobe.granite.taskmanagement.TaskManagerFactory
 *  com.adobe.granite.taskmanagement.TaskNotFoundException
 *  com.adobe.granite.taskmanagement.TaskSecurityException
 *  com.adobe.granite.workflow.exec.Status
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.osgi.service.event.Event
 *  org.osgi.service.event.EventAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.taskmanagement.impl.service;

import com.adobe.granite.taskmanagement.Filter;
import com.adobe.granite.taskmanagement.Task;
import com.adobe.granite.taskmanagement.TaskAction;
import com.adobe.granite.taskmanagement.TaskManager;
import com.adobe.granite.taskmanagement.TaskManagerException;
import com.adobe.granite.taskmanagement.TaskManagerFactory;
import com.adobe.granite.taskmanagement.TaskNotFoundException;
import com.adobe.granite.taskmanagement.TaskSecurityException;
import com.adobe.granite.taskmanagement.impl.TaskImpl;
import com.adobe.granite.taskmanagement.impl.jcr.TaskStorageProvider;
import com.adobe.granite.taskmanagement.impl.jcr.TaskUserContext;
import com.adobe.granite.taskmanagement.impl.service.TaskManagerFactoryImpl;
import com.adobe.granite.taskmanagement.impl.utils.TaskEventHelper;
import com.adobe.granite.workflow.exec.Status;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class TaskManagerImpl
implements TaskManager {
    private static final Logger logger = LoggerFactory.getLogger(TaskManagerImpl.class);
    protected TaskStorageProvider taskStorageProvider;
    protected TaskUserContext userContextService;
    protected EventAdmin eventAdminService;
    private TaskManagerFactory taskManagerFactory;

    public TaskManagerImpl(Session userSession, EventAdmin eventAdminService, TaskStorageProvider taskStorageProvider, SlingRepository repository, List<String> taskAdminGroupName) {
        this.eventAdminService = eventAdminService;
        this.taskStorageProvider = taskStorageProvider;
        this.userContextService = new TaskUserContext(userSession, repository, taskAdminGroupName);
        this.eventAdminService = eventAdminService;
        this.taskManagerFactory = new TaskManagerFactoryImpl();
    }

    public final Task createTask(Task task) throws TaskManagerException {
        return this.createTask(null, task);
    }

    public Task createTask(String parentTaskId, Task task) throws TaskManagerException {
        logger.trace("createTask called with parentTaskId='{}' task='{}'", (Object)(parentTaskId == null ? "null" : parentTaskId), (Object)(task == null ? "null" : task.toString()));
        if (null == task) {
            throw new TaskManagerException("task was null");
        }
        if (!(task instanceof TaskImpl)) {
            throw new IllegalArgumentException("Invalid task instance.");
        }
        TaskImpl theTask = (TaskImpl)task;
        if (null != theTask.getId()) {
            this.taskStorageProvider.fixId(theTask);
            if (this.taskStorageProvider.exists(theTask.getId())) {
                throw new TaskManagerException(MessageFormat.format("createTask: task id ''{0}'' exists already.", theTask.getId()));
            }
        }
        if (null == theTask.getTaskTypeName()) {
            theTask.setTaskTypeName("default");
        }
        String currentUserId = this.userContextService.getCurrentUserId();
        if (null == theTask.getCurrentAssignee()) {
            theTask.setCurrentAssignee(currentUserId);
        }
        theTask.setCreatedBy(currentUserId);
        theTask.setLastModifiedBy(currentUserId);
        if (!this.userContextService.isValidUserOrGroup(task.getCurrentAssignee())) {
            logger.warn("the user with ID {} was not found. This might indicate that the user does not exist or that the user has never logged in.", (Object)task.getCurrentAssignee());
            throw new TaskManagerException("invalid task ownerId '" + task.getCurrentAssignee() + "'");
        }
        theTask.setStatus(Status.ACTIVE);
        Date now = new Date();
        theTask.setTimeStarted(now);
        theTask.setLastModified(now);
        if (parentTaskId != null && parentTaskId.length() > 0) {
            Task parentTask = this.getTaskWithCheck(parentTaskId, false);
            this.verifyAccess(parentTask, "createTask under parent", true);
        }
        theTask = (TaskImpl)this.taskStorageProvider.create(parentTaskId, theTask);
        if (null != this.eventAdminService) {
            this.eventAdminService.sendEvent((Event)TaskEventHelper.newCreateTaskEvent(theTask));
        }
        return theTask;
    }

    public final Iterator<Task> getTasks(Filter filter) throws TaskManagerException {
        return this.getTasks(filter, 0, -1);
    }

    public final Iterator<Task> getTasks(Filter filter, int startIndex, int length) throws TaskManagerException {
        if (logger.isTraceEnabled()) {
            Object[] arrobject = new Object[3];
            arrobject[0] = filter == null ? "null" : filter.toString();
            arrobject[1] = startIndex;
            arrobject[2] = length;
            logger.trace("getTasks called with filter='{}', startIndex='{}', length='{}'", arrobject);
        }
        if (length == 0) {
            throw new TaskManagerException("Error: You must provide a length which is non-zero");
        }
        if (length < 0) {
            length = -1;
        }
        if (startIndex < 0) {
            throw new TaskManagerException("Error: You must provide a start index which is non-negative ");
        }
        Set<String> taskOwnerIds = null;
        if (!this.userContextService.isCurrentUserTaskAdministrator()) {
            taskOwnerIds = this.userContextService.getOwnerIdsForCurrentUser();
        }
        ArrayList<Task> results = new ArrayList<Task>();
        results.addAll(this.taskStorageProvider.findByFilter(taskOwnerIds, filter, startIndex, length));
        return results.iterator();
    }

    public final Task getTask(String taskId) throws TaskManagerException {
        return this.getTask(taskId, false);
    }

    public Task getTask(String taskId, boolean retrieveSubTasks) throws TaskManagerException {
        logger.trace("getTask called with taskId='{}' and retrieveSubTasks='{}'", (Object)(taskId == null ? "null" : taskId), (Object)retrieveSubTasks);
        if (null == taskId) {
            throw new IllegalArgumentException("task id was null");
        }
        Task result = this.getTaskWithCheck(taskId, retrieveSubTasks);
        this.verifyAccess(result, "getTask", false);
        return result;
    }

    public final Task saveTask(Task task) throws TaskNotFoundException, TaskManagerException {
        return this.saveTask(task, true);
    }

    public Task saveTask(Task task, boolean sendUpdateEvent) throws TaskNotFoundException, TaskManagerException {
        logger.trace("saveTask called with task='{}'", (Object)(task == null ? "null" : task.toString()));
        if (null == task) {
            throw new IllegalArgumentException("task was null");
        }
        if (null == task.getId()) {
            throw new IllegalArgumentException("Task ID is required.");
        }
        if (!(task instanceof TaskImpl)) {
            throw new IllegalArgumentException("Invalid task instance.");
        }
        if (task.getStatus() == Status.COMPLETE) {
            throw new TaskManagerException("Task cannot be completed with this method.  In order to save a task call the saveTask() method");
        }
        TaskImpl savedTask = (TaskImpl)task;
        Task existingTask = this.getTaskWithCheck(savedTask.getId(), false);
        this.verifyAccess(existingTask, "saveTask", true);
        savedTask.setLastModified(new Date());
        savedTask.setLastModifiedBy(this.userContextService.getCurrentUserId());
        savedTask.setStatus(existingTask.getStatus());
        if (StringUtils.isBlank((CharSequence)task.getCurrentAssignee())) {
            task.setCurrentAssignee(existingTask.getCurrentAssignee());
        }
        if (!this.userContextService.isValidUserOrGroup(task.getCurrentAssignee())) {
            logger.warn("the user with ID {} was not found. This might indicate that the user does not exist or that the user has never logged in.", (Object)task.getCurrentAssignee());
            throw new TaskManagerException("invalid task ownerId '" + task.getCurrentAssignee() + "'");
        }
        this.taskStorageProvider.update(savedTask);
        if (null != this.eventAdminService && sendUpdateEvent) {
            this.eventAdminService.sendEvent((Event)TaskEventHelper.newTaskSavedEvent(savedTask));
        }
        return savedTask;
    }

    public final void deleteTask(String taskId) throws TaskNotFoundException, TaskManagerException {
        logger.trace("deleteTask called with taskId='{}'", (Object)(taskId == null ? "null" : taskId));
        if (null == taskId) {
            throw new IllegalArgumentException("Task ID is required.");
        }
        Task task = this.getTaskWithCheck(taskId, false);
        this.verifyAccess(task, "deleteTask", true);
        this.taskStorageProvider.deleteTask(taskId);
        if (null != this.eventAdminService) {
            this.eventAdminService.sendEvent((Event)TaskEventHelper.newTaskDeletedEvent(task));
        }
    }

    private void verifyAccess(Task task, String message, boolean writeAccess) throws TaskManagerException {
        if (this.userContextService != null) {
            Set<String> ownerIds;
            if (this.userContextService.isCurrentUserTaskAdministrator()) {
                return;
            }
            if (this.userContextService.getUserSession() != null) {
                try {
                    if (writeAccess && this.userContextService.getUserSession().hasPermission(task.getId(), "set_property")) {
                        return;
                    }
                    if (!writeAccess && this.userContextService.getUserSession().hasPermission(task.getId(), "read")) {
                        return;
                    }
                }
                catch (RepositoryException e) {
                    // empty catch block
                }
            }
            if ((ownerIds = this.userContextService.getOwnerIdsForCurrentUser()) != null && !ownerIds.contains(task.getCurrentAssignee())) {
                boolean isOwner = false;
                if (task.getParentId() != null) {
                    StringTokenizer tokenizer = new StringTokenizer(task.getParentId(), "/");
                    String parentTaskPath = "";
                    if (tokenizer.hasMoreElements()) {
                        parentTaskPath = tokenizer.nextToken();
                    }
                    while (tokenizer.hasMoreElements() && !isOwner) {
                        if (parentTaskPath.length() != 0) {
                            parentTaskPath = parentTaskPath + "/";
                        }
                        if ((parentTaskPath = parentTaskPath + tokenizer.nextToken()).equals(task.getId())) break;
                        Task parentTask = this.getTaskWithCheck(parentTaskPath, false);
                        if (!ownerIds.contains(parentTask.getCurrentAssignee()) && !ownerIds.contains(parentTask.getCreatedBy())) continue;
                        isOwner = true;
                        break;
                    }
                }
                if (!isOwner) {
                    throw new TaskSecurityException(MessageFormat.format("Security Exception.  User [{0}] does not have access to [{1}] for taskId [{2}]", this.userContextService.getCurrentUserId(), message, task.getId()));
                }
            }
        } else {
            throw new RuntimeException("no userContext set");
        }
    }

    public final void completeTask(String taskId, String actionId) throws TaskNotFoundException, TaskManagerException {
        logger.trace("completeTask called with taskId='{}' and action='{}'", (Object)(taskId == null ? "null" : taskId), (Object)(actionId == null ? "null" : actionId));
        if (null == taskId) {
            throw new IllegalArgumentException("Task Id is required.");
        }
        TaskImpl task = (TaskImpl)this.getTaskWithCheck(taskId, false);
        this.verifyAccess(task, "completeTask", true);
        List<TaskAction> actions = task.getActions();
        if (actionId == null && actions != null && actions.size() != 0) {
            throw new TaskManagerException("No task action specified");
        }
        if (actionId != null) {
            TaskAction selectedAction = null;
            for (TaskAction action : actions) {
                if (action == null || !action.getActionID().equals(actionId)) continue;
                selectedAction = action;
                break;
            }
            if (selectedAction != null) {
                task.setSelectedAction(selectedAction);
            } else {
                throw new TaskManagerException("Current action is invalid");
            }
        }
        task.setLastModified(new Date());
        task.setLastModifiedBy(this.userContextService.getCurrentUserId());
        task.setTimeEnded(new Date());
        task.setCompletedBy(this.userContextService.getCurrentUserId());
        task.setStatus(Status.COMPLETE);
        this.taskStorageProvider.update(task);
        if (null != this.eventAdminService) {
            this.eventAdminService.sendEvent((Event)TaskEventHelper.newTaskCompletedEvent(task));
        }
    }

    public void terminateTask(String taskId) throws TaskNotFoundException, TaskManagerException {
        logger.trace("terminateTask called with taskId='{}'", (Object)(taskId == null ? "null" : taskId));
        if (null == taskId) {
            throw new IllegalArgumentException("Task Id is required.");
        }
        TaskImpl task = (TaskImpl)this.getTaskWithCheck(taskId, false);
        this.verifyAccess(task, "terminateTask", true);
        if (task.getStatus() != Status.ACTIVE) {
            throw new TaskManagerException(MessageFormat.format("Only active tasks can be terminated. TaskId: ''{0}''.", taskId));
        }
        task.setLastModified(new Date());
        task.setLastModifiedBy(this.userContextService.getCurrentUserId());
        task.setTimeEnded(new Date());
        task.setCompletedBy(this.userContextService.getCurrentUserId());
        task.setStatus(Status.TERMINATED);
        this.taskStorageProvider.update(task);
        if (null != this.eventAdminService) {
            this.eventAdminService.sendEvent((Event)TaskEventHelper.newTaskTerminatedEvent(task));
        }
    }

    public TaskManagerFactory getTaskManagerFactory() {
        return this.taskManagerFactory;
    }

    protected Task getTaskWithCheck(String taskId, boolean retrieveSubTasks) throws TaskNotFoundException, TaskManagerException {
        Task result = retrieveSubTasks ? this.taskStorageProvider.readRecursive(taskId) : this.taskStorageProvider.getTask(taskId);
        return result;
    }
}