source: trunk/grails-app/controllers/dbnp/importer/ImporterController.groovy @ 661

Last change on this file since 661 was 661, checked in by tabma, 11 years ago
  • fixed property assignment by using lookup from new entity object method getFieldType
  • Property svn:keywords set to Date Author Rev
File size: 9.5 KB
RevLine 
[215]1/**
2 * Importer controller
3 *
4 * The importer controller handles the uploading of tabular, comma delimited and Excel format
5 * based files. When uploaded a preview is shown of the data and the user can adjust the column
6 * type. Data in cells which don't correspond to the specified column type will be represented as "#error".
7 *
8 * The importer controller catches the actions and consecutively performs the
9 * logic behind it.
10 *
11 * @package     importer
12 * @author      t.w.abma@umcutrecht.nl
13 * @since       20100126
14 *
15 * Revision information:
16 * $Rev: 661 $
17 * $Author: tabma $
18 * $Date: 2010-07-19 14:10:09 +0000 (ma, 19 jul 2010) $
19 */
20
21package dbnp.importer
[354]22
[215]23import dbnp.studycapturing.Template
[251]24import dbnp.studycapturing.Study
25import dbnp.studycapturing.Subject
26import dbnp.studycapturing.Event
[354]27
[251]28import dbnp.studycapturing.Sample
29import dbnp.studycapturing.TemplateFieldType
[273]30import dbnp.studycapturing.TemplateField
[449]31import grails.converters.JSON
[485]32import org.apache.poi.hssf.usermodel.HSSFWorkbook
[215]33
34class ImporterController {
[449]35    def ImporterService   
[215]36
37    /**
38     * Default page
39     **/
[417]40    def index = {       
[215]41    }
42
[632]43    def simpleWizard = {
[449]44        render(view:"index_simple", model:[studies:Study.list(), entities: grailsApplication.config.gscf.domain.importableEntities])
[417]45    }
46
[632]47    def advancedWizard = {
[417]48        render(view:"index_advanced", model:[templates:Template.list()])
49    }
50
[215]51    /**
52    * This method will move the uploaded file to a temporary path and send the header
53    * and the first n rows to the preview
54    * @param importfile uploaded file to import
[492]55    * @param study.id study identifier
[215]56    */
[485]57    def upload_advanced = {
58        def wb = handleUpload('importfile')
[492]59
[485]60        session.importer_header = ImporterService.getHeader(wb, 0)
[534]61        session.importer_study = Study.get(params.study.id.toInteger())
[485]62        session.importer_template_id = params.template_id
63        session.importer_workbook = wb
[215]64
[655]65        render (view:"step1_advanced", model:[header:session.importer_header, datamatrix:ImporterService.getDatamatrix(wb, session.importer_header, 0, 5)])
[485]66    }
67
68    /**
69    * This method will move the uploaded file to a temporary path and send the header
70    * and the rows to the postview
71    *
72    * @param importfile uploaded file to import
73    * @param entity string representation of the entity chosen
74    */
75    def upload_simple = {
76        def wb = handleUpload('importfile')
[489]77        def selectedentities = []
[485]78        def entity = grailsApplication.config.gscf.domain.importableEntities.get(params.entity).entity
[489]79        def entityClass = Class.forName(entity, true, this.getClass().getClassLoader())
[485]80
81        session.importer_header = ImporterService.getHeader(wb, 0, entityClass)
[534]82        session.importer_study = Study.get(params.study.id.toInteger())
[328]83        session.importer_template_id = params.template_id
84        session.importer_workbook = wb
[215]85
[489]86        session.importer_header.each {     
87            selectedentities.add([name:params.entity, columnindex:it.key.toInteger()])
88        }
89
[485]90        def templates = Template.get(session.importer_template_id)
91       
[655]92        render(view:"step2_simple", model:[entities: selectedentities, header:session.importer_header, datamatrix:ImporterService.getDatamatrix(wb, session.importer_header, 0, 5), templates:templates])
[215]93    }
94
95    /**
[485]96     * This method handles a file being uploaded and storing it in a temporary directory
97     * and returning a workbook
98     *
99     * @param formfilename name used for the file field in the form
100     * @return workbook object reference
101     */
102    private HSSFWorkbook handleUpload(formfilename) {
103
104        def downloadedfile = request.getFile(formfilename);
105        def tempfile = new File(System.getProperty('java.io.tmpdir') + File.separatorChar + System.currentTimeMillis() + ".nmcdsp")
106        downloadedfile.transferTo(tempfile)
107
108        return ImporterService.getWorkbook(new FileInputStream(tempfile))
109    }
110
111    /**
[632]112     * @param entity entity class we are using (dbnp.studycapturing.Subject etc.)
113     */
114
115    def saveMissingProperties = {
116        println params.entity
117       
118        session.importer_importeddata.each { table ->
119            table.each { entity ->
120                entity.giveFields().each { field ->
121                    print ":" + params["entity_" + entity.hashCode() + "_" + field.escapedName()]
122                    entity.setFieldValue (field.toString(), params["entity_" + entity.hashCode() + "_" + field.escapedName()])
123                }               
124            }
125        }
126
[655]127        render(view:"step3", model:[datamatrix:session.importer_importeddata]) 
[632]128    }
129
130    /**
[256]131    * User has assigned all entities and templatefieldtypes to the columns and continues to the next step (assigning properties to columns)
[251]132    * All information of the columns is stored in a session as MappingColumn object
[215]133    *
[485]134    * @param entities list of entities and columns it has been assigned to (columnindex.entitytype)
[256]135    * @param templatefieldtype list of celltypes and columns it has been assigned to (columnindex:templatefieldtype format)
[215]136    * @return properties page
[251]137    *
138    * @see celltype: http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/Cell.html
[215]139    */
[632]140    def savePreview = {
[415]141        def tft = null 
[328]142        def identifiercolumnindex = (params.identifier!=null) ? params.identifier.toInteger() : -1
[485]143        def selectedentities = []
[215]144
[485]145        // loop all entities and see which column has been assigned which entitytype
146        // and build an array containing the selected entities
147        params.entity.index.each { columnindex, entityname ->
148            def _entity = [name:entityname,columnindex:columnindex.toInteger()]
149            selectedentities.add(_entity)
150        }
151
[415]152        params.templatefieldtype.index.each { columnindex, _templatefieldtype ->
153            switch (_templatefieldtype) {
[256]154                case "STRING"       : tft = TemplateFieldType.STRING
155                                      break
156                case "TEXT"         : tft = TemplateFieldType.TEXT
157                                      break
158                case "INTEGER"      : tft = TemplateFieldType.INTEGER
159                                      break
160                case "FLOAT"        : tft = TemplateFieldType.FLOAT
161                                      break
162                case "DOUBLE"       : tft = TemplateFieldType.DOUBLE
163                                      break
164                case "STRINGLIST"   : tft = TemplateFieldType.STRINGLIST
165                                      break
166                case "ONTOLOGYTERM" : tft = TemplateFieldType.ONTOLOGYTERM
167                                      break
168                case "DATE"         : tft = TemplateFieldType.DATE
169                                      break
[251]170                default: break
171            }
[415]172           
173            session.importer_header[columnindex.toInteger()].templatefieldtype = tft
[245]174        }
175
[485]176        params.entity.index.each { columnindex, entityname ->
[545]177            Class clazz = null
[251]178
[485]179            switch (entityname) {
[545]180                case "Study"    : clazz = dbnp.studycapturing.Study
[245]181                        break
[545]182                case "Subject"  : clazz = dbnp.studycapturing.Subject
[245]183                        break
[545]184                case "Event"    : clazz = dbnp.studycapturing.Event
[245]185                        break
[545]186                case "Protocol" : clazz = dbnp.studycapturing.Protocol
[245]187                        break
[545]188                case "Sample"   : clazz = dbnp.studycapturing.Sample
[245]189                        break
[251]190                default: clazz = Object
[256]191                        break
[245]192            }
[251]193
[415]194            session.importer_header[columnindex.toInteger()].identifier = (columnindex.toInteger() == identifiercolumnindex) ? true : false
195            session.importer_header[columnindex.toInteger()].index = columnindex.toInteger()
196            session.importer_header[columnindex.toInteger()].entity = clazz
[245]197        }
198
[215]199        // currently only one template is used for all entities
200        // TODO: show template fields per entity
201       
[328]202        def templates = Template.get(session.importer_template_id)
[215]203
[485]204        render(view:"step2", model:[entities:selectedentities, header:session.importer_header, templates:templates])
[215]205    }
[245]206
207    /**
[534]208    * @param columnproperty array of columns containing index and property (represented as a String)
[245]209    *
210    */
[632]211    def saveProperties = {
[245]212
[660]213        // Find actual Template object from the chosen template name
[661]214        def template = Template.get(session.importer_template_id)
[660]215
[534]216        params.columnproperty.index.each { columnindex, property ->
217
[660]218                // Create an actual class instance of the selected entity with the selected template
219                // This should be inside the closure because in some cases in the advanced importer, the fields can have different target entities
[534]220                def entityClass = Class.forName(session.importer_header[columnindex.toInteger()].entity.getName(), true, this.getClass().getClassLoader())
[632]221                def entityObj = entityClass.newInstance(template:template)
[660]222
223                // Store the selected property for this column into the column map for the ImporterService
[534]224                session.importer_header[columnindex.toInteger()].property = property
[660]225                // Look up the template field type of the target TemplateField and store it also in the map
[661]226                session.importer_header[columnindex.toInteger()].templatefieldtype = entityObj.getFieldType(property)
[660]227
228                //if it's an identifier set the mapping column true or false
[534]229                entityObj.giveFields().each {
230                    (it.preferredIdentifier && (it.name==property)) ? session.importer_header[columnindex.toInteger()].identifier = true : false
231                }
[251]232        }
[268]233
234        //import workbook
[328]235        session.importer_importeddata = ImporterService.importdata(session.importer_template_id, session.importer_workbook, 0, 1, session.importer_header)
[268]236
[632]237        if (params.layout=="horizontal")
238            render(view:"step3_simple", model:[datamatrix:session.importer_importeddata])
239        else if (params.layout=="vertical")
240            render(view:"step3", model:[datamatrix:session.importer_importeddata])
[245]241    }
[283]242
[632]243    def savePostview = {
[415]244        ImporterService.saveDatamatrix(session.importer_study, session.importer_importeddata)
[283]245        render(view:"step4")
246    }
[449]247
248    /**
249    * Return templates which belong to a certain entity type
250    *
251    * @param entity entity name string (Sample, Subject, Study et cetera)
252    * @return JSON object containing the found templates
253    */
254    def ajaxGetTemplatesByEntity = {
255        def entityClass = grailsApplication.config.gscf.domain.importableEntities.get(params.entity).entity
[632]256       
[449]257
258        // fetch all templates for a specific entity
[632]259        //def templates = Template.findAllByEntity(Class.forName(entityClass, true, this.getClass().getClassLoader()))
260        def templates = Template.list()
[449]261
[632]262        println templates.dump()
263
[449]264        // render as JSON
265        render templates as JSON
266    }
[215]267}
Note: See TracBrowser for help on using the repository browser.