source: trunk/grails-app/controllers/dbnp/studycapturing/StudyController.groovy @ 1440

Last change on this file since 1440 was 1440, checked in by robert@…, 10 years ago

Made the studytoken, assaytoken and sampletoken stable identifiers, as explained in #255.

  • Property svn:keywords set to Rev Author Date
File size: 12.0 KB
Line 
1package dbnp.studycapturing
2
3import grails.converters.*
4import grails.plugins.springsecurity.Secured
5import nl.grails.plugins.gdt.TemplateFieldType
6
7/**
8 * Controller class for studies
9 */
10class StudyController {
11    def AuthenticationService
12   
13    //static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
14
15    def index = {
16        redirect(action: "list", params: params)
17    }
18
19    /**
20     * Shows all studies where the user has access to
21     */
22    def list = {
23
24        def user = AuthenticationService.getLoggedInUser()
25        def max = Math.min(params.max ? params.int('max') : 10, 100)
26
27        def studies = Study.giveReadableStudies( user, max );
28
29        [studyInstanceList: studies, studyInstanceTotal: studies.count(), loggedInUser: user]
30    }
31
32    /**
33     * Shows studies for which the logged in user is the owner
34     */
35    @Secured(['IS_AUTHENTICATED_REMEMBERED'])
36    def myStudies = {
37        def user = AuthenticationService.getLoggedInUser()
38        def max = Math.min(params.max ? params.int('max') : 10, 100)
39
40        def studies = Study.findAllByOwner(user);
41        render( view: "list", model: [studyInstanceList: studies, studyInstanceTotal: studies.count(), loggedInUser: user] )
42    }
43
44    /**
45     * Shows a comparison of multiple studies using the show view
46     *
47     */
48    def list_extended = {
49                // If nothing has been selected, redirect the user
50                if( !params.id ) 
51                        redirect( action: 'list' )
52
53                // Check whether one id has been selected or multiple.
54                def ids = params.id
55                if( ids instanceof String )
56                        redirect( action: 'show', id: ids )
57
58                // Parse strings to a long
59                def long_ids = []
60                ids.each { long_ids.add( Long.parseLong( it ) ) }
61
62                println( long_ids )
63
64        def startTime = System.currentTimeMillis()
65                def c = Study.createCriteria()
66
67        def studyList = c {
68                        maxResults( Math.min(params.max ? params.int('max') : 10, 100) )
69                        'in'( "id", long_ids )
70                }
71        render(view:'show',model:[studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ) ] )
72    }
73
74    /**
75     * Shows one or more studies
76     */
77    def show = {
78        def startTime = System.currentTimeMillis()
79
80        def studyInstance = Study.get( params.long( "id" ) )
81        if (!studyInstance) {
82            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'study.label', default: 'Study'), params.id])}"
83            redirect(action: "list")
84        }
85        else {
86            // Check whether the user may see this study
87            def loggedInUser = AuthenticationService.getLoggedInUser()
88            if( !studyInstance.canRead(loggedInUser) ) {
89                flash.message = "You have no access to this study"
90                redirect(action: "list")
91            }
92
93            // The study instance is packed into an array, to be able to
94            // use the same view for showing the study and comparing multiple
95            // studies
96            [studyList: [ studyInstance ], multipleStudies: false, loggedInUser: loggedInUser, facebookLikeUrl: studyInstance.getFieldValue('published') ? "/study/show/${studyInstance?.id}" : '' ]
97        }
98    }
99
100        /**
101     * Shows the subjects tab of one or more studies. Is called when opening the subjects-tab
102         * on the study overview screen.
103     */
104    def show_subjects = {
105                def studyList = readStudies( params.id );
106
107                if( !studyList )
108                        return
109
110                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
111    }
112
113        /**
114     * Shows the events timeline tab of one or more studies. Is called when opening the events timeline-tab
115         * on the study overview screen.
116     */
117    def show_events_timeline = {
118                def studyList = readStudies( params.id );
119
120                if( !studyList )
121                        return
122
123                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
124    }
125
126        /**
127     * Shows the events table tab of one or more studies. Is called when opening the events table-tab
128         * on the study overview screen.
129     */
130    def show_events_table = {
131                def studyList = readStudies( params.id );
132
133                if( !studyList )
134                        return
135
136                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
137    }
138
139        /**
140     * Shows the assays tab of one or more studies. Is called when opening the assays tab
141         * on the study overview screen.
142     */
143    def show_assays = {
144                def studyList = readStudies( params.id );
145
146                if( !studyList )
147                        return
148
149                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
150    }
151
152        /**
153     * Shows the samples tab of one or more studies. Is called when opening the samples-tab
154         * on the study overview screen.
155     */
156    def show_samples = {
157                def studyList = readStudies( params.id );
158
159                if( !studyList )
160                        return
161
162                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
163    }
164
165        /**
166     * Shows the persons tab of one or more studies. Is called when opening the persons tab
167         * on the study overview screen.
168     */
169    def show_persons = {
170                def studyList = readStudies( params.id );
171
172                if( !studyList )
173                        return
174
175                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
176    }
177
178        /**
179     * Shows the publications tab of one or more studies. Is called when opening the publications tab
180         * on the study overview screen.
181     */
182    def show_publications = {
183                def studyList = readStudies( params.id );
184
185                if( !studyList )
186                        return
187
188                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ), loggedInUser: AuthenticationService.getLoggedInUser() ]
189    }
190
191        /**
192         * Creates the javascript for showing the timeline of one or more studies
193         */
194        def createTimelineBandsJs = {
195                def studyList = readStudies( params.id );
196
197                if( !studyList )
198                        return
199
200                [studyList: studyList, studyInstanceTotal: Study.count(), multipleStudies: ( studyList.size() > 1 ) ]
201        }
202
203    /**
204         * Reads one or more studies from the database and checks whether the logged
205         * in user is allowed to access them.
206         *
207         * Is used by several show_-methods
208         *
209         * @return List with Study objects or false if an error occurred.
210         */
211        private def readStudies( id ) {
212                // If nothing has been selected, redirect the user
213                if( !id || !( id instanceof String)) {
214            response.status = 500;
215            render 'No study selected';
216            return false
217                }
218
219                // Check whether one id has been selected or multiple.
220                def ids = URLDecoder.decode( id ).split( "," );
221
222                // Parse strings to a long
223                def long_ids = []
224                ids.each { long_ids.add( Long.parseLong( it ) ) }
225
226                def c = Study.createCriteria()
227
228        def studyList = c {
229                        maxResults( Math.min(params.max ? params.int('max') : 10, 100) )
230                        'in'( "id", long_ids )
231                }
232
233                // Check whether the user may see these studies
234                def studiesAllowed = []
235        def loggedInUser = AuthenticationService.getLoggedInUser()
236
237                studyList.each { studyInstance ->
238            if( studyInstance.canRead(loggedInUser) ) {
239                                studiesAllowed << studyInstance
240            }
241                }
242
243                // If the user is not allowed to see any of the studies, return 404
244                if( studiesAllowed.size() == 0 ) {
245            response.status = 404;
246            render 'Selected studies not found';
247            return false
248                }
249               
250                return studyList
251        }
252
253    def showByToken = {
254        def studyInstance = Study.findByStudyUUID(params.id)
255        if (!studyInstance) {
256            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'study.label', default: 'Study'), params.id])}"
257            redirect(action: "list")
258        }
259        else {
260            // Check whether the user may see this study
261            def loggedInUser = AuthenticationService.getLoggedInUser()
262            if( !studyInstance.canRead(loggedInUser) ) {
263                flash.message = "You have no access to this study"
264                redirect(action: "list")
265            }
266
267            redirect(action: "show", id: studyInstance.id)
268        }
269    }
270
271    /**
272     * Gives the events for one eventgroup in JSON format
273     *
274     */
275    def events = {
276        def eventGroupId = Integer.parseInt( params.id );
277        def studyId      = Integer.parseInt( params.study );
278        def eventGroup;
279
280        // eventGroupId == -1 means that the orphaned events should be given
281        if( eventGroupId == -1 ) {
282            def studyInstance = Study.get( studyId )
283           
284            if (studyInstance == null) {
285                flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'study.label', default: 'Study'), studyId])}"
286                redirect(action: "list");
287                return;
288            }
289
290            events = studyInstance.getOrphanEvents();
291        } else {
292            eventGroup = EventGroup.get(params.id)
293
294            if (eventGroup == null) {
295                flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'eventgroup.label', default: 'Eventgroup'), params.id])}"
296                redirect(action: "list");
297                return;
298            }
299            events = eventGroup?.events + eventGroup?.samplingEvents;
300        }
301
302        // This parameter should give the startdate of the study in milliseconds
303        // since 1-1-1970
304        long startDate  = Long.parseLong( params.startDate )
305
306        // Create JSON object
307        def json = [ 'dateTimeFormat': 'iso8601', events: [] ];
308
309        // Add all other events
310        for( event in events ) {
311            def parameters = []
312            for( templateField in event.giveTemplateFields() ) {
313                def value = event.getFieldValue( templateField.name );
314                                if( value ) {
315                                        if( templateField.type == TemplateFieldType.RELTIME )
316                                                value = new nl.grails.plugins.gdt.RelTime( value ).toString();
317
318                        def param = templateField.name + " = " + value;
319
320                                        if( templateField.unit )
321                                                param += templateField.unit;
322
323                    parameters << param ;
324                }
325            }
326
327                        def description = parameters.join( '<br />\n' );
328
329                        if( event instanceof SamplingEvent ) {
330                                 json.events << [
331                                        'start':    new Date( startDate + event.startTime * 1000 ),
332                                        'end':      new Date( startDate + event.startTime * 1000 ),
333                                        'durationEvent': false,
334                                        'title': event.template.name,
335                                        'description': description
336                                ]
337                        } else {
338                                 json.events << [
339                                        'start':    new Date( startDate + event.startTime * 1000 ),
340                                        'end':      new Date( startDate + event.endTime * 1000 ),
341                                        'durationEvent': true,
342                                        'title': event.template.name,
343                                        'description': description
344                                ]
345                               
346                        }
347        }
348        render json as JSON
349    }
350
351    def delete = {
352        def studyInstance = Study.get(params.id)
353        if (studyInstance) {
354            try {
355                studyInstance.delete(flush: true)
356                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'study.label', default: 'Study'), params.id])}"
357                redirect(action: "list")
358            }
359            catch (org.springframework.dao.DataIntegrityViolationException e) {
360                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'study.label', default: 'Study'), params.id])}"
361                redirect(action: "show", id: params.id)
362            }
363        }
364        else {
365            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'study.label', default: 'Study'), params.id])}"
366            redirect(action: "list")
367        }
368    }
369
370    /**
371     * Renders assay names and id's as JSON
372     */
373    def ajaxGetAssays = {
374
375        def study = Study.read(params.id)
376        render study?.assays?.collect{[name: it.name, id: it.id]} as JSON
377    }
378
379
380}
Note: See TracBrowser for help on using the repository browser.