Ignore:
Timestamp:
Jan 26, 2011, 5:08:25 PM (9 years ago)
Author:
robert@…
Message:
  • Created tests for the synchronization and trash
  • Improved synchronizationservice and trash
  • Put authorization checks in several pages
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/nl/tno/metagenomics/AssayController.groovy

    r4 r7  
    55class AssayController {
    66        def synchronizationService
     7        def gscfService
    78        def fuzzySearchService
    89
    910        def fileService
    1011        def excelService
    11 
    12         // Fields to be edited using excel file and manually
    13         def sampleNameName = "Sample name"
    14         def tagSequenceName = "Tag sequence"
    15         def oligoNumberName = "Oligo number"
    16         def possibleFields = [sampleNameName, tagSequenceName, oligoNumberName]
    17 
     12        def sampleExcelService
     13
     14        def index = {
     15                // Filter studies for the ones the user is allowed to see
     16                def studies = Study.list();
     17                [studies: studies.findAll { it.canRead( session.user ) },
     18                        gscfAddUrl: gscfService.urlAddStudy() ]
     19        }
     20       
    1821        def show = {
    19                 // load study with id specified by param.id
    20                 def assay = Assay.get(params.id as Long)
    21 
    22                 if (!assay) {
    23                         flash.message = "No assay found with id: $params.id"
    24                         redirect('action': 'errorPage')
    25                         return
    26                 }
     22                def assay = getAssay( params.id );
     23                if( !assay )
     24                        return
    2725
    2826                // Make sure the newest data is available
     
    6159                                if( !assay ) {
    6260                                        flash.message = "No assay found with token: $params.id"
    63                                         redirect('action': 'errorPage')
     61                                        redirect(controller: 'study')
    6462                                }
    6563                        }
     
    7977         */
    8078        def downloadTagsExcel = {
    81                 def sheetIndex = 0;
    82 
    8379                // load study with id specified by param.id
    84                 def assay = Assay.get(params.id as Long)
    85 
    86                 if (!assay) {
    87                         flash.message = "No assay found with id: $params.id"
    88                         redirect('action': 'errorPage')
    89                         return
    90                 }
    91 
    92                 // Create an excel sheet
    93                 def wb = excelService.create();
    94 
    95                 // Put the headers on the first row
    96                 excelService.writeHeader( wb, possibleFields, sheetIndex );
    97 
    98                 // Adding the next lines
    99                 def sortedSamples = assay.assaySamples.toList().sort { it.sample.name }
    100                 ArrayList data = [];
    101                 sortedSamples.each { assaySample ->
    102                         data << [assaySample.sample.name, assaySample.tagSequence, assaySample.oligoNumber ];
    103                 }
    104                 excelService.writeData( wb, data, sheetIndex, 1 );
    105 
    106                 // Auto resize columns
    107                 excelService.autoSizeColumns( wb, sheetIndex, 0..2)
     80                def assay = getAssay( params.id );
     81                if( !assay )
     82                        return
     83
     84                def filename = assay.study.name + "_" + assay.name + "_tags.xls"
     85                excelService.downloadSampleExcel( assay.assaySamples );
    10886
    10987                // Make file downloadable
    110                 log.trace( "Creation for downloading the file " + assay.study.name + "_" + assay.name + "_tags.xls" )
    111                 excelService.downloadFile( wb, assay.study.name + "_" + assay.name + "_tags.xls", response)
     88                log.trace( "Creation for downloading the file " + filename )
     89                sampleExcelService.excelService.downloadFile( wb, filename, response )
    11290        }
    11391
     
    11694         */
    11795        def parseTagExcel = {
    118                 def sheetIndex = 0
    119                 def headerRow = 0
    120                 def dataStartsAtRow = 1
    121                 def numExampleRows = 5
    122 
    123                 // load study with id specified by param.id
    124                 def assay = Assay.get(params.id as Long)
    125 
    126                 if (!assay) {
    127                         flash.message = "No assay found with id: $params.id"
    128                         redirect('action': 'errorPage')
    129                         return
    130                 }
     96                def assay = getAssay( params.id );
     97                if( !assay )
     98                        return
    13199
    132100                def filename = params.filename
     
    150118                // Save the filename in session for later use
    151119                session.filename = filename;
    152 
    153                 // Create an excel workbook instance of the file
    154                 def workbook
     120                def excelData;
    155121                try {
    156                         workbook = excelService.open( file );
     122                        excelData = sampleExcelService.parseTagsExcel( file );
    157123                } catch( Throwable e ) { // Catch a throwable here instead of an exception, since the apache poi stuff gives an Error on failure
    158124                        // Couldn't create a workbook from this file.
    159125                        response.status = 400 // Bad request
    160                         render "Uploaded file is not a valid excel file."
    161                         return
    162                 }
    163 
    164                 // Read headers from the first row and 5 of the first lines as example data
    165                 def headers = excelService.readRow( workbook, sheetIndex, headerRow );
    166                 def exampleData = excelService.readData( workbook, sheetIndex, dataStartsAtRow, -1, numExampleRows ); // -1 means: determine number of rows yourself
    167 
    168                 // Try to guess best matches between the excel file and the column names
    169                 def bestMatches = [:]
    170 
    171                 headers.eachWithIndex { header, idx ->
    172                         // Do matching using fuzzy search. The 0.1 treshold makes sure that no match if chosen if
    173                         // there is actually no match at all.
    174                         bestMatches[idx] = fuzzySearchService.mostSimilar( header, possibleFields, 0.1 );
    175                 }
    176 
    177                 [assay: assay, headers: headers, exampleData: exampleData, filename: filename, possibleFields: [ "Don't import" ] + possibleFields, bestMatches: bestMatches]
     126                        render "Uploaded file is not a valid excel file: " + e.getMessage()
     127                        return
     128                }
     129                session.possibleFields = excelData.possibleFields
     130               
     131                [assay: assay, headers: excelData.headers, exampleData: excelData.exampleData, filename: filename, possibleFields: [ "Don't import" ] + excelData.possibleFields, bestMatches: excelData.bestMatches]
    178132        }
    179133
     
    182136         */
    183137        def updateTagsByExcel = {
    184                 def sheetIndex = 0
    185                 def headerRow = 0
    186                 def dataStartsAtRow = 1
    187 
    188                 // load study with id specified by param.id
    189                 def assay = Assay.get(params.id as Long)
    190 
    191                 if (!assay) {
     138                def assay = getAssay( params.id );
     139                if( !assay ) {
    192140                        // Now delete the file, since we don't need it anymore
    193141                        _deleteUploadedFileFromSession()
    194 
    195                         flash.message = "No assay found with id: $params.id"
    196                         redirect('action': 'errorPage')
    197                         return
     142                        return;
    198143                }
    199144
     
    210155                def matchColumns = params[ 'matches'];
    211156
    212                 if( !matchColumns ) {
    213                         // Now delete the file, since we don't need it anymore
    214                         _deleteUploadedFileFromSession()
    215 
    216                         flash.error = "No column matches found for excel file. Please try again."
    217                         redirect( action: 'show', id: params.id)
    218                         return
    219                 }
    220 
    221                 // Determine column numbers
    222                 def columns = [:]
    223                 def dataMatches = false;
    224                 possibleFields.each { columnName ->
    225                         columns[ columnName ] = matchColumns.findIndexOf { it.value == columnName }
    226 
    227                         if( columnName != sampleNameName && columns[ columnName ] != -1 )
    228                                 dataMatches = true
    229                 }
    230 
    231                 println( "Columns: " + columns)
    232 
    233                 // A column to match the sample name must be present
    234                 if( columns[ sampleNameName ] == -1 ) {
    235                         // Now delete the file, since we don't need it anymore
    236                         _deleteUploadedFileFromSession()
    237 
    238                         flash.error = "There must be a column present in the excel file that matches the sample name. Please try again."
    239                         redirect( action: 'show', id: params.id)
    240                         return
    241                 }
    242 
    243                 // A column with data should also be present
    244                 if( !dataMatches ) {
    245                         // Now delete the file, since we don't need it anymore
    246                         _deleteUploadedFileFromSession()
    247 
    248                         flash.error = "There are no data columns present in the excel file. No samples are updated."
    249                         redirect( action: 'show', id: params.id)
    250                         return
    251                 }
    252 
    253157                // Now loop through the excel sheet and update all samples with the specified data
    254158                File file = new File( fileService.getUploadDir(), session.filename );
     159               
    255160                if( !file.exists() || !file.canRead() ) {
    256161                        flash.error = "Excel file has been removed since previous step. Please try again."
     
    258163                        return
    259164                }
    260 
    261                 def workbook = excelService.open( file )
    262                 ArrayList data = excelService.readData( workbook, sheetIndex, dataStartsAtRow )
    263 
    264                 // Check whether the excel file contains any data
    265                 if( data.size() == 0 ) {
    266                         // Now delete the file, since we don't need it anymore
    267                         _deleteUploadedFileFromSession()
    268 
    269                         flash.error = "The excel sheet contains no data to import. Please upload another excel file."
    270                         redirect( action: 'show', id: params.id)
    271 
    272                         return
    273                 }
    274 
    275                 def numSuccesful = 0
    276                 def failedRows = []
    277 
    278                 // walk through all rows and fill the table with records
    279                 def assaySamples = assay.assaySamples
    280 
    281                 for( def i = 0; i < data.size(); i++ ) {
    282                         def rowData = data[ i ];
    283 
    284                         String sampleName = rowData[ columns[ sampleNameName ] ] as String
    285 
    286                         // Find assay by sample name. Since sample names are unique within an assay (enforced by GSCF),
    287                         // this will always work.
    288                         AssaySample assaySample = assaySamples.find { it.sample.id == Sample.findByName( sampleName )?.id };
    289 
    290                         // If no assaysample is found, add this row to the failed-row list
    291                         if( !assaySample ) {
    292                                 failedRows << [ row: rowData, sampleName: sampleName ];
    293                                 continue;
    294                         }
    295 
    296                         columns.each {
    297                                 if( it.value > -1 ) {
    298                                         switch( it.key ) {
    299                                                 case tagSequenceName:   assaySample.tagSequence = rowData[ it.value ]; break
    300                                                 case oligoNumberName:   assaySample.oligoNumber = rowData[ it.value ]; break
    301                                         }
    302                                 }
    303                         }
    304 
    305                         assaySample.save()
    306 
    307                         numSuccesful++;
    308                 }
    309 
    310                 // Now delete the file, since we don't need it anymore
    311                 _deleteUploadedFileFromSession()
     165               
     166                def excelData = sampleExcelService.updateTagsByExcel( matchColumns, session.possibleFields, file, assay.assaySamples );
    312167
    313168                // Return a message to the user
    314                 if( numSuccesful == 0 ) {
    315                         flash.error = "None of the " + failedRows.size() + " row(s) could be imported, because none of the sample names matched. Have you provided the right excel file?"
     169                if( !excelData.success ) {
     170                        flash.error = excelData.message
     171                } else if( excelData.numSuccesful == 0 ) {
     172                        flash.error = "None of the " + excelData.failedRows.size() + " row(s) could be imported, because none of the sample names matched. Have you provided the right excel file?"
    316173                } else {
    317                         flash.message = numSuccesful + " samples have been updated. "
    318 
    319                         if( failedRows.size() > 0 )
    320                                 flash.message += failedRows.size() + " row(s) could not be imported, because the sample names could not be found in the database."
    321                 }
    322                 redirect( action: 'show', id: params.id)
     174                        flash.message = excelData.numSuccesful + " samples have been updated. "
     175
     176                        if( excelData.failedRows.size() > 0 )
     177                                flash.message += excelData.failedRows.size() + " row(s) could not be imported, because the sample names could not be found in the database."
     178                }
     179                redirect( action: 'show', id: params.id )
    323180        }
    324181
     
    327184         */
    328185        def updateTagsManually = {
    329                 // load study with id specified by param.id
    330                 def assay = Assay.get(params.id as Long)
    331 
    332                 if (!assay) {
    333                         flash.message = "No assay found with id: $params.id"
    334                         redirect('action': 'errorPage')
    335                         return
    336                 }
     186                def assay = getAssay( params.id );
     187                if( !assay )
     188                        return
    337189
    338190                // Loop through all assay samples and set data
     
    342194                        assay.assaySamples.each { assaySample ->
    343195                                def assaySampleParams = sampleParams.get( assaySample.id as String );
     196                                println assaySampleParams
    344197                                if( assaySampleParams ) {
    345                                         assaySample.properties = assaySampleParams
     198                                        assaySample.oligoNumber = assaySampleParams.oligoNumber
     199                                        assaySample.tagSequence = assaySampleParams.tagSequence
     200
     201                                        try {
     202                                                assaySample.run = Run.get( assaySampleParams.run as Long );
     203                                        } catch( Exception e ) {}
     204
    346205                                        assaySample.save()
    347206                                }
     
    363222         */
    364223        def addExistingRuns = {
    365                 // load study with id specified by param.id
    366                 def assay = Assay.get(params.id as Long)
    367 
    368                 if (!assay) {
    369                         flash.message = "No assay found with id: $params.id"
    370                         redirect('action': 'errorPage')
    371                         return
    372                 }
     224                def assay = getAssay( params.id );
     225                if( !assay )
     226                        return
    373227
    374228                // Add checked runs to this assay
     
    397251         */
    398252        def removeRun = {
    399                 // load study with id specified by param.id
    400                 def assay = Assay.get(params.id as Long)
    401 
    402                 if (!assay) {
    403                         flash.message = "No assay found with id: $params.id"
    404                         redirect('action': 'errorPage')
    405                         return
    406                 }
     253                def assay = getAssay( params.id );
     254                if( !assay )
     255                        return
    407256
    408257                if( !params.run_id ) {
     
    449298                session.filename = ''
    450299        }
     300       
     301        protected Assay getAssay(def assayId) {
     302                // load study with id specified by param.id
     303                def assay
     304                try {
     305                        assay = Assay.get(assayId as Long)
     306                } catch( Exception e ) {
     307                        flash.error = "Incorrect id given: " + assayId
     308                        redirect(controller: 'study')
     309                        return null
     310                }
     311
     312                if (!assay) {
     313                        flash.error = "No assay found with id: " + assayId
     314                        redirect(controller: 'study')
     315                        return null
     316                }
     317               
     318                if (!assay.study.canRead( session.user ) ) {
     319                        flash.error = "You don't have the right authorizaton to access assay " + assay.name
     320                        redirect(controller: 'study')
     321                        return null
     322                }
     323               
     324                return assay
     325        }
     326       
    451327
    452328}
Note: See TracChangeset for help on using the changeset viewer.