source: trunk/grails-app/services/nl/tno/metagenomics/files/FileService.groovy @ 2

Last change on this file since 2 was 2, checked in by robert@…, 8 years ago

Initial import of basic functionality

File size: 9.4 KB
Line 
1/**
2 * FileService Service
3 *
4 * Contains methods for file uploads
5 *
6 * @author      Robert Horlings
7 * @since       20100521
8 * @package     dbnp.studycapturing
9 *
10 * Revision information:
11 * $Rev$
12 * $Author$
13 * $Date$
14 */
15package nl.tno.metagenomics.files
16
17import org.codehaus.groovy.grails.commons.ApplicationHolder
18import org.codehaus.groovy.grails.commons.ConfigurationHolder
19
20/**
21 * Convenience methods for uploading and handling files
22 * @author robert@isdat.nl
23 *
24 */
25class FileService implements Serializable {
26        // ApplicationContext applicationContext
27
28        // Must be false, since the webflow can't use a transactional service. See
29        // http://www.grails.org/WebFlow for more information
30        static transactional = false
31
32        /**
33         * Handles the upload of a file using the ajax upload method
34         * @param value                 The value entered into the new filed. May be a File object of an uploaded file or a string containing a filename
35         * @param currentFile   Filename of the current file in the database.
36         * @param directory             Path to the directory where the file should move to. See absolutePath() method for more information.
37         *                                              Defaults to the uploadDir from configuration
38         * @return      Filename of the uploaded file
39         */
40        def String handleUploadedFile( def value, String currentFile, File directory = null) {
41                if( directory == null )
42                        directory = getUploadDir();
43
44                // If NULL is given or "*deleted*", the field value is emptied and the old file is removed
45                // If an empty string is given, the field value is kept as was
46                // If a file is given, it is moved to the right directory. Old files are deleted. If
47                //   the file does not exist, the field is kept
48                // If a string is given, it is supposed to be a file in the upload directory. If
49                //   it is different from the old one, the old one is deleted. If the file does not
50                //   exist, the old one is kept.
51
52                if (value == null || ( value.class == String && value == '*deleted*' ) ) {
53                        // If NULL is given, the field value is emptied and the old file is removed
54                        value = "";
55                        if (currentFile) {
56                                delete(currentFile, directory)
57                        }
58                } else if (value.class == File) {
59                        // a file was given. Attempt to move it to the upload directory, and
60                        // afterwards, store the filename. If the file doesn't exist
61                        // or can't be moved, "" is returned
62                        value = moveFileToUploadDir(value, directory);
63
64                        if (value) {
65                                if (currentFile) {
66                                        delete(currentFile, directory)
67                                }
68                        } else {
69                                value = currentFile;
70                        }
71                } else if (value == "") {
72                        value = currentFile;
73                } else {
74                        if (value != currentFile) {
75                                if (fileExists(value, directory)) {
76                                        // When a FILE field is filled, and a new file is set
77                                        // the existing file should be deleted
78                                        if (currentFile) {
79                                                delete(currentFile, directory)
80                                        }
81                                } else {
82                                        // If the file does not exist, the field is kept
83                                        value = currentFile;
84                                }
85                        }
86                }
87
88                return value as String;
89        }
90
91        /**
92         * Returns the directory for uploading files. Makes it easy to change the
93         * path to the directory, if needed
94         */
95        def File getUploadDir() {
96                // Find the file upload directory name from the configuration
97                String uploadDir = ConfigurationHolder.config.metagenomics.fileUploadDir
98
99                if( !uploadDir )
100                        uploadDir = "fileuploads"
101
102                return absolutePath( uploadDir );
103        }
104
105        /**
106         * Returns as File object to a given file
107         */
108        def File get( String filename, File directory = null ) {
109                if( directory == null )
110                        directory = getUploadDir()
111
112                return new File( directory, filename );
113        }
114
115        /**
116         * Check whether the given file exists in the upload directory
117         */
118        def boolean fileExists( String filename, File directory = null ) {
119                if( directory == null )
120                        directory = getUploadDir()
121
122                return new File( directory, filename ).exists();
123        }
124
125        /**
126         * Deletes a file in the upload dir, if it exists
127         */
128        def boolean delete( String filename, File directory = null ) {
129                if( directory == null )
130                        directory = getUploadDir()
131
132                def f = new File( directory, filename );
133                if( f.exists() ) {
134                        f.delete();
135                }
136        }
137
138        /**
139         * Moves the given file to the upload directory.
140         *
141         * @return Filename given to the file on our system or "" if the moving fails
142         */
143        def String moveFileToUploadDir( File file, String originalFilename, File directory = null ) {
144                if( directory == null )
145                        directory = getUploadDir()
146
147                println "Moving " + file + " with originalname " + originalFilename + " to " + directory
148
149                try {
150                        if( file.exists() ) {
151                                def newFilename = getUniqueFilename( originalFilename, directory );
152                                file.renameTo( new File( directory, newFilename ) )
153                                return newFilename
154                        } else {
155                                return "";
156                        }
157                } catch(Exception exception) {
158                        throw exception; // return ""
159                }
160        }
161
162        /**
163         * Moves the given uploaded file to the upload directory
164         *
165         * MultipartFile is the class used for uploaded files
166         *
167         * @return Filename given to the file on our system or "" if the moving fails
168         */
169        def String moveFileToUploadDir( org.springframework.web.multipart.MultipartFile file, String originalFilename, File directory = null ) {
170                if( directory == null )
171                        directory = getUploadDir()
172
173                try {
174                        def newFilename = getUniqueFilename( originalFilename, directory );
175                        file.transferTo( new File( directory, newFilename ))
176                        return newFilename
177                } catch(Exception exception) {
178                        throw exception; // return ""
179                }
180        }
181
182        /**
183         * Moves the given file to the upload directory.
184         *
185         * @return Filename given to the file on our system or "" if the moving fails
186         */
187        def String moveFileToUploadDir( File file, File dir = null ) {
188                moveFileToUploadDir( file, file.getName(), dir );
189        }
190
191        /**
192         * Moves the given uploaded file to the upload directory
193         *
194         * MultipartFile is the class used for uploaded files
195         *
196         * @return Filename given to the file on our system or "" if the moving fails
197         */
198        def String moveFileToUploadDir( org.springframework.web.multipart.MultipartFile file, File dir = null ) {
199                moveFileToUploadDir( file, file.getOriginalFilename(), dir );
200        }
201
202        /**
203         * Returns a filename that looks like the originalFilename and does not yet
204         * exist in the upload directory.
205         *
206         * @return String filename that does not yet exist in the upload directory
207         */
208        def String getUniqueFilename( String originalFilename, File directory = null ) {
209                if( directory == null )
210                        directory = getUploadDir()
211
212                if( fileExists( originalFilename, directory ) ) {
213                        def basename;
214                        def extension;
215
216                        // Split the filename into basename and extension
217                        if( originalFilename.lastIndexOf('.') >= 0 ) {
218                                basename = originalFilename[ 0 .. originalFilename.lastIndexOf('.') - 1 ];
219                                extension = originalFilename[ originalFilename.lastIndexOf('.')..originalFilename.size() - 1];
220                        } else {
221                                basename = originalFilename;
222                                extension = '';
223                        }
224
225                        // Find a filename that does not yet exist
226                        def postfix = 0;
227                        def newFilename = basename + '.copy' + postfix + extension;
228                        while( fileExists( newFilename, directory ) ) {
229                                postfix++;
230                                newFilename = basename + '.copy' + postfix + extension;
231                        }
232
233                        return newFilename;
234                } else {
235                        return originalFilename;
236                }
237        }
238
239       
240        /**
241         * Returns the original filename for a file that has been uploaded, but renamed
242         * using the uniqueFilename method
243         *
244         * @return String Original filename
245         */
246        def String originalFilename( String filename ) {
247                def basename;
248                def extension;
249
250                // Split the filename into basename and extension
251                if( filename.lastIndexOf('.') >= 0 ) {
252                        basename = filename[ 0 .. filename.lastIndexOf('.') - 1 ];
253                        extension = filename[ filename.lastIndexOf('.')..filename.size() - 1];
254                } else {
255                        basename = originalFilename;
256                        extension = '';
257                }
258
259                // Search whether this file has been renamed (containing copy#)
260                if( basename.lastIndexOf('.') >= 0 ) {
261                        def copypart = basename[ basename.lastIndexOf('.')+1..basename.size() - 1];
262                        def rest = basename[ 0 .. basename.lastIndexOf('.') - 1 ];
263                        if( copypart ==~ /copy[0-9]+/ ) {
264                                return rest + extension;
265                        } else {
266                                return filename;
267                        }
268                } else {
269                        return filename;
270                }
271        }
272       
273        /**
274         * Returns the absolute path for the given pathname. It the pathname is relative, it is taken relative to the web-app directory
275         * @param pathname
276         * @return
277         */
278        private File absolutePath( String pathname ) {
279                if( pathname == null)
280                        return null
281
282                // Check if this is an absolute path
283                File f = new File( pathname );
284
285                if( f.isAbsolute() ) {
286                        return f
287                } else {
288                        // Find the absolute path relative to the web-app directory. This code is found on
289                        // http://stackoverflow.com/questions/491067/how-to-find-the-physical-path-of-a-gsp-file-in-a-deployed-grails-application
290                        return ApplicationHolder.application.parentContext.getResource(pathname).getFile()
291                }
292        }
293
294        /**
295         * Removes all files with modified date older than 'age' from the given directory.  This method doesn't recurse into directories.
296         * @param directory             File object of the directory to clean
297         * @param age                   Maximum age of the files that should be kept in seconds. If you want to delete all files older than 1 hour, enter 3600
298         */
299        public void cleanDirectory( File directory = null, long age = 0 ) {
300                if( !directory ) {
301                        directory = getUploadDir();
302                }
303
304                if( !age ) {
305                        age = ConfigurationHolder.config.metagenomics.fileUploadMaxAge
306                }
307               
308                // Compute the minimum timestamp a file should have not to be deleted
309                Date today = new Date();
310                long treshold = today.getTime() - age * 1000;
311
312                // Loop through all files in this directory
313                File[] files = directory.listFiles();
314                for (File file : files) {
315                        // Check for the age of the file
316                        if (file.lastModified() < treshold) {
317                                file.delete();
318                        }
319                }
320
321        }
322
323}
Note: See TracBrowser for help on using the repository browser.