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 */ 187 @Deprecated 188 String getUndoFromRunningOperationChainId(String documentType); 189 190 /** 191 * Return the operation chain to undo a step when the step is in done state. The document type should extend the 192 * DocumentRouteStep. Use the <code>chainsToType</code> extension point to contribute new mapping. 193 */ 194 String getUndoFromDoneOperationChainId(String documentType); 195 196 /** 197 * Validates the given {@link DocumentRoute} model by changing its lifecycle state and setting it and all its 198 * children in ReadOnly. 199 * 200 * @return The validated route. 201 */ 202 DocumentRoute validateRouteModel(DocumentRoute routeModel, CoreSession session) 203 throws DocumentRouteNotLockedException; 204 205 /** 206 * Unlock the given {@link DocumentRoute} model under unrestricted session. 207 * 208 * @return The unlocked route. 209 * @since 1.9 210 */ 211 DocumentRoute unlockDocumentRouteUnrestrictedSession(final DocumentRoute routeModel, CoreSession userSession); 212 213 /** 214 * Computes the list of elements {@link DocumentRouteTableElement} for this {@link DocumentRoute}. 215 * 216 * @param route {@link DocumentRoute}. 217 * @param session The session used to query the {@link DocumentRoute}. 218 */ 219 List<DocumentRouteTableElement> getRouteElements(DocumentRoute route, CoreSession session); 220 221 /** 222 * Return the list of related {@link DocumentRoute} in a state for a given attached document. 223 * 224 * @param session The session used to query the {@link DocumentRoute}. 225 * @param states the list of states. 226 * @return A list of available {@link DocumentRoute} 227 */ 228 List<DocumentRoute> getDocumentRoutesForAttachedDocument(CoreSession session, String attachedDocId, 229 List<DocumentRouteElement.ElementLifeCycleState> states); 230 231 /** 232 * @see #getDocumentRoutesForAttachedDocument(CoreSession, String, List) for route running or ready. 233 */ 234 List<DocumentRoute> getDocumentRoutesForAttachedDocument(CoreSession session, String attachedDocId); 235 236 /** 237 * if the user can validate a route. 238 * 239 * @deprecated use {@link #canValidateRoute(DocumentModel, CoreSession)} instead. 240 */ 241 @Deprecated 242 boolean canUserValidateRoute(NuxeoPrincipal currentUser); 243 244 /** 245 * Checks if the principal that created the client session can validate the route 246 */ 247 boolean canValidateRoute(DocumentModel documentRoute, CoreSession coreSession); 248 249 /** 250 * Add a route element in another route element. 251 * 252 * @deprecated since 5.9.2 - Use only routes of type 'graph' 253 * @param parentDocumentRef The DocumentRef of the parent document. 254 * @param idx The position of the document in its container. 255 * @param routeElement The document to add. 256 */ 257 @Deprecated 258 void addRouteElementToRoute(DocumentRef parentDocumentRef, int idx, DocumentRouteElement routeElement, 259 CoreSession session) throws DocumentRouteNotLockedException; 260 261 /** 262 * Add a route element in another route element. 263 * <p> 264 * If the parent element is in draft state, the routeElement is kept in draft state. Otherwise, the element is set 265 * to 'ready' state. 266 * 267 * @deprecated since 5.9.2 - Use only routes of type 'graph' 268 * @param parentDocumentRef The DocumentRef of the parent document. 269 * @param sourceName the name of the previous document in the container. 270 * @param routeElement the document to add. 271 */ 272 @Deprecated 273 void addRouteElementToRoute(DocumentRef parentDocumentRef, String sourceName, DocumentRouteElement routeElement, 274 CoreSession session) throws DocumentRouteNotLockedException; 275 276 /** 277 * Remove the given route element 278 * 279 * @deprecated since 5.9.2 - Use only routes of type 'graph' 280 */ 281 @Deprecated 282 void removeRouteElement(DocumentRouteElement routeElement, CoreSession session) 283 throws DocumentRouteNotLockedException; 284 285 /** 286 * Get the children of the given stepFolder ordered by the ecm:pos metadata. 287 * 288 * @deprecated since 5.9.2 - Use only routes of type 'graph' 289 */ 290 @Deprecated 291 DocumentModelList getOrderedRouteElement(String routeElementId, CoreSession session); 292 293 /** 294 * Locks this {@link DocumentRoute} if not already locked by the current user. If the document is already locked by 295 * another user and {@link DocumentRouteAlredayLockedException} is thrown 296 * 297 * @param session The session used to lock the {@link DocumentRoute}. 298 */ 299 void lockDocumentRoute(DocumentRoute routeModel, CoreSession session) throws DocumentRouteAlredayLockedException; 300 301 /** 302 * Unlocks this {@link DocumentRoute}.If the document is not locked throws a {@link DocumentRouteNotLockedException} 303 * 304 * @param session The session used to lock the {@link DocumentRoute}. 305 */ 306 void unlockDocumentRoute(DocumentRoute routeModel, CoreSession session) throws DocumentRouteNotLockedException; 307 308 /** 309 * Update the given route element 310 */ 311 void updateRouteElement(DocumentRouteElement routeModel, CoreSession session) 312 throws DocumentRouteNotLockedException; 313 314 /** 315 * Verify is this {@link DocumentRoute} is already locked by the current user. 316 */ 317 boolean isLockedByCurrentUser(DocumentRoute routeModel, CoreSession session); 318 319 /** 320 * Checks if the given document can be associated to a DocumentRoute. 321 * 322 * @param doc the document 323 * @return {@code true} if the document can be routed 324 */ 325 boolean isRoutable(DocumentModel doc); 326 327 /** 328 * Imports all the route models resource templates. 329 * 330 * @param session the core session to use 331 * 332 * @since 7.3 333 */ 334 void importAllRouteModels(CoreSession session); 335 336 /** 337 * Creates a route model in the root models folder defined by the current persister. The templateResource is a zip 338 * tree xml export of a route document and it is imported using the core-io importer. 339 * 340 * @since 5.6 341 */ 342 DocumentRoute importRouteModel(URL templateResource, boolean overwrite, CoreSession session); 343 344 /** 345 * Registers a new route model template to be imported at application startup. 346 * 347 * @param resource the resource 348 * @since 5.6 349 */ 350 void registerRouteResource(RouteModelResourceType resource, RuntimeContext extensionContext); 351 352 /** 353 * Returns all the route models resource templates. Use the <code>routeModelImporter</code> extension point to 354 * contribute new resources. 355 * 356 * @since 5.6 357 */ 358 List<URL> getRouteModelTemplateResources(); 359 360 /** 361 * Returns the route models matching the {@code searchString}. 362 * 363 * @since 5.6 364 */ 365 List<DocumentModel> searchRouteModels(CoreSession session, String searchString); 366 367 /** 368 * Returns the route model with the given id 369 * 370 * @since 5.6 371 */ 372 DocumentRoute getRouteModelWithId(CoreSession session, String id); 373 374 // copied from the deprecated RoutingTaskService 375 376 /** 377 * Returns the doc id of the route model with the given id 378 * 379 * @since 5.7 380 */ 381 String getRouteModelDocIdWithId(CoreSession session, String id); 382 383 /** 384 * Marks the tasks as Routing tasks. 385 * <p> 386 * This allows the related documents to be adapted to {@code RoutingTask}. 387 * 388 * @param session the session 389 * @param tasks the tasks 390 * @since 5.6, was on RoutingTaskService before 391 * 392 * @deprecated The facet RoutingTask is statically attached to the new 393 * RoutingTask Document type since 7.1 394 */ 395 @Deprecated 396 void makeRoutingTasks(CoreSession session, List<Task> tasks); 397 398 /** 399 * Ends a task. If this is the last task the workflow will continue. 400 * 401 * @param status name of the button clicked to submit the task form 402 * @since 5.6, was on RoutingTaskService before 403 */ 404 void endTask(CoreSession session, Task task, Map<String, Object> data, String status); 405 406 /** 407 * Grants on these documents the specified assignees permissions for this task. 408 * 409 * @param session the session 410 * @param permission the permission 411 * @param docs the documents 412 * @param task the task 413 * @since 5.6 414 */ 415 void grantPermissionToTaskAssignees(CoreSession session, String permission, List<DocumentModel> docs, Task task); 416 417 /** 418 * Removes on these documents the specified assignees permissions for this task. 419 * 420 * @param session the session 421 * @param docs the documents 422 * @param task the task 423 * @since 5.6 424 */ 425 void removePermissionFromTaskAssignees(CoreSession session, List<DocumentModel> docs, Task task); 426 427 /** 428 * Gets the documents following the workflow to which the given task belongs 429 * 430 * @since 5.6, was on RoutingTaskService before 431 */ 432 List<DocumentModel> getWorkflowInputDocuments(CoreSession session, Task task); 433 434 /** 435 * Finishes an open task. All permissions granted to the tasks assignees on the document following the worklflow are 436 * removed. Doesn't resume the workflow as the <code>completeTask</code> method. Not executed using an unrestricted 437 * session. 438 * 439 * @since 5.7 440 * @deprecated // will be removed in 5.8, use completeTask instead 441 */ 442 @Deprecated 443 void finishTask(CoreSession session, DocumentRoute route, Task task, boolean delete) throws DocumentRouteException; 444 445 /** 446 * Cancels an open task. If the task was created by an workflow, all permissions granted to the tasks assignees on 447 * the document following the worklflow are removed. Doesn't resume the workflow as the <code>completeTask</code> 448 * method. 449 * 450 * @since 5.7.3 451 */ 452 void cancelTask(CoreSession session, String taskId) throws DocumentRouteException; 453 454 /** 455 * Reassigns the given task to the list of actors. Removes the permissions granted on the document following the 456 * workflow to the current task assignees and grants them to the new actors. 457 * 458 * @since 5.7.3 459 */ 460 void reassignTask(CoreSession session, String taskId, List<String> actors, String comment) 461 throws DocumentRouteException; 462 463 /** 464 * Reassigns the given task to the list of actors. Grants to new delegated actors the same permissions as the task 465 * assignees on the document following the workflow . 466 * 467 * @since 5.8 468 */ 469 void delegateTask(CoreSession session, String taskId, List<String> delegatedActors, String comment) 470 throws DocumentRouteException; 471 472 /** 473 * Grants on these documents the specified assignees permissions for this task to the tasks delegated actors. 474 * 475 * @param session the session 476 * @param permission the permission 477 * @param docs the documents 478 * @param task the task 479 * @since 5.8 480 */ 481 void grantPermissionToTaskDelegatedActors(CoreSession session, String permission, List<DocumentModel> docs, 482 Task task); 483 484 /** 485 * Removes on these documents the specified assignees permissions for the task actors and also tasks delegated 486 * actors if this task was delegated 487 * 488 * @param session the session 489 * @param docs the documents 490 * @param task the task 491 * @since 5.8 492 */ 493 void removePermissionsForTaskActors(CoreSession session, List<DocumentModel> docs, Task task); 494 495 /** 496 * Removes on these documents the specified assignees permissions for the task actors and also tasks delegated 497 * actors if this task was delegated 498 * 499 * @param session the session 500 * @param docs the documents 501 * @param taskId the taskId 502 * @since 7.4 503 */ 504 void removePermissionsForTaskActors(CoreSession session, List<DocumentModel> docs, String taskId); 505 506 /** 507 * Query for the routes 'done' or 'canceled' and delete them. The max no of the routes that will be deleted is 508 * specified by the 'limit' parameter. When the limit is '0' all the completed routes are deleted. The routes to be 509 * deleted are ordered ascending by their creation date. 510 * 511 * @since 5.8 512 */ 513 void cleanupDoneAndCanceledRouteInstances(String repositoryName, int limit); 514 515 /** 516 * @since 5.9.3 517 */ 518 void invalidateRouteModelsCache(); 519 520 /** 521 * Query for the routes 'done' or 'canceled' and delete them. The max no of the routes that will be deleted is 522 * specified by the 'limit' parameter. When the limit is '0' all the completed routes are deleted. The routes to be 523 * deleted are ordered ascending by their creation date. 524 * 525 * @return the number of cleaned up workflow instance 526 * @since 7.1 527 */ 528 int doCleanupDoneAndCanceledRouteInstances(String reprositoryName, int limit); 529 530 /** 531 * @since 7.2 532 * @deprecated since 11.1 this method does not scale as it does not paginate results. Use 533 * {@code org.nuxeo.ecm.platform.routing.core.provider.RoutingTaskPageProvider#getCurrentPage()} 534 * instead. 535 */ 536 @Deprecated 537 List<Task> getTasks(final DocumentModel document, String actorId, String workflowInstanceId, 538 String workflowModelName, CoreSession session); 539 540 /** 541 * @since 7.2 542 */ 543 List<DocumentRoute> getDocumentRelatedWorkflows(final DocumentModel document, final CoreSession session); 544 545 /** 546 * @since 7.2 547 */ 548 List<DocumentRoute> getRunningWorkflowInstancesLaunchedByCurrentUser(final CoreSession session); 549 550 /** 551 * @since 7.2 552 */ 553 List<DocumentRoute> getRunningWorkflowInstancesLaunchedByCurrentUser(CoreSession session, String worflowModelName); 554 555 /** 556 * Returns true id the document route is a model, false if it is just an instance i.e. a running workflow. 557 * 558 * @since 7.2 559 */ 560 boolean isWorkflowModel(final DocumentRoute documentRoute); 561 562 /** 563 * Returns {@code true} if the workflow model can be started on the document list. 564 * 565 * @since 11.4 566 */ 567 boolean canCreateInstance(CoreSession session, List<String> documentIds, String worflowModelName); 568 569 /** 570 * Returns a list of runnable document routes for the input document IDs. 571 * 572 * @since 11.4 573 */ 574 List<DocumentRoute> getRunnableWorkflows(CoreSession session, List<String> documentIds); 575 576}