source: trunk/grails-app/services/dbnp/studyXML/StudyXMLService.groovy @ 1695

Last change on this file since 1695 was 1695, checked in by j.saito@…, 9 years ago

This is the new structure for importing / exporting studies from / to XML.
Currently, much functionality is in the Controller. This should all move back to the Service (studyXMLService).
However, as long as the code is in the controller, interactive debugging is much faster as modifying services often seems to require re-running the whole app.

File size: 4.9 KB
Line 
1/**
2 *  This service is for exporting studies to a XML flat list and for
3 *  importing them back.
4 * 
5 *  @author Jahn
6 * 
7 *  The file is used in combination with a controller.
8 */ 
9
10
11package dbnp.studyXML
12
13import dbnp.authentication.*
14import dbnp.studycapturing.*
15import grails.converters.XML
16import groovy.util.slurpersupport.*
17import org.dbnp.bgdt.*
18import org.dbnp.gdt.*
19
20class StudyXMLService 
21{
22
23    static transactional = true
24    static scope = "session"
25
26
27    def grailsApplication
28    /**
29     *  List of classes that recursion does not go further into when building an XML 
30     *  document.
31         * 
32         *  @see #getRelatedObjects().
33     */ 
34        def static IgnoredClasses = [ String, long, Date, Boolean, SecUser, Publication, SecUser ]
35
36
37    /**
38     *  List of classes that recursion does not go further into when building an XML 
39     *  document; the elements are still included.
40         * 
41         *  (For importing Study objects)
42         * 
43         *  @see #getRelatedObjects().
44     */ 
45        def static TerminalClasses = [ AssayModule, Identity, Ontology, PersonAffiliation, 
46                        PersonRole, Template, TemplateField, 
47                        TemplateFieldListItem, TemplateFieldType, Term ] 
48
49
50    /**
51     *  List of domain classes related to Study.
52     */ 
53        def static DomainClasses = [ 
54                        'Assay':dbnp.studycapturing.Assay,
55                        'AssayModule':org.dbnp.gdt.AssayModule,
56                        'Event':dbnp.studycapturing.Event, 'EventGroup':dbnp.studycapturing.EventGroup,
57                        'Identity':org.dbnp.gdt.Identity,
58                        'PersonAffiliation':dbnp.studycapturing.PersonAffiliation,
59                        'Person':dbnp.studycapturing.Person,
60                        'PersonRole':dbnp.studycapturing.PersonRole,
61                        'Publication':dbnp.studycapturing.Publication,
62                        'RegistrationCode':dbnp.authentication.RegistrationCode,
63                        'RelTime':org.dbnp.gdt.RelTime,
64                        'Sample':dbnp.studycapturing.Sample,
65                        'SamplingEvent':dbnp.studycapturing.SamplingEvent,
66                        'SecRole':dbnp.authentication.SecRole, 'SecUser':dbnp.authentication.SecUser,
67                        'SecUserSecRole':dbnp.authentication.SecUserSecRole,
68                        'SessionAuthenticatedUser':dbnp.authentication.SessionAuthenticatedUser,
69                        'Study':dbnp.studycapturing.Study,
70                        'StudyPerson':dbnp.studycapturing.StudyPerson,
71                        'Subject':dbnp.studycapturing.Subject,
72                        'TemplateEntity':org.dbnp.gdt.TemplateEntity,
73                        'TemplateFieldListItem':org.dbnp.gdt.TemplateFieldListItem,
74                        'TemplateField':org.dbnp.gdt.TemplateField,
75                        'TemplateFieldType':org.dbnp.gdt.TemplateFieldType,
76                        'Template':org.dbnp.gdt.Template ]
77
78
79
80        /**
81         *  Returns a list of all Grails domain objects relevant for creating a full
82         *  XML representation of a Study.
83         * 
84         *  The actual XML is then created by the controller using Grails' XML converter.
85         * 
86         *  @param Study
87         *
88         *  @return List of all Grails domain objects
89         */ 
90
91        def getDependentObjects( Study study ) {
92                return getRelatedObjects( study )
93        }
94
95
96        /**
97         *  Returns a list of Grails domain objects. 
98         * 
99         *  Helper method for getDependentObjects().
100         * 
101         *  This method produces a list of all objects that need to be
102         *  written out in order to get an XML representation of a Study object.
103         * 
104         *  This is achieved by recursion. The recursion stops at objects whose
105         *  class is member of IgnoredClasses or TerminalClasses.
106         * 
107         *      Example call:
108         * 
109         *              def objects = getDependentObjects( Study.get(1) )
110         *              (objects*.class).unique().sort().each { println it }
111         * 
112         *  @param domainObject  A grails domain object.
113         * 
114         *  @return List of all Grails domain objects
115         */ 
116
117        def     getRelatedObjects( domainObject ) {
118
119                if(domainObject==null) {
120                        return []
121                }
122
123                def domainClass = domainObject.class
124                def objects = []
125
126
127                if( IgnoredClasses.contains(domainClass) )   {
128                        return objects
129                }
130
131                if( domainClass.toString()==~/class dbnp.authentication.SecUser.+/ || 
132                    domainClass.toString()==~/class dbnp.studycapturing.Publication.+/ ) {
133                        return objects
134                }
135
136
137                if(domainObject instanceof TemplateEntity ) {
138                        objects.push(domainObject.template)
139                        domainObject.template.fields.each { 
140                                        objects.push(it) 
141                                        if(domainClass==Assay)
142                                                println "${domainObject.class} ${it}"
143                        }
144
145                        if(domainClass==Assay) {
146                                domainObject.domainFields.each { 
147                                        def memberClass = domainObject."$it".class
148                                        println "${it.class} ${it}. member class: ${memberClass}"
149                                }
150                        }
151
152                }
153
154
155                if( TerminalClasses.contains(domainClass) )  {
156                        objects.push(domainObject)
157                        return objects
158                }
159
160                objects.push(domainObject)
161
162                                                                                                // enter recursion with regular domain fields
163                domainObject.properties.domainFields.each { field ->
164                        objects.addAll( getRelatedObjects(field) )
165                }
166
167                                                                                                // enter recursion with hasMany fields
168                domainObject.getProperties().hasMany.each { property, theClass ->
169
170                        boolean isTemplateField = ( domainObject instanceof TemplateEntity  && 
171                                property==~/template(.+)Fields/ ) 
172                        if( !isTemplateField ) {
173                                domainObject."$property".each { 
174                                                objects.addAll( getRelatedObjects(it) )
175                                }
176                        }
177
178                }
179                return objects.unique()
180        }
181
182
183}
Note: See TracBrowser for help on using the repository browser.