View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.elasticdata.modules.workflow.business;
35  
36  import java.sql.Timestamp;
37  import java.util.ArrayList;
38  import java.util.Comparator;
39  import java.util.List;
40  import java.util.Map;
41  import java.util.Vector;
42  import java.util.stream.Collectors;
43  import javax.inject.Inject;
44  import fr.paris.lutece.plugins.elasticdata.business.AbstractDataSource;
45  import fr.paris.lutece.plugins.elasticdata.business.DataObject;
46  import fr.paris.lutece.plugins.elasticdata.service.DataSourceIncrementalService;
47  import fr.paris.lutece.plugins.workflowcore.business.action.Action;
48  import fr.paris.lutece.plugins.workflowcore.business.action.ActionFilter;
49  import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceHistory;
50  import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceHistoryFilter;
51  import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceUserHistory;
52  import fr.paris.lutece.plugins.workflowcore.business.state.State;
53  import fr.paris.lutece.plugins.workflowcore.business.state.StateFilter;
54  import fr.paris.lutece.plugins.workflowcore.business.workflow.Workflow;
55  import fr.paris.lutece.plugins.workflowcore.business.workflow.WorkflowFilter;
56  import fr.paris.lutece.plugins.workflowcore.service.action.IActionService;
57  import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceHistoryService;
58  import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceWorkflowService;
59  import fr.paris.lutece.plugins.workflowcore.service.state.IStateService;
60  import fr.paris.lutece.plugins.workflowcore.service.workflow.IWorkflowService;
61  import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService;
62  
63  public class WorkflowDataSource extends AbstractDataSource
64  {
65      @Inject
66      private IActionService _actionService;
67      @Inject
68      private IResourceHistoryService _resourceHistoryService;
69      @Inject
70      private IStateService _stateService;
71      @Inject
72      private IWorkflowService _workflowService;
73      @Inject
74      private IResourceWorkflowService _resourceWorkflowService;
75  
76      private static final String DATA_SOURCE_NAME = "WorkflowDataSource";
77      
78      @Override
79      public List<String> getIdDataObjects( )
80      {
81          List<Integer> idResourceList = new ArrayList<>( );
82          for ( Workflow wf : getWorkflowList( ) )
83          {
84              idResourceList.addAll( _resourceWorkflowService.getAllResourceIdByWorkflow( wf.getId( ) ) );
85          }
86          return idResourceList.stream( ).map( idResource -> String.valueOf( idResource ) ).collect( Collectors.toList( ) );
87      }
88  
89      @Override
90      public List<DataObject> getDataObjects( List<String> listIdResource )
91      {
92          List<DataObject> collResult = new Vector<>( );
93          List<ResourceHistory> listResourceHistory = getResourceHistoryList( listIdResource );
94          Map<Integer, List<ResourceHistory>> listWorkflowResourceHistory = listResourceHistory.stream( )
95                  .collect( Collectors.groupingBy( rh -> rh.getWorkflow( ).getId( ) ) );
96          List<Workflow> listWorkflow = getWorkflowList( );
97  
98          for ( Map.Entry<Integer, List<ResourceHistory>> entry : listWorkflowResourceHistory.entrySet( ) )
99          {
100             int nIdWorkflow = entry.getKey( );
101             Workflow wf = listWorkflow.stream( ).filter( workflow -> workflow.getId( ) == nIdWorkflow ).findFirst( ).orElse( null );
102             String strWorkflowName = wf.getName( );
103             List<State> listStates = getStateList( nIdWorkflow );
104             List<Action> listActions = getActionList( nIdWorkflow );
105             Map<Integer, List<ResourceHistory>> listResourceHistorybyIdResource = entry.getValue( ).stream( )
106                     .collect( Collectors.groupingBy( rh -> rh.getIdResource( ) ) );
107 
108             listResourceHistorybyIdResource.values( ).parallelStream( ).forEach( listResourceHistoryIdResource -> {
109                 Map<String, List<ResourceHistory>> listResourceHistoryByType = listResourceHistoryIdResource.stream( )
110                         .collect( Collectors.groupingBy( rh -> rh.getResourceType( ) ) );
111                 listResourceHistoryByType.values( ).stream( ).forEach( listHistory -> {
112 
113                     List<WorkflowResourceHistory> listWorkflowHistory = new ArrayList<WorkflowResourceHistory>();
114                     List<ResourceHistory> listHistoryOrdered = listHistory.stream( ).sorted( Comparator.comparing( ResourceHistory::getCreationDate ) )
115                             .collect( Collectors.toList( ) );
116                             Timestamp lStartingResource = listHistoryOrdered.get( 0 ).getCreationDate( );
117                             Timestamp lstartingDateDuration = lStartingResource;
118                     
119                     WorkflowDataObjectns/elasticdata/modules/workflow/business/WorkflowDataObject.html#WorkflowDataObject">WorkflowDataObject/../../../../../../../fr/paris/lutece/plugins/elasticdata/modules/workflow/business/WorkflowDataObject.html#WorkflowDataObject">WorkflowDataObject WorkflowDataObjectns/elasticdata/modules/workflow/business/WorkflowDataObject.html#WorkflowDataObject">WorkflowDataObject = new WorkflowDataObject( );
120                     WorkflowDataObject.setId( String.valueOf( listHistory.get( 0 ).getIdResource( ) ) );
121                     WorkflowDataObject.setWorkflowName(strWorkflowName);
122                     WorkflowDataObject.setIdWorkflow(nIdWorkflow);
123                     WorkflowDataObject.setTimestamp( listHistoryOrdered.get( 0 ).getCreationDate( ).getTime( ) );
124                     WorkflowDataObject.setIdResource( listHistoryOrdered.get( 0 ).getIdResource( ) );
125                     WorkflowDataObject.setDateLastUpdate(listHistoryOrdered.get( listHistoryOrdered.size( ) - 1 ).getCreationDate( ).getTime( ) );
126          
127                     for ( ResourceHistory rh : listHistoryOrdered )
128                     {
129                         WorkflowResourceHistoryow/business/WorkflowResourceHistory.html#WorkflowResourceHistory">WorkflowResourceHistory workflowResourceHistory = new WorkflowResourceHistory( );
130                         long lTaskDuration = duration( lstartingDateDuration, rh.getCreationDate( ) );
131                         long lCompleteDuration = duration( lStartingResource, rh.getCreationDate( ) );
132                         ResourceUserHistory ruh = rh.getResourceUserHistory( );
133                         workflowResourceHistory.setId( String.valueOf( rh.getId( ) ) );
134                         workflowResourceHistory.setTimestamp( rh.getCreationDate( ).getTime( ) );
135                         workflowResourceHistory.setIdResource( rh.getIdResource( ) );
136                         workflowResourceHistory.setResourceType( rh.getResourceType( ) );
137                         workflowResourceHistory.setUserAccessCode( ruh.getUserAccessCode( ) );
138                         workflowResourceHistory.setIdWorkflow( nIdWorkflow );
139                         workflowResourceHistory.setWorkflowName( strWorkflowName );
140                         workflowResourceHistory.setTaskDuration( lTaskDuration );
141                         workflowResourceHistory.setCompleteDuration( lCompleteDuration );
142                         Action action = listActions.stream( ).filter( ac -> ac.getId( ) == rh.getAction( ).getId( ) ).findFirst( ).orElse( null );
143                         if ( action != null )
144                         {
145                             workflowResourceHistory.setActionName( action.getName( ) );
146                             workflowResourceHistory.setIdAction( action.getId( ) );
147                             State stateResourceHistory = listStates.stream( ).filter( st -> st.getId( ) == action.getStateAfter( ).getId( ) ).findFirst( )
148                                     .orElse( null );
149                             if ( stateResourceHistory != null )
150                             {
151                                 workflowResourceHistory.setWorkflowState( stateResourceHistory.getName( ) );
152                             }
153                         }
154                         listWorkflowHistory.add( workflowResourceHistory );
155                     }
156                     WorkflowDataObject.setLastWorkflowState( listWorkflowHistory.get( listWorkflowHistory.size() - 1 ).getWorkflowState( ) );
157                     WorkflowDataObject.setWorkflows(listWorkflowHistory);  
158                     
159                     collResult.add( WorkflowDataObject );
160                 } );
161             } );
162         }
163         return collResult;
164     }
165 
166     /**
167      * Index the worflow resource history to Elasticdata ( incremental )
168      * 
169      * @param nIdResource
170      *            The id resource
171      * @param nIdTask
172      *            The task id
173      */
174     public void indexDocument( int nIdResource, int nIdTask )
175     {
176         DataSourceIncrementalService.addTask( DATA_SOURCE_NAME, String.valueOf( nIdResource ), nIdTask );
177     }
178 
179     /**
180      * return a list of resource history according to workflow id
181      * 
182      * @param nIdWorkflow
183      *            the workflow id
184      * @return list of ressource history
185      */
186     private List<ResourceHistory> getResourceHistoryList( List<String> listIdResource )
187     {
188         ResourceHistoryFilter rhf = new ResourceHistoryFilter( );
189         rhf.setListIdResources( listIdResource.stream( ).map( idResource -> Integer.valueOf( idResource ) ).collect( Collectors.toList( ) ) );
190         return _resourceHistoryService.getAllHistoryByFilter( rhf ).stream( ).collect( Collectors.toList( ) );
191     }
192 
193     /**
194      * return a list of states according to workflow id
195      * 
196      * @param nIdWorkflow
197      *            the workflow id
198      * @return list of states
199      */
200     private List<State> getStateList( int nIdWorkflow )
201     {
202         StateFilter stateFilter = new StateFilter( );
203         stateFilter.setIdWorkflow( nIdWorkflow );
204         return _stateService.getListStateByFilter( stateFilter );
205     }
206 
207     private List<Workflow> getWorkflowList( )
208     {
209         WorkflowFilter filter = new WorkflowFilter( );
210         filter.setWorkGroup( AdminWorkgroupService.ALL_GROUPS );
211         return _workflowService.getListWorkflowsByFilter( filter );
212     }
213 
214     /**
215      * return a list of actions according to workflow id
216      * 
217      * @param nIdWorkflow
218      *            the workflow id
219      * @return list of actions
220      */
221     private List<Action> getActionList( int nIdWorkflow )
222     {
223         ActionFilter actionFilter = new ActionFilter( );
224         actionFilter.setIdWorkflow( nIdWorkflow );
225         return _actionService.getListActionByFilter( actionFilter );
226     }
227 
228     /**
229      * return The duration in milliseconds
230      * 
231      * @param start
232      *            The start time.
233      * @param end
234      *            The end time.
235      * @return The duration in days
236      */
237     private static long duration( java.sql.Timestamp start, java.sql.Timestamp end )
238     {
239         long milliseconds1 = start.getTime( );
240         long milliseconds2 = end.getTime( );
241         return milliseconds2 - milliseconds1;
242     }
243 }