1 /*
2 * Copyright (c) 2002-2025, 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.util.filesystem;
35
36 import fr.paris.lutece.portal.service.util.AppLogService;
37 import fr.paris.lutece.portal.service.util.AppPathService;
38
39 // Java IO
40 import java.io.File;
41 import java.io.IOException;
42
43 // Java Util
44 import java.util.ArrayList;
45 import java.util.List;
46 import java.util.TreeSet;
47
48 import javax.activation.MimetypesFileTypeMap;
49
50 import org.apache.commons.lang3.ArrayUtils;
51
52 /**
53 * This Service is used to manipulate Files and Directories in the File System.
54 */
55 public final class FileSystemUtil
56 {
57 private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
58 private static final String FILE_SEPARATOR = File.separator;
59 private static final String FILE_MIME_TYPE = "WEB-INF" + FILE_SEPARATOR + "conf" + FILE_SEPARATOR + "mime.types";
60
61 /**
62 * Private constructor
63 */
64 private FileSystemUtil( )
65 {
66 }
67
68 /**
69 * Returns the sub-directories of a directory.
70 *
71 * @param strRoot
72 * the root directory.
73 * @param strDirectoryRelativePath
74 * the parent directory.
75 * @throws DirectoryNotFoundException
76 * if the directory does not exist.
77 * @return The list of sub-directories.
78 */
79 public static List<File> getSubDirectories( String strRoot, String strDirectoryRelativePath ) throws DirectoryNotFoundException
80 {
81 // Files' list init
82 ArrayList<File> listFiles = new ArrayList<>( );
83
84 // Directory path
85 String strDirectory = strRoot + strDirectoryRelativePath;
86
87 // Directory
88 File fDirectory = new File( strDirectory );
89
90 if ( !fDirectory.exists( ) )
91 {
92 throw new DirectoryNotFoundException( );
93 }
94
95 File [ ] files = fDirectory.listFiles( );
96 if ( ArrayUtils.isEmpty( files ) )
97 {
98 return listFiles;
99 }
100
101 for ( int i = 0; i < files.length; i++ )
102 {
103 File file = files [i];
104
105 if ( file.isDirectory( ) )
106 {
107 listFiles.add( file );
108 }
109 }
110
111 return listFiles;
112 }
113
114 /**
115 * Returns the files of a directory, alphabetically ordered.
116 *
117 * @param strRoot
118 * The root directory
119 * @param strDirectoryRelativePath
120 * The directory's path relative to the root directory.
121 * @throws DirectoryNotFoundException
122 * if the directory does not exist.
123 * @return The list of files.
124 */
125 public static List<File> getFiles( String strRoot, String strDirectoryRelativePath ) throws DirectoryNotFoundException
126 {
127 // Use a treeset to order files with a comparator
128 TreeSet<File> set = new TreeSet<>( new FileNameComparator( ) );
129
130 // Directory path
131 String strDirectory = strRoot + strDirectoryRelativePath;
132
133 // Directory
134 File fDirectory = new File( strDirectory );
135
136 if ( !fDirectory.exists( ) )
137 {
138 throw new DirectoryNotFoundException( );
139 }
140
141 File [ ] files = fDirectory.listFiles( );
142 if ( ArrayUtils.isEmpty( files ) )
143 {
144 return new ArrayList<>( set );
145 }
146
147 for ( int i = 0; i < files.length; i++ )
148 {
149 File file = files [i];
150
151 if ( file.isFile( ) )
152 {
153 set.add( file );
154 }
155 }
156
157 // Convert into a list to preserve the order
158 return new ArrayList<>( set );
159 }
160
161 /**
162 * Return the mimetype of the file depending of his extension and the mime.types file
163 *
164 * @param strFilename
165 * the file name
166 * @return the file mime type
167 */
168 public static String getMIMEType( String strFilename )
169 {
170 try
171 {
172 MimetypesFileTypeMap mimeTypeMap = new MimetypesFileTypeMap( AppPathService.getWebAppPath( ) + File.separator + FILE_MIME_TYPE );
173
174 return mimeTypeMap.getContentType( strFilename.toLowerCase( ) );
175 }
176 catch( IOException e )
177 {
178 AppLogService.error( e.getMessage( ), e );
179
180 return DEFAULT_MIME_TYPE;
181 }
182 }
183 }