| Quintiq file version 2.0 | 
| #parent: #root | 
| Method DoFinalize (LibOpt_Task task, output Boolean hascreatedstream_o) as stream[JSON] | 
| { | 
|   Description: | 
|   [* | 
|     This method makes sure that the `DoFinalizeCurrentComponent` method is executed in the right order. This method should be executed for all components. | 
|     When a `LibOpt_TaskTransporterOneTransaction` is used to execute a component, then the execution of the `DoFinalize` method can be delayed. When this happens, the `DoFinalize` method is called in a single transaction together with the `DoFinalize` methods of other components. | 
|     We want to finalize the component that is the most downstream first.  | 
|     Therefore, this method ensures that the `DoFinalizeCurrentComponent` method is called first for the most downstream component for which the `DoFinalizeCurrentComponent` method hasn't been excuted yet. | 
|   *] | 
|   TextBody: | 
|   [* | 
|     // evr3 Jun-16-2020 (created) | 
|      | 
|     streamJSON := stream[JSON]::Success(); | 
|      | 
|     // If this task has any subtasks, then we call DoFinalize for each of these subtasks. | 
|     // Note: A subtask can only exist if DoFinalize/DoFinalizeCurrentComponent has not been executed yet for this subtask,  | 
|     // because executing DoFinalizeCurrentComponent for a (sub)task results in the deletion of the (sub)task. | 
|     traverse( task, Children, subtask, not hascreatedstream_o ) | 
|     {   | 
|       streamJSON := subtask.Component().DoFinalize( subtask, hascreatedstream_o ); | 
|       // If calling DoFinalize for a subtask did not create a stream, then the subtask is deleted when DoFinalize finished executing for that subtask. | 
|       // If calling DoFinalize for a subtask did create a stream, then hascreatedstream_o will be true. The subtask will only be deleted after this stream terminates. | 
|       // We therefore escape this traverse and wait until the stream is terminated. | 
|     } | 
|      | 
|     if( not hascreatedstream_o ) | 
|     { | 
|       // If none of the subtasks created a stream, then we execute DoFinalizeCurrentComponent, which performs the actual finalize actions for this component.  | 
|       // Note: We will call DoFinalizeCurrentComponent eventually for this component, because if we did create a stream, then we will call DoFinalize again in the 'else'-block below. | 
|       streamJSON := this.DoFinalizeCurrentComponent( task, hascreatedstream_o );  | 
|     } | 
|     else | 
|     { | 
|       // If we did create a stream, then we wait until we have resolved this stream (which will delete a subtask). Then we call DoFinalize again.  | 
|       streamJSON := streamJSON->|this->DoFinalize( task );  | 
|     } | 
|      | 
|     return streamJSON; | 
|   *] | 
|   InterfaceProperties { Accessibility: 'Module' } | 
| } |