001/* 002 * (C) Copyright 2012-2018 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 */ 018package org.nuxeo.ecm.platform.task.core.service; 019 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.apache.commons.lang3.StringUtils; 027import org.nuxeo.ecm.core.api.CoreSession; 028import org.nuxeo.ecm.core.api.DocumentModel; 029import org.nuxeo.ecm.core.api.DocumentModelList; 030import org.nuxeo.ecm.core.api.NuxeoException; 031import org.nuxeo.ecm.core.api.NuxeoPrincipal; 032import org.nuxeo.ecm.core.api.SortInfo; 033import org.nuxeo.ecm.platform.query.api.PageProvider; 034import org.nuxeo.ecm.platform.query.api.PageProviderDefinition; 035import org.nuxeo.ecm.platform.query.api.PageProviderService; 036import org.nuxeo.ecm.platform.query.nxql.CoreQueryDocumentPageProvider; 037import org.nuxeo.ecm.platform.task.Task; 038import org.nuxeo.ecm.platform.task.TaskEventNames; 039import org.nuxeo.ecm.platform.task.TaskProvider; 040import org.nuxeo.ecm.platform.task.TaskQueryConstant; 041import org.nuxeo.ecm.platform.task.TaskService; 042import org.nuxeo.ecm.platform.task.core.helpers.TaskActorsHelper; 043import org.nuxeo.runtime.api.Framework; 044 045/** 046 * @author Laurent Doguin 047 * @author Antoine Taillefer 048 * @since 5.5 049 */ 050public class DocumentTaskProvider implements TaskProvider { 051 052 private static final long serialVersionUID = 1L; 053 054 @Override 055 public List<Task> getCurrentTaskInstances(CoreSession coreSession) { 056 057 // Get tasks for current user 058 // We need to build the task actors list: prefixed and unprefixed names 059 // of the principal and all its groups 060 NuxeoPrincipal principal = coreSession.getPrincipal(); 061 List<String> actors = TaskActorsHelper.getTaskActors(principal); 062 063 return getCurrentTaskInstances(actors, coreSession); 064 } 065 066 /** 067 * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) 068 * 069 * @since 5.9.3 070 */ 071 @Override 072 public List<Task> getCurrentTaskInstances(CoreSession coreSession, List<SortInfo> sortInfos) { 073 074 // Get tasks for current user 075 // We need to build the task actors list: prefixed and unprefixed names 076 // of the principal and all its groups 077 NuxeoPrincipal principal = coreSession.getPrincipal(); 078 List<String> actors = TaskActorsHelper.getTaskActors(principal); 079 080 return getCurrentTaskInstances(actors, coreSession, sortInfos); 081 } 082 083 /** 084 * Returns a list of task instances assigned to one of the actors in the list or to its pool. 085 * 086 * @param actors a list used as actorId to retrieve the tasks. 087 */ 088 @Override 089 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession) { 090 if (actors == null || actors.isEmpty()) { 091 return new ArrayList<>(); 092 } 093 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, null, actors); 094 } 095 096 /** 097 * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) 098 * 099 * @since 5.9.3 100 */ 101 @Override 102 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession, List<SortInfo> sortInfos) { 103 if (actors == null || actors.isEmpty()) { 104 return new ArrayList<>(); 105 } 106 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, sortInfos, actors); 107 } 108 109 @Override 110 public List<Task> getTaskInstances(DocumentModel dm, NuxeoPrincipal user, CoreSession coreSession) { 111 if (user == null) { 112 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_PP, coreSession, true, null, dm.getId(), 113 dm.getId()); 114 } else { 115 List<String> actors = TaskActorsHelper.getTaskActors(user); 116 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, 117 dm.getId(), dm.getId(), actors); 118 } 119 } 120 121 @Override 122 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, CoreSession coreSession) { 123 if (actors == null || actors.isEmpty()) { 124 return new ArrayList<>(); 125 } 126 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, 127 dm.getId(), dm.getId(), actors); 128 } 129 130 @Override 131 public List<Task> getAllTaskInstances(String processId, CoreSession session) { 132 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_PP, session, true, null, processId); 133 } 134 135 @Override 136 public List<Task> getAllTaskInstances(String processId, NuxeoPrincipal user, CoreSession session) { 137 List<String> actors = TaskActorsHelper.getTaskActors(user); 138 return getAllTaskInstances(processId, actors, session); 139 } 140 141 @Override 142 public List<Task> getAllTaskInstances(String processId, List<String> actors, CoreSession session) { 143 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_ACTORS_PP, session, true, null, processId, actors); 144 } 145 146 /** 147 * Converts a {@link DocumentModelList} to a list of {@link Task}s. 148 * 149 * @since 6.0 150 */ 151 public static List<Task> wrapDocModelInTask(List<DocumentModel> taskDocuments) { 152 List<Task> tasks = new ArrayList<>(); 153 for (DocumentModel doc : taskDocuments) { 154 tasks.add(doc.getAdapter(Task.class)); 155 } 156 return tasks; 157 } 158 159 /** 160 * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. 161 */ 162 @Deprecated 163 public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments) { 164 return wrapDocModelInTask(taskDocuments, false); 165 } 166 167 /** 168 * Converts a {@link DocumentModelList} to a list of {@link Task}s. 169 * 170 * @param detach if {@code true}, detach each document before converting it to a {@code Task}. 171 * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. 172 */ 173 @Deprecated 174 public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments, boolean detach) { 175 List<Task> tasks = new ArrayList<>(); 176 for (DocumentModel doc : taskDocuments) { 177 if (detach) { 178 doc.detach(true); 179 } 180 tasks.add(doc.getAdapter(Task.class)); 181 } 182 return tasks; 183 } 184 185 @Override 186 public String endTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment, 187 String eventName, boolean isValidated) { 188 189 // put user comment on the task 190 if (!StringUtils.isEmpty(comment)) { 191 task.addComment(principal.getName(), comment); 192 } 193 194 // end the task, adding boolean marker that task was validated or 195 // rejected 196 task.setVariable(TaskService.VariableName.validated.name(), String.valueOf(isValidated)); 197 task.end(coreSession); 198 // make sure taskDoc is attached to prevent sending event with null session 199 DocumentModel taskDocument = task.getDocument(); 200 if (!taskDocument.isAttached()) { 201 taskDocument.attach(coreSession); 202 } 203 coreSession.saveDocument(taskDocument); 204 if (StringUtils.isNotBlank(eventName)) { 205 TaskEventNotificationHelper.notifyTaskEnded(coreSession, principal, task, comment, eventName, null); 206 } 207 return isValidated ? TaskEventNames.WORKFLOW_TASK_COMPLETED : TaskEventNames.WORKFLOW_TASK_REJECTED; 208 } 209 210 @Override 211 public List<Task> getAllTaskInstances(String processId, String nodeId, CoreSession session) { 212 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_NODE_PP, session, true, null, processId, nodeId); 213 } 214 215 @Override 216 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, boolean includeDelegatedTasks, 217 CoreSession session) { 218 if (includeDelegatedTasks) { 219 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_OR_DELEGATED_ACTORS_PP, session, 220 true, null, dm.getId(), dm.getId(), actors, actors); 221 } else { 222 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, session, true, null, 223 dm.getId(), dm.getId(), actors); 224 } 225 } 226 227 @Override 228 public List<Task> getAllCurrentTaskInstances(CoreSession session, List<SortInfo> sortInfos) { 229 // Get tasks for current user 230 // We need to build the task actors list: prefixed and unprefixed names 231 // of the principal and all its groups 232 NuxeoPrincipal principal = session.getPrincipal(); 233 List<String> actors = TaskActorsHelper.getTaskActors(principal); 234 235 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_OR_DELEGATED_ACTORS_PP, session, true, sortInfos, actors, 236 actors); 237 } 238 239 /** 240 * @since 6.0 241 */ 242 @SuppressWarnings("unchecked") 243 public static List<Task> getTasks(String pageProviderName, CoreSession session, boolean unrestricted, 244 List<SortInfo> sortInfos, Object... params) { 245 PageProviderService ppService = Framework.getService(PageProviderService.class); 246 if (ppService == null) { 247 throw new RuntimeException("Missing PageProvider service"); 248 } 249 Map<String, Serializable> props = new HashMap<>(); 250 // first retrieve potential props from definition 251 PageProviderDefinition def = ppService.getPageProviderDefinition(pageProviderName); 252 if (def != null) { 253 Map<String, String> defProps = def.getProperties(); 254 if (defProps != null) { 255 props.putAll(defProps); 256 } 257 } 258 props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) session); 259 if (unrestricted) { 260 props.put(CoreQueryDocumentPageProvider.USE_UNRESTRICTED_SESSION_PROPERTY, Boolean.TRUE); 261 } 262 PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) ppService.getPageProvider(pageProviderName, 263 sortInfos, null, null, props, params); 264 if (pp == null) { 265 throw new NuxeoException("Page provider not found: " + pageProviderName); 266 } 267 return wrapDocModelInTask(pp.getCurrentPage()); 268 } 269 270}