source: trunk/grails-app/services/nl/tno/massSequencing/imports/ImportService.groovy @ 58

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

Implemented importing of classifications

File size: 4.6 KB
Line 
1package nl.tno.massSequencing.imports
2
3import groovy.lang.Closure;
4
5import java.io.File;
6import java.util.ArrayList;
7import org.codehaus.groovy.grails.commons.ConfigurationHolder
8import nl.tno.massSequencing.files.*
9import nl.tno.massSequencing.FastaService
10
11class ImportService {
12        def fileService
13        def fastaService
14        def excelService
15        def zipService
16        def classificationService
17       
18        static transactional = false
19       
20        /**
21         * Parses uploaded files and checks them for FASTA and QUAL files
22         * @param filenames             List of filenames currently existing in the upload directory
23         * @param onProgress    Closure to execute when progress indicators should be updated.
24         *                                              Has 2 parameters: progress that indicates the progress with respect to the second parameter total. This
25         *                                              might be indicated by returning the number of bytes processed and the total number of bytes that have to be processed
26         * @param directory             Directory to move the files to
27         * @return                              Structure with information about the parsed files. The 'success' files are
28         *                                              moved to the given directory
29         *
30         * [
31         *              success: [
32         *                      [filename: 'abc.fasta', type: FASTA, numSequences: 190]
33         *                      [filename: 'cde.fasta', type: FASTA, numSequences: 140]
34         *                      [filename: 'abc.qual', type: QUAL, numSequences: 190, avgQuality: 38]
35         *                      [filename: 'cde.qual', type: QUAL, numSequences: 140, avgQuality: 29]
36         *              ],
37         *              failure: [
38         *                      [filename: 'testing.xls', type: 'unknown', message: 'Type not recognized']
39         *              ]
40         * ]
41         *
42         */
43        def parseFiles( ArrayList filenames, Closure onProgress, def initialProgress, Closure newStep, File directory = null ) {
44                if( filenames.size() == 0 ) {
45                        return [ success: [], failure: [] ];
46                }
47
48                if( !directory ) {
49                        directory = fileService.absolutePath( ConfigurationHolder.config.massSequencing.fileDir )
50                }
51
52                def success = [];
53                def failure = [];
54
55                // Keep track of the current progress
56                def currentProgress = initialProgress;
57               
58                // Give the other methods a way to update the progress, by just telling how much work they have done
59                def updateProgressClosure = { progress, total ->
60                        // Update the current progress by adding the progress and total values from this file.
61                        currentProgress[ 'progress' ] += progress;
62                        currentProgress[ 'total' ] += total;
63                       
64                        onProgress( currentProgress[ 'progress' ], currentProgress[ 'total' ] );
65                }
66
67                // which importer services do we have?
68                def importerServices = [ fastaService, zipService, excelService, classificationService ].findAll { it && it instanceof Importer }
69
70                // Loop through all filenames and find a service to handle this file
71                for( int i = 0; i < filenames.size(); i++ ) {
72                        def parsed = false;
73                        def filename = filenames[ i ]
74                        def file = fileService.get( filename );
75                        String filetype = fileService.determineFileType( file );
76
77                        // Search which importer service is capable of handling this file. If none is capable,
78                        // discard the file and report back to the user
79                        for( service in importerServices ) {
80                                if( service.canParseFileType( filetype ) ) {
81                                        try {
82                                                // Parse the file
83                                                def contents = service.parseFile( file, filetype, updateProgressClosure );
84                                               
85                                                contents.filename = file.getName();
86                                                contents.originalfilename = fileService.originalFilename( contents.filename )
87
88                                                if( contents.success ) {
89                                                        success << contents;
90                                                       
91                                                        // If new files are retrieved, put them in the list
92                                                        if( contents.extraFiles ) {
93                                                                contents.extraFiles.each {
94                                                                        filenames.add( it );
95                                                                }
96                                                               
97                                                        }
98                                                } else {
99                                                        fileService.delete(filename);
100                                                        failure << contents;
101                                                }
102                                        } catch( Exception e ) {
103                                                e.printStackTrace();
104                                               
105                                                // If anything fails during parsing, return an error message
106                                                fileService.delete(filename);
107                                                failure << [ filename: filename, originalfilename: fileService.originalFilename( filename ), type: filetype, message: e.getMessage() ];
108                                        }
109                                       
110                                        parsed = true;
111                                        break;  // out of the services loop: the other services don't have to parse this file
112                                }
113                        }
114                       
115                        // If the file couldn't be parsed by any service, return it to the user
116                        if( !parsed ) {
117                                // Update progress since we don't have to handle this file
118                                currentProgress[ 'progress' ] += file.size()
119                                onProgress( currentProgress[ 'progress' ], currentProgress[ 'total' ] );
120                               
121                                // If files are not valid for parsing, delete them and return a message to the user
122                                fileService.delete(filename);
123                                failure << [ filename: filename, originalfilename: fileService.originalFilename( filename ), type: filetype, message: 'File type not accepted' ];
124                        }       
125                }
126
127                return [ 'success': success, 'failure': failure ];
128        }
129
130}
Note: See TracBrowser for help on using the repository browser.