001/* 002 * (C) Copyright 2011 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.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.lang.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<Task>(); 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<DocumentModel>(); 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, List<String> prefixedActorIds, 159 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 160 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, prefixedActorIds, 178 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<DocumentModel>(); 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, List<String> prefixedActorIds, 211 boolean createOneTaskPerActor, String directive, String comment, Date dueDate, 212 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 if (principal != null) { 235 String username = principal.getActingUser(); 236 task.setInitiator(username); 237 } 238 task.setActors(prefixedActorIds); 239 task.setDueDate(dueDate); 240 241 if (documents != null) { 242 List<String> docIds = new ArrayList<String>(); 243 for (DocumentModel doc : documents) { 244 docIds.add(doc.getId()); 245 } 246 task.setTargetDocumentsIds(docIds); 247 } 248 task.setDirective(directive); 249 250 if (!StringUtils.isEmpty(comment)) { 251 task.addComment(principal.getName(), comment); 252 } 253 254 // add variables 255 Map<String, String> variables = new HashMap<String, String>(); 256 if (document != null) { 257 variables.put(TaskService.VariableName.documentId.name(), document.getId()); 258 variables.put(TaskService.VariableName.documentRepositoryName.name(), document.getRepositoryName()); 259 } 260 variables.put(TaskService.VariableName.directive.name(), directive); 261 variables.put(TaskService.VariableName.createdFromTaskService.name(), "true"); 262 if (taskVariables != null) { 263 variables.putAll(taskVariables); 264 } 265 task.setVariables(variables); 266 267 // create document in order to set its ACP 268 taskDocument = session.createDocument(taskDocument); 269 270 // re-fetch task from task document to set its id 271 task = taskDocument.getAdapter(Task.class); 272 273 // Set rights 274 List<String> actorIds = new ArrayList<String>(); 275 for (String actor : prefixedActorIds) { 276 if (actor.startsWith(NotificationConstants.GROUP_PREFIX) 277 || actor.startsWith(NotificationConstants.USER_PREFIX)) { 278 // prefixed assignees with "user:" or "group:" 279 actorIds.add(actor.substring(actor.indexOf(":") + 1)); 280 } else { 281 actorIds.add(actor); 282 } 283 } 284 ACP acp = taskDocument.getACP(); 285 ACL acl = acp.getOrCreateACL(ACL.LOCAL_ACL); 286 if (principal != null) { 287 acl.add(new ACE(principal.getName(), SecurityConstants.EVERYTHING, true)); 288 289 } 290 for (String actorId : actorIds) { 291 acl.add(new ACE(actorId, SecurityConstants.EVERYTHING, true)); 292 } 293 acp.addACL(acl); 294 taskDocument.setACP(acp, true); 295 taskDocument = session.saveDocument(taskDocument); 296 tasks.add(task); 297 } 298 } 299 300 public void createTask(CoreSession coreSession, NuxeoPrincipal principal, DocumentModel document, String taskName, 301 List<String> prefixedActorIds, boolean createOneTaskPerActor, String directive, String comment, 302 Date dueDate, Map<String, String> taskVariables, String parentPath) { 303 createTask(coreSession, principal, document, TaskConstants.TASK_TYPE_NAME, taskName, null, null, 304 prefixedActorIds, createOneTaskPerActor, directive, comment, dueDate, taskVariables, parentPath); 305 } 306 307 public List<Task> getTasks() { 308 return tasks; 309 } 310 311}