/* * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. * * 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. * * Contributors: */ package org.nuxeo.ecm.platform.task.core.service; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.NuxeoException; import org.nuxeo.ecm.core.api.NuxeoPrincipal; import org.nuxeo.ecm.core.api.SortInfo; import org.nuxeo.ecm.platform.query.api.PageProvider; import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; import org.nuxeo.ecm.platform.query.api.PageProviderService; import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; import org.nuxeo.ecm.platform.task.Task; import org.nuxeo.ecm.platform.task.TaskEventNames; import org.nuxeo.ecm.platform.task.TaskProvider; import org.nuxeo.ecm.platform.task.TaskQueryConstant; import org.nuxeo.ecm.platform.task.TaskService; import org.nuxeo.ecm.platform.task.core.helpers.TaskActorsHelper; import org.nuxeo.runtime.api.Framework; /** * @author Laurent Doguin * @author Antoine Taillefer * @since 5.5 */ public class DocumentTaskProvider implements TaskProvider { private static final long serialVersionUID = 1L; @Override public List<Task> getCurrentTaskInstances(CoreSession coreSession) { // Get tasks for current user // We need to build the task actors list: prefixed and unprefixed names // of the principal and all its groups NuxeoPrincipal principal = (NuxeoPrincipal) coreSession.getPrincipal(); List<String> actors = TaskActorsHelper.getTaskActors(principal); return getCurrentTaskInstances(actors, coreSession); } /** * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) * * @since 5.9.3 */ @Override public List<Task> getCurrentTaskInstances(CoreSession coreSession, List<SortInfo> sortInfos) { // Get tasks for current user // We need to build the task actors list: prefixed and unprefixed names // of the principal and all its groups NuxeoPrincipal principal = (NuxeoPrincipal) coreSession.getPrincipal(); List<String> actors = TaskActorsHelper.getTaskActors(principal); return getCurrentTaskInstances(actors, coreSession, sortInfos); } /** * Returns a list of task instances assigned to one of the actors in the list or to its pool. * * @param actors a list used as actorId to retrieve the tasks. * @param filter * @return */ @Override public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession) { if (actors == null || actors.isEmpty()) { return new ArrayList<Task>(); } return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, null, actors); } /** * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) * * @since 5.9.3 */ @Override public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession, List<SortInfo> sortInfos) { if (actors == null || actors.isEmpty()) { return new ArrayList<Task>(); } return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, sortInfos, actors); } @Override public List<Task> getTaskInstances(DocumentModel dm, NuxeoPrincipal user, CoreSession coreSession) { if (user == null) { return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_PP, coreSession, true, null, dm.getId(), dm.getId()); } else { List<String> actors = TaskActorsHelper.getTaskActors(user); return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, dm.getId(), dm.getId(), actors); } } @Override public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, CoreSession coreSession) { if (actors == null || actors.isEmpty()) { return new ArrayList<Task>(); } return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, dm.getId(), dm.getId(), actors); } @Override public List<Task> getAllTaskInstances(String processId, CoreSession session) { return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_PP, session, true, null, processId); } @Override public List<Task> getAllTaskInstances(String processId, NuxeoPrincipal user, CoreSession session) { List<String> actors = TaskActorsHelper.getTaskActors(user); return getAllTaskInstances(processId, actors, session); } @Override public List<Task> getAllTaskInstances(String processId, List<String> actors, CoreSession session) { return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_ACTORS_PP, session, true, null, processId, actors); } /** * Converts a {@link DocumentModelList} to a list of {@link Task}s. * * @since 6.0 * @param taskDocuments */ public static List<Task> wrapDocModelInTask(List<DocumentModel> taskDocuments) { List<Task> tasks = new ArrayList<Task>(); for (DocumentModel doc : taskDocuments) { tasks.add(doc.getAdapter(Task.class)); } return tasks; } /** * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. */ @Deprecated public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments) { return wrapDocModelInTask(taskDocuments, false); } /** * Converts a {@link DocumentModelList} to a list of {@link Task}s. * * @param detach if {@code true}, detach each document before converting it to a {@code Task}. * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. */ @Deprecated public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments, boolean detach) { List<Task> tasks = new ArrayList<Task>(); for (DocumentModel doc : taskDocuments) { if (detach) { doc.detach(true); } tasks.add(doc.getAdapter(Task.class)); } return tasks; } @Override public String endTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment, String eventName, boolean isValidated) { // put user comment on the task if (!StringUtils.isEmpty(comment)) { task.addComment(principal.getName(), comment); } // end the task, adding boolean marker that task was validated or // rejected task.setVariable(TaskService.VariableName.validated.name(), String.valueOf(isValidated)); task.end(coreSession); // make sure taskDoc is attached to prevent sending event with null session DocumentModel taskDocument = task.getDocument(); if (taskDocument.getSessionId() == null) { taskDocument.attach(coreSession.getSessionId()); } coreSession.saveDocument(taskDocument); if (StringUtils.isNotBlank(eventName)) { TaskEventNotificationHelper.notifyTaskEnded(coreSession, principal, task, comment, eventName, null); } String seamEventName = isValidated ? TaskEventNames.WORKFLOW_TASK_COMPLETED : TaskEventNames.WORKFLOW_TASK_REJECTED; return seamEventName; } @Override public List<Task> getAllTaskInstances(String processId, String nodeId, CoreSession session) { return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_NODE_PP, session, true, null, processId, nodeId); } @Override public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, boolean includeDelegatedTasks, CoreSession session) { if (includeDelegatedTasks) { return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_OR_DELEGATED_ACTORS_PP, session, true, null, dm.getId(), dm.getId(), actors, actors); } else { return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, session, true, null, dm.getId(), dm.getId(), actors); } } @Override public List<Task> getAllCurrentTaskInstances(CoreSession session, List<SortInfo> sortInfos) { // Get tasks for current user // We need to build the task actors list: prefixed and unprefixed names // of the principal and all its groups NuxeoPrincipal principal = (NuxeoPrincipal) session.getPrincipal(); List<String> actors = TaskActorsHelper.getTaskActors(principal); return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_OR_DELEGATED_ACTORS_PP, session, true, sortInfos, actors, actors); } /** * @since 6.0 */ @SuppressWarnings("unchecked") public static List<Task> getTasks(String pageProviderName, CoreSession session, boolean unrestricted, List<SortInfo> sortInfos, Object... params) { PageProviderService ppService = Framework.getService(PageProviderService.class); if (ppService == null) { throw new RuntimeException("Missing PageProvider service"); } Map<String, Serializable> props = new HashMap<String, Serializable>(); // first retrieve potential props from definition PageProviderDefinition def = ppService.getPageProviderDefinition(pageProviderName); if (def != null) { Map<String, String> defProps = def.getProperties(); if (defProps != null) { props.putAll(defProps); } } props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) session); if (unrestricted) { props.put(CoreQueryDocumentPageProvider.USE_UNRESTRICTED_SESSION_PROPERTY, Boolean.TRUE); } PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) ppService.getPageProvider(pageProviderName, sortInfos, null, null, props, params); if (pp == null) { throw new NuxeoException("Page provider not found: " + pageProviderName); } return wrapDocModelInTask(pp.getCurrentPage()); } }