View Javadoc
1   /*
2    * Copyright (c) 2002-2017, Mairie de 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.fdw.modules.wizard.service;
35  
36  import fr.paris.lutece.plugins.directory.business.Directory;
37  import fr.paris.lutece.plugins.directory.business.DirectoryHome;
38  import fr.paris.lutece.plugins.fdw.modules.wizard.exception.DuplicationException;
39  import fr.paris.lutece.plugins.form.business.Form;
40  import fr.paris.lutece.plugins.form.business.FormHome;
41  import fr.paris.lutece.plugins.workflowcore.business.action.Action;
42  import fr.paris.lutece.plugins.workflowcore.business.action.ActionFilter;
43  import fr.paris.lutece.plugins.workflowcore.business.config.ITaskConfig;
44  import fr.paris.lutece.plugins.workflowcore.business.state.State;
45  import fr.paris.lutece.plugins.workflowcore.business.workflow.Workflow;
46  import fr.paris.lutece.plugins.workflowcore.service.action.IActionService;
47  import fr.paris.lutece.plugins.workflowcore.service.config.ITaskConfigService;
48  import fr.paris.lutece.plugins.workflowcore.service.state.IStateService;
49  import fr.paris.lutece.plugins.workflowcore.service.task.ITask;
50  import fr.paris.lutece.plugins.workflowcore.service.task.ITaskService;
51  import fr.paris.lutece.plugins.workflowcore.service.workflow.IWorkflowService;
52  import fr.paris.lutece.portal.service.plugin.Plugin;
53  import fr.paris.lutece.portal.service.spring.SpringContextService;
54  import fr.paris.lutece.util.method.MethodUtil;
55  
56  import java.lang.reflect.InvocationTargetException;
57  import java.util.ArrayList;
58  import java.util.HashMap;
59  import java.util.List;
60  import java.util.Locale;
61  import java.util.Map;
62  
63  import org.apache.commons.collections.iterators.EntrySetMapIterator;
64  
65  
66  /**
67   *
68   * WizardService
69   *
70   */
71  public class WizardService
72  {
73      public static final String BEAN_SERVICE = "fdw-wizard.wizardService";
74      private static WizardService _singleton;
75  
76      //services
77      private IWorkflowService _workflowService;
78      private IActionService _actionService;
79      private IStateService _stateService;
80      private ITaskService _taskService;
81  
82      /**
83       * Initialize the service
84       *
85       */
86      public void init(  )
87      {
88      }
89  
90      /**
91       * Returns the instance of the singleton
92       *
93       * @return The instance of the singleton
94       */
95      public static synchronized WizardService getInstance( )
96      {
97          if ( _singleton == null )
98          {
99              _singleton = new WizardService(  );
100         }
101 
102         return _singleton;
103     }
104 
105     /**
106      * @param workflowService the workflowService to set
107      */
108     public void setWorkflowService( IWorkflowService workflowService )
109     {
110         this._workflowService = workflowService;
111     }
112 
113     /**
114      * @param actionService the actionService to set
115      */
116     public void setActionService( IActionService actionService )
117     {
118         this._actionService = actionService;
119     }
120 
121     /**
122      * @param stateService the stateService to set
123      */
124     public void setStateService( IStateService stateService )
125     {
126         this._stateService = stateService;
127     }
128 
129     /**
130      * @param taskService the taskService to set
131      */
132     public void setTaskService( ITaskService taskService )
133     {
134         this._taskService = taskService;
135     }
136 
137     /**
138      * Gets a directory
139      * @param nIdDirectory the id of the directory
140      * @param plugin the plugin
141      * @return the directory
142      */
143     public Directory getDirectory( int nIdDirectory, Plugin plugin )
144     {
145         return DirectoryHome.findByPrimaryKey( nIdDirectory, plugin );
146     }
147 
148     /**
149      * Gets a form
150      * @param nIdForm the id of the form
151      * @param plugin the plugin
152      * @return the form
153      */
154     public Form getForm( int nIdForm, Plugin plugin )
155     {
156         return FormHome.findByPrimaryKey( nIdForm, plugin );
157     }
158 
159     /**
160      * Gets a workflow
161      * @param nIdWorkflow the id of the workflow
162      * @return the workflow
163      */
164     public Workflow getWorkflow( int nIdWorkflow )
165     {
166         return _workflowService.findByPrimaryKey( nIdWorkflow );
167     }
168 
169     /**
170      * Copy a given workflow
171      * @param workflowToCopy the workflow to copy
172      * @param copyName the name of the copy
173      * @param locale the locale
174      * @return the id of the copy
175      * @throws DuplicationException the duplication exception
176      */
177     public int doCopyWorkflow( Workflow workflowToCopy, String copyName, Locale locale )
178         throws DuplicationException
179     {
180         try
181         {
182             int nIdWorkflow = workflowToCopy.getId(  );
183             Map<Integer, Integer> mapIdStates = new HashMap<Integer, Integer>(  );
184             Map<Integer, Integer> mapIdActions = new HashMap<Integer, Integer>(  );
185 
186             workflowToCopy.setName( copyName );
187             _workflowService.create( workflowToCopy );
188 
189             //get all the states of the workflow to copy
190             List<State> listStatesOfWorkflow = (List<State>) _workflowService.getAllStateByWorkflow( nIdWorkflow );
191 
192             for ( State state : listStatesOfWorkflow )
193             {
194                 state.setWorkflow( workflowToCopy );
195 
196                 //get the maximum order number in this workflow and set max+1
197                 int nMaximumOrder = _stateService.findMaximumOrderByWorkflowId( state.getWorkflow(  ).getId(  ) );
198                 state.setOrder( nMaximumOrder + 1 );
199 
200                 // Save state to copy id
201                 Integer nOldIdState = state.getId(  );
202 
203                 // Create new state (this action will change state id with the new idState)
204                 _stateService.create( state );
205 
206                 mapIdStates.put( nOldIdState, state.getId(  ) );
207             }
208 
209             //get all the actions of the workflow to copy
210             ActionFilter actionFilter = new ActionFilter(  );
211             actionFilter.setIdWorkflow( nIdWorkflow );
212 
213             List<Action> listActionsOfWorkflow = _actionService.getListActionByFilter( actionFilter );
214 
215             for ( Action action : listActionsOfWorkflow )
216             {
217                 action.setWorkflow( workflowToCopy );
218 
219                 //get the maximum order number in this workflow and set max+1
220                 int nMaximumOrder = _actionService.findMaximumOrderByWorkflowId( action.getWorkflow(  ).getId(  ) );
221                 action.setOrder( nMaximumOrder + 1 );
222 
223                 // Change idState to set the new state
224                 action.getStateBefore(  ).setId( mapIdStates.get( action.getStateBefore(  ).getId(  ) ) );
225                 action.getStateAfter(  ).setId( mapIdStates.get( action.getStateAfter(  ).getId(  ) ) );
226 
227                 int nOldIdAction = action.getId(  );
228 
229                 //get the linked tasks and duplicate them
230                 List<ITask> listLinkedTasks = _taskService.getListTaskByIdAction( action.getId(  ), locale );
231 
232                 _actionService.create( action );
233 
234                 mapIdActions.put( nOldIdAction, action.getId(  ) );
235 
236                 for ( ITask task : listLinkedTasks )
237                 {
238                     //for each we change the linked action
239                     task.setAction( action );
240 
241                     //and then we create the new task duplicated
242                     this.doCopyTaskWithModifiedParam( task, null );
243                 }
244             }
245 
246             //get all the linked actions
247             actionFilter = new ActionFilter(  );
248             actionFilter.setIdWorkflow( workflowToCopy.getId(  ) );
249 
250             List<Action> listActionsOfNewWorkflow = _actionService.getListActionByFilter( actionFilter );
251 
252             for ( Action action : listActionsOfNewWorkflow )
253             {
254                 List<Integer> newListIdsLinkedAction = new ArrayList<Integer>(  );
255 
256                 for ( Integer nIdActionLinked : action.getListIdsLinkedAction(  ) )
257                 {
258                     newListIdsLinkedAction.add( mapIdActions.get( nIdActionLinked ) );
259                 }
260 
261                 action.setListIdsLinkedAction( newListIdsLinkedAction );
262                 _actionService.update( action );
263             }
264         }
265         catch ( InvocationTargetException e )
266         {
267             throw new DuplicationException( e );
268         }
269         catch ( NoSuchMethodException e )
270         {
271             throw new DuplicationException( e );
272         }
273         catch ( IllegalAccessException e )
274         {
275             throw new DuplicationException( e );
276         }
277 
278         return workflowToCopy.getId(  );
279     }
280 
281     /**
282      * Copy the task whose key is specified in the Http request and update param
283      * if exists
284      * @param taskToCopy the task to copy
285      * @param mapParamToChange the map<String, String> of <Param, Value> to
286      *            change
287      * @throws NoSuchMethodException NoSuchMethodException the
288      *             {@link NoSuchMethodException}
289      * @throws IllegalAccessException IllegalAccessException the
290      *             {@link IllegalAccessException}
291      * @throws InvocationTargetException InvocationTargetException the
292      *             {@link InvocationTargetException}
293      */
294     public void doCopyTaskWithModifiedParam( ITask taskToCopy, Map<String, String> mapParamToChange )
295         throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
296     {
297         // Save nIdTaskToCopy
298         Integer nIdTaskToCopy = taskToCopy.getId(  );
299 
300         //get the maximum order number in this workflow and set max+1
301         int nMaximumOrder = _taskService.findMaximumOrderByActionId( taskToCopy.getAction( ).getId( ) );
302         taskToCopy.setOrder( nMaximumOrder + 1 );
303 
304         // Create the new task (taskToCopy id will be update with the new idTask)
305         _taskService.create( taskToCopy );
306 
307         // get all taskConfigService
308         List<ITaskConfigService> listTaskConfigService = SpringContextService.getBeansOfType( ITaskConfigService.class );
309 
310         // For each taskConfigService, update parameter if exists
311         for ( ITaskConfigService taskConfigService : listTaskConfigService )
312         {
313             ITaskConfig taskConfig = taskConfigService.findByPrimaryKey( nIdTaskToCopy );
314 
315             if ( taskConfig != null )
316             {
317                 taskConfig.setIdTask( taskToCopy.getId(  ) );
318 
319                 if ( mapParamToChange != null )
320                 {
321                     EntrySetMapIterator it = new EntrySetMapIterator( mapParamToChange );
322 
323                     while ( it.hasNext(  ) )
324                     {
325                         String key = (String) it.next(  );
326                         String value = (String) it.getValue(  );
327                         MethodUtil.set( taskConfig, key, value );
328                     }
329                 }
330 
331                 taskConfigService.create( taskConfig );
332             }
333         }
334     }
335 
336     /**
337      * Copy a given directory
338      * @param directoryToCopy the directory to copy
339      * @param copyName the name of the copy
340      * @param plugin the plugin
341      * @return the id of the copy
342      */
343     public int doCopyDirectory( Directory directoryToCopy, String copyName, Plugin plugin )
344     {
345         directoryToCopy.setTitle( copyName );
346         DirectoryHome.copy( directoryToCopy, plugin );
347 
348         return directoryToCopy.getIdDirectory(  );
349     }
350 
351     /**
352      * Copy a given form
353      * @param formToCopy the form to copy
354      * @param copyName the name of the copy
355      * @param plugin the plugin
356      * @return the id of the copy
357      */
358     public int doCopyForm( Form formToCopy, String copyName, Plugin plugin )
359     {
360         formToCopy.setTitle( copyName );
361         FormHome.copy( formToCopy, plugin );
362 
363         return formToCopy.getIdForm(  );
364     }
365 
366     /**
367      * Copy a given directory and its workflow
368      * @param directoryToCopy the directory to copy
369      * @param directoryCopyName the name of the copy
370      * @param workflowCopyName the name of the copy
371      * @param plugin the plugin
372      * @param locale the locale
373      * @return the id of the copy
374      * @throws DuplicationException the duplication exception
375      */
376     public int doCopyDirectoryWithWorkflow( Directory directoryToCopy, String directoryCopyName,
377         String workflowCopyName, Plugin plugin, Locale locale )
378         throws DuplicationException
379     {
380         Workflow workflowToCopy = _workflowService.findByPrimaryKey( directoryToCopy.getIdWorkflow(  ) );
381         int nIdWorkflowCopy = doCopyWorkflow( workflowToCopy, workflowCopyName, locale );
382 
383         directoryToCopy.setIdWorkflow( nIdWorkflowCopy );
384 
385         int nIdDirectoryCopy = doCopyDirectory( directoryToCopy, directoryCopyName, plugin );
386 
387         return nIdDirectoryCopy;
388     }
389 
390     /**
391      * Gets the directory associted to a given form
392      * @param form the form
393      * @return the directory or null if no directory found
394      */
395     public Directory getDirectoryAssociatedToForm( Form form )
396     {
397         Directory directory = null;
398 
399         for ( IFormDirectoryAssociationService associationService : SpringContextService.getBeansOfType( 
400                 IFormDirectoryAssociationService.class ) )
401         {
402             Directory tmpDirectory = associationService.getDirectoryAssociatedToForm( form );
403 
404             if ( tmpDirectory != null )
405             {
406                 directory = tmpDirectory;
407             }
408         }
409 
410         return directory;
411     }
412 
413     /**
414      * Deletes a given workflow
415      * @param nIdWorkflow the id of the workflow
416      */
417     public void deleteWorkflow( int nIdWorkflow )
418     {
419         _workflowService.remove( nIdWorkflow );
420     }
421 }