001/* 002 * (C) Copyright 2011-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.util.ArrayList; 021import java.util.Collections; 022import java.util.Date; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.apache.commons.lang3.StringUtils; 028import org.nuxeo.ecm.core.api.CoreSession; 029import org.nuxeo.ecm.core.api.DocumentModel; 030import org.nuxeo.ecm.core.api.NuxeoException; 031import org.nuxeo.ecm.core.api.NuxeoPrincipal; 032import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 033import org.nuxeo.ecm.core.api.security.ACE; 034import org.nuxeo.ecm.core.api.security.ACL; 035import org.nuxeo.ecm.core.api.security.ACP; 036import org.nuxeo.ecm.core.api.security.SecurityConstants; 037import org.nuxeo.ecm.platform.ec.notification.NotificationConstants; 038import org.nuxeo.ecm.platform.task.Task; 039import org.nuxeo.ecm.platform.task.TaskConstants; 040import org.nuxeo.ecm.platform.task.TaskService; 041 042/** 043 * @since 5.5 044 */ 045public class CreateTaskUnrestricted extends UnrestrictedSessionRunner { 046 047 private NuxeoPrincipal principal; 048 049 private DocumentModel document; 050 051 private String taskName; 052 053 /** 054 * @since 5.6 055 */ 056 private String taskType; 057 058 /** 059 * @since 5.6 060 */ 061 private String processId; 062 063 /** 064 * @since 5.6 065 */ 066 private String taskDocumentType; 067 068 private List<String> prefixedActorIds; 069 070 private boolean createOneTaskPerActor; 071 072 private String directive; 073 074 private String comment; 075 076 private Date dueDate; 077 078 private Map<String, String> taskVariables; 079 080 private String parentPath; 081 082 /** 083 * @since 7.4 084 */ 085 private String processName; 086 087 List<Task> tasks = new ArrayList<>(); 088 089 /** 090 * @since 5.8 A task can have many target documents 091 */ 092 protected List<DocumentModel> documents; 093 094 public CreateTaskUnrestricted(CoreSession session, NuxeoPrincipal principal, DocumentModel document, 095 String taskName, List<String> prefixedActorIds, boolean createOneTaskPerActor, String directive, 096 String comment, Date dueDate, Map<String, String> taskVariables, String parentPath) { 097 this(session, principal, document, taskName, null, null, prefixedActorIds, createOneTaskPerActor, directive, 098 comment, dueDate, taskVariables, parentPath); 099 } 100 101 /** 102 * @since 5.6 103 */ 104 public CreateTaskUnrestricted(CoreSession session, NuxeoPrincipal principal, DocumentModel document, 105 String taskName, String taskType, String processId, List<String> prefixedActorIds, 106 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 107 Map<String, String> taskVariables, String parentPath) { 108 super(session); 109 this.principal = principal; 110 this.document = document; 111 this.taskName = taskName; 112 this.taskType = taskType; 113 this.processId = processId; 114 this.prefixedActorIds = prefixedActorIds; 115 this.createOneTaskPerActor = createOneTaskPerActor; 116 this.directive = directive; 117 this.comment = comment; 118 this.dueDate = dueDate; 119 this.taskVariables = taskVariables; 120 this.parentPath = parentPath; 121 this.documents = new ArrayList<>(); 122 this.documents.add(document); 123 } 124 125 /** 126 * @since 5.6 127 */ 128 public CreateTaskUnrestricted(CoreSession session, NuxeoPrincipal principal, DocumentModel document, 129 String taskDocumentType, String taskName, String taskType, String processId, List<String> prefixedActorIds, 130 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 131 Map<String, String> taskVariables, String parentPath) { 132 this(session, principal, document, taskName, taskType, processId, prefixedActorIds, createOneTaskPerActor, 133 directive, comment, dueDate, taskVariables, parentPath); 134 this.taskDocumentType = taskDocumentType; 135 } 136 137 /** 138 * @since 5.8 139 */ 140 public CreateTaskUnrestricted(CoreSession session, NuxeoPrincipal principal, List<DocumentModel> documents, 141 String taskDocumentType, String taskName, String taskType, String processId, List<String> prefixedActorIds, 142 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 143 Map<String, String> taskVariables, String parentPath) { 144 this(session, principal, documents != null && documents.size() > 0 ? documents.get(0) : null, taskName, 145 taskType, processId, prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, 146 taskVariables, parentPath); 147 this.taskDocumentType = taskDocumentType; 148 this.documents = documents; 149 if (this.documents != null && this.documents.size() > 0) { 150 this.document = documents.get(0); 151 } 152 } 153 154 /** 155 * @since 7.4 156 */ 157 public CreateTaskUnrestricted(CoreSession session, NuxeoPrincipal principal, List<DocumentModel> documents, 158 String taskDocumentType, String taskName, String taskType, String processId, String processName, 159 List<String> prefixedActorIds, boolean createOneTaskPerActor, String directive, String comment, 160 Date dueDate, Map<String, String> taskVariables, String parentPath) { 161 this(session, principal, documents != null && documents.size() > 0 ? documents.get(0) : null, taskName, 162 taskType, processId, prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, 163 taskVariables, parentPath); 164 this.taskDocumentType = taskDocumentType; 165 this.documents = documents; 166 this.processName = processName; 167 if (this.documents != null && this.documents.size() > 0) { 168 this.document = documents.get(0); 169 } 170 } 171 172 @Override 173 public void run() { 174 if (StringUtils.isEmpty(taskDocumentType)) { 175 taskDocumentType = TaskConstants.TASK_TYPE_NAME; 176 } 177 createTask(session, principal, documents, taskDocumentType, taskName, taskType, processId, processName, 178 prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath); 179 } 180 181 /** 182 * @since 5.6 183 */ 184 public void createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, 185 String taskDocumentType, String taskName, String taskType, String processId, List<String> prefixedActorIds, 186 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 187 Map<String, String> taskVariables, String parentPath) { 188 List<DocumentModel> docs = new ArrayList<>(); 189 docs.add(document); 190 createTask(coreSession, principal, docs, taskDocumentType, taskName, taskType, processId, prefixedActorIds, 191 createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath); 192 193 } 194 195 /** 196 * @since 5.8 197 */ 198 public void createTask(CoreSession coreSession, NuxeoPrincipal principal, List<DocumentModel> documents, 199 String taskDocumentType, String taskName, String taskType, String processId, List<String> prefixedActorIds, 200 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 201 Map<String, String> taskVariables, String parentPath) { 202 createTask(coreSession, principal, documents, taskDocumentType, taskName, taskType, processId, null, 203 prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath); 204 } 205 206 /** 207 * @since 7.4 208 */ 209 public void createTask(CoreSession coreSession, NuxeoPrincipal principal, List<DocumentModel> documents, 210 String taskDocumentType, String taskName, String taskType, String processId, String processName, 211 List<String> prefixedActorIds, boolean createOneTaskPerActor, String directive, String comment, 212 Date dueDate, Map<String, String> taskVariables, String parentPath) { 213 if (createOneTaskPerActor) { 214 for (String prefixedActorId : prefixedActorIds) { 215 createTask(coreSession, principal, documents, taskDocumentType, taskName, taskType, processId, 216 Collections.singletonList(prefixedActorId), false, directive, comment, dueDate, taskVariables, 217 parentPath); 218 } 219 } else { 220 // use task type as a docName (is actually the nodeId so it 221 // doesn't contain "/" characters), but fallback on task name 222 // if task type is null (for old API kept for compat) 223 String docName = taskType == null ? taskName : taskType; 224 DocumentModel taskDocument = session.createDocumentModel(parentPath, docName, taskDocumentType); 225 Task task = taskDocument.getAdapter(Task.class); 226 if (task == null) { 227 throw new NuxeoException("Document " + taskDocumentType + " can not be adapted to a Task"); 228 } 229 task.setName(taskName); 230 task.setType(taskType); 231 task.setProcessId(processId); 232 task.setProcessName(processName); 233 task.setCreated(new Date()); 234 task.setInitiator(principal.getActingUser()); 235 task.setActors(prefixedActorIds); 236 task.setDueDate(dueDate); 237 238 if (documents != null) { 239 List<String> docIds = new ArrayList<>(); 240 for (DocumentModel doc : documents) { 241 docIds.add(doc.getId()); 242 } 243 task.setTargetDocumentsIds(docIds); 244 } 245 task.setDirective(directive); 246 247 if (!StringUtils.isEmpty(comment)) { 248 task.addComment(principal.getName(), comment); 249 } 250 251 // add variables 252 Map<String, String> variables = new HashMap<>(); 253 if (document != null) { 254 variables.put(TaskService.VariableName.documentId.name(), document.getId()); 255 variables.put(TaskService.VariableName.documentRepositoryName.name(), document.getRepositoryName()); 256 } 257 variables.put(TaskService.VariableName.directive.name(), directive); 258 variables.put(TaskService.VariableName.createdFromTaskService.name(), "true"); 259 if (taskVariables != null) { 260 variables.putAll(taskVariables); 261 } 262 task.setVariables(variables); 263 264 // create document in order to set its ACP 265 taskDocument = session.createDocument(taskDocument); 266 267 // re-fetch task from task document to set its id 268 task = taskDocument.getAdapter(Task.class); 269 270 // Set rights 271 List<String> actorIds = new ArrayList<>(); 272 for (String actor : prefixedActorIds) { 273 if (actor.startsWith(NotificationConstants.GROUP_PREFIX) 274 || actor.startsWith(NotificationConstants.USER_PREFIX)) { 275 // prefixed assignees with "user:" or "group:" 276 actorIds.add(actor.substring(actor.indexOf(":") + 1)); 277 } else { 278 actorIds.add(actor); 279 } 280 } 281 ACP acp = taskDocument.getACP(); 282 ACL acl = acp.getOrCreateACL(ACL.LOCAL_ACL); 283 if (principal != null) { 284 acl.add(new ACE(principal.getName(), SecurityConstants.EVERYTHING, true)); 285 286 } 287 for (String actorId : actorIds) { 288 acl.add(new ACE(actorId, SecurityConstants.EVERYTHING, true)); 289 } 290 acp.addACL(acl); 291 taskDocument.setACP(acp, true); 292 taskDocument = session.saveDocument(taskDocument); 293 tasks.add(task); 294 } 295 } 296 297 public void createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, String taskName, 298 List<String> prefixedActorIds, boolean createOneTaskPerActor, String directive, String comment, 299 Date dueDate, Map<String, String> taskVariables, String parentPath) { 300 createTask(coreSession, principal, document, TaskConstants.TASK_TYPE_NAME, taskName, null, null, 301 prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath); 302 } 303 304 public List<Task> getTasks() { 305 return tasks; 306 } 307 308}