View Javadoc
1   /*
2    * Copyright (c) 2002-2022, 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.workflow.modules.archive.service;
35  
36  import java.sql.Timestamp;
37  import java.time.LocalDate;
38  import java.time.LocalDateTime;
39  import java.util.List;
40  import java.util.Locale;
41  
42  import javax.inject.Inject;
43  import javax.inject.Named;
44  
45  import fr.paris.lutece.plugins.workflow.modules.archive.IResourceArchiver;
46  import fr.paris.lutece.plugins.workflow.modules.archive.WorkflowResourceArchiver;
47  import fr.paris.lutece.plugins.workflow.modules.archive.business.ArchiveConfig;
48  import fr.paris.lutece.plugins.workflow.modules.archive.business.ArchiveResource;
49  import fr.paris.lutece.plugins.workflow.modules.archive.business.IArchiveResourceDao;
50  import fr.paris.lutece.plugins.workflow.utils.WorkflowUtils;
51  import fr.paris.lutece.plugins.workflowcore.business.action.Action;
52  import fr.paris.lutece.plugins.workflowcore.business.resource.IResourceHistoryDAO;
53  import fr.paris.lutece.plugins.workflowcore.business.resource.IResourceWorkflowDAO;
54  import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceHistory;
55  import fr.paris.lutece.plugins.workflowcore.business.resource.ResourceWorkflow;
56  import fr.paris.lutece.plugins.workflowcore.business.state.State;
57  import fr.paris.lutece.plugins.workflowcore.service.action.IActionService;
58  import fr.paris.lutece.plugins.workflowcore.service.config.ITaskConfigService;
59  import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceHistoryService;
60  import fr.paris.lutece.plugins.workflowcore.service.resource.IResourceWorkflowService;
61  import fr.paris.lutece.plugins.workflowcore.service.state.IStateService;
62  import fr.paris.lutece.plugins.workflowcore.service.task.ITask;
63  import fr.paris.lutece.portal.service.i18n.I18nService;
64  import fr.paris.lutece.portal.service.spring.SpringContextService;
65  import fr.paris.lutece.portal.service.workflow.WorkflowService;
66  
67  /**
68   * Implements {@link IArchiveService}
69   */
70  public class ArchiveService implements IArchiveService
71  {
72      public static final String BEAN_SERVICE = "workflow.archiveService";
73  
74      @Inject
75      @Named( "workflow.taskArchiveConfigService" )
76      private ITaskConfigService _taskArchiveConfigService;
77  
78      @Inject
79      private IResourceHistoryDAO _resourceHistoryDAO;
80  
81      @Inject
82      private IResourceWorkflowDAO _resourceWorkflowDAO;
83  
84      @Inject
85      private IArchiveResourceDao _archiveResourceDao;
86  
87      @Inject
88      private IActionService _actionService;
89  
90      @Inject
91      private IStateService _stateService;
92  
93      @Inject
94      private IResourceHistoryService _resourceHistoryService;
95  
96      @Inject
97      private IResourceWorkflowService _resourceWorkflowService;
98  
99      private static final String USER_AUTO = "auto";
100 
101     @Override
102     public ArchiveConfig loadConfig( ITask task )
103     {
104         return _taskArchiveConfigService.findByPrimaryKey( task.getId( ) );
105     }
106 
107     @Override
108     public ArchiveResource getArchiveResource( int nIdHistory, int nIdTask )
109     {
110         ResourceHistory history = _resourceHistoryDAO.load( nIdHistory );
111         if ( history == null )
112         {
113             return null;
114         }
115 
116         ResourceWorkflow resource = _resourceWorkflowDAO.load( history.getIdResource( ), history.getResourceType( ), history.getWorkflow( ).getId( ) );
117         if ( resource == null )
118         {
119             return null;
120         }
121         return _archiveResourceDao.load( resource.getIdResource( ), nIdTask );
122     }
123 
124     @Override
125     public void createArchiveResource( ResourceWorkflow resourceWorkflow, ArchiveConfig config )
126     {
127         ArchiveResource archiveResource = _archiveResourceDao.load( resourceWorkflow.getIdResource( ), config.getIdTask( ) );
128         if ( archiveResource == null )
129         {
130             archiveResource = new ArchiveResource( );
131             archiveResource.setIdResource( resourceWorkflow.getIdResource( ) );
132             archiveResource.setIdTask( config.getIdTask( ) );
133             archiveResource.setIsArchived( false );
134             archiveResource.setInitialDate( Timestamp.valueOf( LocalDateTime.now( ) ) );
135             _archiveResourceDao.insert( archiveResource );
136         }
137     }
138 
139     @Override
140     public boolean isResourceUpForArchival( ResourceWorkflow resourceWorkflow, ArchiveConfig config )
141     {
142         if ( config.getDelayArchival( ) <= 0 )
143         {
144             return true;
145         }
146         ArchiveResource archiveResource = _archiveResourceDao.load( resourceWorkflow.getIdResource( ), config.getIdTask( ) );
147 
148         if ( archiveResource == null || archiveResource.isArchived( ) )
149         {
150             return false;
151         }
152         return LocalDateTime.now( ).isAfter( calculateArchivalDate( archiveResource, config.getDelayArchival( ) ) );
153     }
154 
155     @Override
156     public ResourceWorkflow getResourceWorkflowByHistory( int nIdHistory )
157     {
158         ResourceHistory history = _resourceHistoryDAO.load( nIdHistory );
159         if ( history == null )
160         {
161             return null;
162         }
163 
164         return _resourceWorkflowDAO.load( history.getIdResource( ), history.getResourceType( ), history.getWorkflow( ).getId( ) );
165     }
166 
167     private LocalDateTime calculateArchivalDate( ArchiveResource archiveResource, int daysBeforeArchival )
168     {
169         if ( daysBeforeArchival > 0 )
170         {
171             return archiveResource.getInitialDate( ).toLocalDateTime( ).plusDays( daysBeforeArchival );
172         }
173         return LocalDate.now( ).atStartOfDay( );
174     }
175 
176     @Override
177     public void archiveResource( ResourceWorkflow resourceWorkflow, ITask task, ArchiveConfig config )
178     {
179         if ( config.getNextState( ) != resourceWorkflow.getState( ).getId( ) )
180         {
181             doChangeState( task, resourceWorkflow.getIdResource( ), resourceWorkflow.getResourceType( ), resourceWorkflow.getWorkflow( ).getId( ),
182                     config.getNextState( ) );
183         }
184         List<IResourceArchiver> archiverList = SpringContextService.getBeansOfType( IResourceArchiver.class );
185         IResourceArchiver lastArchiver = null;
186 
187         for ( IResourceArchiver archiver : archiverList )
188         {
189             if ( WorkflowResourceArchiver.BEAN_NAME.equals( archiver.getBeanName( ) ) )
190             {
191                 lastArchiver = archiver;
192             }
193             else
194             {
195                 archiver.archiveResource( config.getTypeArchival( ), resourceWorkflow );
196             }
197         }
198         if ( lastArchiver != null )
199         {
200             lastArchiver.archiveResource( config.getTypeArchival( ), resourceWorkflow );
201         }
202 
203         ArchiveResource archiveResource = _archiveResourceDao.load( resourceWorkflow.getIdResource( ), config.getIdTask( ) );
204         // If the archival process is not a full deletion and keeps the archiveResource,
205         // it must be updated
206         if ( archiveResource != null )
207         {
208             archiveResource.setArchivalDate( Timestamp.valueOf( LocalDateTime.now( ) ) );
209             archiveResource.setIsArchived( true );
210             _archiveResourceDao.store( archiveResource );
211         }
212     }
213 
214     private void doChangeState( ITask task, int nIdResource, String strResourceType, int nIdWorkflow, int newState )
215     {
216         Locale locale = I18nService.getDefaultLocale( );
217         State state = _stateService.findByPrimaryKey( newState );
218         Action action = _actionService.findByPrimaryKey( task.getAction( ).getId( ) );
219 
220         if ( state != null && action != null )
221         {
222 
223             // Create Resource History
224             ResourceHistory resourceHistory = new ResourceHistory( );
225             resourceHistory.setIdResource( nIdResource );
226             resourceHistory.setResourceType( strResourceType );
227             resourceHistory.setAction( action );
228             resourceHistory.setWorkFlow( action.getWorkflow( ) );
229             resourceHistory.setCreationDate( WorkflowUtils.getCurrentTimestamp( ) );
230             resourceHistory.setUserAccessCode( USER_AUTO );
231             _resourceHistoryService.create( resourceHistory );
232 
233             // Update Resource
234             ResourceWorkflow resourceWorkflow = _resourceWorkflowService.findByPrimaryKey( nIdResource, strResourceType, nIdWorkflow );
235             resourceWorkflow.setState( state );
236             _resourceWorkflowService.update( resourceWorkflow );
237 
238             // Execute the relative tasks of the state in the workflow
239             // We use AutomaticReflexiveActions because we don't want to change the state of the resource by executing actions.
240             WorkflowService.getInstance( ).doProcessAutomaticReflexiveActions( nIdResource, strResourceType, state.getId( ), null, locale, null );
241         }
242     }
243 
244     @Override
245     public void removeArchiveResource( int idResource, int idTask )
246     {
247         _archiveResourceDao.delete( idResource, idTask );
248     }
249 
250     @Override
251     public void removeConfig( ITask task )
252     {
253         _taskArchiveConfigService.remove( task.getId( ) );
254     }
255 }