source: trunk/grails-app/controllers/dbnp/studycapturing/SimpleWizardController.groovy @ 1576

Last change on this file since 1576 was 1576, checked in by robert@…, 10 years ago
  • Solved locking problems with module communication
  • Fixed a null pointer bug in assayController
File size: 25.6 KB
Line 
1/**
2 * SimpleWizardController Controler
3 *
4 * Description of my controller
5 *
6 * @author  your email (+name?)
7 * @since       2010mmdd
8 * @package     ???
9 *
10 * Revision information:
11 * $Rev: 1430 $
12 * $Author: work@osx.eu $
13 * $Date: 2011-01-21 21:05:36 +0100 (Fri, 21 Jan 2011) $
14 */
15package dbnp.studycapturing
16
17import org.dbnp.gdt.*
18import grails.plugins.springsecurity.Secured
19import dbnp.authentication.SecUser
20import dbnp.importer.ImportCell
21import dbnp.importer.ImportRecord
22import dbnp.importer.MappingColumn
23
24@Secured(['IS_AUTHENTICATED_REMEMBERED'])
25class SimpleWizardController extends StudyWizardController {
26        def authenticationService
27        def fileService
28        def importerService
29        def gdtService
30
31        /**
32         * index closure
33         */
34        def index = {
35                redirect( action: "study" );
36        }
37
38        /**
39         * Shows the study page
40         */
41        def study = {
42                // Retrieve the correct study
43                Study study = getStudyInWizard( params );
44
45                // If no study is found in the wizard, this is the entry page of the
46                // wizard. Retrieve the study from request parameters
47                if( !study ) {
48                        study = getStudyFromRequest( params );
49
50                        // Some error might have occurred during the retrieval of the study
51                        if( !study ) {
52                                redirect( controller: 'simpleWizard', action: 'study' );
53                                return;
54                        }
55
56                        session.simpleWizard = [ study: study ]
57                }
58
59                def event = getEvent(params);
60
61                // If any event on this page is triggered, we should save the entered data.
62                // If no event is triggered, the user gets here from another page. In that case,
63                // we don't set the values
64                if( event ) {
65                        // Only continue to the next or previous page if the information entered is correct
66                        if( handleStudy( study, params ) ) {
67                                // Now determine what action to perform
68                                // If the user clicks next, the study should be validated
69                                if( event == "next" && validateObject( study ) ) {
70                                        toPage( "samples" );
71                                        return;
72                                }
73                        }
74                }
75
76                // Give the study to the user
77                [ study: study ]
78        }
79
80        /**
81         * Shows the samples page
82         */
83        def samples = {
84                // Retrieve the correct study
85                study = getStudyInWizard( params );
86                if( !study ) {
87                        redirect( controller: 'simpleWizard', action: 'study' );
88                        return;
89                }
90
91                def event = getEvent(params);
92
93                // If any event on this page is triggered, we should save the entered data.
94                // If no event is triggered, the user gets here from another page. In that case,
95                // we don't set the values
96                if( event ) {
97                        // Now determine what action to perform
98                        if( event == "next" && handleSamples( study, params )) {
99                                // Only continue to the next page if the information entered is correct
100                                toPage( "columns" );
101                                return;
102                        } else if( event == "previous" ) {
103                                // The user may go to the previous page, even if none of the data entered is OK.
104                                toPage( "study" );
105                                return;
106                        } else if( event == "skip" ) {
107                                // The user may skip the complete samples page
108                                toPage( "assays" );
109                                return;
110                        }
111                }
112
113                // Give the study and other data to the user
114                [ study: study, sampleTemplates: Template.findAllByEntity( Sample.class ), encodedEntity: gdtService.encryptEntity( Sample.class.name ), sampleForm: session.simpleWizard.sampleForm ]
115        }
116
117        /**
118         * Shows the columns page
119         */
120        def columns = {
121                // Retrieve the correct study
122                study = getStudyInWizard( params );
123                if( !study ) {
124                        redirect( controller: 'simpleWizard', action: 'study' );
125                        return;
126                }
127
128                def event = getEvent(params);
129
130                // If any event on this page is triggered, we should save the entered data.
131                // If no event is triggered, the user gets here from another page. In that case,
132                // we don't set the values
133                if( event ) {
134                        // Now determine what action to perform
135                        if( event == "next" && handleColumns( study, params ) ) {
136                                // Only continue to the next page if the information entered is correct
137                                if( session.simpleWizard.imported.numInvalidEntities > 0 ) {
138                                        toPage( "missingFields" );
139                                } else {
140                                        // The import of the excel file has finished. Now delete the excelfile
141                                        if( session.simpleWizard.sampleForm.importFile )
142                                                fileService.delete( session.simpleWizard.sampleForm.importFile );
143
144                                        toPage( "assays" );
145                                }
146                                return;
147                        } else if( event == "previous" ) {
148                                // THe user may go to the previous page, even if the data is not correct
149                                toPage( "samples" );
150                                return;
151                        }
152                }
153
154                // Give the study and other data to the user
155                [ study: study,
156                                        filename: session.simpleWizard.sampleForm.importFile,
157                                        template: Template.get( session.simpleWizard.sampleForm.templateId ),
158                                        excel: session.simpleWizard.excel]
159        }
160
161        /**
162         * Shows the page where missing fields can be filled in
163         */
164        def missingFields = {
165                // Retrieve the correct study
166                study = getStudyInWizard( params );
167                if( !study ) {
168                        redirect( controller: 'simpleWizard', action: 'study' );
169                        return;
170                }
171
172                def event = getEvent(params);
173
174                // If any event on this page is triggered, we should save the entered data.
175                // If no event is triggered, the user gets here from another page. In that case,
176                // we don't set the values
177                if( event ) {
178                        // Now determine what action to perform
179                        if( event == "next" && handleMissingFields( study, params ) ) {
180                                if( session.simpleWizard.imported.numInvalidEntities == 0 ) {
181                                        // Only continue to the next page if the information entered is correct
182                                       
183                                        // The import of the excel file has finished. Now delete the excelfile
184                                        if( session.simpleWizard.sampleForm.importFile ) 
185                                                fileService.delete( session.simpleWizard.sampleForm.importFile );
186                                               
187                                        toPage( "assays" );
188                                        return;
189                                }
190                        } else if( event == "previous" ) {
191                                // THe user may go to the previous page, even if the data is not correct
192                                toPage( "columns" );
193                                return;
194                        }
195                }
196
197                // If any errors have occurred during validation, show them to the user. However,
198                // the same error might have occurred for multiple entities. For that reason,
199                // we only show unique errors
200                def rules
201                if( session.simpleWizard.imported.errors ) {
202                        rules = session.simpleWizard.imported.errors*.values().flatten().unique().join( "<br /> \n" );
203                }
204
205                // Give the study and other data to the user
206                [ study: study, imported: session.simpleWizard.imported, rules: rules ]
207        }
208
209        /**
210         * Shows the assay page
211         */
212        def assays = {
213                // Retrieve the correct study
214                Study study = getStudyInWizard( params );
215                if( !study ) {
216                        redirect( controller: 'simpleWizard', action: 'study' );
217                        return;
218                }
219               
220                Assay assay
221                if( study.assays?.size() ) {
222                        assay = study.assays[0];
223                        study.removeFromAssays( assay );
224                } else {
225                        assay = new Assay();
226                }
227                       
228                def event = getEvent(params);
229
230                // If any event on this page is triggered, we should save the entered data.
231                // If no event is triggered, the user gets here from another page. In that case,
232                // we don't set the values
233                if( event ) {
234                        // Only continue to the next or previous page if the information entered is correct
235                        if( event == "skip" ) {
236                                // The user may skip the complete assay page
237                                toPage( "overview" );
238                                return;
239                        } else if( handleAssays( assay, params ) ) {
240                                study.addToAssays( assay );
241                               
242                                // Now determine what action to perform
243                                if( event == "next" && validateObject( study ) ) {
244                                        toPage( "overview" );
245                                        return;
246                                } else if( event == "previous" ) {
247                                        toPage( "samples" )
248                                        return;
249                                }
250                        }
251                }
252
253                // Give the study to the user
254                [ study: study, assay: assay ]
255        }
256       
257        /**
258         * Shows an overview of the entered study
259         */
260        def overview = {
261                // Retrieve the correct study
262                Study study = getStudyInWizard( params );
263                if( !study ) {
264                        redirect( controller: 'simpleWizard', action: 'study' );
265                        return;
266                }
267                       
268                def event = getEvent(params);
269
270                // If any event on this page is triggered, we should save the entered data.
271                // If no event is triggered, the user gets here from another page. In that case,
272                // we don't set the values
273                if( event ) {
274                        // Now determine what action to perform
275                        if( event == "save" ) {
276                                toPage( "save" );
277                                return;
278                        } else if( event == "previous" ) {
279                                toPage( "assay" )
280                                return;
281                        }
282                }
283
284                // Give the study to the user
285                [ study: study ]
286        }
287       
288        def save = {
289                // Retrieve the correct study
290                Study study = getStudyInWizard( params );
291                if( !study ) {
292                        redirect( controller: 'simpleWizard', action: 'study' );
293                        return;
294                }
295               
296                // Make sure all samples are attached to all assays
297                study.assays.each { assay ->
298                        assay.samples?.clear();
299                        study.samples.each { sample ->
300                                assay.addToSamples( sample )
301                        }
302                }
303               
304                // Save the study
305                if( study.save( flush: true ) ) {
306                        // Clear session
307                        session.simpleWizard = null;
308                       
309                        flash.message = "Your study is succesfully saved.";
310                } else {
311                        flash.error = "An error occurred while saving your study";
312                        //validateObject( study );
313                }
314
315                // Give the study to the user
316                [ study: study ]
317        }
318
319        /**
320         * Handles study input
321         * @param study         Study to update
322         * @param params        Request parameter map
323         * @return                      True if everything went OK, false otherwise. An error message is put in flash.error
324         */
325        def handleStudy( study, params ) {
326                // did the study template change?
327                if (params.get('template') && study.template?.name != params.get('template')) {
328                        // set the template
329                        study.template = Template.findByName(params.remove('template'))
330                }
331
332                // does the study have a template set?
333                if (study.template && study.template instanceof Template) {
334                        // yes, iterate through template fields
335                        study.giveFields().each() {
336                                // and set their values
337                                study.setFieldValue(it.name, params.get(it.escapedName()))
338                        }
339                }
340
341                // handle public checkbox
342                if (params.get("publicstudy")) {
343                        study.publicstudy = params.get("publicstudy")
344                }
345
346                // handle publications
347                handleStudyPublications(study, params)
348
349                // handle contacts
350                handleStudyContacts(study, params)
351
352                // handle users (readers, writers)
353                handleStudyUsers(study, params, 'readers')
354                handleStudyUsers(study, params, 'writers')
355               
356                return true
357        }
358
359        /**
360         * Handles the upload of sample data
361         * @param study         Study to update
362         * @param params        Request parameter map
363         * @return                      True if everything went OK, false otherwise. An error message is put in flash.error
364         */
365        def handleSamples( study, params ) {
366                def filename = params.get( 'importfile' );
367
368                // Handle 'existing*' in front of the filename. This is put in front to make a distinction between
369                // an already uploaded file test.txt (maybe moved to some other directory) and a newly uploaded file test.txt
370                // still being in the temporary directory.
371                // This import step doesn't have to make that distinction, since all files remain in the temporary directory.
372                if( filename[0..8] == 'existing*' )
373                        filename = filename[9..-1]
374
375                def templateId  = params.long( 'template_id' )
376                int sheetIndex = (params.int( 'sheetindex' ) ?: 1 )
377                int dataMatrixStart = (params.int( 'datamatrix_start' ) ?: 2 )
378                int headerRow = (params.int( 'headerrow' ) ?: 1 )
379
380                // Save form data in session
381                session.simpleWizard.sampleForm = [
382                                        importFile: filename,
383                                        templateId: templateId,
384                                        sheetIndex: sheetIndex,
385                                        dataMatrixStart: dataMatrixStart,
386                                        headerRow: headerRow
387                                ];
388
389                // Check whether the template exists
390                if (!templateId || !Template.get( templateId ) ){
391                        log.error ".simple study wizard not all fields are filled in"
392                        flash.error = "No template was chosen. Please choose a template for the samples you provided."
393                        return false
394                }
395
396                def importedfile = fileService.get( filename )
397                def workbook
398                if (importedfile.exists()) {
399                        try {
400                                workbook = importerService.getWorkbook(new FileInputStream(importedfile))
401                        } catch (Exception e) {
402                                log.error ".simple study wizard could not load file: " + e
403                                flash.error = "The given file doesn't seem to be an excel file. Please provide an excel file for entering samples.";
404                                return false
405                        }
406                } else {
407                        log.error ".simple study wizard no file given";
408                        flash.error = "No file was given. Please provide an excel file for entering samples.";
409                        return false;
410                }
411
412                if( !workbook ) {
413                        log.error ".simple study wizard could not load file into a workbook"
414                        flash.error = "The given file doesn't seem to be an excel file. Please provide an excel file for entering samples.";
415                        return false
416                }
417
418                def selectedentities = []
419
420                if( !excelChecks( workbook, sheetIndex, headerRow, dataMatrixStart ) )
421                        return false;
422
423                // Get the header from the Excel file using the arguments given in the first step of the wizard
424                def importerHeader;
425                def importerDataMatrix;
426
427                try {
428                        importerHeader = importerService.getHeader(workbook,
429                                        sheetIndex - 1,                 // 0 == first sheet
430                                        headerRow,                              // 1 == first row :s
431                                        dataMatrixStart - 1,    // 0 == first row
432                                        Sample.class)
433
434                        importerDataMatrix = importerService.getDatamatrix(
435                                        workbook,
436                                        importerHeader,
437                                        sheetIndex - 1,                 // 0 == first sheet
438                                        dataMatrixStart - 1,    // 0 == first row
439                                        5)
440                } catch( Exception e ) {
441                        // An error occurred while reading the excel file.
442                        log.error ".simple study wizard error while reading the excel file";
443                        e.printStackTrace();
444
445                        // Show a message to the user
446                        flash.error = "An error occurred while reading the excel file. Have you provided the right sheet number and row numbers. Contact your system administrator if this problem persists.";
447                        return false;
448                }
449
450                // Save read excel data into session
451                session.simpleWizard.excel = [
452                                        workbook: workbook,
453                                        sheetIndex: sheetIndex,
454                                        dataMatrixStart: dataMatrixStart,
455                                        headerRow: headerRow,
456                                        data: [
457                                                header: importerHeader,
458                                                dataMatrix: importerDataMatrix
459                                        ]
460                                ]
461
462                return true
463        }
464
465        /**
466         * Handles the matching of template fields with excel columns by the user
467         * @param study         Study to update
468         * @param params        Request parameter map
469         * @return                      True if everything went OK, false otherwise. An error message is put in flash.error
470         *                                      The field session.simpleWizard.imported.numInvalidEntities reflects the number of
471         *                                      entities that have errors, and should be fixed before saving. The errors for those entities
472         *                                      are saved into session.simpleWizard.imported.errors
473         */
474        def handleColumns( study, params ) {
475                // Find actual Template object from the chosen template name
476                def template = Template.get(session.simpleWizard.sampleForm.templateId)
477                def headers = session.simpleWizard.excel.data.header;
478
479                if( !params.matches ) {
480                        log.error( ".simple study wizard no column matches given" );
481                        flash.error = "No column matches given";
482                        return false;
483                }
484
485                // Retrieve the chosen matches from the request parameters and put them into
486                // the headers-structure, for later reference
487                params.matches.index.each { columnindex, property ->
488                        // Create an actual class instance of the selected entity with the selected template
489                        // This should be inside the closure because in some cases in the advanced importer, the fields can have different target entities
490                        def entityClass = Class.forName( headers[columnindex.toInteger()].entityclass.getName(), true, this.getClass().getClassLoader())
491                        def entityObj = entityClass.newInstance(template: template)
492
493                        // Store the selected property for this column into the column map for the ImporterService
494                        headers[columnindex.toInteger()].property = property
495
496                        // Look up the template field type of the target TemplateField and store it also in the map
497                        headers[columnindex.toInteger()].templatefieldtype = entityObj.giveFieldType(property)
498
499                        // Is a "Don't import" property assigned to the column?
500                        headers[columnindex.toInteger()].dontimport = (property == "dontimport") ? true : false
501
502                        //if it's an identifier set the mapping column true or false
503                        entityObj.giveFields().each {
504                                headers[columnindex.toInteger()].identifier = ( it.preferredIdentifier && (it.name == property) )
505                        }
506                }
507
508                // Import the workbook and store the table with entity records and store the failed cells
509                def (table, failedcells) = importerService.importData(session.simpleWizard.sampleForm.templateId,
510                                session.simpleWizard.excel.workbook,
511                                session.simpleWizard.excel.sheetIndex - 1,
512                                session.simpleWizard.excel.dataMatrixStart - 1,
513                                session.simpleWizard.excel.data.header)
514
515                session.simpleWizard.imported = [
516                                        data: table,
517                                        failedCells: failedcells
518                                ];
519
520                // loop through all entities to validate them and add them to failedcells if an error occurs
521                def numInvalidEntities = 0;
522                def errors = [];
523
524                // Remove all samples
525                study.samples?.clear();
526
527                table.each { record ->
528                        record.each { entity ->
529                                // Determine entity class and add a parent
530                                entity.parent = study
531                                study.addToSamples( entity );
532
533                                if (!entity.validate()) {
534                                        numInvalidEntities++;
535
536                                        // Add this field to the list of failed cells, in order to give the user feedback
537                                        failedcells = addNonValidatingCells( failedcells, entity )
538
539                                        // Also create a full list of errors
540                                        errors += getHumanReadableErrors( entity );
541                                }
542                        }
543                }
544
545                session.simpleWizard.imported.numInvalidEntities = numInvalidEntities;
546                session.simpleWizard.imported.errors = errors;
547
548                return true
549        }
550       
551        /**
552        * Handles the update of the edited fields by the user
553        * @param study          Study to update
554        * @param params         Request parameter map
555        * @return                       True if everything went OK, false otherwise. An error message is put in flash.error.
556        *                                       The field session.simpleWizard.imported.numInvalidEntities reflects the number of
557        *                                       entities that still have errors, and should be fixed before saving. The errors for those entities
558        *                                       are saved into session.simpleWizard.imported.errors
559        */
560   def handleMissingFields( study, params ) {
561           def numInvalidEntities = 0;
562           def errors = [];
563
564           // Remove all samples before adding them again
565           study.samples?.clear();
566
567           // Check which fields failed previously
568           def failedCells = session.simpleWizard.imported.failedCells
569
570           session.simpleWizard.imported.data.each { table ->
571                   table.each { entity ->
572                           def invalidFields = 0
573
574                           // Set the fields for this entity by retrieving values from the params
575                           entity.giveFields().each { field ->
576                                   def fieldName = importerService.getFieldNameInTableEditor( entity, field );
577
578                                   if( params[ fieldName ] == "#invalidterm" ) {
579                                           // If the value '#invalidterm' is chosen, the user hasn't fixed anything, so this field is still incorrect
580                                           invalidFields++;
581                                   } else {
582                                           if( field.type == org.dbnp.gdt.TemplateFieldType.ONTOLOGYTERM || field.type == org.dbnp.gdt.TemplateFieldType.STRINGLIST ) {
583                                                   // If this field is an ontologyterm field or a stringlist field, the value has changed, so remove the field from
584                                                   // the failedCells list
585                                                   importerService.removeFailedCell( failedCells, entity, field )
586                                           }
587
588                                           // Update the field, regardless of the type of field
589                                           entity.setFieldValue(field.name, params[ fieldName ] )
590                                   }
591                           }
592
593                           // Determine entity class and add a parent
594                           entity.parent = study;
595                           study.addToSamples( entity );
596
597                           // Try to validate the entity now all fields have been set. If it fails, return an error
598                           if (!entity.validate() || invalidFields) {
599                                   numInvalidEntities++;
600
601                                   // Add this field to the list of failed cells, in order to give the user feedback
602                                   failedCells = addNonValidatingCells( failedCells, entity )
603
604                                   // Also create a full list of errors
605                                   errors += getHumanReadableErrors( entity );
606                           } else {
607                                   importerService.removeFailedCell( failedCells, entity )
608                           }
609                   } // end of record
610           } // end of table
611
612           session.simpleWizard.imported.numInvalidEntities = numInvalidEntities;
613           session.simpleWizard.imported.errors = errors;
614
615           return true
616   }
617       
618        /**
619        * Handles assay input
620        * @param study          Study to update
621        * @param params         Request parameter map
622        * @return                       True if everything went OK, false otherwise. An error message is put in flash.error
623        */
624   def handleAssays( assay, params ) {
625           // did the study template change?
626           if (params.get('template') && assay.template?.name != params.get('template')) {
627                   // set the template
628                   assay.template = Template.findByName(params.remove('template'))
629           }
630
631           // does the study have a template set?
632           if (assay.template && assay.template instanceof Template) {
633                   // yes, iterate through template fields
634                   assay.giveFields().each() {
635                           // and set their values
636                           assay.setFieldValue(it.name, params.get(it.escapedName()))
637                   }
638           }
639
640           return true
641   }
642
643   /**
644    * Validates an object and puts human readable errors in validationErrors variable
645    * @param entity             Entity to validate
646    * @return                   True iff the entity validates, false otherwise
647    */
648   protected boolean validateObject( def entity ) {
649           if( !entity.validate() ) {
650                   flash.validationErrors = getHumanReadableErrors( entity )
651                   return false;
652           }
653           return true;
654   }
655   
656   
657        /**
658         * Adds all fields of this entity that have given an error when validating to the failedcells list
659         * @param failedcells   Current list of ImportRecords
660         * @param entity                Entity to check. The entity must have been validated before
661         * @return                              Updated list of ImportRecords
662         */
663        protected def addNonValidatingCells( failedcells, entity ) {
664                // Add this entity and the fields with an error to the failedCells list
665                ImportRecord failedRecord = new ImportRecord();
666
667                entity.getErrors().getFieldErrors().each { error ->
668                        String field = error.getField();
669                        def mc = importerService.findMappingColumn( session.simpleWizard.excel.data.header, field );
670                        def mcInstance = new MappingColumn( name: field, entityClass: Sample.class, index: -1, property: field.toLowerCase(), templateFieldType: entity.giveFieldType( field ) );
671
672                        // Create a clone of the mapping column
673                        if( mc ) {
674                                mcInstance.properties = mc.properties
675                        }
676
677                        failedRecord.addToImportcells( new ImportCell(mappingcolumn: mcInstance, value: error.getRejectedValue(), entityidentifier: importerService.getFieldNameInTableEditor( entity, field ) ) )
678                }
679                failedcells.add( failedRecord );
680
681                return failedcells
682        }
683
684
685
686
687        /**
688         * Checks an excel workbook whether the given sheetindex and rownumbers are correct     
689         * @param workbook                      Excel workbook to read
690         * @param sheetIndex            1-based sheet index for the sheet to read (1=first sheet)
691         * @param headerRow                     1-based row number for the header row (1=first row)
692         * @param dataMatrixStart       1-based row number for the first data row (1=first row)
693         * @return                                      True if the sheet index and row numbers are correct.
694         */
695        protected boolean excelChecks( def workbook, int sheetIndex, int headerRow, int dataMatrixStart ) {
696                // Perform some basic checks on the excel file. These checks should be performed by the importerservice
697                // in a perfect scenario.
698                if( sheetIndex > workbook.getNumberOfSheets() ) {
699                        log.error ".simple study wizard Sheet index is too high: " + sheetIndex + " / " + workbook.getNumberOfSheets();
700                        flash.error = "The sheet number you provided is too high. The provided excel sheet has only " + workbook.getNumberOfSheets() + " sheet(s).";
701                        return false
702                }
703
704                def sheet = workbook.getSheetAt(sheetIndex - 1);
705                def firstRowNum = sheet.getFirstRowNum();
706                def lastRowNum = sheet.getLastRowNum();
707                def numRows = lastRowNum - firstRowNum + 1;
708
709                if( headerRow > numRows  ) {
710                        log.error ".simple study wizard Header row number is incorrect: " + headerRow + " / " + numRows;
711                        flash.error = "The header row number you provided is too high. Please provide a number equal to or below " + numRows;
712                        return false
713                }
714
715                if( dataMatrixStart > numRows  ) {
716                        log.error ".simple study wizard Data row number is incorrect: " + dataMatrixStart + " / " + numRows;
717                        flash.error = "The data row number you provided is too high. Please provide a number equal to or below " + numRows;
718                        return false
719                }
720
721                return true;
722        }
723
724        /**
725         * Redirects the user to the page with the given name
726         * @param action
727         */
728        protected void toPage( String action ) {
729                println "Redirecting to: " + action;
730                redirect( action: action, params: [ "wizard": true ] );
731        }
732
733        /**
734         * Returns the event that is specified by the user form
735         * @param params
736         * @return
737         */
738        protected String getEvent( def params ) {
739                return params.get( 'event' );
740        }
741
742        /**
743         * Retrieves the required study from the database or return an empty Study object if
744         * no id is given
745         *
746         * @param params        Request parameters with params.id being the ID of the study to be retrieved
747         * @return                      A study from the database or an empty study if no id was given
748         */
749        protected Study getStudyFromRequest( def params ) {
750                int id = params.int( "id" );
751
752                if( !id ) {
753                        return new Study( title: "New study", owner: authenticationService.getLoggedInUser() );
754                }
755
756                Study s = Study.get( id );
757
758                if( !s.canWrite( authenticationService.getLoggedInUser() ) ) {
759                        flash.error = "No authorization to edit this study."
760                        return null;
761                }
762
763                return s
764        }
765
766        /**
767         * Retrieves the study that is saved in the wizard,
768         *
769         * @param params        Request parameters
770         * @return                      The found study object, or null if no study object is found
771         */
772        protected Study getStudyInWizard( def params ) {
773                if( params.wizard && session.simpleWizard && session.simpleWizard.study ) {
774                        // The user came here by clicking previous or a link on another page. Use the existing study
775                        return session.simpleWizard.study;
776                } else {
777                        // The user didn't get here from the wizard or no study is found
778                        return null;
779                }
780        }
781
782        /**
783         * transform domain class validation errors into a human readable
784         * linked hash map
785         * @param object validated domain class
786         * @return object  linkedHashMap
787         */
788        def getHumanReadableErrors(object) {
789                def errors = [:]
790                object.errors.getAllErrors().each() { error ->
791                        // error.codes.each() { code -> println code }
792
793                        // generally speaking g.message(...) should work,
794                        // however it fails in some steps of the wizard
795                        // (add event, add assay, etc) so g is not always
796                        // availably. Using our own instance of the
797                        // validationTagLib instead so it is always
798                        // available to us
799                        errors[error.getArguments()[0]] = validationTagLib.message(error: error)
800                }
801
802                return errors
803        }
804
805}
Note: See TracBrowser for help on using the repository browser.