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 * ldoguin, Antoine Taillefer 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.task.core.service; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.Date; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031import org.apache.commons.lang.StringUtils; 032import org.nuxeo.common.utils.Path; 033import org.nuxeo.ecm.core.api.CoreSession; 034import org.nuxeo.ecm.core.api.DocumentModel; 035import org.nuxeo.ecm.core.api.DocumentModelList; 036import org.nuxeo.ecm.core.api.DocumentNotFoundException; 037import org.nuxeo.ecm.core.api.DocumentRef; 038import org.nuxeo.ecm.core.api.IdRef; 039import org.nuxeo.ecm.core.api.NuxeoException; 040import org.nuxeo.ecm.core.api.NuxeoPrincipal; 041import org.nuxeo.ecm.core.api.PathRef; 042import org.nuxeo.ecm.core.api.SortInfo; 043import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 044import org.nuxeo.ecm.core.api.security.ACE; 045import org.nuxeo.ecm.core.api.security.ACL; 046import org.nuxeo.ecm.core.api.security.ACP; 047import org.nuxeo.ecm.core.api.security.SecurityConstants; 048import org.nuxeo.ecm.platform.ec.notification.NotificationConstants; 049import org.nuxeo.ecm.platform.task.Task; 050import org.nuxeo.ecm.platform.task.TaskConstants; 051import org.nuxeo.ecm.platform.task.TaskEventNames; 052import org.nuxeo.ecm.platform.task.TaskPersisterDescriptor; 053import org.nuxeo.ecm.platform.task.TaskProvider; 054import org.nuxeo.ecm.platform.task.TaskProviderDescriptor; 055import org.nuxeo.ecm.platform.task.TaskService; 056import org.nuxeo.runtime.model.ComponentContext; 057import org.nuxeo.runtime.model.ComponentInstance; 058import org.nuxeo.runtime.model.ComponentName; 059import org.nuxeo.runtime.model.DefaultComponent; 060 061/** 062 * @author <a href="mailto:ldoguin@nuxeo.com">Laurent Doguin</a> 063 * @since 5.5 064 */ 065public class TaskServiceImpl extends DefaultComponent implements TaskService { 066 067 private static final long serialVersionUID = 1L; 068 069 public static final ComponentName NAME = new ComponentName("org.nuxeo.ecm.platform.task.core.TaskService"); 070 071 public static final String DEFAULT_TASK_PROVIDER = "documentTaskProvider"; 072 073 private static final String TASK_PROVIDER_XP = "taskProvider"; 074 075 private static final String TASK_PERSISTER_XP = "taskPersister"; 076 077 private Map<String, TaskProvider> tasksProviders; 078 079 private String parentPath = "/task-root"; 080 081 @Override 082 public void activate(ComponentContext context) { 083 super.activate(context); 084 tasksProviders = new HashMap<String, TaskProvider>(); 085 } 086 087 @Override 088 public void deactivate(ComponentContext context) { 089 super.deactivate(context); 090 tasksProviders = null; 091 } 092 093 @Override 094 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 095 if (extensionPoint.equals(TASK_PROVIDER_XP)) { 096 if (contribution instanceof TaskProviderDescriptor) { 097 TaskProviderDescriptor taskProviderDescriptor = (TaskProviderDescriptor) contribution; 098 String providerId = taskProviderDescriptor.getId(); 099 if (taskProviderDescriptor.isEnabled()) { 100 tasksProviders.put(providerId, taskProviderDescriptor.getNewInstance()); 101 } else { 102 if (tasksProviders.get(providerId) != null) { 103 tasksProviders.remove(providerId); 104 } 105 } 106 } 107 } else if (extensionPoint.equals(TASK_PERSISTER_XP)) { 108 if (contribution instanceof TaskPersisterDescriptor) { 109 TaskPersisterDescriptor taskPersisterDescriptor = (TaskPersisterDescriptor) contribution; 110 parentPath = taskPersisterDescriptor.getPath(); 111 } 112 } 113 } 114 115 @Override 116 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 117 if (extensionPoint.equals(TASK_PROVIDER_XP)) { 118 if (contribution instanceof TaskProviderDescriptor) { 119 TaskProviderDescriptor taskProviderDescriptor = (TaskProviderDescriptor) contribution; 120 String providerId = taskProviderDescriptor.getId(); 121 if (tasksProviders.get(providerId) != null) { 122 tasksProviders.remove(providerId); 123 } 124 } 125 } 126 } 127 128 @Override 129 public List<Task> createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, 130 String taskName, List<String> actorIds, boolean createOneTaskPerActor, String directive, String comment, 131 Date dueDate, Map<String, String> taskVariables, String parentPath) { 132 return createTask(coreSession, principal, document, taskName, null, null, actorIds, createOneTaskPerActor, 133 directive, comment, dueDate, taskVariables, parentPath); 134 } 135 136 /** 137 * @since 5.6 138 */ 139 @Override 140 public List<Task> createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, 141 String taskDocumentType, String taskName, String taskType, String processId, List<String> actorIds, 142 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 143 Map<String, String> taskVariables, String parentPath, Map<String, Serializable> eventInfo) 144 { 145 List<DocumentModel> docs = new ArrayList<DocumentModel>(); 146 docs.add(document); 147 return createTask(coreSession, principal, docs, taskDocumentType, taskName, taskType, processId, actorIds, 148 createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath, eventInfo); 149 } 150 151 /** 152 * @since 5.6 153 */ 154 @Override 155 public List<Task> createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, 156 String taskName, String taskType, String processId, List<String> prefixedActorIds, 157 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 158 Map<String, String> taskVariables, String parentPath) { 159 return createTask(coreSession, principal, document, TaskConstants.TASK_TYPE_NAME, taskName, taskType, 160 processId, prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, 161 parentPath, null); 162 } 163 164 @Override 165 public String acceptTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment) 166 { 167 return endTask(coreSession, principal, task, comment, TaskEventNames.WORKFLOW_TASK_COMPLETED, true); 168 } 169 170 @Override 171 public String rejectTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment) 172 { 173 return endTask(coreSession, principal, task, comment, TaskEventNames.WORKFLOW_TASK_REJECTED, false); 174 } 175 176 /** 177 * Use the task provider held by the {@link Task#TASK_PROVIDER_KEY} task variable to end the {@code task}. If null 178 * use the {@link #DEFAULT_TASK_PROVIDER}. 179 */ 180 @Override 181 public String endTask(CoreSession coreSession, NuxeoPrincipal principal, Task task, String comment, 182 String eventName, boolean isValidated) { 183 184 if (!canEndTask(principal, task)) { 185 throw new NuxeoException(String.format("User with id '%s' cannot end this task", principal.getName())); 186 } 187 String taskProviderId = task.getVariable(Task.TASK_PROVIDER_KEY); 188 if (taskProviderId == null) { 189 taskProviderId = DEFAULT_TASK_PROVIDER; 190 } 191 TaskProvider taskProvider = tasksProviders.get(taskProviderId); 192 if (taskProvider == null) { 193 throw new NuxeoException( 194 String.format( 195 "No task provider registered, cannot end task. Please contribute at least the default task provider: %s.", 196 DEFAULT_TASK_PROVIDER)); 197 } 198 return taskProvider.endTask(coreSession, principal, task, comment, eventName, isValidated); 199 } 200 201 @Override 202 public boolean canEndTask(NuxeoPrincipal principal, Task task) { 203 if (task != null && (!task.isCancelled() && !task.hasEnded())) { 204 return principal.isAdministrator() || principal.getName().equals(task.getInitiator()) 205 || isTaskAssignedToUser(task, principal, true); 206 } 207 return false; 208 } 209 210 protected boolean isTaskAssignedToUser(Task task, NuxeoPrincipal user, boolean checkDelegatedActors) 211 { 212 if (task != null && user != null) { 213 // user actors 214 List<String> actors = user.getAllGroups(); 215 actors.add(user.getName()); 216 217 // initiator 218 if (actors.contains(task.getInitiator())) { 219 return true; 220 } 221 // users 222 List<String> users = task.getActors(); 223 if (checkDelegatedActors) { 224 users.addAll(task.getDelegatedActors()); 225 } 226 if (users != null) { 227 for (String userName : users) { 228 if (userName.contains(":")) { 229 if (actors.contains(userName.split(":")[1])) { 230 return true; 231 } 232 } 233 if (actors.contains(userName)) { 234 return true; 235 } 236 } 237 } 238 } 239 return false; 240 } 241 242 @Override 243 public Task getTask(CoreSession coreSession, String taskId) { 244 DocumentRef docRef = new IdRef(taskId); 245 DocumentModel taskDoc = coreSession.getDocument(docRef); 246 if (taskDoc != null) { 247 Task task = taskDoc.getAdapter(Task.class); 248 if (task != null) { 249 return task; 250 } 251 } 252 return null; 253 } 254 255 @Override 256 public void deleteTask(CoreSession coreSession, String taskId) { 257 final DocumentRef docRef = new IdRef(taskId); 258 UnrestrictedSessionRunner runner = new UnrestrictedSessionRunner(coreSession) { 259 @Override 260 public void run() { 261 session.removeDocument(docRef); 262 } 263 }; 264 runner.runUnrestricted(); 265 } 266 267 @Override 268 public DocumentModel getTargetDocumentModel(Task task, CoreSession coreSession) { 269 try { 270 return coreSession.getDocument(new IdRef(task.getTargetDocumentId())); 271 } catch (DocumentNotFoundException e) { 272 return null; 273 } 274 } 275 276 @Override 277 public List<Task> getCurrentTaskInstances(CoreSession coreSession) { 278 List<Task> tasks = new ArrayList<Task>(); 279 List<Task> newTasks; 280 for (TaskProvider taskProvider : tasksProviders.values()) { 281 newTasks = taskProvider.getCurrentTaskInstances(coreSession); 282 if (newTasks != null) { 283 tasks.addAll(newTasks); 284 } 285 } 286 return tasks; 287 } 288 289 /** 290 * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) 291 * 292 * @since 5.9.3 293 */ 294 @Override 295 public List<Task> getCurrentTaskInstances(CoreSession coreSession, List<SortInfo> sortInfos) { 296 List<Task> tasks = new ArrayList<Task>(); 297 List<Task> newTasks; 298 for (TaskProvider taskProvider : tasksProviders.values()) { 299 newTasks = taskProvider.getCurrentTaskInstances(coreSession, sortInfos); 300 if (newTasks != null) { 301 tasks.addAll(newTasks); 302 } 303 } 304 return tasks; 305 } 306 307 @Override 308 public List<Task> getAllCurrentTaskInstances(CoreSession coreSession, List<SortInfo> sortInfos) { 309 List<Task> tasks = new ArrayList<Task>(); 310 List<Task> newTasks; 311 for (TaskProvider taskProvider : tasksProviders.values()) { 312 newTasks = taskProvider.getAllCurrentTaskInstances(coreSession, 313 sortInfos); 314 if (newTasks != null) { 315 tasks.addAll(newTasks); 316 } 317 } 318 return tasks; 319 } 320 321 /** 322 * Returns a list of task instances assigned to one of the actors in the list or to its pool. 323 * 324 * @param actors a list used as actorId to retrieve the tasks. 325 * @return 326 */ 327 @Override 328 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession) { 329 List<Task> tasks = new ArrayList<Task>(); 330 List<Task> newTasks; 331 for (TaskProvider taskProvider : tasksProviders.values()) { 332 newTasks = taskProvider.getCurrentTaskInstances(actors, coreSession); 333 if (newTasks != null) { 334 tasks.addAll(newTasks); 335 } 336 } 337 return tasks; 338 } 339 340 /** 341 * Provide @param sortInfo to handle sort page-provider contributions (see {@link #getCurrentTaskInstances}) 342 * 343 * @since 5.9.3 344 */ 345 @Override 346 public List<Task> getCurrentTaskInstances(List<String> actors, CoreSession coreSession, List<SortInfo> sortInfos) 347 { 348 List<Task> tasks = new ArrayList<Task>(); 349 List<Task> newTasks; 350 for (TaskProvider taskProvider : tasksProviders.values()) { 351 newTasks = taskProvider.getCurrentTaskInstances(actors, coreSession, sortInfos); 352 if (newTasks != null) { 353 tasks.addAll(newTasks); 354 } 355 } 356 return tasks; 357 } 358 359 @Override 360 public List<Task> getTaskInstances(DocumentModel dm, NuxeoPrincipal user, CoreSession coreSession) 361 { 362 List<Task> tasks = new ArrayList<Task>(); 363 List<Task> newTasks; 364 for (TaskProvider taskProvider : tasksProviders.values()) { 365 newTasks = taskProvider.getTaskInstances(dm, user, coreSession); 366 if (newTasks != null) { 367 tasks.addAll(newTasks); 368 } 369 } 370 return tasks; 371 } 372 373 @Override 374 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, CoreSession coreSession) 375 { 376 List<Task> tasks = new ArrayList<Task>(); 377 List<Task> newTasks; 378 for (TaskProvider taskProvider : tasksProviders.values()) { 379 newTasks = taskProvider.getTaskInstances(dm, actors, coreSession); 380 if (newTasks != null) { 381 tasks.addAll(newTasks); 382 } 383 } 384 return tasks; 385 } 386 387 @Override 388 public List<Task> getAllTaskInstances(String processId, CoreSession session) { 389 List<Task> tasks = new ArrayList<Task>(); 390 List<Task> newTasks; 391 for (TaskProvider taskProvider : tasksProviders.values()) { 392 newTasks = taskProvider.getAllTaskInstances(processId, session); 393 if (newTasks != null) { 394 tasks.addAll(newTasks); 395 } 396 } 397 return tasks; 398 } 399 400 @Override 401 public List<Task> getAllTaskInstances(String processId, NuxeoPrincipal user, CoreSession session) 402 { 403 List<Task> tasks = new ArrayList<Task>(); 404 List<Task> newTasks; 405 for (TaskProvider taskProvider : tasksProviders.values()) { 406 newTasks = taskProvider.getAllTaskInstances(processId, user, session); 407 if (newTasks != null) { 408 tasks.addAll(newTasks); 409 } 410 } 411 return tasks; 412 } 413 414 @Override 415 public List<Task> getAllTaskInstances(String processId, List<String> actors, CoreSession session) 416 { 417 List<Task> tasks = new ArrayList<Task>(); 418 List<Task> newTasks; 419 for (TaskProvider taskProvider : tasksProviders.values()) { 420 newTasks = taskProvider.getAllTaskInstances(processId, actors, session); 421 if (newTasks != null) { 422 tasks.addAll(newTasks); 423 } 424 } 425 return tasks; 426 } 427 428 /** 429 * @deprecated since 5.6 430 */ 431 @Deprecated 432 protected List<Task> wrapDocModelInTask(DocumentModelList taskDocuments) { 433 List<Task> tasks = new ArrayList<Task>(); 434 for (DocumentModel doc : taskDocuments) { 435 tasks.add(doc.getAdapter(Task.class)); 436 } 437 return tasks; 438 } 439 440 @Override 441 public String getTaskRootParentPath(CoreSession coreSession) { 442 GetTaskRootParentPathUnrestricted runner = new GetTaskRootParentPathUnrestricted(coreSession); 443 runner.runUnrestricted(); 444 return runner.getParentPath(); 445 } 446 447 public class GetTaskRootParentPathUnrestricted extends UnrestrictedSessionRunner { 448 449 protected DocumentModel taskRootDoc; 450 451 public GetTaskRootParentPathUnrestricted(CoreSession session) { 452 super(session); 453 } 454 455 @Override 456 public void run() { 457 DocumentRef pathRef = new PathRef(parentPath); 458 if (session.exists(pathRef)) { 459 taskRootDoc = session.getDocument(pathRef); 460 } else { 461 Path path = new Path(parentPath); 462 taskRootDoc = session.createDocumentModel(path.removeLastSegments(1).toString(), path.lastSegment(), 463 TaskConstants.TASK_ROOT_TYPE_NAME); 464 taskRootDoc = session.createDocument(taskRootDoc); 465 ACP acp = taskRootDoc.getACP(); 466 ACL acl = acp.getOrCreateACL(ACL.LOCAL_ACL); 467 acl.add(new ACE("Everyone", "Everything", false)); 468 taskRootDoc.setACP(acp, true); 469 taskRootDoc = session.saveDocument(taskRootDoc); 470 } 471 } 472 473 public DocumentModel getTaskRootDoc() { 474 return taskRootDoc; 475 } 476 477 public String getParentPath() { 478 return taskRootDoc.getPathAsString(); 479 } 480 } 481 482 @Override 483 public List<Task> getAllTaskInstances(String processId, String nodeId, CoreSession session) { 484 List<Task> tasks = new ArrayList<Task>(); 485 List<Task> newTasks; 486 for (TaskProvider taskProvider : tasksProviders.values()) { 487 newTasks = taskProvider.getAllTaskInstances(processId, nodeId, session); 488 if (newTasks != null) { 489 tasks.addAll(newTasks); 490 } 491 } 492 return tasks; 493 } 494 495 @Override 496 public void reassignTask(CoreSession session, final String taskId, final List<String> newActors, 497 final String comment) { 498 499 new UnrestrictedSessionRunner(session) { 500 501 @Override 502 public void run() { 503 DocumentModel taskDoc = session.getDocument(new IdRef(taskId)); 504 Task task = taskDoc.getAdapter(Task.class); 505 if (task == null) { 506 throw new NuxeoException("Invalid taskId: " + taskId); 507 } 508 List<String> currentAssignees = task.getActors(); 509 List<String> currentActors = new ArrayList<String>(); 510 for (String currentAssignee : currentAssignees) { 511 if (currentAssignee.startsWith(NotificationConstants.GROUP_PREFIX) 512 || currentAssignee.startsWith(NotificationConstants.USER_PREFIX)) { 513 // prefixed assignees with "user:" or "group:" 514 currentActors.add(currentAssignee.substring(currentAssignee.indexOf(":") + 1)); 515 } else { 516 currentActors.add(currentAssignee); 517 } 518 } 519 String taskInitator = task.getInitiator(); 520 521 // remove ACLs set for current assignees 522 ACP acp = taskDoc.getACP(); 523 ACL acl = acp.getOrCreateACL(ACL.LOCAL_ACL); 524 List<ACE> toRemove = new ArrayList<ACE>(); 525 526 for (ACE ace : acl.getACEs()) { 527 if (currentActors.contains(ace.getUsername()) || taskInitator.equals(ace.getUsername())) { 528 toRemove.add(ace); 529 } 530 } 531 acl.removeAll(toRemove); 532 533 // grant EVERYTHING on task doc to the new actors 534 List<String> actorIds = new ArrayList<String>(); 535 for (String actor : newActors) { 536 if (actor.startsWith(NotificationConstants.GROUP_PREFIX) 537 || actor.startsWith(NotificationConstants.USER_PREFIX)) { 538 // prefixed assignees with "user:" or "group:" 539 actorIds.add(actor.substring(actor.indexOf(":") + 1)); 540 } else { 541 actorIds.add(actor); 542 } 543 } 544 for (String actorId : actorIds) { 545 acl.add(new ACE(actorId, SecurityConstants.EVERYTHING, true)); 546 } 547 548 taskDoc.setACP(acp, true); 549 task.setActors(actorIds); 550 String currentUser = ((NuxeoPrincipal) session.getPrincipal()).getActingUser(); 551 task.addComment(currentUser, comment); 552 session.saveDocument(taskDoc); 553 554 List<DocumentModel> docs = new ArrayList<DocumentModel>(); 555 for (String string : task.getTargetDocumentsIds()) { 556 docs.add(session.getDocument(new IdRef(string))); 557 558 } 559 notifyEvent(session, task, docs, TaskEventNames.WORKFLOW_TASK_REASSIGNED, 560 new HashMap<String, Serializable>(), comment, (NuxeoPrincipal) session.getPrincipal(), actorIds); 561 562 } 563 }.runUnrestricted(); 564 565 } 566 567 @Override 568 public void delegateTask(CoreSession session, final String taskId, final List<String> delegatedActors, 569 final String comment) { 570 571 new UnrestrictedSessionRunner(session) { 572 @Override 573 public void run() { 574 DocumentModel taskDoc = session.getDocument(new IdRef(taskId)); 575 Task task = taskDoc.getAdapter(Task.class); 576 if (task == null) { 577 throw new NuxeoException("Invalid taskId: " + taskId); 578 } 579 // grant EVERYTHING on task doc to the delegated actors 580 List<String> actorIds = new ArrayList<String>(); 581 ACP acp = taskDoc.getACP(); 582 ACL acl = acp.getOrCreateACL(ACL.LOCAL_ACL); 583 584 for (String actor : delegatedActors) { 585 if (actor.startsWith(NotificationConstants.GROUP_PREFIX) 586 || actor.startsWith(NotificationConstants.USER_PREFIX)) { 587 // prefixed assignees with "user:" or "group:" 588 actorIds.add(actor.substring(actor.indexOf(":") + 1)); 589 } else { 590 actorIds.add(actor); 591 } 592 } 593 for (String actorId : actorIds) { 594 ACE ace = new ACE(actorId, SecurityConstants.EVERYTHING, true); 595 if (!acl.contains(ace)) { 596 acl.add(ace); 597 } 598 } 599 taskDoc.setACP(acp, true); 600 601 List<String> allDelegatedActors = new ArrayList<String>(); 602 allDelegatedActors.addAll(task.getDelegatedActors()); 603 for (String actor : actorIds) { 604 if (!allDelegatedActors.contains(actor)) { 605 allDelegatedActors.add(actor); 606 } 607 } 608 task.setDelegatedActors(allDelegatedActors); 609 610 String currentUser = ((NuxeoPrincipal) session.getPrincipal()).getActingUser(); 611 task.addComment(currentUser, comment); 612 session.saveDocument(taskDoc); 613 List<DocumentModel> docs = new ArrayList<DocumentModel>(); 614 for (String string : task.getTargetDocumentsIds()) { 615 docs.add(session.getDocument(new IdRef(string))); 616 617 } 618 notifyEvent(session, task, docs, TaskEventNames.WORKFLOW_TASK_DELEGATED, 619 new HashMap<String, Serializable>(), 620 String.format("Task delegated by '%s' to '%s'", currentUser, StringUtils.join(actorIds, ",")) 621 + (!StringUtils.isEmpty(comment) ? " with the following comment: " + comment : ""), 622 (NuxeoPrincipal) session.getPrincipal(), actorIds); 623 } 624 625 }.runUnrestricted(); 626 } 627 628 protected void notifyEvent(CoreSession session, Task task, List<DocumentModel> docs, String event, 629 Map<String, Serializable> eventInfo, String comment, NuxeoPrincipal principal, List<String> actorIds) 630 { 631 Map<String, Serializable> eventProperties = new HashMap<String, Serializable>(); 632 ArrayList<String> notificationRecipients = new ArrayList<String>(); 633 notificationRecipients.addAll(actorIds); 634 eventProperties.put(NotificationConstants.RECIPIENTS_KEY, 635 notificationRecipients.toArray(new String[notificationRecipients.size()])); 636 if (eventInfo != null) { 637 eventProperties.putAll(eventInfo); 638 } 639 for (DocumentModel doc : docs) { 640 TaskEventNotificationHelper.notifyEvent(session, doc, principal, task, event, eventProperties, comment, 641 null); 642 } 643 } 644 645 @Override 646 public List<Task> getTaskInstances(DocumentModel dm, List<String> actors, boolean includeDelegatedTasks, 647 CoreSession session) { 648 List<Task> tasks = new ArrayList<Task>(); 649 for (TaskProvider taskProvider : tasksProviders.values()) { 650 tasks.addAll(taskProvider.getTaskInstances(dm, actors, includeDelegatedTasks, session)); 651 } 652 return tasks; 653 } 654 655 /** 656 * @since 5.8 657 * @deprecated since 7.4 use 658 * {@link #org.nuxeo.ecm.platform.task.core.service.TaskServiceImpl.createTaskWithProcessName(CoreSession, 659 * NuxeoPrincipal, List<DocumentModel>, String, String, String, String, String, List<String>, boolean, 660 * String, String, Date, Map<String, String>, String, Map<String, Serializable>) 661 * createTaskWithProcessName} instead 662 */ 663 @Override 664 @Deprecated 665 public List<Task> createTask(CoreSession coreSession, NuxeoPrincipal principal, List<DocumentModel> documents, 666 String taskDocumentType, String taskName, String taskType, String processId, List<String> actorIds, 667 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 668 Map<String, String> taskVariables, String parentPath, Map<String, Serializable> eventInfo) { 669 return createTaskForProcess(coreSession, principal, documents, taskDocumentType, taskName, taskType, processId, 670 null, actorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath, 671 eventInfo); 672 } 673 674 /** 675 * @since 7.4 676 */ 677 @Override 678 public List<Task> createTaskForProcess(CoreSession coreSession, NuxeoPrincipal principal, List<DocumentModel> documents, 679 String taskDocumentType, String taskName, String taskType, String processId, String processName, List<String> actorIds, 680 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 681 Map<String, String> taskVariables, String parentPath, Map<String, Serializable> eventInfo) 682 { 683 if (StringUtils.isBlank(parentPath)) { 684 parentPath = getTaskRootParentPath(coreSession); 685 } 686 CreateTaskUnrestricted runner = new CreateTaskUnrestricted(coreSession, principal, documents, taskDocumentType, 687 taskName, taskType, processId, processName, actorIds, createOneTaskPerActor, directive, comment, 688 dueDate, taskVariables, parentPath); 689 runner.runUnrestricted(); 690 691 List<Task> tasks = runner.getTasks(); 692 693 for (Task task : tasks) { 694 // notify 695 notifyEvent(coreSession, task, documents, TaskEventNames.WORKFLOW_TASK_ASSIGNED, eventInfo, comment, 696 principal, task.getActors()); 697 } 698 return tasks; 699 } 700}