001/* 002 * (C) Copyright 2012 Nuxeo SA (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.lang.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 = (NuxeoPrincipal) 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 = (NuxeoPrincipal) 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 * @param filter 088 * @return 089 */ 090 @Override 091 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession) { 092 if (actors == null || actors.isEmpty()) { 093 return new ArrayList<Task>(); 094 } 095 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, null, actors); 096 } 097 098 /** 099 * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) 100 * 101 * @since 5.9.3 102 */ 103 @Override 104 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession, List<SortInfo> sortInfos) 105 { 106 if (actors == null || actors.isEmpty()) { 107 return new ArrayList<Task>(); 108 } 109 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_PP, coreSession, true, sortInfos, actors); 110 } 111 112 @Override 113 public List<Task> getTaskInstances(DocumentModel dm, NuxeoPrincipal user, CoreSession coreSession) 114 { 115 if (user == null) { 116 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_PP, coreSession, true, null, dm.getId(), 117 dm.getId()); 118 } else { 119 List<String> actors = TaskActorsHelper.getTaskActors(user); 120 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, 121 dm.getId(), dm.getId(), actors); 122 } 123 } 124 125 @Override 126 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, CoreSession coreSession) 127 { 128 if (actors == null || actors.isEmpty()) { 129 return new ArrayList<Task>(); 130 } 131 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, coreSession, true, null, 132 dm.getId(), dm.getId(), actors); 133 } 134 135 @Override 136 public List<Task> getAllTaskInstances(String processId, CoreSession session) { 137 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_PP, session, true, null, processId); 138 } 139 140 @Override 141 public List<Task> getAllTaskInstances(String processId, NuxeoPrincipal user, CoreSession session) 142 { 143 List<String> actors = TaskActorsHelper.getTaskActors(user); 144 return getAllTaskInstances(processId, actors, session); 145 } 146 147 @Override 148 public List<Task> getAllTaskInstances(String processId, List<String> actors, CoreSession session) 149 { 150 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_ACTORS_PP, session, true, null, processId, actors); 151 } 152 153 /** 154 * Converts a {@link DocumentModelList} to a list of {@link Task}s. 155 * 156 * @since 6.0 157 * @param taskDocuments 158 */ 159 public static List<Task> wrapDocModelInTask(List<DocumentModel> taskDocuments) { 160 List<Task> tasks = new ArrayList<Task>(); 161 for (DocumentModel doc : taskDocuments) { 162 tasks.add(doc.getAdapter(Task.class)); 163 } 164 return tasks; 165 } 166 167 /** 168 * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. 169 */ 170 @Deprecated 171 public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments) { 172 return wrapDocModelInTask(taskDocuments, false); 173 } 174 175 /** 176 * Converts a {@link DocumentModelList} to a list of {@link Task}s. 177 * 178 * @param detach if {@code true}, detach each document before converting it to a {@code Task}. 179 * @deprecated since 6.0, use {@link #wrapDocModelInTask(List)} instead. 180 */ 181 @Deprecated 182 public static List<Task> wrapDocModelInTask(DocumentModelList taskDocuments, boolean detach) { 183 List<Task> tasks = new ArrayList<Task>(); 184 for (DocumentModel doc : taskDocuments) { 185 if (detach) { 186 doc.detach(true); 187 } 188 tasks.add(doc.getAdapter(Task.class)); 189 } 190 return tasks; 191 } 192 193 @Override 194 public String endTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment, 195 String eventName, boolean isValidated) { 196 197 // put user comment on the task 198 if (!StringUtils.isEmpty(comment)) { 199 task.addComment(principal.getName(), comment); 200 } 201 202 // end the task, adding boolean marker that task was validated or 203 // rejected 204 task.setVariable(TaskService.VariableName.validated.name(), String.valueOf(isValidated)); 205 task.end(coreSession); 206 // make sure taskDoc is attached to prevent sending event with null session 207 DocumentModel taskDocument = task.getDocument(); 208 if (taskDocument.getSessionId() == null) { 209 taskDocument.attach(coreSession.getSessionId()); 210 } 211 coreSession.saveDocument(taskDocument); 212 if (StringUtils.isNotBlank(eventName)) { 213 TaskEventNotificationHelper.notifyTaskEnded(coreSession, principal, task, comment, eventName, null); 214 } 215 String seamEventName = isValidated ? TaskEventNames.WORKFLOW_TASK_COMPLETED 216 : TaskEventNames.WORKFLOW_TASK_REJECTED; 217 return seamEventName; 218 } 219 220 221 222 @Override 223 public List<Task> getAllTaskInstances(String processId, String nodeId, CoreSession session) { 224 return getTasks(TaskQueryConstant.GET_TASKS_FOR_PROCESS_AND_NODE_PP, session, true, null, processId, nodeId); 225 } 226 227 @Override 228 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, boolean includeDelegatedTasks, 229 CoreSession session) { 230 if (includeDelegatedTasks) { 231 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_OR_DELEGATED_ACTORS_PP, 232 session, true, null, dm.getId(), dm.getId(), actors, actors); 233 } else { 234 return getTasks(TaskQueryConstant.GET_TASKS_FOR_TARGET_DOCUMENTS_AND_ACTORS_PP, session, true, null, 235 dm.getId(), dm.getId(), actors); 236 } 237 } 238 239 @Override 240 public List<Task> getAllCurrentTaskInstances(CoreSession session, 241 List<SortInfo> sortInfos) { 242 // Get tasks for current user 243 // We need to build the task actors list: prefixed and unprefixed names 244 // of the principal and all its groups 245 NuxeoPrincipal principal = (NuxeoPrincipal) session.getPrincipal(); 246 List<String> actors = TaskActorsHelper.getTaskActors(principal); 247 248 return getTasks(TaskQueryConstant.GET_TASKS_FOR_ACTORS_OR_DELEGATED_ACTORS_PP, session, true, sortInfos, 249 actors, actors); 250 } 251 252 /** 253 * @since 6.0 254 */ 255 @SuppressWarnings("unchecked") 256 public static List<Task> getTasks(String pageProviderName, CoreSession session, boolean unrestricted, 257 List<SortInfo> sortInfos, Object... params) { 258 PageProviderService ppService = Framework.getService(PageProviderService.class); 259 if (ppService == null) { 260 throw new RuntimeException("Missing PageProvider service"); 261 } 262 Map<String, Serializable> props = new HashMap<String, Serializable>(); 263 // first retrieve potential props from definition 264 PageProviderDefinition def = ppService.getPageProviderDefinition(pageProviderName); 265 if (def != null) { 266 Map<String, String> defProps = def.getProperties(); 267 if (defProps != null) { 268 props.putAll(defProps); 269 } 270 } 271 props.put(CoreQueryDocumentPageProvider.CORE_SESSION_PROPERTY, (Serializable) session); 272 if (unrestricted) { 273 props.put(CoreQueryDocumentPageProvider.USE_UNRESTRICTED_SESSION_PROPERTY, Boolean.TRUE); 274 } 275 PageProvider<DocumentModel> pp = (PageProvider<DocumentModel>) ppService.getPageProvider(pageProviderName, 276 sortInfos, null, null, props, params); 277 if (pp == null) { 278 throw new NuxeoException("Page provider not found: " + pageProviderName); 279 } 280 return wrapDocModelInTask(pp.getCurrentPage()); 281 } 282 283}