root/trunk/grails-app/controllers/dbnp/studycapturing/StudyController.groovy @ 1213

Revision 1213, 13.9 KB (checked in by robert@…, 3 years ago)

Improved the study overview page such that the different tabs are loaded when needed. Also rewritten parts of the code. See ticket #155

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