Changeset 1419

Show
Ignore:
Timestamp:
20-01-11 16:28:45 (3 years ago)
Author:
work@…
Message:

- importer title fixed
- indentation fixed
- all fixed time for drinks

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/importer/ImporterController.groovy

    r1418 r1419  
    11package dbnp.importer 
     2 
    23import dbnp.studycapturing.Study 
    34import dbnp.studycapturing.Subject 
     
    2021 * Wizard Controller 
    2122 * 
    22  * @author      Jeroen Wesbeek 
    23  * @since       20101206 
     23 * @author Jeroen Wesbeek 
     24 * @since 20101206 
    2425 * 
    2526 * Revision information: 
     
    3031@Secured(['IS_AUTHENTICATED_REMEMBERED']) 
    3132class ImporterController { 
    32     // the pluginManager is used to check if the Grom 
    33     // plugin is available so we can 'Grom' development 
    34     // notifications to the unified notifications daemon 
    35     // (see http://www.grails.org/plugin/grom) 
    36     def pluginManager 
    37     def AuthenticationService 
    38     def fileService 
    39     def ImporterService 
    40     def validationTagLib = new ValidationTagLib() 
    41          
    42     /** 
    43      * index method, redirect to the webflow 
    44      * @void 
    45      */ 
    46     def index = { 
    47         // Grom a development message 
    48         if (pluginManager.getGrailsPlugin('grom')) "redirecting into the webflow".grom() 
    49  
    50  
    51         // TODO --> move this logic to the application Bootstrapping as this 
     33        // the pluginManager is used to check if the Grom 
     34        // plugin is available so we can 'Grom' development 
     35        // notifications to the unified notifications daemon 
     36        // (see http://www.grails.org/plugin/grom) 
     37        def pluginManager 
     38        def AuthenticationService 
     39        def fileService 
     40        def ImporterService 
     41        def validationTagLib = new ValidationTagLib() 
     42 
     43        /** 
     44         * index method, redirect to the webflow 
     45         * @void 
     46         */ 
     47        def index = { 
     48                // Grom a development message 
     49                if (pluginManager.getGrailsPlugin('grom')) "redirecting into the webflow".grom() 
     50 
     51                // TODO --> move this logic to the application Bootstrapping as this 
    5252                //                      does not need to run every time the importer is started 
    5353                // 
    54         // encrypt the importable entities 
    55         grailsApplication.config.gscf.domain.importableEntities.each { 
    56             it.value.encrypted =             
    57             URLEncoder.encode(Blowfish.encryptBase64( 
    58                 it.value.entity.toString().replaceAll(/^class /, ''), 
    59                 grailsApplication.config.crypto.shared.secret 
    60             )) 
    61         } 
    62  
    63         /** 
    64         * Do you believe it in your head? 
    65         * I can go with the flow 
    66         * Don't say it doesn't matter (with the flow) matter anymore 
    67         * I can go with the flow (I can go) 
    68         * Do you believe it in your head? 
    69         */ 
    70         redirect(action: 'pages') 
    71     } 
    72  
    73     /** 
    74     * WebFlow definition 
    75     * @void 
    76     */ 
    77     def pagesFlow = { 
    78         // start the flow 
    79         onStart { 
    80             // Grom a development message 
    81             if (pluginManager.getGrailsPlugin('grom')) "entering the WebFlow".grom() 
    82  
    83             // define variables in the flow scope which is availabe 
    84             // throughout the complete webflow also have a look at 
    85             // the Flow Scopes section on http://www.grails.org/WebFlow 
    86             // 
    87             // The following flow scope variables are used to generate 
    88             // wizard tabs. Also see common/_tabs.gsp for more information 
    89             flow.page = 0 
    90             flow.pages = [ 
    91                 [title: 'Import file'], 
    92                 [title: 'Properties'], 
    93                 [title: 'Mappings'], 
    94                 //[title: 'Imported'], 
    95                 [title: 'Persist'] 
    96             ] 
    97             flow.cancel = true; 
    98             flow.quickSave = true; 
    99  
    100             success() 
    101         } 
    102  
    103         // render the main wizard page which immediately 
    104         // triggers the 'next' action (hence, the main 
    105         // page dynamically renders the study template 
    106         // and makes the flow jump to the study logic) 
    107         mainPage { 
    108             render(view: "/importer/index") 
    109             onRender { 
    110                 // Grom a development message 
    111                 if (pluginManager.getGrailsPlugin('grom')) "rendering the main Ajaxflow page (index.gsp)".grom() 
    112                  
    113                 // let the view know we're in page 1 
    114                 flow.page = 1 
    115                 success() 
    116             } 
    117             on("next").to "pageOne" 
    118         } 
    119  
    120         // File import and entitie template selection page 
    121         pageOne { 
    122             render(view: "_page_one") 
    123             onRender { 
    124                 log.info ".entering import wizard" 
    125                 // Grom a development message 
    126                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial: pages/_page_one.gsp".grom() 
    127  
    128                 flow.page = 1 
    129                 flow.studies = Study.findAllWhere(owner:AuthenticationService.getLoggedInUser()) 
    130                 flow.importer_importableentities = grailsApplication.config.gscf.domain.importableEntities 
    131  
    132                 success() 
    133             } 
    134             on("next") { 
    135                 flash.wizardErrors = [:] 
    136                  
    137                 // Study selected? 
    138                 flow.importer_study = (params.study) ? Study.get(params.study.id.toInteger()) : null 
    139  
    140                 // Trying to import data into an existing study? 
    141                 if (flow.importer_study) 
    142                     if (flow.importer_study.canWrite(AuthenticationService.getLoggedInUser())) { 
    143                         if (fileImportPage(flow, params)) { 
    144                             success() 
    145                         } else { 
    146                             log.error ".importer wizard not all fields are filled in" 
    147                             this.appendErrorMap(['error': "Not all fields are filled in, please fill in or select all fields"], flash.wizardErrors) 
    148                             error() 
    149                         } 
    150                     } else 
    151                     { 
    152                         log.error ".importer wizard wrong permissions" 
    153                         this.appendErrorMap(['error': "You don't have the right permissions"], flash.wizardErrors) 
    154  
    155                         error() 
    156                     } 
    157                 else { 
    158                    if (fileImportPage(flow, params)) { 
    159                             success() 
    160                         } else { 
    161                             log.error ".importer wizard not all fields are filled in" 
    162                             this.appendErrorMap(['error': "Not all fields are filled in, please fill in or select all fields"], flash.wizardErrors) 
    163                             error() 
    164                         } 
    165                 } 
    166                  
    167                 // put your bussiness logic (if applicable) in here 
    168             }.to "pageTwo" 
    169         } 
    170  
    171         // Property to column assignment page 
    172         pageTwo {             
    173             render(view: "_page_two") 
    174             onRender { 
    175                 log.info ".import wizard properties page" 
    176                 // Grom a development message 
    177                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial: pages/_page_two.gsp".grom() 
    178                  
    179                 flow.page = 2 
    180                 success() 
    181             } 
    182             on("next") { 
    183                 if (propertiesPage(flow, params)) {                     
    184                     success() 
    185                 } else { 
    186                     log.error ".import wizard, properties are set wrong" 
    187                     error() 
    188                 } 
    189             }.to "pageThree" 
    190             on("previous").to "pageOne" 
    191         } 
    192  
    193         // Mapping page 
    194         pageThree {             
    195             render(view: "_page_three") 
    196             onRender {                 
    197                 log.info ".import wizard mapping page" 
    198                 // Grom a development message 
    199                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_page_three.gsp".grom() 
    200  
    201                 flow.page = 3 
    202                 success() 
    203             }             
    204             on("refresh") {                 
    205                     success() 
    206             }.to "pageThree" 
    207             on("next") { 
    208                 if (mappingsPage(flow, flash, params)) { 
    209                     success() 
    210                 } else { 
    211                     log.error ".import wizard mapping error, could not validate all entities" 
    212                     error() 
    213                 } 
    214             }.to "save" 
    215             on("previous").to "pageTwo" 
    216         } 
    217  
    218         // Imported data overview page 
    219         pageFour { 
    220             render(view: "_page_four") 
    221             onRender { 
    222                 // Grom a development message 
    223                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_page_four.gsp".grom() 
    224  
    225                 flow.page = 4 
    226                 success() 
    227             } 
    228             on("next") { 
    229                 if (importedPage(flow, params)) { 
    230                     success() 
    231                 } else { 
    232                     log.error ".import wizard imported error, something went wrong showing the imported entities" 
    233                     error() 
    234                 } 
    235                 flow.page = 5 
    236             }.to "save" 
    237             on("previous").to "pageThree" 
    238         } 
    239  
    240         // Save the imported data 
    241         save { 
    242             action { 
    243                 // here you can validate and save the 
    244                 // instances you have created in the 
    245                 // ajax flow. 
    246                     // Grom a development message 
    247                     if (pluginManager.getGrailsPlugin('grom')) ".persisting instances to the database...".grom()                     
    248  
    249                     if (saveEntities(flow, params)) { 
     54                // encrypt the importable entities 
     55                grailsApplication.config.gscf.domain.importableEntities.each { 
     56                        it.value.encrypted = 
     57                                URLEncoder.encode(Blowfish.encryptBase64( 
     58                                        it.value.entity.toString().replaceAll(/^class /, ''), 
     59                                        grailsApplication.config.crypto.shared.secret 
     60                                )) 
     61                } 
     62 
     63                /** 
     64                * Do you believe it in your head? 
     65                * I can go with the flow 
     66                * Don't say it doesn't matter (with the flow) matter anymore 
     67                * I can go with the flow (I can go) 
     68                * Do you believe it in your head? 
     69                */ 
     70                redirect(action: 'pages') 
     71        } 
     72 
     73        /** 
     74        * WebFlow definition 
     75        * @void 
     76        */ 
     77        def pagesFlow = { 
     78                // start the flow 
     79                onStart { 
     80                        // Grom a development message 
     81                        if (pluginManager.getGrailsPlugin('grom')) "entering the WebFlow".grom() 
     82 
     83                        // define variables in the flow scope which is availabe 
     84                        // throughout the complete webflow also have a look at 
     85                        // the Flow Scopes section on http://www.grails.org/WebFlow 
     86                        // 
     87                        // The following flow scope variables are used to generate 
     88                        // wizard tabs. Also see common/_tabs.gsp for more information 
     89                        flow.page = 0 
     90                        flow.pages = [ 
     91                                [title: 'Import file'], 
     92                                [title: 'Properties'], 
     93                                [title: 'Mappings'], 
     94                                //[title: 'Imported'], 
     95                                [title: 'Persist'] 
     96                        ] 
     97                        flow.cancel = true; 
     98                        flow.quickSave = true; 
     99 
     100                        success() 
     101                } 
     102 
     103                // render the main wizard page which immediately 
     104                // triggers the 'next' action (hence, the main 
     105                // page dynamically renders the study template 
     106                // and makes the flow jump to the study logic) 
     107                mainPage { 
     108                        render(view: "/importer/index") 
     109                        onRender { 
     110                                // Grom a development message 
     111                                if (pluginManager.getGrailsPlugin('grom')) "rendering the main Ajaxflow page (index.gsp)".grom() 
     112 
     113                                // let the view know we're in page 1 
     114                                flow.page = 1 
     115                                success() 
     116                        } 
     117                        on("next").to "pageOne" 
     118                } 
     119 
     120                // File import and entitie template selection page 
     121                pageOne { 
     122                        render(view: "_page_one") 
     123                        onRender { 
     124                                log.info ".entering import wizard" 
     125                                // Grom a development message 
     126                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial: pages/_page_one.gsp".grom() 
     127 
     128                                flow.page = 1 
     129                                flow.studies = Study.findAllWhere(owner: AuthenticationService.getLoggedInUser()) 
     130                                flow.importer_importableentities = grailsApplication.config.gscf.domain.importableEntities 
     131 
     132                                success() 
     133                        } 
     134                        on("next") { 
     135                                flash.wizardErrors = [:] 
     136 
     137                                // Study selected? 
     138                                flow.importer_study = (params.study) ? Study.get(params.study.id.toInteger()) : null 
     139 
     140                                // Trying to import data into an existing study? 
     141                                if (flow.importer_study) 
     142                                        if (flow.importer_study.canWrite(AuthenticationService.getLoggedInUser())) { 
     143                                                if (fileImportPage(flow, params)) { 
     144                                                        success() 
     145                                                } else { 
     146                                                        log.error ".importer wizard not all fields are filled in" 
     147                                                        this.appendErrorMap(['error': "Not all fields are filled in, please fill in or select all fields"], flash.wizardErrors) 
     148                                                        error() 
     149                                                } 
     150                                        } else { 
     151                                                log.error ".importer wizard wrong permissions" 
     152                                                this.appendErrorMap(['error': "You don't have the right permissions"], flash.wizardErrors) 
     153 
     154                                                error() 
     155                                        } 
     156                                else { 
     157                                        if (fileImportPage(flow, params)) { 
     158                                                success() 
     159                                        } else { 
     160                                                log.error ".importer wizard not all fields are filled in" 
     161                                                this.appendErrorMap(['error': "Not all fields are filled in, please fill in or select all fields"], flash.wizardErrors) 
     162                                                error() 
     163                                        } 
     164                                } 
     165 
     166                                // put your bussiness logic (if applicable) in here 
     167                        }.to "pageTwo" 
     168                } 
     169 
     170                // Property to column assignment page 
     171                pageTwo { 
     172                        render(view: "_page_two") 
     173                        onRender { 
     174                                log.info ".import wizard properties page" 
     175                                // Grom a development message 
     176                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial: pages/_page_two.gsp".grom() 
     177 
     178                                flow.page = 2 
     179                                success() 
     180                        } 
     181                        on("next") { 
     182                                if (propertiesPage(flow, params)) { 
     183                                        success() 
     184                                } else { 
     185                                        log.error ".import wizard, properties are set wrong" 
     186                                        error() 
     187                                } 
     188                        }.to "pageThree" 
     189                        on("previous").to "pageOne" 
     190                } 
     191 
     192                // Mapping page 
     193                pageThree { 
     194                        render(view: "_page_three") 
     195                        onRender { 
     196                                log.info ".import wizard mapping page" 
     197                                // Grom a development message 
     198                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_page_three.gsp".grom() 
     199 
     200                                flow.page = 3 
     201                                success() 
     202                        } 
     203                        on("refresh") { 
     204                                success() 
     205                        }.to "pageThree" 
     206                        on("next") { 
     207                                if (mappingsPage(flow, flash, params)) { 
     208                                        flow.page = 4 
     209                                        success() 
     210                                } else { 
     211                                        log.error ".import wizard mapping error, could not validate all entities" 
     212                                        error() 
     213                                } 
     214                        }.to "save" 
     215                        on("previous").to "pageTwo" 
     216                } 
     217 
     218                // Imported data overview page 
     219                pageFour { 
     220                        render(view: "_page_four") 
     221                        onRender { 
     222                                // Grom a development message 
     223                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_page_four.gsp".grom() 
     224 
     225                                flow.page = 4 
     226                                success() 
     227                        } 
     228                        on("next") { 
     229                                if (importedPage(flow, params)) { 
     230                                        flow.page = 4 
     231                                        success() 
     232                                } else { 
     233                                        log.error ".import wizard imported error, something went wrong showing the imported entities" 
     234                                        error() 
     235                                } 
     236                        }.to "save" 
     237                        on("previous").to "pageThree" 
     238                } 
     239 
     240                // Save the imported data 
     241                save { 
     242                        action { 
     243                                // here you can validate and save the 
     244                                // instances you have created in the 
     245                                // ajax flow. 
     246                                // Grom a development message 
     247                                if (pluginManager.getGrailsPlugin('grom')) ".persisting instances to the database...".grom() 
     248 
     249                                if (saveEntities(flow, params)) { 
    250250                                        //if (ImporterService.saveDatamatrix(flow.importer_study, flow.importer_importeddata)) { 
    251                         log.error ".import wizard succesfully persisted all entities"                         
    252                         //def session = sessionFactory.getCurrentSession() 
    253                         //session.clear() 
    254                         success() 
    255                     } else {                         
    256                         log.error ".import wizard, could not save entities:\n" + e.dump() 
    257                         flow.page = 4 
    258                         error() 
    259                     } 
    260             } 
    261             on("error").to "error" 
    262             on(Exception).to "error" 
    263             on("success").to "finalPage" 
    264         } 
    265  
    266         // render errors 
    267         error { 
    268             render(view: "_error") 
    269             onRender { 
    270                  
    271                 // Grom a development message 
    272                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_error.gsp".grom() 
    273  
    274                 // set page to 4 so that the navigation 
    275                 // works (it is disabled on the final page) 
    276                 flow.page = 4 
    277             } 
    278             on("next").to "save" 
    279             on("previous").to "pageFour" 
    280         } 
    281  
    282         // last wizard page 
    283         finalPage {             
    284             render(view: "_final_page") 
    285             onRender { 
    286                 println "EEN" 
    287                 // Grom a development message 
    288                 if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_final_page.gsp".grom() 
    289                 println "TWEE" 
    290                                  
    291                 success() 
    292                 println "DRIE" 
    293             } 
    294             onEnd { 
     251                                        log.error ".import wizard succesfully persisted all entities" 
     252                                        //def session = sessionFactory.getCurrentSession() 
     253                                        //session.clear() 
     254                                        success() 
     255                                } else { 
     256                                        log.error ".import wizard, could not save entities:\n" + e.dump() 
     257                                        flow.page = 4 
     258                                        error() 
     259                                } 
     260                        } 
     261                        on("error").to "error" 
     262                        on(Exception).to "error" 
     263                        on("success").to "finalPage" 
     264                } 
     265 
     266                // render errors 
     267                error { 
     268                        render(view: "_error") 
     269                        onRender { 
     270 
     271                                // Grom a development message 
     272                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_error.gsp".grom() 
     273 
     274                                // set page to 4 so that the navigation 
     275                                // works (it is disabled on the final page) 
     276                                flow.page = 4 
     277                        } 
     278                        on("next").to "save" 
     279                        on("previous").to "pageFour" 
     280                } 
     281 
     282                // last wizard page 
     283                finalPage { 
     284                        render(view: "_final_page") 
     285                        onRender { 
     286                                println "EEN" 
     287                                // Grom a development message 
     288                                if (pluginManager.getGrailsPlugin('grom')) ".rendering the partial pages/_final_page.gsp".grom() 
     289                                println "TWEE" 
     290 
     291                                success() 
     292                                println "DRIE" 
     293                        } 
     294                        onEnd { 
    295295                                // clean flow scope 
    296296                                flow.clear() 
    297297                        } 
    298         } 
    299     } 
    300  
    301     /** 
    302     * Return templates which belong to a certain entity type 
    303     * 
    304     * @param entity entity name string (Sample, Subject, Study et cetera) 
    305     * @return JSON object containing the found templates 
    306     */ 
    307     def ajaxGetTemplatesByEntity = {         
    308         def entityName = Blowfish.decryptBase64(             
    309             URLDecoder.decode(params.entity), 
    310             grailsApplication.config.crypto.shared.secret 
    311         ) 
    312  
    313         //def entityClass = grailsApplication.config.gscf.domain.importableEntities.get(params.entity).entity 
    314         def entityClass = entityName 
    315  
    316         // fetch all templates for a specific entity 
    317         def templates = Template.findAllByEntity(Class.forName(entityClass, true, this.getClass().getClassLoader())) 
    318  
    319         // render as JSON 
    320         render templates as JSON 
    321     } 
    322  
    323     /** 
    324     * Handle the file import page. 
    325     * 
    326     * @param Map LocalAttributeMap (the flow scope) 
    327     * @param Map GrailsParameterMap (the flow parameters = form data) 
    328     * @returns boolean true if correctly validated, otherwise false 
    329     */ 
    330     boolean fileImportPage(flow, params) { 
    331         def importedfile = fileService.get(params['importfile']) 
    332         //fileService.delete(YourFile) 
    333  
    334         if (params.entity && params.template_id && importedfile.exists()) { 
    335             // create a workbook instance of the file 
    336             session.importer_workbook = ImporterService.getWorkbook(new FileInputStream(importedfile)) 
    337              
    338             def selectedentities = [] 
    339              
    340             def entityName = Blowfish.decryptBase64( 
    341                 URLDecoder.decode(params.entity), 
    342                 grailsApplication.config.crypto.shared.secret 
    343             ) 
    344              
    345             def entityClass = Class.forName(entityName, true, this.getClass().getClassLoader()) 
    346              
    347             // Initialize some session variables 
    348             //flow.importer_workbook = wb // workbook object must be serialized for this to work             
    349               
    350                 flow.importer_template_id = params.template_id 
    351                 flow.importer_sheetindex = params.sheetindex.toInteger() -1 // 0 == first sheet 
    352                 flow.importer_datamatrix_start = params.datamatrix_start.toInteger() -1 // 0 == first row 
    353                 flow.importer_headerrow = params.headerrow.toInteger() 
    354  
    355                 // Get the header from the Excel file using the arguments given in the first step of the wizard 
    356                 flow.importer_header = ImporterService.getHeader(session.importer_workbook, 
    357                     flow.importer_sheetindex, 
    358                     flow.importer_headerrow, 
    359                     flow.importer_datamatrix_start, 
    360                     entityClass) 
    361  
    362                 // Initialize 'selected entities', used to show entities above the columns 
    363                 flow.importer_header.each { 
    364                     selectedentities.add([name:entityName, columnindex:it.key.toInteger()]) 
    365                 } 
    366                  
    367                 flow.importer_selectedentities = selectedentities                 
    368  
    369                 session.importer_datamatrix = ImporterService.getDatamatrix( 
    370                             session.importer_workbook, flow.importer_header, 
    371                             flow.importer_sheetindex, 
    372                             flow.importer_datamatrix_start, 
    373                             5) 
    374                
    375                 flow.importer_templates = Template.get(flow.importer_template_id) 
    376                 flow.importer_allfieldtypes = "true"      
    377             /*else { 
    378                 render (template:"common/error", 
    379                     model:[error:"Wrong permissions: you are not allowed to write to the study you selected (${flow.importer_study})."]) 
    380             }*/ 
    381  
    382             return true 
    383         } 
    384     } 
    385  
    386     /** 
    387     * Handle the property mapping page. 
    388     * 
    389     * @param Map LocalAttributeMap (the flow scope) 
    390     * @param Map GrailsParameterMap (the flow parameters = form data) 
    391     * @returns boolean true if correctly validated, otherwise false 
    392     */ 
    393     boolean propertiesPage (flow, params) { 
    394         // Find actual Template object from the chosen template name 
    395         def template = Template.get(flow.importer_template_id) 
    396  
    397         params.columnproperty.index.each { columnindex, property -> 
    398             // Create an actual class instance of the selected entity with the selected template 
    399             // This should be inside the closure because in some cases in the advanced importer, the fields can have different target entities 
    400             def entityClass = Class.forName(flow.importer_header[columnindex.toInteger()].entity.getName(), true, this.getClass().getClassLoader()) 
    401             def entityObj = entityClass.newInstance(template:template) 
    402  
    403             // Store the selected property for this column into the column map for the ImporterService 
    404             flow.importer_header[columnindex.toInteger()].property = property 
    405  
    406             // Look up the template field type of the target TemplateField and store it also in the map 
    407             flow.importer_header[columnindex.toInteger()].templatefieldtype = entityObj.giveFieldType(property) 
    408  
    409             // Is a "Don't import" property assigned to the column? 
    410             flow.importer_header[columnindex.toInteger()].dontimport = (property=="dontimport") ? true : false 
    411  
    412             //if it's an identifier set the mapping column true or false 
    413             entityObj.giveFields().each { 
    414                 (it.preferredIdentifier && (it.name==property)) ? flow.importer_header[columnindex.toInteger()].identifier = true : false 
    415             } 
    416         } 
    417  
    418         // Import the workbook and store the table with entity records and store the failed cells 
    419         def (table, failedcells) = ImporterService.importData(flow.importer_template_id, 
    420                                                               session.importer_workbook, 
    421                                                               flow.importer_sheetindex, 
    422                                                               flow.importer_datamatrix_start, 
    423                                                               flow.importer_header) 
    424  
    425         flow.importer_importeddata = table         
    426         flow.importer_failedcells = failedcells 
    427         return true 
    428     } 
    429  
    430     /** 
    431     * Handle the mapping page. 
    432     * 
    433     * @param Map LocalAttributeMap (the flow scope) 
    434     * @param Map GrailsParameterMap (the flow parameters = form data) 
    435     * @returns boolean true if correctly validated, otherwise false 
    436     */ 
    437     boolean mappingsPage(flow, flash, params) { 
    438         flash.wizardErrors = [:] 
    439         flow.importer_invalidentities = 0         
    440  
    441         flow.importer_importeddata.each { table -> 
    442             table.each { entity ->                 
    443                 def invalidontologies = 0 
    444  
    445                 // Set the fields for this entity by retrieving values from the params 
    446                 entity.giveFields().each { field ->                     
    447                         // field of type ontology and value "#invalidterm"? 
    448                         if (field.type == dbnp.studycapturing.TemplateFieldType.ONTOLOGYTERM && 
    449                             params["entity_" + entity.getIdentifier() + "_" + field.escapedName()] == "#invalidterm" 
    450                         ) { 
    451                             invalidontologies++ 
    452                         } else 
    453                         if (field.type == dbnp.studycapturing.TemplateFieldType.ONTOLOGYTERM && 
    454                             params["entity_" + entity.getIdentifier() + "_" + field.escapedName()] != "#invalidterm") { 
    455                             removeFailedCell(flow.importer_failedcells, entity) 
    456                             entity.setFieldValue (field.toString(), params["entity_" + entity.getIdentifier() + "_" + field.escapedName()]) 
    457                         } 
    458                         else 
    459                             entity.setFieldValue (field.toString(), params["entity_" + entity.getIdentifier() + "_" + field.escapedName()]) 
    460                 } 
    461  
    462                 // Determine entity class and add a parent (defined as Study in first step of wizard) 
    463                 switch (entity.getClass()) { 
    464                     case [Subject, Sample, Event]:  entity.parent = flow.importer_study 
    465                 } 
    466  
    467                 // Try to validate the entity now all fields have been set 
    468                 if (!entity.validate() || invalidontologies) { 
    469                     flow.importer_invalidentities++ 
    470  
    471                     // add errors to map                     
    472                     this.appendErrors(entity, flash.wizardErrors, "entity_"+entity.getIdentifier() + "_") 
    473                      
     298                } 
     299        } 
     300 
     301        /** 
     302        * Return templates which belong to a certain entity type 
     303        * 
     304        * @param entity entity name string (Sample, Subject, Study et cetera) 
     305        * @return JSON object containing the found templates 
     306        */ 
     307        def ajaxGetTemplatesByEntity = { 
     308                def entityName = Blowfish.decryptBase64( 
     309                        URLDecoder.decode(params.entity), 
     310                        grailsApplication.config.crypto.shared.secret 
     311                ) 
     312 
     313                //def entityClass = grailsApplication.config.gscf.domain.importableEntities.get(params.entity).entity 
     314                def entityClass = entityName 
     315 
     316                // fetch all templates for a specific entity 
     317                def templates = Template.findAllByEntity(Class.forName(entityClass, true, this.getClass().getClassLoader())) 
     318 
     319                // render as JSON 
     320                render templates as JSON 
     321        } 
     322 
     323        /** 
     324        * Handle the file import page. 
     325        * 
     326        * @param Map LocalAttributeMap (the flow scope) 
     327        * @param Map GrailsParameterMap (the flow parameters = form data) 
     328        * @returns boolean true if correctly validated, otherwise false 
     329        */ 
     330        boolean fileImportPage(flow, params) { 
     331                def importedfile = fileService.get(params['importfile']) 
     332                //fileService.delete(YourFile) 
     333 
     334                if (params.entity && params.template_id && importedfile.exists()) { 
     335                        // create a workbook instance of the file 
     336                        session.importer_workbook = ImporterService.getWorkbook(new FileInputStream(importedfile)) 
     337 
     338                        def selectedentities = [] 
     339 
     340                        def entityName = Blowfish.decryptBase64( 
     341                                URLDecoder.decode(params.entity), 
     342                                grailsApplication.config.crypto.shared.secret 
     343                        ) 
     344 
     345                        def entityClass = Class.forName(entityName, true, this.getClass().getClassLoader()) 
     346 
     347                        // Initialize some session variables 
     348                        //flow.importer_workbook = wb // workbook object must be serialized for this to work 
     349 
     350                        flow.importer_template_id = params.template_id 
     351                        flow.importer_sheetindex = params.sheetindex.toInteger() - 1 // 0 == first sheet 
     352                        flow.importer_datamatrix_start = params.datamatrix_start.toInteger() - 1 // 0 == first row 
     353                        flow.importer_headerrow = params.headerrow.toInteger() 
     354 
     355                        // Get the header from the Excel file using the arguments given in the first step of the wizard 
     356                        flow.importer_header = ImporterService.getHeader(session.importer_workbook, 
     357                                flow.importer_sheetindex, 
     358                                flow.importer_headerrow, 
     359                                flow.importer_datamatrix_start, 
     360                                entityClass) 
     361 
     362                        // Initialize 'selected entities', used to show entities above the columns 
     363                        flow.importer_header.each { 
     364                                selectedentities.add([name: entityName, columnindex: it.key.toInteger()]) 
     365                        } 
     366 
     367                        flow.importer_selectedentities = selectedentities 
     368 
     369                        session.importer_datamatrix = ImporterService.getDatamatrix( 
     370                                session.importer_workbook, flow.importer_header, 
     371                                flow.importer_sheetindex, 
     372                                flow.importer_datamatrix_start, 
     373                                5) 
     374 
     375                        flow.importer_templates = Template.get(flow.importer_template_id) 
     376                        flow.importer_allfieldtypes = "true" 
     377                        /*else { 
     378                                                        render (template:"common/error", 
     379                                                                model:[error:"Wrong permissions: you are not allowed to write to the study you selected (${flow.importer_study})."]) 
     380                                                }*/ 
     381 
     382                        return true 
     383                } 
     384        } 
     385 
     386        /** 
     387        * Handle the property mapping page. 
     388        * 
     389        * @param Map LocalAttributeMap (the flow scope) 
     390        * @param Map GrailsParameterMap (the flow parameters = form data) 
     391        * @returns boolean true if correctly validated, otherwise false 
     392        */ 
     393        boolean propertiesPage(flow, params) { 
     394                // Find actual Template object from the chosen template name 
     395                def template = Template.get(flow.importer_template_id) 
     396 
     397                params.columnproperty.index.each { columnindex, property -> 
     398                        // Create an actual class instance of the selected entity with the selected template 
     399                        // This should be inside the closure because in some cases in the advanced importer, the fields can have different target entities 
     400                        def entityClass = Class.forName(flow.importer_header[columnindex.toInteger()].entity.getName(), true, this.getClass().getClassLoader()) 
     401                        def entityObj = entityClass.newInstance(template: template) 
     402 
     403                        // Store the selected property for this column into the column map for the ImporterService 
     404                        flow.importer_header[columnindex.toInteger()].property = property 
     405 
     406                        // Look up the template field type of the target TemplateField and store it also in the map 
     407                        flow.importer_header[columnindex.toInteger()].templatefieldtype = entityObj.giveFieldType(property) 
     408 
     409                        // Is a "Don't import" property assigned to the column? 
     410                        flow.importer_header[columnindex.toInteger()].dontimport = (property == "dontimport") ? true : false 
     411 
     412                        //if it's an identifier set the mapping column true or false 
     413                        entityObj.giveFields().each { 
     414                                (it.preferredIdentifier && (it.name == property)) ? flow.importer_header[columnindex.toInteger()].identifier = true : false 
     415                        } 
     416                } 
     417 
     418                // Import the workbook and store the table with entity records and store the failed cells 
     419                def (table, failedcells) = ImporterService.importData(flow.importer_template_id, 
     420                        session.importer_workbook, 
     421                        flow.importer_sheetindex, 
     422                        flow.importer_datamatrix_start, 
     423                        flow.importer_header) 
     424 
     425                flow.importer_importeddata = table 
     426                flow.importer_failedcells = failedcells 
     427                return true 
     428        } 
     429 
     430        /** 
     431        * Handle the mapping page. 
     432        * 
     433        * @param Map LocalAttributeMap (the flow scope) 
     434        * @param Map GrailsParameterMap (the flow parameters = form data) 
     435        * @returns boolean true if correctly validated, otherwise false 
     436        */ 
     437        boolean mappingsPage(flow, flash, params) { 
     438                flash.wizardErrors = [:] 
     439                flow.importer_invalidentities = 0 
     440 
     441                flow.importer_importeddata.each { table -> 
     442                        table.each { entity -> 
     443                                def invalidontologies = 0 
     444 
     445                                // Set the fields for this entity by retrieving values from the params 
     446                                entity.giveFields().each { field -> 
     447                                        // field of type ontology and value "#invalidterm"? 
     448                                        if (field.type == dbnp.studycapturing.TemplateFieldType.ONTOLOGYTERM && 
     449                                                params["entity_" + entity.getIdentifier() + "_" + field.escapedName()] == "#invalidterm" 
     450                                        ) { 
     451                                                invalidontologies++ 
     452                                        } else 
     453                                        if (field.type == dbnp.studycapturing.TemplateFieldType.ONTOLOGYTERM && 
     454                                                params["entity_" + entity.getIdentifier() + "_" + field.escapedName()] != "#invalidterm") { 
     455                                                removeFailedCell(flow.importer_failedcells, entity) 
     456                                                entity.setFieldValue(field.toString(), params["entity_" + entity.getIdentifier() + "_" + field.escapedName()]) 
     457                                        } 
     458                                        else 
     459                                                entity.setFieldValue(field.toString(), params["entity_" + entity.getIdentifier() + "_" + field.escapedName()]) 
     460                                } 
     461 
     462                                // Determine entity class and add a parent (defined as Study in first step of wizard) 
     463                                switch (entity.getClass()) { 
     464                                        case [Subject, Sample, Event]: entity.parent = flow.importer_study 
     465                                } 
     466 
     467                                // Try to validate the entity now all fields have been set 
     468                                if (!entity.validate() || invalidontologies) { 
     469                                        flow.importer_invalidentities++ 
     470 
     471                                        // add errors to map 
     472                                        this.appendErrors(entity, flash.wizardErrors, "entity_" + entity.getIdentifier() + "_") 
     473 
    474474                                        entity.errors.getAllErrors().each() { 
    475475                                                log.error ".import wizard imported validation error:" + it 
    476476                                        } 
    477                 } else {                     
    478                     removeFailedCell(flow.importer_failedcells, entity) 
    479                 } // end else if 
    480  
    481             } // end of record 
    482         } // end of table 
    483  
    484         return (flow.importer_invalidentities == 0) ? true : false 
    485     } // end of method 
    486  
    487     /** 
    488     * @param failedcell failed ontology cells 
    489     * @param entity entity to remove from the failedcells list 
    490     */ 
    491     def removeFailedCell(failedcells, entity) {         
    492         // Valid entity, remove it from failedcells 
    493         failedcells.each { record -> 
    494             def tempimportcells = [] 
    495              
    496             record.importcells.each { cell ->             
    497             // remove the cell from the failed cells session 
    498                 if (cell.entityidentifier != entity.getIdentifier()) { 
    499                     //record.removeFromImportcells(cell) 
    500                     tempimportcells.add(cell) 
    501                 } 
    502             } 
    503  
    504             record.importcells = tempimportcells 
    505            // } // end of importcells 
    506         } // end of failedcells 
    507     } 
    508  
    509     /** 
    510     * Handle the imported entities page. 
    511     * 
    512     * @param Map LocalAttributeMap (the flow scope) 
    513     * @param Map GrailsParameterMap (the flow parameters = form data) 
    514     * @returns boolean true if correctly validated, otherwise false 
    515     */ 
    516     boolean importedPage(flow, params) { 
    517         return true 
    518     } 
    519  
    520     boolean saveEntities(flow, params) {             
    521             //def (validatedSuccesfully, updatedEntities, failedToPersist) = 
    522             //try { 
    523                 ImporterService.saveDatamatrix(flow.importer_study, flow.importer_importeddata) 
    524                  
    525             //} 
    526             //catch (Exception e) { 
     477                                } else { 
     478                                        removeFailedCell(flow.importer_failedcells, entity) 
     479                                } // end else if 
     480 
     481                        } // end of record 
     482                } // end of table 
     483 
     484                return (flow.importer_invalidentities == 0) ? true : false 
     485        } // end of method 
     486 
     487        /** 
     488        * @param failedcell failed ontology cells 
     489        * @param entity entity to remove from the failedcells list 
     490        */ 
     491        def removeFailedCell(failedcells, entity) { 
     492                // Valid entity, remove it from failedcells 
     493                failedcells.each { record -> 
     494                        def tempimportcells = [] 
     495 
     496                        record.importcells.each { cell -> 
     497                                // remove the cell from the failed cells session 
     498                                if (cell.entityidentifier != entity.getIdentifier()) { 
     499                                        //record.removeFromImportcells(cell) 
     500                                        tempimportcells.add(cell) 
     501                                } 
     502                        } 
     503 
     504                        record.importcells = tempimportcells 
     505                        // } // end of importcells 
     506                } // end of failedcells 
     507        } 
     508 
     509        /** 
     510        * Handle the imported entities page. 
     511        * 
     512        * @param Map LocalAttributeMap (the flow scope) 
     513        * @param Map GrailsParameterMap (the flow parameters = form data) 
     514        * @returns boolean true if correctly validated, otherwise false 
     515        */ 
     516        boolean importedPage(flow, params) { 
     517                return true 
     518        } 
     519 
     520        boolean saveEntities(flow, params) { 
     521                //def (validatedSuccesfully, updatedEntities, failedToPersist) = 
     522                //try { 
     523                ImporterService.saveDatamatrix(flow.importer_study, flow.importer_importeddata) 
     524 
     525                //} 
     526                //catch (Exception e) { 
    527527//                log.error ".import wizard saveEntities error\n" + e.dump() 
    528528//            } 
    529              
    530             //flow.importer_validatedsuccesfully = validatedSuccesfully 
    531             //flow.importer_failedtopersist = failedToPersist 
    532             //flow.imported_updatedentities = updatedEntities 
    533             //flow.importer_totalrows = flow.importer_importeddata.size 
    534             //flow.importer_referer = ""             
    535  
    536             return true 
    537     } 
    538  
    539     /** 
     529 
     530                //flow.importer_validatedsuccesfully = validatedSuccesfully 
     531                //flow.importer_failedtopersist = failedToPersist 
     532                //flow.imported_updatedentities = updatedEntities 
     533                //flow.importer_totalrows = flow.importer_importeddata.size 
     534                //flow.importer_referer = "" 
     535 
     536                return true 
     537        } 
     538 
     539        /** 
    540540         * append errors of a particular object to a map 
    541541         * @param object 
     
    545545        def appendErrors(object, map) { 
    546546                this.appendErrorMap(getHumanReadableErrors(object), map) 
    547     } 
     547        } 
    548548 
    549549        def appendErrors(object, map, prepend) { 
     
    551551        } 
    552552 
    553     /** 
     553        /** 
    554554         * append errors of one map to another map 
    555555         * @param map linkedHashMap 
     
    559559        def appendErrorMap(map, mapToExtend) { 
    560560                map.each() {key, value -> 
    561                         mapToExtend[key] = ['key': key, 'value': value, 'dynamic': false]             
     561                        mapToExtend[key] = ['key': key, 'value': value, 'dynamic': false] 
    562562                } 
    563563        } 
     
    569569        } 
    570570 
    571     /** 
     571        /** 
    572572         * transform domain class validation errors into a human readable 
    573573         * linked hash map 
     
    586586                        // validationTagLib instead so it is always 
    587587                        // available to us 
    588                         errors[ error.getArguments()[0] ] = validationTagLib.message(error: error) 
     588                        errors[error.getArguments()[0]] = validationTagLib.message(error: error) 
    589589                } 
    590590