Ignore:
Timestamp:
Jan 26, 2011, 5:08:25 PM (11 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/RunController.groovy

    r4 r7  
    77class RunController {
    88        def fileService
    9        
    10         /** 
    11          * Shows information about this run in dialog style
    12          */
     9        def synchronizationService
     10        def sampleExcelService
     11
     12        def index = {
     13                [runs: Run.list()]
     14        }
     15
    1316        def show = {
    14                 Run run = Run.get( params.id as long );
    15                 Assay assay = Assay.get( params.assayId as long );
    16                
    17                 if( !run ) {
    18                         render "Run not found";
    19                         return
    20                 }
    21                
    22                 if( !assay ) {
    23                         render "Assay not found";
    24                         return
    25                 }
    26                
     17                // load run with id specified by param.id
     18                def run = getRun( params.id );
     19
     20                if (!run) {
     21                        redirect(controller: 'study', action: 'index')
     22                        return
     23                }
     24
     25                // Make sure the newest data is available
     26                synchronizationService.sessionToken = session.sessionToken
     27                synchronizationService.synchronizeStudies();
     28
     29                // Determine runs not used in this assay
     30                def otherAssays = Assay.list( sort: "name" ).findAll { !it.runs.contains( run ) }
     31
     32                // Send the assay information to the view
     33                [run: run, otherAssays: otherAssays, editable: true]
     34        }
     35
     36        /**
     37         * Shows a form to edit the specified run in dialog mode
     38         */
     39        def editForm = {
     40                // load run with id specified by param.id
     41                Run run = getRun( params.id );
     42
     43                if (!run) {
     44                        render flash.error
     45                        return
     46                }
     47
     48                Assay assay = getAssay( params.id )
     49
     50                if( !assay ) {
     51                        render flash.error;
     52                        return
     53                }
     54
    2755                [assay: assay, run: run]
    2856        }
    29        
    30         /**
    31          * Shows a form to edit the specified run in dialog mode
    32          */
    33         def editForm = {
    34                 Run run = Run.get( params.id as long );
    35                 Assay assay = Assay.get( params.assayId as long );
    36                
    37                 if( !run ) {
    38                         render "Run not found";
    39                         return
    40                 }
    41                
    42                 if( !assay ) {
    43                         render "Assay not found";
    44                         return
    45                 }
    46                
    47                 [assay: assay, run: run]
    48         }
    49        
    50     def create = {
    51                 Assay a = Assay.get( params.id as long );
     57
     58        def create = {
     59                Assay a = getAssay(params.id);
     60                flash.error = "";
    5261
    5362                // Create run based on given parameters
    5463                Run run = new Run();
    55                
     64
    5665                run.setPropertiesFromForm( params );
    5766
    58                 a.addToRuns( run );
     67                if( a )
     68                        a.addToRuns( run );
    5969
    6070                if( !run.save() ) {
     
    6474                }
    6575
    66                 redirect( controller: "assay", action: "show", id: params.id )
    67         }
    68        
     76                if( a )
     77                        redirect( controller: "assay", action: "show", id: a.id )
     78                else
     79                        redirect( controller: 'run' );
     80        }
     81
    6982        def update = {
    7083                if( !params.assayId ) {
    7184                        flash.error = "No assay id given"
    72                         redirect(controller: 'assay', action: 'errorpage')
    73                         return
    74                 }
    75                 def assay = Assay.get(params.assayId as Long)
    76                
    77                 // load run with id specified by param.id
    78                 if (!assay) {
    79                         flash.message = "No assay found with id: ${params.assayId}"
    80                         redirect(controller: 'assay', 'action': 'errorPage')
    81                         return
    82                 }
    83 
    84 
    85                 def run
    86 
    87                 try {
    88                         run = Run.get( params.id as Long );
    89                 } catch( Exception e ) {
    90                         throw e
    91                         flash.message = "Incorrect run id given: "
     85                        redirect(controller: 'study')
     86                        return
     87                }
     88
     89                Assay assay = getAssay(params.assayId);
     90
     91                if( !a ) {
     92                        redirect( controller: 'study' );
     93                }
     94
     95                Run run = getRun( params.id );
     96
     97                if( !run ) {
    9298                        redirect(controller: 'assay', action: 'show', id: params.assayId)
    9399                        return
     
    106112                redirect( controller: 'assay', action: 'show', id: params.assayId)
    107113        }
    108        
     114
    109115        def delete = {
    110                 Run run = Run.get( params.id as long );
     116                Run run = getRun( params.id );
     117
     118                if( !run ) {
     119                        redirect(controller: 'assay', action: 'show', id: params.assayId)
     120                        return
     121                }
    111122
    112123                // Don't remove runs for which data exists
     
    115126                        redirect( controller: "assay", action: "show", id: params.assayId )
    116127                }
    117                
     128
    118129                // Remove all associations
    119130                run.assays.each {
    120131                        run.removeFromAssays( it );
    121132                }
    122                
     133
    123134                def name = run.name
    124135                run.delete();
     
    126137
    127138                redirect( controller: "assay", action: "show", id: params.assayId )
     139        }
     140
     141        /**************************************************************************
     142         *
     143         * Methods for handling data about the samples in this run
     144         *
     145         *************************************************************************/
     146
     147        /**
     148         * Downloads an excel sheet with data about the assay samples, to enter data in excel
     149         */
     150        def downloadTagsExcel = {
     151                Run run = getRun( params.id );
     152
     153                if( !run ) {
     154                        redirect(controller: 'study')
     155                        return
     156                }
     157
     158                // Make it only possible to update samples writable by the user
     159                def assaySamples = run.assaySamples.findAll { it.assay.study.canWrite( session.user ) }
     160
     161                def filename = "Run " + run.name + "_tags.xls"
     162                def wb = sampleExcelService.downloadSampleExcel( assaySamples, false );
     163
     164                // Make file downloadable
     165                log.trace( "Creation for downloading the file " + filename )
     166                sampleExcelService.excelService.downloadFile( wb, filename, response )
     167        }
     168
     169
     170        /**
     171         * Parses an uploaded excel file and shows a form to match columns
     172         */
     173        def parseTagExcel = {
     174                Run run = getRun( params.id );
     175
     176                if( !run ) {
     177                        redirect(controller: 'study')
     178                        return
     179                }
     180
     181                def filename = params.filename
     182
     183                // Security check to prevent accessing files in other directories
     184                if( !filename || filename.contains( '..' ) ) {
     185                        response.status = 500;
     186                        render "Invalid filename given";
     187                        return;
     188                }
     189
     190                // Check for existence and readability
     191                File file = new File( fileService.getUploadDir(), filename)
     192
     193                if( !file.exists() || !file.canRead() ) {
     194                        response.status = 404;
     195                        render "The uploaded file doesn't exist or doesn't work as expected.";
     196                        return;
     197                }
     198
     199                // Save the filename in session for later use
     200                session.filename = filename;
     201                def excelData;
     202                try {
     203                        excelData = sampleExcelService.parseTagsExcel( file, false );
     204                } catch( Throwable e ) { // Catch a throwable here instead of an exception, since the apache poi stuff gives an Error on failure
     205                        // Couldn't create a workbook from this file.
     206                        response.status = 400 // Bad request
     207                        render "Uploaded file is not a valid excel file: " + e.getMessage()
     208                        return
     209                }
     210                session.possibleFields = excelData.possibleFields
     211
     212                [run: run, headers: excelData.headers, exampleData: excelData.exampleData, filename: filename, possibleFields: [ "Don't import" ] + excelData.possibleFields, bestMatches: excelData.bestMatches]
     213        }
     214
     215        /**
     216         * Updates the assay samples based on the given excel file and the column matches
     217         */
     218        def updateTagsByExcel = {
     219                Run run = getRun( params.id );
     220
     221                if( !run ) {
     222                        // Now delete the file, since we don't need it anymore
     223                        _deleteUploadedFileFromSession()
     224
     225                        redirect(controller: 'study')
     226                        return
     227                }
     228
     229                if( !session.filename ) {
     230                        // Now delete the file, since we don't need it anymore
     231                        _deleteUploadedFileFromSession()
     232
     233                        flash.error = "No excel file found because session timed out. Please try again."
     234                        redirect( action: 'show', id: params.id)
     235                        return
     236                }
     237
     238                // Determine the match-columns
     239                def matchColumns = params[ 'matches'];
     240
     241                // Now loop through the excel sheet and update all samples with the specified data
     242                File file = new File( fileService.getUploadDir(), session.filename );
     243
     244                if( !file.exists() || !file.canRead() ) {
     245                        flash.error = "Excel file has been removed since previous step. Please try again."
     246                        redirect( action: 'show', id: params.id)
     247                        return
     248                }
    128249               
     250                // Make it only possible to update samples writable by the user
     251                def assaySamples = run.assaySamples.findAll { it.assay.study.canWrite( session.user ) }
     252               
     253                def excelData = sampleExcelService.updateTagsByExcel( matchColumns, session.possibleFields, file, assaySamples );
     254
     255                // Return a message to the user
     256                if( !excelData.success ) {
     257                        flash.error = excelData.message
     258                } else if( excelData.numSuccesful == 0 ) {
     259                        flash.error = "None of the " + excelData.failedRows.size() + " row(s) could be imported, because none of the sample names matched or no samples are writable. Have you provided the right excel file?"
     260                } else {
     261                        flash.message = excelData.numSuccesful + " samples have been updated. "
     262
     263                        if( excelData.failedRows.size() > 0 )
     264                                flash.message += excelData.failedRows.size() + " row(s) could not be imported, because the sample names could not be found in the database or you don't have the proper permissions to change them."
     265                }
     266                redirect( action: 'show', id: params.id )
     267        }
     268
     269
     270        /**
     271         * Update the properties of the assay samples manually
     272         */
     273        def updateTagsManually = {
     274                Run run = getRun( params.id );
     275
     276                if( !run ) {
     277                        redirect(controller: 'study')
     278                        return
     279                }
     280
     281                // Loop through all assay samples and set data
     282                def sampleParams = params.assaySample;
     283
     284                if( sampleParams ) {
     285                        run.assaySamples.each { assaySample ->
     286                                def assaySampleParams = sampleParams.get( assaySample.id as String );
     287                                if( assaySampleParams ) {
     288                                        assaySample.oligoNumber = assaySampleParams.oligoNumber
     289                                        assaySample.tagSequence = assaySampleParams.tagSequence
     290
     291                                        assaySample.save()
     292                                }
     293                        }
     294                }
     295
     296                flash.message = "Data about samples is saved."
     297                redirect( action: 'show', id: params.id )
     298        }
     299
     300        /**************************************************************************
     301         *
     302         * Methods for handling data about assays for this run
     303         *
     304         *************************************************************************/
     305
     306        /**
     307         * Adds existing assays to this run
     308         */
     309        def addAssays = {
     310                Run run = getRun( params.id );
     311
     312                if( !run ) {
     313                        redirect(controller: 'study')
     314                        return
     315                }
     316
     317                // Add checked runs to this assay
     318                def assays = params.assays
     319                if( assays instanceof String ) {
     320                        assays = [ assays ]
     321                }
     322
     323                def numAdded = 0;
     324                assays.each { assay_id ->
     325                        try {
     326                                def assay = Assay.findById( assay_id as Long )
     327                                if( run.assays == null || !run.assays.contains( assay ) ) {
     328                                        run.addToAssays( assay );
     329                                        numAdded++;
     330                                }
     331                        } catch( Exception e ) {}
     332                }
     333
     334                flash.message = numAdded + " runs are added to this assay."
     335                redirect( action: 'show', id: params.id)
     336        }
     337
     338        /**
     339         * Removes assay for this run
     340         */
     341        def removeAssay = {
     342                Run run = getRun( params.id );
     343
     344                if( !run ) {
     345                        redirect(controller: 'study')
     346                        return
     347                }
     348               
     349                if( !params.assay_id ) {
     350                        flash.message = "No assay id given"
     351                        redirect(action: 'show', id: params.id)
     352                        return
     353                }
     354
     355                def assay
     356
     357                try {
     358                        assay = Assay.findById( params.assay_id as Long )
     359                } catch( Exception e ) {
     360                        throw e
     361                        flash.message = "Incorrect assay id given: "
     362                        redirect(action: 'show', id: params.id)
     363                        return
     364                }
     365
     366                if( run.assays.contains( assay ) ) {
     367                        run.removeFromAssays( assay );
     368                        flash.message = "The assay has been removed from this run."
     369                } else {
     370                        flash.message = "The given assay was not associated with this run."
     371                }
     372
     373                redirect( action: 'show', id: params.id)
     374        }
     375
     376
     377        /**
     378         * Deletes an uploaded file for which the filename is given in the session.
     379         * @return
     380         */
     381        def _deleteUploadedFileFromSession() {
     382                if( !session.filename )
     383                        return
     384
     385                // Now delete the file, since we don't need it anymore
     386                fileService.delete( session.filename  )
     387                session.filename = ''
     388        }
     389
     390        protected Run getRun(def runId) {
     391                // load study with id specified by param.id
     392                def run
     393                try {
     394                        run = Run.get(runId as Long)
     395                } catch( Exception e ) {
     396                        flash.error = "Incorrect id given: " + runId
     397                        return null
     398                }
     399
     400                if (!run) {
     401                        flash.error = "No run found with id: " + runId
     402                        return null
     403                }
     404
     405                return run
     406        }
     407
     408        protected Assay getAssay(def assayId) {
     409                // load study with id specified by param.id
     410                def assay
     411                try {
     412                        assay = Assay.get(assayId as Long)
     413                } catch( Exception e ) {
     414                        flash.error = "Incorrect id given: " + assayId
     415                        return null
     416                }
     417
     418                if (!assay) {
     419                        flash.error = "No assay found with id: " + assayId
     420                        return null
     421                }
     422
     423                if (!assay.study.canRead( session.user ) ) {
     424                        flash.error = "You don't have the right authorizaton to access assay " + assay.name
     425                        return null
     426                }
     427
     428                return assay
    129429        }
    130430}
Note: See TracChangeset for help on using the changeset viewer.