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