Changeset 1560


Ignore:
Timestamp:
Feb 24, 2011, 11:59:08 PM (13 years ago)
Author:
j.saito@…
Message:

Added import methods for XML import of studies.

Still not workig (and therefore omitted):

Still missing:

  • Error handling for clashes and omissions in importing
  • Removing unneccessary output of static fields in exporter
  • exporting templates (connect to Template exporter)
  • Move in Modules for Assay import
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/services/dbnp/studyexport/ExportService.groovy

    r1545 r1560  
    1414import dbnp.studycapturing.*
    1515import grails.converters.XML
     16import groovy.util.*
     17import groovy.util.slurpersupport.*
     18import groovy.util.slurpersupport.Node as Node
     19import java.util.ArrayList
    1620import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationHolder
     21import org.dbnp.bgdt.*
    1722import org.dbnp.gdt.*
     23import org.exolab.castor.xml.Unmarshaller
    1824
    1925
     
    3844     *  List of classes that recursion does not go further into when building an XML 
    3945     *  document; the elements are still included.
     46         * 
     47         *  (For importing Study objects)
    4048         * 
    4149         *  @see #getRelatedObjects().
     
    4654
    4755
     56    /**
     57     *  List of domain classes related to Study.
     58     */
     59        def static DomainClasses = [ 'RegistrationCode':dbnp.authentication.RegistrationCode,
     60                        'SecRole':dbnp.authentication.SecRole, 'SecUser':dbnp.authentication.SecUser,
     61                        'SecUserSecRole':dbnp.authentication.SecUserSecRole,
     62                        'SessionAuthenticatedUser':dbnp.authentication.SessionAuthenticatedUser,
     63                        'Assay':dbnp.studycapturing.Assay,
     64                        'Book':dbnp.studycapturing.Book,
     65                        'Event':dbnp.studycapturing.Event, 'EventGroup':dbnp.studycapturing.EventGroup,
     66                        'PersonAffiliation':dbnp.studycapturing.PersonAffiliation,
     67                        'Person':dbnp.studycapturing.Person,
     68                        'PersonRole':dbnp.studycapturing.PersonRole,
     69                        'Publication':dbnp.studycapturing.Publication,
     70                        'Sample':dbnp.studycapturing.Sample,
     71                        'SamplingEvent':dbnp.studycapturing.SamplingEvent,
     72                        'Study':dbnp.studycapturing.Study,
     73                        'StudyPerson':dbnp.studycapturing.StudyPerson,
     74                        'Subject':dbnp.studycapturing.Subject,
     75                        'AssayModule':org.dbnp.gdt.AssayModule,
     76                        'Identity':org.dbnp.gdt.Identity,
     77                        'RelTime':org.dbnp.gdt.RelTime,
     78                        'TemplateEntity':org.dbnp.gdt.TemplateEntity,
     79                        'TemplateField':org.dbnp.gdt.TemplateField,
     80                        'TemplateFieldListItem':org.dbnp.gdt.TemplateFieldListItem,
     81                        'TemplateFieldType':org.dbnp.gdt.TemplateFieldType,
     82                        'Template':org.dbnp.gdt.Template ]
     83
     84
    4885        /**
    4986         *  Returns a list of all Grails domain objects relevant for creating a full
     
    98135                if( domainClass.toString()==~/class dbnp.authentication.SecUser.+/ ||
    99136                    domainClass.toString()==~/class dbnp.studycapturing.Publication.+/ ) {
    100                         println "${domainClass} -- ${domainObject}"
    101137                        return objects
    102138                }
     
    111147
    112148                                                                                                // enter recursion with regular domain fields
    113                 domainObject.getProperties().domainFields.each { field ->
     149                domainObject.properties.domainFields.each { field ->
    114150                        objects.addAll( getRelatedObjects(field) )
    115151                }
     
    131167
    132168
    133         /**
    134          *  Returns Study object from List of objects created by
    135          *  XML representation of a Study.
    136          * 
    137          *  @param List of objects
    138          *
    139          *  @return Study object that has to be saved
    140          *
    141          *  @see getDependentObjects()
    142          */
    143 
    144         def     getStudy( Collection objectList ) {
    145         }
    146 
    147169
    148170
     
    158180         */
    159181
    160         def     parseXMLStudy( XML xml ) {
     182        def     parseXMLStudy() {
     183                XML.parse(new FileInputStream('/tmp/test.xml'), "UTF-8")
     184        }
     185
     186
     187
     188        def     parseXMLStudyList( GPathResult result ) {
     189                def parseObjects =
     190                        result.childNodes().collect {
     191                                new ParseObject(it)
     192                        }               
     193                def study = createStudy( parseObjects )
     194                study.save()   
     195        }
     196
     197
     198
     199
     200        /**
     201         *  Create Study from list of objects repesenting a Study.
     202         * 
     203         *  (For importing Study objects)
     204         * 
     205         *  @param  List of objects representing a Study.
     206         *
     207         *  @return void
     208         */
     209
     210        def createStudy( List parseObjects ) {
     211                parseObjects.each{
     212                        populateFields( it.domainObject, it.node, parseObjects )
     213                }
     214                parseObjects.each{
     215                        populateOneToManies( it.domainObject, it.node, parseObjects )
     216                }
     217                parseObjects.each{
     218                        populateTemplateFields( it.domainObject, it.node, parseObjects )
     219                }
     220        }
     221
     222
     223
     224        /**
     225         *  Populate fields of a domainObject to be created.
     226         *  The fields of a new object are filled with simple Class objects.
     227         * 
     228         *  (For importing Study objects)
     229         * 
     230         *  @param domainObject   The Object to be fielled 
     231         * 
     232         *  @param  List of ParseObjects representing a Study.
     233         *
     234         *  @return the new domainObject
     235         */
     236
     237        def populateFields( domainObject, node, List parseObjects ) {
     238
     239                def fields =
     240                        domainObject.getProperties().domainFields.collect { it.toString() }
     241
     242                def map = [:]
     243                domainObject.metaClass.getProperties().each { property ->
     244                        def name = property.name
     245                        def field = fields.find{ it == name }
     246
     247                        if(field) {
     248                                def type = property.type
     249                                def value = node.children().find{ it.name == field }.text()
     250
     251                                switch(type) {
     252                                        case String: map[field]=value; break
     253                                        case Date: map[field] = Date.parse( 'yyyy-MM-dd', value ); break
     254                                }
     255                        }
     256                }
     257
     258                def newDomainObject = domainObject.class.newInstance(map)
     259                newDomainObject.id = 0
     260                domainObject = newDomainObject
     261        }
     262
     263
     264
     265        /**
     266         *  Populate one-to-many maps of a new domainObject 
     267         *  from list of ParseObjects.
     268         * 
     269         *  (For importing Study objects)
     270         * 
     271         *  @param domainObject   domainObject to be fielled 
     272         * 
     273         *  @param  List of parseObjects representing a Study.
     274         *
     275         *  @return the new domainObject
     276         */
     277       
     278        def populateOneToManies( domainObject, node, parseObjects ) {
     279                if( !domainObject.class.metaClass.getProperties().find{ it.name=='hasMany' } ) {
     280                        return
     281                }
     282
     283                domainObject.class.hasMany.each{ name, theClass ->
     284                        node.children().each { child ->
     285                                if(child.name==name) {
     286                                        child.children().each { grandChild ->
     287                                                def id = grandChild.attributes.id
     288                                                if(id) {
     289                                                        def ref = parseObjects.find{ it.theClass==theClass && it.id==id }
     290                                                        if(ref) {
     291                                                                def addTo = "addTo" + name.replaceFirst(name[0],name[0].toUpperCase())
     292                                                                domainObject.invokeMethod(addTo,(Object) ref.domainObject )
     293                                                        }
     294                                                }
     295                                        }
     296                                }
     297                        }
     298                }
     299        }
     300
     301
     302        def populateTemplateFields( domainObject, Node node, List parseObjects ) {
     303        }
     304
     305
     306
     307        /**
     308         *  Populate one-to-many maps of a new domainObject 
     309         *  from list of ParseObjects.
     310         *
     311         *  (For importing Study objects)
     312         *
     313         *  @param domainObject   domainObject to be fielled 
     314         * 
     315         *  @param  List of parseObjects representing a Study.
     316         *
     317         *  @return the new domainObject
     318         */
     319
     320        private class ParseObject {
     321                String tag
     322                String id
     323                Class theClass
     324                Object domainObject
     325                groovy.util.slurpersupport.Node node
     326       
     327
     328                public ParseObject( node ){
     329                        tag = node.name()
     330                        theClass = getClassForTag( tag )
     331                        domainObject = theClass.newInstance()
     332                        id = null
     333                        if(node.attributes && node.attributes.id) {
     334                                id = node.attributes.id
     335                        }
     336                        this.node=node
     337                }
     338
     339                private static getClassForTag( String tag ) {
     340                        def shortName = tag.replaceFirst( tag[0], tag[0].toUpperCase() )
     341                        return DomainClasses[ shortName ]
     342                }
     343
    161344        }
    162345
Note: See TracChangeset for help on using the changeset viewer.