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.directory.utils;
35  
36  import fr.paris.lutece.plugins.blobstore.service.BlobStoreClientException;
37  import fr.paris.lutece.plugins.directory.business.Directory;
38  import fr.paris.lutece.plugins.directory.business.DirectoryHome;
39  import fr.paris.lutece.plugins.directory.business.EntryFilter;
40  import fr.paris.lutece.plugins.directory.business.EntryHome;
41  import fr.paris.lutece.plugins.directory.business.EntryType;
42  import fr.paris.lutece.plugins.directory.business.EntryTypeDownloadUrl;
43  import fr.paris.lutece.plugins.directory.business.EntryTypeHome;
44  import fr.paris.lutece.plugins.directory.business.Field;
45  import fr.paris.lutece.plugins.directory.business.FieldHome;
46  import fr.paris.lutece.plugins.directory.business.File;
47  import fr.paris.lutece.plugins.directory.business.IEntry;
48  import fr.paris.lutece.plugins.directory.business.PhysicalFile;
49  import fr.paris.lutece.plugins.directory.business.Record;
50  import fr.paris.lutece.plugins.directory.business.RecordField;
51  import fr.paris.lutece.plugins.directory.business.RecordFieldFilter;
52  import fr.paris.lutece.plugins.directory.business.RecordFieldHome;
53  import fr.paris.lutece.plugins.directory.business.attribute.DirectoryAttribute;
54  import fr.paris.lutece.plugins.directory.service.DirectoryPlugin;
55  import fr.paris.lutece.plugins.directory.service.directorysearch.DirectorySearchService;
56  import fr.paris.lutece.plugins.directory.service.upload.DirectoryAsynchronousUploadHandler;
57  import fr.paris.lutece.plugins.directory.web.action.DirectoryAdminSearchFields;
58  import fr.paris.lutece.plugins.directory.web.action.DirectorySiteSearchFields;
59  import fr.paris.lutece.plugins.directory.web.action.IDirectorySearchFields;
60  import fr.paris.lutece.portal.business.user.AdminUser;
61  import fr.paris.lutece.portal.service.fileupload.FileUploadService;
62  import fr.paris.lutece.portal.service.plugin.Plugin;
63  import fr.paris.lutece.portal.service.plugin.PluginService;
64  import fr.paris.lutece.portal.service.security.SecurityService;
65  import fr.paris.lutece.portal.service.util.AppLogService;
66  import fr.paris.lutece.portal.service.util.AppPathService;
67  import fr.paris.lutece.portal.service.util.AppPropertiesService;
68  import fr.paris.lutece.portal.service.workflow.WorkflowService;
69  import fr.paris.lutece.portal.service.workgroup.AdminWorkgroupService;
70  import fr.paris.lutece.portal.web.constants.Parameters;
71  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
72  import fr.paris.lutece.util.ReferenceList;
73  import fr.paris.lutece.util.date.DateUtil;
74  import fr.paris.lutece.util.filesystem.FileSystemUtil;
75  import fr.paris.lutece.util.string.StringUtil;
76  import fr.paris.lutece.util.url.UrlItem;
77  
78  import org.apache.commons.fileupload.FileItem;
79  import org.apache.commons.lang.StringUtils;
80  
81  import org.springframework.util.ReflectionUtils;
82  
83  import java.sql.Timestamp;
84  
85  import java.util.ArrayList;
86  import java.util.Date;
87  import java.util.GregorianCalendar;
88  import java.util.HashMap;
89  import java.util.Iterator;
90  import java.util.List;
91  import java.util.Locale;
92  import java.util.Map;
93  import java.util.Map.Entry;
94  import java.util.Set;
95  import java.util.TreeSet;
96  import java.util.stream.Collectors;
97  
98  import javax.servlet.http.HttpServletRequest;
99  import javax.servlet.http.HttpServletResponse;
100 
101 /**
102  *
103  * class DirectoryUtils
104  *
105  */
106 public final class DirectoryUtils
107 {
108     // other constants
109     public static final String CONSTANT_WHERE = " WHERE ";
110     public static final String CONSTANT_AND = " AND ";
111     public static final String CONSTANT_OR = " OR ";
112     public static final String CONSTANT_EQUAL = "=";
113     public static final String CONSTANT_COMA = ",";
114     public static final String CONSTANT_INTERROGATION_MARK = "?";
115     public static final String CONSTANT_AMPERSAND = "&";
116     public static final int CONSTANT_ID_NULL = -1;
117     public static final int CONSTANT_ID_ZERO = 0;
118     public static final String EMPTY_STRING = "";
119     public static final String CONSTANT_ID = "id";
120     public static final String CONSTANT_NAME = "name";
121     public static final String CONSTANT_TRUE = "true";
122     public static final String CONSTANT_DOT = ".";
123     public static final String CONSTANT_UNDERSCORE = "_";
124 
125     // TEMPLATES
126     public static final String TEMPLATE_FORM_DIRECTORY_RECORD = "admin/plugins/directory/html_code_form_directory_record.html";
127     public static final String TEMPLATE_FORM_SEARCH_DIRECTORY_RECORD = "admin/plugins/directory/html_code_form_search_directory_record.html";
128 
129     // MESSAGES
130     public static final String MESSAGE_DIRECTORY_ERROR_MANDATORY_FIELD = "directory.message.directory_error.mandatory.field";
131     public static final String MESSAGE_DIRECTORY_ERROR = "directory.message.directory_error";
132     public static final String MESSAGE_DIRECTORY_ERROR_MIME_TYPE = "directory.message.directory_error.mime_type";
133     public static final String MESSAGE_SELECT_RECORDS = "directory.message.select_records";
134     public static final String MESSAGE_RECORD_INVALID_STATE = "directory.message.record.invalid_state";
135 
136     // PARAMETERS
137     public static final String PARAMETER_ID_DIRECTORY = "id_directory";
138     public static final String PARAMETER_ID_DIRECTORY_RECORD = "id_directory_record";
139     public static final String PARAMETER_ID_ENTRY = "id_entry";
140     public static final String PARAMETER_SESSION = "session";
141     public static final String PARAMETER_DELETE_PREFIX = "delete_";
142     public static final String PARAMETER_UPLOAD_SUBMIT = "_directory_upload_submit_";
143     public static final String PARAMETER_ID_FILE = "id_file";
144     public static final String PARAMETER_ID_ACTION = "id_action";
145     public static final String PARAMETER_SHOW_ACTION_RESULT = "show_action_result";
146     public static final String PARAMETER_DATECREATION = "dateCreation";
147     public static final String PARAMETER_DATEMODIFICATION = "dateModification";
148 
149     // JSP
150     public static final String JSP_MANAGE_DIRECTORY_RECORD = "jsp/admin/plugins/directory/ManageDirectoryRecord.jsp";
151 
152     // SESSION
153     public static final String SESSION_DIRECTORY_LIST_SUBMITTED_RECORD_FIELDS = "directory_list_submitted_record_fields";
154     public static final String SESSION_DIRECTORY_TASKS_SUBMITTED_RECORD_FIELDS = "directory_tasks_submitted_record_fields";
155 
156     // PROPERTIES
157     public static final String PROPERTY_LUTECE_BASE_URL = "lutece.base.url";
158     public static final String PROPERTY_LUTECE_PROD_URL = "lutece.prod.url";
159     private static final String PARAMETER_ID_ENTRY_TYPE = "id_type";
160     private static final String CONSTANT_CHARACTER_DOUBLE_QUOTE = "\"";
161     private static final String CONSTANT_CHARACTER_SIMPLE_QUOTE = "'";
162     private static final String CONSTANTE_CHARACTERNEW_LINE = "\n";
163     private static final String CONSTANTE_CHARACTER_RETURN = "\r";
164     private static final String REGEX_ID = "^[\\d]+$";
165 
166     /**
167      * DirectoryUtils
168      *
169      */
170     private DirectoryUtils( )
171     {
172     }
173 
174     /**
175      * return current Timestamp
176      *
177      * @return return current Timestamp
178      */
179     public static Timestamp getCurrentTimestamp( )
180     {
181         return new Timestamp( GregorianCalendar.getInstance( ).getTimeInMillis( ) );
182     }
183 
184     /**
185      * return an instance of IEntry function of type entry
186      *
187      * @param request
188      *            the request
189      * @param plugin
190      *            the plugin
191      * @return an instance of IEntry function of type entry
192      */
193     public static IEntry createEntryByType( HttpServletRequest request, Plugin plugin )
194     {
195         String strIdType = request.getParameter( PARAMETER_ID_ENTRY_TYPE );
196         int nIdType = convertStringToInt( strIdType );
197 
198         return createEntryByType( nIdType, plugin );
199     }
200 
201     /**
202      * return an instance of IEntry function of type entry
203      *
204      * @param nIdType
205      *            the type id
206      * @param plugin
207      *            the plugin
208      * @return an instance of IEntry function of type entry
209      */
210     public static IEntry createEntryByType( int nIdType, Plugin plugin )
211     {
212         IEntry entry = null;
213         EntryType entryType;
214         entryType = EntryTypeHome.findByPrimaryKey( nIdType, plugin );
215 
216         if ( entryType != null )
217         {
218             try
219             {
220                 entry = (IEntry) Class.forName( entryType.getClassName( ) ).newInstance( );
221                 entry.setEntryType( entryType );
222             }
223             catch( ClassNotFoundException e )
224             {
225                 // class doesn't exist
226                 AppLogService.error( e );
227             }
228             catch( InstantiationException e )
229             {
230                 // Class is abstract or is an interface or haven't accessible
231                 // builder
232                 AppLogService.error( e );
233             }
234             catch( IllegalAccessException e )
235             {
236                 // can't access to rhe class
237                 AppLogService.error( e );
238             }
239         }
240 
241         return entry;
242     }
243 
244     /**
245      * return the index in the list of the entry whose key is specified in parameter
246      *
247      * @param nIdEntry
248      *            the key of the entry
249      * @param listEntry
250      *            the list of the entry
251      * @return the index in the list of the entry whose key is specified in parameter
252      */
253     public static int getIndexEntryInTheEntryList( int nIdEntry, List<IEntry> listEntry )
254     {
255         int nIndex = 0;
256 
257         for ( IEntry entry : listEntry )
258         {
259             if ( entry.getIdEntry( ) == nIdEntry )
260             {
261                 return nIndex;
262             }
263 
264             nIndex++;
265         }
266 
267         return nIndex;
268     }
269 
270     /**
271      * return the index in the list of the field whose key is specified in parameter
272      *
273      * @param nIdField
274      *            the key of the field
275      * @param listField
276      *            the list of field
277      * @return the index in the list of the field whose key is specified in parameter
278      */
279     public static int getIndexFieldInTheFieldList( int nIdField, List<Field> listField )
280     {
281         int nIndex = 0;
282 
283         for ( Field field : listField )
284         {
285             if ( field.getIdField( ) == nIdField )
286             {
287                 return nIndex;
288             }
289 
290             nIndex++;
291         }
292 
293         return nIndex;
294     }
295 
296     /**
297      * return all entry associate to the directory
298      *
299      * @param nIdDirectory
300      *            the id of the directory
301      * @param plugin
302      *            the plugin
303      * @param user
304      *            the AdminUser
305      * @return list of entry
306      */
307     public static List<IEntry> getFormEntries( int nIdDirectory, Plugin plugin, AdminUser user )
308     {
309         IEntry entryFistLevel;
310         EntryFilter filter = new EntryFilter( );
311         filter.setIdDirectory( nIdDirectory );
312         filter.setIsEntryParentNull( EntryFilter.FILTER_TRUE );
313 
314         List<IEntry> listEntryFirstLevel = EntryHome.getEntryList( filter, plugin );
315         List<IEntry> listEntryChildren;
316         List<IEntry> listEntryImbricate = new ArrayList<IEntry>( );
317 
318         for ( IEntry entry : listEntryFirstLevel )
319         {
320             entryFistLevel = EntryHome.findByPrimaryKey( entry.getIdEntry( ), plugin );
321 
322             if ( entryFistLevel.isWorkgroupAssociated( ) )
323             {
324                 entryFistLevel.setFields( DirectoryUtils.getAuthorizedFieldsByWorkgroup( entryFistLevel.getFields( ), user ) );
325             }
326 
327             if ( entryFistLevel.getEntryType( ).getGroup( ) )
328             {
329                 filter = new EntryFilter( );
330                 filter.setIdEntryParent( entryFistLevel.getIdEntry( ) );
331                 listEntryChildren = new ArrayList<IEntry>( );
332 
333                 for ( IEntry entryChildren : EntryHome.getEntryList( filter, plugin ) )
334                 {
335                     IEntry entryTmp = EntryHome.findByPrimaryKey( entryChildren.getIdEntry( ), plugin );
336 
337                     if ( entryTmp.isWorkgroupAssociated( ) )
338                     {
339                         entryTmp.setFields( DirectoryUtils.getAuthorizedFieldsByWorkgroup( entryFistLevel.getFields( ), user ) );
340                     }
341 
342                     listEntryChildren.add( entryTmp );
343                 }
344 
345                 entryFistLevel.setChildren( listEntryChildren );
346             }
347 
348             listEntryImbricate.add( entryFistLevel );
349         }
350 
351         return listEntryImbricate;
352     }
353 
354     /**
355      * return all entry associate to the directory
356      *
357      * @param filter
358      *            entry filter
359      * @param plugin
360      *            the plugin
361      * @return list of entry
362      */
363     public static List<IEntry> getFormEntriesByFilter( EntryFilter filter, Plugin plugin )
364     {
365         IEntry entryFistLevel;
366         filter.setIsEntryParentNull( EntryFilter.FILTER_TRUE );
367 
368         List<IEntry> listEntryFirstLevel = EntryHome.getEntryList( filter, plugin );
369         List<IEntry> listEntryChildren;
370         List<IEntry> listEntryImbricate = new ArrayList<IEntry>( );
371 
372         for ( IEntry entry : listEntryFirstLevel )
373         {
374             entryFistLevel = EntryHome.findByPrimaryKey( entry.getIdEntry( ), plugin );
375 
376             if ( entryFistLevel.getEntryType( ).getGroup( ) )
377             {
378                 EntryFilter entryFilter = new EntryFilter( );
379                 entryFilter.setIdEntryParent( entryFistLevel.getIdEntry( ) );
380                 entryFilter.setIsComment( EntryFilter.FILTER_FALSE );
381                 entryFilter.setIsShownInResultRecord( EntryFilter.FILTER_TRUE );
382                 listEntryChildren = new ArrayList<IEntry>( );
383 
384                 for ( IEntry entryChildren : EntryHome.getEntryList( entryFilter, plugin ) )
385                 {
386                     IEntry entryTmp = EntryHome.findByPrimaryKey( entryChildren.getIdEntry( ), plugin );
387                     listEntryChildren.add( entryTmp );
388                 }
389 
390                 entryFistLevel.setChildren( listEntryChildren );
391             }
392 
393             listEntryImbricate.add( entryFistLevel );
394         }
395 
396         return listEntryImbricate;
397     }
398 
399     /**
400      * get a Map which contains for each entry the list of recordField object associated
401      *
402      * @param lisEntry
403      *            the list of entry associate to the record
404      * @param nIdRecord
405      *            the id of the record
406      * @param plugin
407      *            plugin
408      * @return a map
409      */
410     public static Map<String, List<RecordField>> getMapIdEntryListRecordField( List<IEntry> lisEntry, int nIdRecord, Plugin plugin )
411     {
412         return getMapIdEntryListRecordField( lisEntry, nIdRecord, plugin, true );
413     }
414 
415     /**
416      * get a Map which contains for each entry the list of recordField object associated
417      *
418      * @param lisEntry
419      *            the list of entry associate to the record
420      * @param nIdRecord
421      *            the id of the record
422      * @param plugin
423      *            plugin
424      * @param bGetFileName
425      *            true if it must get the file name, false otherwise <br>
426      *            Warning : The file name is fetch by a webservice call. Beware of performance.
427      * @return a map
428      */
429     public static Map<String, List<RecordField>> getMapIdEntryListRecordField( List<IEntry> lisEntry, int nIdRecord, Plugin plugin, boolean bGetFileName )
430     {
431         Map<String, List<RecordField>> map = new HashMap<String, List<RecordField>>( );
432 
433         RecordFieldFilter filter = new RecordFieldFilter( );
434         filter.setIdRecord( nIdRecord );
435 
436         for ( IEntry entryFistLevel : lisEntry )
437         {
438             if ( entryFistLevel.getChildren( ) != null )
439             {
440                 for ( IEntry child : entryFistLevel.getChildren( ) )
441                 {
442                     buildMapIdEntryListRecordField( map, child, filter, plugin, bGetFileName );
443                 }
444             }
445 
446             buildMapIdEntryListRecordField( map, entryFistLevel, filter, plugin, bGetFileName );
447         }
448 
449         return map;
450     }
451 
452     /**
453      * Build the map of idEntry, RecordFields from a given record
454      * 
455      * @param record
456      *            the record
457      * @return the map of idEntry, RecordFields
458      */
459     public static Map<String, List<RecordField>> buildMapIdEntryListRecordField( Record record )
460     {
461         Map<String, List<RecordField>> map = new HashMap<String, List<RecordField>>( );
462 
463         for ( RecordField recordField : record.getListRecordField( ) )
464         {
465             if ( ( recordField != null ) && ( recordField.getEntry( ) != null ) )
466             {
467                 recordField.setRecord( record );
468 
469                 String strIdEntry = Integer.toString( recordField.getEntry( ).getIdEntry( ) );
470                 List<RecordField> listRecordFields = map.get( strIdEntry );
471 
472                 if ( listRecordFields == null )
473                 {
474                     listRecordFields = new ArrayList<RecordField>( );
475                 }
476 
477                 listRecordFields.add( recordField );
478                 map.put( strIdEntry, listRecordFields );
479             }
480         }
481 
482         return map;
483     }
484 
485     /**
486      * Gets all {@link RecordField} for the entry
487      *
488      * @param entry
489      *            the entry
490      * @param nIdRecord
491      *            the record id
492      * @param plugin
493      *            the plugin
494      * @return the list
495      */
496     public static List<RecordField> getListRecordField( IEntry entry, int nIdRecord, Plugin plugin )
497     {
498         RecordFieldFilter filter = new RecordFieldFilter( );
499         filter.setIdRecord( nIdRecord );
500 
501         filter.setIdEntry( entry.getIdEntry( ) );
502 
503         return RecordFieldHome.getRecordFieldList( filter, plugin );
504     }
505 
506     /**
507      * get a Map which contains for each entry the list of recordField object associated
508      *
509      * @param lisEntry
510      *            the list of entry associate to the record
511      * @param nIdRecord
512      *            the id of the record
513      * @param plugin
514      *            plugin
515      * @param mapFieldEntry
516      *            a map containing all fields associated to the list of entry
517      * @return a map
518      */
519     public static Map<String, List<RecordField>> getSpecificMapIdEntryListRecordField( List<IEntry> lisEntry, int nIdRecord, Plugin plugin,
520             Map<Integer, Field> mapFieldEntry )
521     {
522         Map<String, List<RecordField>> map = new HashMap<String, List<RecordField>>( );
523 
524         List<Integer> listIdEntry = new ArrayList<Integer>( );
525 
526         for ( IEntry entryFistLevel : lisEntry )
527         {
528             listIdEntry.add( entryFistLevel.getIdEntry( ) );
529 
530             if ( entryFistLevel.getChildren( ) != null )
531             {
532                 for ( IEntry child : entryFistLevel.getChildren( ) )
533                 {
534                     listIdEntry.add( child.getIdEntry( ) );
535                 }
536             }
537         }
538 
539         List<RecordField> lRF = RecordFieldHome.getRecordFieldSpecificList( listIdEntry, nIdRecord, plugin, mapFieldEntry );
540         Map<Integer, List<RecordField>> tt = new HashMap<Integer, List<RecordField>>( );
541 
542         for ( RecordField rf : lRF )
543         {
544             Integer nIdEntry = Integer.valueOf( rf.getEntry( ).getIdEntry( ) );
545 
546             if ( tt.containsKey( nIdEntry ) )
547             {
548                 tt.get( nIdEntry ).add( rf );
549             }
550             else
551             {
552                 List<RecordField> lRFTmp = new ArrayList<RecordField>( );
553                 lRFTmp.add( rf );
554                 tt.put( nIdEntry, lRFTmp );
555             }
556         }
557 
558         Iterator<Entry<Integer, List<RecordField>>> it = tt.entrySet( ).iterator( );
559 
560         while ( it.hasNext( ) )
561         {
562             Entry<Integer, List<RecordField>> ent = it.next( );
563             map.put( ent.getKey( ).toString( ), ent.getValue( ) );
564         }
565 
566         return map;
567     }
568 
569     /**
570      * Get the request data and if there is no error insert the data in the record specified in parameter. return null if there is no error or else return a
571      * DirectoryError object
572      *
573      * @param request
574      *            the request
575      * @param record
576      *            the record
577      * @param plugin
578      *            the plugin
579      * @param locale
580      *            the locale
581      * @throws DirectoryErrorException
582      *             If an error occurs
583      */
584     public static void getDirectoryRecordData( HttpServletRequest request, Record record, Plugin plugin, Locale locale ) throws DirectoryErrorException
585     {
586         boolean bTestDirectoryError = true;
587         String strUploadAction = DirectoryAsynchronousUploadHandler.getHandler( ).getUploadAction( request );
588 
589         if ( StringUtils.isNotBlank( strUploadAction ) )
590         {
591             bTestDirectoryError = false;
592         }
593 
594         List<RecordField> listRecordFieldResult = new ArrayList<RecordField>( );
595         EntryFilter filter = new EntryFilter( );
596         filter.setIdDirectory( record.getDirectory( ).getIdDirectory( ) );
597         filter.setIsComment( EntryFilter.FILTER_FALSE );
598         filter.setIsEntryParentNull( EntryFilter.FILTER_TRUE );
599 
600         List<IEntry> listEntryFirstLevel = EntryHome.getEntryList( filter, plugin );
601 
602         for ( IEntry entry : listEntryFirstLevel )
603         {
604             DirectoryUtils.getDirectoryRecordFieldData( record, request, entry.getIdEntry( ), bTestDirectoryError, listRecordFieldResult, plugin, locale );
605         }
606 
607         record.setListRecordField( listRecordFieldResult );
608     }
609 
610     /**
611      * Get the request data and return a Map which contains for each entry the list of recordField object associated
612      *
613      * @param request
614      *            the request
615      * @param nIdDirectory
616      *            the id of the directory
617      * @param plugin
618      *            the plugin
619      * @param locale
620      *            the locale
621      * @return a map
622      * @throws DirectoryErrorException
623      *             If an error occurs
624      */
625     public static HashMap<String, List<RecordField>> getSearchRecordData( HttpServletRequest request, int nIdDirectory, Plugin plugin, Locale locale )
626             throws DirectoryErrorException
627     {
628         HashMap<String, List<RecordField>> mapSearchQuery = new HashMap<String, List<RecordField>>( );
629         List<RecordField> listRecordFieldTmp;
630         EntryFilter filter = new EntryFilter( );
631         filter.setIdDirectory( nIdDirectory );
632         filter.setIsComment( EntryFilter.FILTER_FALSE );
633         filter.setIsGroup( EntryFilter.FILTER_FALSE );
634         filter.setIsIndexed( EntryFilter.FILTER_TRUE );
635 
636         List<IEntry> listEntry = EntryHome.getEntryList( filter, plugin );
637 
638         for ( IEntry entry : listEntry )
639         {
640             listRecordFieldTmp = new ArrayList<RecordField>( );
641             DirectoryUtils.getDirectoryRecordFieldData( null, request, entry.getIdEntry( ), false, listRecordFieldTmp, plugin, locale );
642 
643             mapSearchQuery.put( Integer.toString( entry.getIdEntry( ) ), listRecordFieldTmp );
644         }
645 
646         return mapSearchQuery;
647     }
648 
649     /**
650      * perform in the record field list the record field associates with a entry specify in parameter. return null if there is no error in the response else
651      * return a DirectoryError Object
652      * 
653      * @param record
654      *            The record
655      * @param request
656      *            the request
657      * @param nIdEntry
658      *            the key of the entry
659      * @param bTestDirectoryError
660      *            true if we must test the validity of user input
661      * @param listRecordFieldResult
662      *            the list of record field result
663      * @param plugin
664      *            the plugin
665      * @param locale
666      *            the locale
667      * @throws DirectoryErrorException
668      *             If an error occurs
669      */
670     public static void getDirectoryRecordFieldData( Record record, HttpServletRequest request, int nIdEntry, boolean bTestDirectoryError,
671             List<RecordField> listRecordFieldResult, Plugin plugin, Locale locale ) throws DirectoryErrorException
672     {
673         IEntry entry = null;
674 
675         entry = EntryHome.findByPrimaryKey( nIdEntry, plugin );
676 
677         List<Field> listField = new ArrayList<Field>( );
678 
679         for ( Field field : entry.getFields( ) )
680         {
681             field = FieldHome.findByPrimaryKey( field.getIdField( ), plugin );
682             listField.add( field );
683         }
684 
685         entry.setFields( listField );
686 
687         if ( entry.getEntryType( ).getGroup( ) )
688         {
689             for ( IEntry entryChild : entry.getChildren( ) )
690             {
691                 getDirectoryRecordFieldData( record, request, entryChild.getIdEntry( ), bTestDirectoryError, listRecordFieldResult, plugin, locale );
692             }
693         }
694         else
695             if ( !entry.getEntryType( ).getComment( ) )
696             {
697                 entry.getRecordFieldData( record, request, bTestDirectoryError, false, listRecordFieldResult, locale );
698             }
699     }
700 
701     /**
702      * return the field which key is specified in parameter
703      *
704      * @param nIdField
705      *            the id of the field who is search
706      * @param listField
707      *            the list of field
708      * @return the field which key is specified in parameter
709      */
710     public static Field findFieldByIdInTheList( int nIdField, List<Field> listField )
711     {
712         if ( ( listField != null ) && !listField.isEmpty( ) )
713         {
714             for ( Field field : listField )
715             {
716                 if ( field.getIdField( ) == nIdField )
717                 {
718                     return field;
719                 }
720             }
721         }
722 
723         return null;
724     }
725 
726     /**
727      * return the field which value is specified in parameter
728      *
729      * @param strFieldValue
730      *            the value of the field who is search
731      * @param listField
732      *            the list of field
733      * @return the field which key is specified in parameter
734      */
735     public static Field findFieldByValueInTheList( String strFieldValue, List<Field> listField )
736     {
737         if ( ( strFieldValue != null ) && ( listField != null ) && !listField.isEmpty( ) )
738         {
739             for ( Field field : listField )
740             {
741                 if ( ( field.getValue( ) != null ) && field.getValue( ).trim( ).equals( strFieldValue.trim( ) ) )
742                 {
743                     return field;
744                 }
745             }
746         }
747 
748         return null;
749     }
750 
751     /**
752      * Return the field which title is specified in parameter
753      * 
754      * @param strTitle
755      *            the title
756      * @param listFields
757      *            the list of fields
758      * @return the field which title is specified in parameter
759      */
760     public static Field findFieldByTitleInTheList( String strTitle, List<Field> listFields )
761     {
762         if ( ( listFields == null ) || listFields.isEmpty( ) )
763         {
764             return null;
765         }
766 
767         for ( Field field : listFields )
768         {
769             if ( StringUtils.isNotBlank( strTitle ) )
770             {
771                 if ( trim( strTitle ).equals( trim( field.getTitle( ) ) ) )
772                 {
773                     return field;
774                 }
775             }
776             else
777                 if ( StringUtils.isBlank( field.getTitle( ) ) )
778                 {
779                     return field;
780                 }
781         }
782 
783         return null;
784     }
785 
786     /**
787      * return true if the field which key is specified in parameter is in the response list
788      *
789      * @param nIdField
790      *            the id of the field who is search
791      * @param listRecordField
792      *            the list of object Response
793      * @return true if the field which key is specified in parameter is in the response list
794      */
795     public static Boolean isFieldInTheRecordFieldList( int nIdField, List<RecordField> listRecordField )
796     {
797         for ( RecordField recordField : listRecordField )
798         {
799             if ( ( recordField.getField( ) != null ) && ( recordField.getField( ).getIdField( ) == nIdField ) )
800             {
801                 return true;
802             }
803         }
804 
805         return false;
806     }
807 
808     /**
809      * write the http header in the response
810      *
811      * @param request
812      *            the httpServletRequest
813      * @param response
814      *            the http response
815      * @param strFileName
816      *            the name of the file who must insert in the response
817      *
818      */
819     public static void addHeaderResponse( HttpServletRequest request, HttpServletResponse response, String strFileName )
820     {
821         response.setHeader( "Content-Disposition", "attachment ;filename=\"" + strFileName + "\"" );
822         response.setHeader( "Pragma", "public" );
823         response.setHeader( "Expires", "0" );
824         response.setHeader( "Cache-Control", "must-revalidate,post-check=0,pre-check=0" );
825     }
826 
827     /**
828      * convert a string to int
829      *
830      * @param strParameter
831      *            the string parameter to convert
832      * @return the conversion
833      */
834     public static int convertStringToInt( String strParameter )
835     {
836         int nIdParameter = -1;
837 
838         try
839         {
840             if ( strParameter != null )
841             {
842                 String strTrimedParameter = strParameter.trim( );
843 
844                 if ( strTrimedParameter.matches( REGEX_ID ) )
845                 {
846                     nIdParameter = Integer.parseInt( strTrimedParameter );
847                 }
848             }
849         }
850         catch( NumberFormatException ne )
851         {
852             AppLogService.error( ne );
853         }
854 
855         return nIdParameter;
856     }
857 
858     /**
859      * Returns a copy of the string , with leading and trailing whitespace omitted.
860      *
861      * @param strParameter
862      *            the string parameter to convert
863      * @return null if the strParameter is null other return with leading and trailing whitespace omitted.
864      */
865     public static String trim( String strParameter )
866     {
867         if ( strParameter != null )
868         {
869             return strParameter.trim( );
870         }
871 
872         return strParameter;
873     }
874 
875     /**
876      * Get the file contains in the request from the name of the input file
877      *
878      * @param strFileInputName
879      *            le name of the input file file
880      * @param request
881      *            the request
882      * @return file the file contains in the request from the name of the input file
883      */
884     public static File getFileData( String strFileInputName, HttpServletRequest request )
885     {
886         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
887         FileItem fileItem = multipartRequest.getFile( strFileInputName );
888 
889         if ( ( fileItem != null ) && ( fileItem.getName( ) != null ) && !EMPTY_STRING.equals( fileItem.getName( ) ) )
890         {
891             File file = new File( );
892             PhysicalFile physicalFile = new PhysicalFile( );
893             physicalFile.setValue( fileItem.get( ) );
894             file.setTitle( FileUploadService.getFileNameOnly( fileItem ) );
895             file.setSize( (int) fileItem.getSize( ) );
896             file.setPhysicalFile( physicalFile );
897             file.setMimeType( FileSystemUtil.getMIMEType( FileUploadService.getFileNameOnly( fileItem ) ) );
898 
899             return file;
900         }
901 
902         return null;
903     }
904 
905     /**
906      * Builds a query with filters placed in parameters. Consider using {@link #buildQueryWithFilter(StringBuilder, List, String)} instead.
907      *
908      * @param strSelect
909      *            the select of the query
910      * @param listStrFilter
911      *            the list of filter to add in the query
912      * @param strOrder
913      *            the order by of the query
914      * @return a query
915      */
916     public static String buildRequetteWithFilter( String strSelect, List<String> listStrFilter, String strOrder )
917     {
918         return buildQueryWithFilter( new StringBuilder( strSelect ), listStrFilter, strOrder );
919     }
920 
921     /**
922      * Builds a query with filters placed in parameters
923      *
924      * @param sbSQL
925      *            the beginning of the query
926      * @param listFilter
927      *            the list of filter to add in the query
928      * @param strOrder
929      *            the order by of the query
930      * @return a query
931      */
932     public static String buildQueryWithFilter( StringBuilder sbSQL, List<String> listFilter, String strOrder )
933     {
934         int nCount = 0;
935 
936         for ( String strFilter : listFilter )
937         {
938             if ( ++nCount == 1 )
939             {
940                 sbSQL.append( CONSTANT_WHERE );
941             }
942 
943             sbSQL.append( strFilter );
944 
945             if ( nCount != listFilter.size( ) )
946             {
947                 sbSQL.append( CONSTANT_AND );
948             }
949         }
950 
951         if ( strOrder != null )
952         {
953             sbSQL.append( strOrder );
954         }
955 
956         return sbSQL.toString( );
957     }
958 
959     /**
960      * replace special characters in the string passed as a parameter
961      *
962      * @param strSource
963      *            the string
964      * @return substitute special in the string passed as a parameter
965      */
966     public static String substituteSpecialCaractersForExport( String strSource )
967     {
968         String strResult = EMPTY_STRING;
969 
970         if ( strSource != null )
971         {
972             strResult = strSource;
973         }
974 
975         strResult = StringUtil.substitute( strResult, CONSTANT_CHARACTER_SIMPLE_QUOTE, CONSTANT_CHARACTER_DOUBLE_QUOTE );
976         strResult = StringUtil.substitute( strResult, EMPTY_STRING, CONSTANTE_CHARACTER_RETURN );
977         strResult = StringUtil.substitute( strResult, EMPTY_STRING, CONSTANTE_CHARACTERNEW_LINE );
978 
979         return strResult;
980     }
981 
982     /**
983      * Filter a list of field for a given user
984      *
985      * @param listField
986      *            a list of field
987      * @param user
988      *            an adminUser
989      * @return a field list
990      */
991     public static List<Field> getAuthorizedFieldsByWorkgroup( List<Field> listField, AdminUser user )
992     {
993         List<Field> listFieldAuthorized = new ArrayList<Field>( );
994 
995         for ( Field field : listField )
996         {
997             // filter by workgroup
998             if ( AdminWorkgroupService.isAuthorized( field, user ) )
999             {
1000                 listFieldAuthorized.add( field );
1001             }
1002         }
1003 
1004         return listFieldAuthorized;
1005     }
1006 
1007     /**
1008      * Filter a list of field for a given user
1009      *
1010      * @param listField
1011      *            a list of field
1012      * @param request
1013      *            The http request
1014      * @return a field list
1015      */
1016     public static List<Field> getAuthorizedFieldsByRole( HttpServletRequest request, List<Field> listField )
1017     {
1018         List<Field> listFieldAuthorized = new ArrayList<Field>( );
1019 
1020         for ( Field field : listField )
1021         {
1022             // filter by workgroup
1023             if ( ( !SecurityService.isAuthenticationEnable( ) ) || ( field.getRoleKey( ) == null ) || field.getRoleKey( ).equals( Directory.ROLE_NONE )
1024                     || SecurityService.getInstance( ).isUserInRole( request, field.getRoleKey( ) ) )
1025             {
1026                 listFieldAuthorized.add( field );
1027             }
1028         }
1029 
1030         return listFieldAuthorized;
1031     }
1032 
1033     /**
1034      * Removes from list all the elements that are not contained in the other list Faster than classic "List.retainAll" because each id is unique
1035      *
1036      * @param list1
1037      *            input list 1
1038      * @param list2
1039      *            input list 2
1040      * @return the result list
1041      */
1042     public static List<Integer> retainAll( List<Integer> list1, List<Integer> list2 )
1043     {
1044         List<Integer> lresult = null;
1045 
1046         if ( list1.size( ) < list2.size( ) )
1047         {
1048             Set<Integer> ts1 = new TreeSet<Integer>( list2 );
1049 
1050             Iterator<Integer> it = list1.iterator( );
1051 
1052             while ( it.hasNext( ) )
1053             {
1054                 if ( !ts1.contains( it.next( ) ) )
1055                 {
1056                     it.remove( );
1057                 }
1058             }
1059 
1060             lresult = list1;
1061         }
1062         else
1063         {
1064             Set<Integer> ts1 = new TreeSet<Integer>( list1 );
1065 
1066             Iterator<Integer> it = list2.iterator( );
1067 
1068             while ( it.hasNext( ) )
1069             {
1070                 if ( !ts1.contains( it.next( ) ) )
1071                 {
1072                     it.remove( );
1073                 }
1074             }
1075 
1076             lresult = list2;
1077         }
1078 
1079         return lresult;
1080     }
1081 
1082     /**
1083      * Like {@link List#retainAll(java.util.Collection)}, keeping first list order. This method is based on the fact that list1 and list2 have unique elements.
1084      *
1085      * @param list1
1086      *            the first list
1087      * @param list2
1088      *            the other list
1089      * @return first list
1090      */
1091     public static List<Integer> retainAllIdsKeepingFirstOrder( List<Integer> list1, List<Integer> list2 )
1092     {
1093         
1094         // makes contains quicker
1095         TreeSet<Integer> ts = new TreeSet<>( list2 );
1096 
1097         return list1.stream().filter(ts::contains).collect(Collectors.toList());
1098     }
1099 
1100     /**
1101      * Get the search record creation date from the request
1102      * 
1103      * @param request
1104      *            The request
1105      * @param dateTypeParameter
1106      *            The date type parameter
1107      * @param locale
1108      *            The locale
1109      * @return The date formation into the given locale, or null if no date was found
1110      */
1111     public static Date getSearchRecordDateCreationFromRequest( HttpServletRequest request, String dateTypeParameter, Locale locale )
1112     {
1113         String strDate = request.getParameter( dateTypeParameter );
1114 
1115         if ( strDate != null )
1116         {
1117             return DateUtil.formatDate( strDate, locale );
1118         }
1119 
1120         return null;
1121     }
1122 
1123     /**
1124      * Get the result list according to queries
1125      *
1126      * @param request
1127      *            The {@link HttpServletRequest}
1128      * @param directory
1129      *            The {@link Directory}
1130      * @param bWorkflowServiceEnable
1131      *            true if the WorkflowService is enabled
1132      * @param bUseFilterDirectory
1133      *            True to use filter directory
1134      * @param searchFields
1135      *            The search field
1136      * @param adminUser
1137      *            The admin user
1138      * @param locale
1139      *            The locale
1140      * @return The list of id records
1141      */
1142     public static List<Integer> getListResults( HttpServletRequest request, Directory directory, boolean bWorkflowServiceEnable, boolean bUseFilterDirectory,
1143             IDirectorySearchFields searchFields, AdminUser adminUser, Locale locale )
1144     {
1145         return getListResults( request, directory, bWorkflowServiceEnable, bUseFilterDirectory, null, RecordFieldFilter.ORDER_NONE, searchFields, adminUser,
1146                 locale );
1147     }
1148 
1149     /**
1150      * Get the result list according to queries
1151      *
1152      * @param request
1153      *            The {@link HttpServletRequest}
1154      * @param directory
1155      *            The {@link Directory}
1156      * @param bWorkflowServiceEnable
1157      *            true if the WorkflowService is enabled
1158      * @param bUseFilterDirectory
1159      *            True to use filter directory
1160      * @param sortEntry
1161      *            The entry to sort results by
1162      * @param nSortOrder
1163      *            The sort order
1164      * @param searchFields
1165      *            The search field
1166      * @param adminUser
1167      *            The admin user
1168      * @param locale
1169      *            The locale
1170      * @return The list of id records
1171      */
1172     public static List<Integer> getListResults( HttpServletRequest request, Directory directory, boolean bWorkflowServiceEnable, boolean bUseFilterDirectory,
1173             IEntry sortEntry, int nSortOrder, IDirectorySearchFields searchFields, AdminUser adminUser, Locale locale )
1174     {
1175         // call search service
1176         RecordFieldFilter filter = new RecordFieldFilter( );
1177         filter.setIdDirectory( directory.getIdDirectory( ) );
1178 
1179         List<Integer> listResultRecordId = null;
1180 
1181         // filter by record state
1182         filter.setIsDisabled( searchFields.getIsDisabled( ) );
1183 
1184         // filter by role
1185         if ( searchFields instanceof DirectorySiteSearchFields && ( ( (DirectorySiteSearchFields) searchFields ).getRoleKeyList( ) != null ) )
1186         {
1187             filter.setRoleKeyList( ( (DirectorySiteSearchFields) searchFields ).getRoleKeyList( ),
1188                     ( (DirectorySiteSearchFields) searchFields ).isIncludeRoleNone( ), ( (DirectorySiteSearchFields) searchFields ).isIncludeRoleNull( ) );
1189         }
1190 
1191         // filter by workgroup
1192         if ( adminUser != null )
1193         {
1194             filter.setWorkgroupKeyList( AdminWorkgroupService.getUserWorkgroups( adminUser, locale ) );
1195         }
1196 
1197         // sort filter
1198         if ( sortEntry == null )
1199         {
1200             filter.setSortEntry( searchFields.getSortEntry( ) );
1201         }
1202         else
1203         {
1204             filter.setSortEntry( sortEntry );
1205         }
1206 
1207         if ( nSortOrder == RecordFieldFilter.ORDER_NONE )
1208         {
1209             filter.setSortOrder( searchFields.getSortOrder( ) );
1210         }
1211         else
1212         {
1213             filter.setSortOrder( nSortOrder );
1214         }
1215 
1216         filter.setOrderByDateModification( searchFields.isSortByDateModification( ) );
1217 
1218         // If workflow active, filter by workflow state
1219         if ( ( directory.getIdWorkflow( ) != DirectoryUtils.CONSTANT_ID_NULL ) && bWorkflowServiceEnable )
1220         {
1221             if ( bUseFilterDirectory )
1222             {
1223                 listResultRecordId = DirectorySearchService.getInstance( ).getSearchResults( directory, searchFields.getMapQuery( ),
1224                         searchFields.getDateCreationRecord( ), searchFields.getDateCreationBeginRecord( ), searchFields.getDateCreationEndRecord( ),
1225                         searchFields.getDateModificationRecord( ), searchFields.getDateModificationBeginRecord( ),
1226                         searchFields.getDateModificationEndRecord( ), filter, getPlugin( ) );
1227             }
1228             else
1229             {
1230                 listResultRecordId = DirectorySearchService.getInstance( ).getSearchResults( directory, null, null, null, null, filter, getPlugin( ) );
1231             }
1232 
1233             List<Integer> listTmpResultRecordId = WorkflowService.getInstance( ).getAuthorizedResourceList( Record.WORKFLOW_RESOURCE_TYPE,
1234                     directory.getIdWorkflow( ), ( (DirectoryAdminSearchFields) searchFields ).get_nIdWorkflowSate( ),
1235                     Integer.valueOf( directory.getIdDirectory( ) ), adminUser );
1236 
1237             listResultRecordId = DirectoryUtils.retainAllIdsKeepingFirstOrder( listResultRecordId, listTmpResultRecordId );
1238         }
1239         else
1240         {
1241             if ( bUseFilterDirectory )
1242             {
1243                 listResultRecordId = DirectorySearchService.getInstance( ).getSearchResults( directory, searchFields.getMapQuery( ),
1244                         searchFields.getDateCreationRecord( ), searchFields.getDateCreationBeginRecord( ), searchFields.getDateCreationEndRecord( ),
1245                         searchFields.getDateModificationRecord( ), searchFields.getDateModificationBeginRecord( ),
1246                         searchFields.getDateModificationEndRecord( ), filter, getPlugin( ) );
1247             }
1248             else
1249             {
1250                 listResultRecordId = DirectorySearchService.getInstance( ).getSearchResults( directory, null, null, null, null, filter, getPlugin( ) );
1251             }
1252         }
1253 
1254         return listResultRecordId;
1255     }
1256 
1257     /**
1258      * Gets the plugin
1259      *
1260      * @return the plugin
1261      */
1262     public static Plugin getPlugin( )
1263     {
1264         return PluginService.getPlugin( DirectoryPlugin.PLUGIN_NAME );
1265     }
1266 
1267     /**
1268      * return url of the jsp manage directory record
1269      *
1270      * @param request
1271      *            The HTTP request
1272      * @param nIdDirectory
1273      *            the directory id
1274      * @return url of the jsp manage directory record
1275      */
1276     public static String getJspManageDirectoryRecord( HttpServletRequest request, int nIdDirectory )
1277     {
1278         UrlItem urlItem = new UrlItem( AppPathService.getBaseUrl( request ) + JSP_MANAGE_DIRECTORY_RECORD );
1279         urlItem.addParameter( PARAMETER_ID_DIRECTORY, nIdDirectory );
1280         urlItem.addParameter( PARAMETER_SESSION, PARAMETER_SESSION );
1281 
1282         String strSortedAttributeName = request.getParameter( Parameters.SORTED_ATTRIBUTE_NAME );
1283         String strAscSort = null;
1284         Directory directory = DirectoryHome.findByPrimaryKey( nIdDirectory, getPlugin( ) );
1285 
1286         if ( ( directory != null ) && ( ( strSortedAttributeName != null ) || ( directory.getIdSortEntry( ) != null ) ) )
1287         {
1288             if ( strSortedAttributeName == null )
1289             {
1290                 strSortedAttributeName = directory.getIdSortEntry( );
1291             }
1292 
1293             strAscSort = request.getParameter( Parameters.SORTED_ASC );
1294 
1295             urlItem.addParameter( Parameters.SORTED_ATTRIBUTE_NAME, strSortedAttributeName );
1296             urlItem.addParameter( Parameters.SORTED_ASC, strAscSort );
1297         }
1298 
1299         return urlItem.getUrl( );
1300     }
1301 
1302     /**
1303      * Convert a map of ( String, String ) into a {@link ReferenceList}
1304      *
1305      * @param map
1306      *            the map to convert
1307      * @return a {@link ReferenceList}
1308      */
1309     public static ReferenceList convertMapToReferenceList( Map<String, String> map )
1310     {
1311         ReferenceList ref = new ReferenceList( );
1312 
1313         if ( map != null )
1314         {
1315             for ( Entry<String, String> userInfo : map.entrySet( ) )
1316             {
1317                 ref.addItem( userInfo.getKey( ), userInfo.getValue( ) );
1318             }
1319         }
1320 
1321         return ref;
1322     }
1323 
1324     /**
1325      * Get the file name of a file from the url
1326      *
1327      * @param strUrl
1328      *            the url of the file
1329      * @return the file name
1330      */
1331     public static String getFileName( String strUrl )
1332     {
1333         String strFileName = StringUtils.EMPTY;
1334         DirectoryAsynchronousUploadHandler handler = DirectoryAsynchronousUploadHandler.getHandler( );
1335 
1336         try
1337         {
1338             strFileName = handler.getFileName( strUrl );
1339         }
1340         catch( BlobStoreClientException e )
1341         {
1342             AppLogService.error( e );
1343         }
1344 
1345         return strFileName;
1346     }
1347 
1348     /**
1349      * Do download a file
1350      *
1351      * @param strUrl
1352      *            the url of the file to download
1353      * @param strFilePath
1354      *            the file path to download the file
1355      */
1356     public static void doDownloadFile( String strUrl, String strFilePath )
1357     {
1358         DirectoryAsynchronousUploadHandler handler = DirectoryAsynchronousUploadHandler.getHandler( );
1359 
1360         try
1361         {
1362             handler.doDownloadFile( strUrl, strFilePath );
1363         }
1364         catch( BlobStoreClientException e )
1365         {
1366             AppLogService.error( e );
1367         }
1368     }
1369 
1370     /**
1371      * Do download a file
1372      *
1373      * @param strUrl
1374      *            the url of the file to download
1375      * @return a {@link FileItem}
1376      */
1377     public static File doDownloadFile( String strUrl )
1378     {
1379         FileItem fileItem = null;
1380         File file = null;
1381         DirectoryAsynchronousUploadHandler handler = DirectoryAsynchronousUploadHandler.getHandler( );
1382 
1383         try
1384         {
1385             fileItem = handler.doDownloadFile( strUrl );
1386         }
1387         catch( BlobStoreClientException e )
1388         {
1389             AppLogService.error( e );
1390         }
1391 
1392         if ( fileItem != null )
1393         {
1394             if ( fileItem.getSize( ) < Integer.MAX_VALUE )
1395             {
1396                 PhysicalFile physicalFile = new PhysicalFile( );
1397                 physicalFile.setValue( fileItem.get( ) );
1398 
1399                 String strFileName = fileItem.getName( );
1400 
1401                 if ( StringUtils.isNotBlank( strFileName ) )
1402                 {
1403                     String strExtension = StringUtils.EMPTY;
1404                     int nLastIndexOfDot = strFileName.lastIndexOf( CONSTANT_DOT );
1405 
1406                     if ( nLastIndexOfDot != DirectoryUtils.CONSTANT_ID_NULL )
1407                     {
1408                         strExtension = strFileName.substring( nLastIndexOfDot + 1 );
1409                     }
1410 
1411                     file = new File( );
1412                     file.setPhysicalFile( physicalFile );
1413                     file.setSize( (int) fileItem.getSize( ) );
1414                     file.setTitle( strFileName );
1415 
1416                     if ( StringUtils.isNotBlank( fileItem.getContentType( ) ) )
1417                     {
1418                         file.setMimeType( fileItem.getContentType( ) );
1419                     }
1420                     else
1421                     {
1422                         file.setMimeType( FileSystemUtil.getMIMEType( strFileName ) );
1423                     }
1424 
1425                     file.setExtension( strExtension );
1426                 }
1427             }
1428             else
1429             {
1430                 AppLogService.error( "DirectoryUtils : File too big ! fr.paris.lutece.plugins.directory.business.File.setSize "
1431                         + "must have Integer parameter, in other words a size lower than '" + Integer.MAX_VALUE + "'" );
1432             }
1433         }
1434 
1435         return file;
1436     }
1437 
1438     /**
1439      * Build the map id entry - list record field
1440      *
1441      * @param map
1442      *            the map
1443      * @param entry
1444      *            the entry
1445      * @param filter
1446      *            the filter
1447      * @param plugin
1448      *            the plugin
1449      * @param bGetFileName
1450      *            true if it must get the file name, false otherwise <br>
1451      *            Warning : The file name is fetch by a webservice call. Beware of performance.
1452      */
1453     private static void buildMapIdEntryListRecordField( Map<String, List<RecordField>> map, IEntry entry, RecordFieldFilter filter, Plugin plugin,
1454             boolean bGetFileName )
1455     {
1456         filter.setIdEntry( entry.getIdEntry( ) );
1457 
1458         List<RecordField> listRecordFields = RecordFieldHome.getRecordFieldList( filter, plugin );
1459 
1460         // If entry is type download url, then fetch the file name
1461         if ( entry instanceof EntryTypeDownloadUrl && bGetFileName )
1462         {
1463             if ( ( listRecordFields != null ) && !listRecordFields.isEmpty( ) )
1464             {
1465                 for ( RecordField recordField : listRecordFields )
1466                 {
1467                     if ( ( recordField != null ) && StringUtils.isNotBlank( recordField.getValue( ) ) )
1468                     {
1469                         recordField.setFileName( getFileName( recordField.getValue( ) ) );
1470                     }
1471                 }
1472             }
1473         }
1474 
1475         map.put( Integer.toString( entry.getIdEntry( ) ), listRecordFields );
1476     }
1477 
1478     /**
1479      * Get the base url
1480      *
1481      * @param request
1482      *            the HTTP request
1483      * @return the base url
1484      */
1485     public static String getBaseUrl( HttpServletRequest request )
1486     {
1487         String strBaseUrl = StringUtils.EMPTY;
1488 
1489         if ( request != null )
1490         {
1491             strBaseUrl = AppPathService.getBaseUrl( request );
1492         }
1493         else
1494         {
1495             strBaseUrl = AppPropertiesService.getProperty( PROPERTY_LUTECE_BASE_URL );
1496 
1497             if ( StringUtils.isBlank( strBaseUrl ) )
1498             {
1499                 strBaseUrl = AppPropertiesService.getProperty( PROPERTY_LUTECE_PROD_URL );
1500             }
1501         }
1502 
1503         return strBaseUrl;
1504     }
1505 
1506     /**
1507      * Depopulate the directory into a map of key - value
1508      * 
1509      * @param directory
1510      *            the directory
1511      * @return a map of key - value
1512      */
1513     public static Map<String, Object> depopulate( Directory directory )
1514     {
1515         Map<String, Object> mapAttributes = new HashMap<String, Object>( );
1516 
1517         for ( java.lang.reflect.Field field : Directory.class.getDeclaredFields( ) )
1518         {
1519             DirectoryAttribute attribute = field.getAnnotation( DirectoryAttribute.class );
1520 
1521             if ( attribute != null )
1522             {
1523                 String strAttributeKey = attribute.value( );
1524 
1525                 try
1526                 {
1527                     field.setAccessible( true );
1528 
1529                     Object attributeValue = ReflectionUtils.getField( field, directory );
1530                     mapAttributes.put( strAttributeKey, attributeValue );
1531                 }
1532                 catch( SecurityException e )
1533                 {
1534                     AppLogService.error( e );
1535                 }
1536             }
1537         }
1538 
1539         return mapAttributes;
1540     }
1541 
1542     /**
1543      * return a map containing all fields containing in the list of entry
1544      * 
1545      * @param listEntry
1546      *            the entyList
1547      * @param plugin
1548      *            the plugin
1549      * @return a map of fields associated
1550      */
1551     public static Map<Integer, Field> getMapFieldsOfListEntry( List<IEntry> listEntry, Plugin plugin )
1552     {
1553 
1554         Map<Integer, Field> mapFieldEntry = new HashMap<Integer, Field>( );
1555 
1556         for ( IEntry entry : listEntry )
1557         {
1558 
1559             List<Field> listField = FieldHome.getFieldListByIdEntry( entry.getIdEntry( ), plugin );
1560             for ( Field field : listField )
1561             {
1562                 mapFieldEntry.put( field.getIdField( ), field );
1563             }
1564 
1565         }
1566 
1567         return mapFieldEntry;
1568     }
1569 
1570 }