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