001/* 002 * (C) Copyright 2009-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 * Alexandre Russel 018 * Florent Guillaume 019 */ 020package org.nuxeo.ecm.platform.routing.api; 021 022import java.io.Serializable; 023import java.net.URL; 024import java.util.List; 025import java.util.Map; 026 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.DocumentRef; 031import org.nuxeo.ecm.core.api.NuxeoPrincipal; 032import org.nuxeo.ecm.platform.routing.api.exception.DocumentRouteAlredayLockedException; 033import org.nuxeo.ecm.platform.routing.api.exception.DocumentRouteException; 034import org.nuxeo.ecm.platform.routing.api.exception.DocumentRouteNotLockedException; 035import org.nuxeo.ecm.platform.task.Task; 036import org.nuxeo.runtime.model.RuntimeContext; 037 038/** 039 * The DocumentRoutingService allows manipulation of {@link DocumentRoute DocumentRoutes}. 040 */ 041public interface DocumentRoutingService { 042 043 /** 044 * Creates a new route instance and optionally starts it. 045 * <p> 046 * If {@code startInstance = false}, then the route can be started later by calling {@link #startInstance}. 047 * 048 * @param routeModelId the route model id 049 * @param docIds the list of document bound to the instance 050 * @param map the values to pass as initial workflow variables 051 * @param session the session 052 * @param startInstance if the route is automatically started 053 * @return the created route instance id 054 */ 055 String createNewInstance(String routeModelId, List<String> docIds, Map<String, Serializable> map, 056 CoreSession session, boolean startInstance); 057 058 /** 059 * Creates a new route instance and optionally starts it. 060 * <p> 061 * If {@code startInstance = false}, then the route can be started later by calling {@link #startInstance}. 062 * 063 * @param routeModelId the route model id 064 * @param docIds The list of document bound to the instance. 065 * @param session the session 066 * @param startInstance if the route is automatically started 067 * @return the created route instance id 068 */ 069 String createNewInstance(String routeModelId, List<String> docIds, CoreSession session, boolean startInstance); 070 071 /** 072 * Create a new {@link DocumentRoute} instance from this {@link DocumentRoute} model. 073 * 074 * @param model The model used to create the instance. 075 * @param documentIds The list of document bound to the instance. 076 * @param startInstance if the {@link DocumentRoute} is automatically started. 077 * @return the created {@link DocumentRoute} instance. 078 */ 079 DocumentRoute createNewInstance(DocumentRoute model, List<String> documentIds, CoreSession session, 080 boolean startInstance); 081 082 /** 083 * @deprecated since 5.6, use other APIs 084 */ 085 @Deprecated 086 DocumentRoute createNewInstance(DocumentRoute model, String documentId, CoreSession session, boolean startInstance); 087 088 /** 089 * @deprecated since 5.6, use other APIs 090 */ 091 @Deprecated 092 DocumentRoute createNewInstance(DocumentRoute model, List<String> documentIds, CoreSession session); 093 094 /** 095 * @deprecated since 5.6, use other APIs 096 */ 097 @Deprecated 098 DocumentRoute createNewInstance(DocumentRoute model, String documentId, CoreSession session); 099 100 /** 101 * Starts an instance that was created with {@link #createNewInstance} but with {@code startInstance = false}. 102 * 103 * @param routeInstanceId the route instance id 104 * @param docIds the list of document bound to the instance 105 * @param map the values to pass as initial workflow variables 106 * @param session the session 107 * @since 5.7.2 108 */ 109 void startInstance(String routeInstanceId, List<String> docIds, Map<String, Serializable> map, CoreSession session); 110 111 /** 112 * Resumes a route instance on a give node. Any remaining tasks on this node will be cancelled. 113 * <p/> 114 * Called by the UI action corresponding to a task button. 115 * <p/> 116 * If all attached documents of the workflow instance have been deleted then the workflow is cancelled. 117 * 118 * @param routeId the id of the route instance 119 * @param nodeId the node id to resume on 120 * @param data the data coming from UI form 121 * @param status the status coming from UI form 122 * @param session the session 123 * @since 5.6 124 */ 125 void resumeInstance(String routeId, String nodeId, Map<String, Object> data, String status, CoreSession session); 126 127 /** 128 * Completes a task on a give node. If this is the last task the workflow will continue. 129 * <p/> 130 * Called by the UI action corresponding to a task button. 131 * 132 * @param routeId the id of the route instance 133 * @param taskId the id of the task 134 * @param data the data coming from UI form 135 * @param status the status coming from UI form 136 * @param session the session 137 * @since 5.6 138 */ 139 void completeTask(String routeId, String taskId, Map<String, Object> data, String status, CoreSession session); 140 141 /** 142 * Save a route instance as a new model of route. 143 * <p/> 144 * The place in which the new instance is persisted and its name depends on {@link DocumentRoutingPersister}. The 145 * route instance should be in either running, done or ready state. The new route model will be in draft state and 146 * won't have any attached documents. 147 * 148 * @param route the instance from which we create a new model. 149 * @return the new model in draft state. 150 */ 151 DocumentRoute saveRouteAsNewModel(DocumentRoute route, CoreSession session); 152 153 /** 154 * Return the list of available {@link DocumentRoute} model the user can start. 155 * 156 * @param session The session of the user. 157 * @return A list of available {@link DocumentRoute} 158 */ 159 List<DocumentRoute> getAvailableDocumentRouteModel(CoreSession session); 160 161 /** 162 * Return the list of available {@link DocumentRoute} document route. 163 * 164 * @param session The session of the user. 165 * @return A list of available {@link DocumentRoute} 166 * @since 7.2 167 */ 168 List<DocumentRoute> getAvailableDocumentRoute(CoreSession session); 169 170 /** 171 * Return the operation chain to run for a documentType. The document type should extend the DocumentRouteStep. Use 172 * the <code>chainsToType</code> extension point to contribute new mapping. 173 * 174 * @deprecated since 5.9.2 - Use only routes of type 'graph' 175 * @param documentType The document type 176 * @return The operation chain id. 177 */ 178 @Deprecated 179 String getOperationChainId(String documentType); 180 181 /** 182 * Return the operation chain to undo a step when the step is in running state. The document type should extend the 183 * DocumentRouteStep. Use the <code>chainsToType</code> extension point to contribute new mapping. 184 * 185 * @deprecated since 5.9.2 - Use only routes of type 'graph' 186 * @param documentType 187 * @return 188 */ 189 @Deprecated 190 String getUndoFromRunningOperationChainId(String documentType); 191 192 /** 193 * Return the operation chain to undo a step when the step is in done state. The document type should extend the 194 * DocumentRouteStep. Use the <code>chainsToType</code> extension point to contribute new mapping. 195 * 196 * @param documentType 197 * @return 198 */ 199 String getUndoFromDoneOperationChainId(String documentType); 200 201 /** 202 * Validates the given {@link DocumentRoute} model by changing its lifecycle state and setting it and all its 203 * children in ReadOnly. 204 * 205 * @return The validated route. 206 */ 207 DocumentRoute validateRouteModel(DocumentRoute routeModel, CoreSession session) 208 throws DocumentRouteNotLockedException; 209 210 /** 211 * Unlock the given {@link DocumentRoute} model under unrestricted session. 212 * 213 * @param routeModel 214 * @param userSession 215 * @return The unlocked route. 216 * @since 1.9 217 */ 218 public DocumentRoute unlockDocumentRouteUnrestrictedSession(final DocumentRoute routeModel, CoreSession userSession); 219 220 /** 221 * Computes the list of elements {@link DocumentRouteTableElement} for this {@link DocumentRoute}. 222 * 223 * @param routeDocument {@link DocumentRoute}. 224 * @param session The session used to query the {@link DocumentRoute}. 225 * @param A list of {@link DocumentRouteElement} 226 */ 227 List<DocumentRouteTableElement> getRouteElements(DocumentRoute route, CoreSession session); 228 229 /** 230 * Return the list of related {@link DocumentRoute} in a state for a given attached document. 231 * 232 * @param session The session used to query the {@link DocumentRoute}. 233 * @param states the list of states. 234 * @return A list of available {@link DocumentRoute} 235 */ 236 List<DocumentRoute> getDocumentRoutesForAttachedDocument(CoreSession session, String attachedDocId, 237 List<DocumentRouteElement.ElementLifeCycleState> states); 238 239 /** 240 * @param session 241 * @param attachedDocId 242 * @return 243 * @see #getDocumentRoutesForAttachedDocument(CoreSession, String, List) for route running or ready. 244 */ 245 List<DocumentRoute> getDocumentRoutesForAttachedDocument(CoreSession session, String attachedDocId); 246 247 /** 248 * if the user can validate a route. 249 * 250 * @deprecated use {@link #canValidateRoute(DocumentModel, CoreSession)} instead. 251 */ 252 @Deprecated 253 boolean canUserValidateRoute(NuxeoPrincipal currentUser); 254 255 /** 256 * Checks if the principal that created the client session can validate the route 257 * 258 * @param documentRoute 259 * @param coreSession 260 */ 261 boolean canValidateRoute(DocumentModel documentRoute, CoreSession coreSession); 262 263 /** 264 * Add a route element in another route element. 265 * 266 * @deprecated since 5.9.2 - Use only routes of type 'graph' 267 * @param parentDocumentRef The DocumentRef of the parent document. 268 * @param idx The position of the document in its container. 269 * @param routeElement The document to add. 270 * @param session 271 */ 272 @Deprecated 273 void addRouteElementToRoute(DocumentRef parentDocumentRef, int idx, DocumentRouteElement routeElement, 274 CoreSession session) throws DocumentRouteNotLockedException; 275 276 /** 277 * Add a route element in another route element. 278 * <p/> 279 * If the parent element is in draft state, the routeElement is kept in draft state. Otherwise, the element is set 280 * to 'ready' state. 281 * 282 * @deprecated since 5.9.2 - Use only routes of type 'graph' 283 * @param parentDocumentRef The DocumentRef of the parent document. 284 * @param sourceName the name of the previous document in the container. 285 * @param routeElement the document to add. 286 * @param session 287 */ 288 @Deprecated 289 void addRouteElementToRoute(DocumentRef parentDocumentRef, String sourceName, DocumentRouteElement routeElement, 290 CoreSession session) throws DocumentRouteNotLockedException; 291 292 /** 293 * Remove the given route element 294 * 295 * @deprecated since 5.9.2 - Use only routes of type 'graph' 296 * @param The route element document. 297 * @param session 298 */ 299 @Deprecated 300 void removeRouteElement(DocumentRouteElement routeElement, CoreSession session) 301 throws DocumentRouteNotLockedException; 302 303 /** 304 * Get the children of the given stepFolder ordered by the ecm:pos metadata. 305 * 306 * @deprecated since 5.9.2 - Use only routes of type 'graph' 307 * @param stepFolderId 308 * @param session 309 * @return 310 */ 311 @Deprecated 312 DocumentModelList getOrderedRouteElement(String routeElementId, CoreSession session); 313 314 /** 315 * Locks this {@link DocumentRoute} if not already locked by the current user. If the document is already locked by 316 * another user and {@link DocumentRouteAlredayLockedException} is thrown 317 * 318 * @param routeDocument {@link DocumentRoute}. 319 * @param session The session used to lock the {@link DocumentRoute}. 320 * @throws {@link DocumentRouteAlredayLockedException} 321 */ 322 void lockDocumentRoute(DocumentRoute routeModel, CoreSession session) throws DocumentRouteAlredayLockedException; 323 324 /** 325 * Unlocks this {@link DocumentRoute}.If the document is not locked throws a {@link DocumentRouteNotLockedException} 326 * 327 * @param routeDocument {@link DocumentRoute}. 328 * @param session The session used to lock the {@link DocumentRoute}. 329 */ 330 void unlockDocumentRoute(DocumentRoute routeModel, CoreSession session) throws DocumentRouteNotLockedException; 331 332 /** 333 * Update the given route element 334 * 335 * @param The route element document. 336 * @param session 337 */ 338 void updateRouteElement(DocumentRouteElement routeModel, CoreSession session) 339 throws DocumentRouteNotLockedException; 340 341 /** 342 * Verify is this {@link DocumentRoute} is already locked by the current user. 343 * 344 * @param routeDocument {@link DocumentRoute}. 345 * @param session 346 */ 347 boolean isLockedByCurrentUser(DocumentRoute routeModel, CoreSession session); 348 349 /** 350 * Checks if the given document can be associated to a DocumentRoute. 351 * 352 * @param doc the document 353 * @return {@code true} if the document can be routed 354 */ 355 boolean isRoutable(DocumentModel doc); 356 357 /** 358 * Imports all the route models resource templates. 359 * 360 * @param session the core session to use 361 * 362 * @since 7.3 363 */ 364 void importAllRouteModels(CoreSession session); 365 366 /** 367 * Creates a route model in the root models folder defined by the current persister. The templateResource is a zip 368 * tree xml export of a route document and it is imported using the core-io importer. 369 * 370 * @param templateResource 371 * @param overwrite 372 * @param session 373 * @since 5.6 374 */ 375 DocumentRoute importRouteModel(URL templateResource, boolean overwrite, CoreSession session); 376 377 /** 378 * Registers a new route model template to be imported at application startup. 379 * 380 * @param resource the resource 381 * @since 5.6 382 */ 383 void registerRouteResource(RouteModelResourceType resource, RuntimeContext extensionContext); 384 385 /** 386 * Returns all the route models resource templates. Use the <code>routeModelImporter</code> extension point to 387 * contribute new resources. 388 * 389 * @since 5.6 390 */ 391 List<URL> getRouteModelTemplateResources(); 392 393 /** 394 * Returns the route models matching the {@code searchString}. 395 * 396 * @since 5.6 397 */ 398 List<DocumentModel> searchRouteModels(CoreSession session, String searchString); 399 400 /** 401 * Returns the route model with the given id 402 * 403 * @since 5.6 404 */ 405 DocumentRoute getRouteModelWithId(CoreSession session, String id); 406 407 // copied from the deprecated RoutingTaskService 408 409 /** 410 * Returns the doc id of the route model with the given id 411 * 412 * @since 5.7 413 */ 414 String getRouteModelDocIdWithId(CoreSession session, String id); 415 416 /** 417 * Marks the tasks as Routing tasks. 418 * <p> 419 * This allows the related documents to be adapted to {@link RoutingTask}. 420 * 421 * @param session the session 422 * @param tasks the tasks 423 * @since 5.6, was on RoutingTaskService before 424 * 425 * @deprecated The facet RoutingTask is statically attached to the new 426 * RoutingTask Document type since 7.1 427 */ 428 @Deprecated 429 void makeRoutingTasks(CoreSession session, List<Task> tasks); 430 431 /** 432 * Ends a task. If this is the last task the workflow will continue. 433 * 434 * @param session 435 * @param task 436 * @param data 437 * @param status name of the button clicked to submit the task form 438 * @since 5.6, was on RoutingTaskService before 439 */ 440 void endTask(CoreSession session, Task task, Map<String, Object> data, String status); 441 442 /** 443 * Grants on these documents the specified assignees permissions for this task. 444 * 445 * @param session the session 446 * @param permission the permission 447 * @param docs the documents 448 * @param task the task 449 * @since 5.6 450 */ 451 void grantPermissionToTaskAssignees(CoreSession session, String permission, List<DocumentModel> docs, Task task); 452 453 /** 454 * Removes on these documents the specified assignees permissions for this task. 455 * 456 * @param session the session 457 * @param docs the documents 458 * @param task the task 459 * @since 5.6 460 */ 461 void removePermissionFromTaskAssignees(CoreSession session, List<DocumentModel> docs, Task task); 462 463 /** 464 * Gets the documents following the workflow to which the given task belongs 465 * 466 * @param session 467 * @param task 468 * @return 469 * @since 5.6, was on RoutingTaskService before 470 */ 471 List<DocumentModel> getWorkflowInputDocuments(CoreSession session, Task task); 472 473 /** 474 * Finishes an open task. All permissions granted to the tasks assignees on the document following the worklflow are 475 * removed. Doesn't resume the workflow as the <code>completeTask</code> method. Not executed using an unrestricted 476 * session. 477 * 478 * @param session 479 * @param route 480 * @param task 481 * @param delete 482 * @throws DocumentRouteException 483 * @since 5.7 484 * @deprecated // will be removed in 5.8, use completeTask instead 485 */ 486 void finishTask(CoreSession session, DocumentRoute route, Task task, boolean delete) throws DocumentRouteException; 487 488 /** 489 * Cancels an open task. If the task was created by an workflow, all permissions granted to the tasks assignees on 490 * the document following the worklflow are removed. Doesn't resume the workflow as the <code>completeTask</code> 491 * method. 492 * 493 * @param session 494 * @param task 495 * @param delete 496 * @throws DocumentRouteException 497 * @since 5.7.3 498 */ 499 void cancelTask(CoreSession session, String taskId) throws DocumentRouteException; 500 501 /** 502 * Reassigns the given task to the list of actors. Removes the permissions granted on the document following the 503 * workflow to the current task assignees and grants them to the new actors. 504 * 505 * @param session 506 * @param taskId 507 * @param actors 508 * @param comment 509 * @since 5.7.3 510 */ 511 void reassignTask(CoreSession session, String taskId, List<String> actors, String comment) 512 throws DocumentRouteException; 513 514 /** 515 * Reassigns the given task to the list of actors. Grants to new delegated actors the same permissions as the task 516 * assignees on the document following the workflow . 517 * 518 * @param session 519 * @param taskId 520 * @param delegatedActors 521 * @param comment 522 * @since 5.8 523 */ 524 void delegateTask(CoreSession session, String taskId, List<String> delegatedActors, String comment) 525 throws DocumentRouteException; 526 527 /** 528 * Grants on these documents the specified assignees permissions for this task to the tasks delegated actors. 529 * 530 * @param session the session 531 * @param permission the permission 532 * @param docs the documents 533 * @param task the task 534 * @since 5.8 535 */ 536 void grantPermissionToTaskDelegatedActors(CoreSession session, String permission, List<DocumentModel> docs, 537 Task task); 538 539 /** 540 * Removes on these documents the specified assignees permissions for the task actors and also tasks delegated 541 * actors if this task was delegated 542 * 543 * @param session the session 544 * @param docs the documents 545 * @param task the task 546 * @since 5.8 547 */ 548 void removePermissionsForTaskActors(CoreSession session, List<DocumentModel> docs, Task task); 549 550 /** 551 * Removes on these documents the specified assignees permissions for the task actors and also tasks delegated 552 * actors if this task was delegated 553 * 554 * @param session the session 555 * @param docs the documents 556 * @param taskId the taskId 557 * @since 7.4 558 */ 559 void removePermissionsForTaskActors(CoreSession session, List<DocumentModel> docs, String taskId); 560 561 /** 562 * Query for the routes 'done' or 'canceled' and delete them. The max no of the routes that will be deleted is 563 * specified by the 'limit' parameter. When the limit is '0' all the completed routes are deleted. The routes to be 564 * deleted are ordered ascending by their creation date. 565 * 566 * @since 5.8 567 */ 568 void cleanupDoneAndCanceledRouteInstances(String repositoryName, int limit); 569 570 /** 571 * @since 5.9.3 572 */ 573 void invalidateRouteModelsCache(); 574 575 /** 576 * Query for the routes 'done' or 'canceled' and delete them. The max no of the routes that will be deleted is 577 * specified by the 'limit' parameter. When the limit is '0' all the completed routes are deleted. The routes to be 578 * deleted are ordered ascending by their creation date. 579 * 580 * @return the number of cleaned up workflow instance 581 * @since 7.1 582 */ 583 int doCleanupDoneAndCanceledRouteInstances(String reprositoryName, int limit); 584 585 /** 586 * @param userId 587 * @param workflowInstanceId 588 * @param session 589 * @return 590 * @since 7.2 591 */ 592 List<Task> getTasks(final DocumentModel document, String actorId, String workflowInstanceId, 593 String workflowModelName, CoreSession session); 594 595 /** 596 * @param document 597 * @param session 598 * @return 599 * @since 7.2 600 */ 601 List<DocumentRoute> getDocumentRelatedWorkflows(final DocumentModel document, final CoreSession session); 602 603 /** 604 * @since 7.2 605 */ 606 List<DocumentRoute> getRunningWorkflowInstancesLaunchedByCurrentUser(final CoreSession session); 607 608 /** 609 * @since 7.2 610 */ 611 List<DocumentRoute> getRunningWorkflowInstancesLaunchedByCurrentUser(CoreSession session, String worflowModelName); 612 613 /** 614 * Returns true id the document route is a model, false if it is just an instance i.e. a running workflow. 615 * 616 * @since 7.2 617 */ 618 boolean isWorkflowModel(final DocumentRoute documentRoute); 619 620}