source: trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy @ 396

Last change on this file since 396 was 396, checked in by duh, 8 years ago
  • fixed incomplete implementation of domain fields (getters, setters and constrains logic were all not implemented correctly)
  • refactored wizards pages
  • TODO: constraints on (templated) domain fields are not working anymore, this needs to be implemented properly in TemplateEntity?
  • Property svn:keywords set to Date Author Rev
File size: 21.9 KB
Line 
1package dbnp.studycapturing
2
3import dbnp.data.*
4
5/**
6 * Wizard Controler
7 *
8 * The wizard controller handles the handeling of pages and data flow
9 * through the study capturing wizard.
10 *
11 * TODO: refactor the 'handle*' methods to work as subflows instead
12 *               of methods outside of the flow
13 *
14 * @author Jeroen Wesbeek
15 * @since 20100107
16 * @package studycapturing
17 *
18 * Revision information:
19 * $Rev: 396 $
20 * $Author: duh $
21 * $Date: 2010-05-07 12:24:27 +0000 (vr, 07 mei 2010) $
22 */
23class WizardController {
24        /**
25         * index method, redirect to the webflow
26         * @void
27         */
28        def index = {
29                /**
30                 * Do you believe it in your head?
31                 * I can go with the flow
32                 * Don't say it doesn't matter (with the flow) matter anymore
33                 * I can go with the flow (I can go)
34                 * Do you believe it in your head?
35                 */
36                redirect(action: 'pages')
37        }
38
39        /**
40         * WebFlow definition
41         * @see http://grails.org/WebFlow
42         * @void
43         */
44        def pagesFlow = {
45                // start the flow
46                onStart {
47                        // define flow variables
48                        flow.page = 0
49                        flow.pages = [
50                                //[title: 'Templates'],                 // templates
51                                [title: 'Start'],                               // load or create a study
52                                [title: 'Study'],                               // study
53                                [title: 'Subjects'],                    // subjects
54                                [title: 'Events'],                              // events and event grouping
55                                [title: 'Confirmation'],                // confirmation page
56                                [title: 'Done']                                 // finish page
57                        ]
58                }
59
60                // render the main wizard page which immediately
61                // triggers the 'next' action (hence, the main
62                // page dynamically renders the study template
63                // and makes the flow jump to the study logic)
64                mainPage {
65                        render(view: "/wizard/index")
66                        onRender {
67                                flow.page = 1
68                        }
69                        on("next").to "start"
70                }
71
72                // create or modify a study
73                start {
74                        render(view: "_start")
75                        onRender {
76                                flow.page = 1
77                        }
78                        on("next").to "study"
79                        on("modify").to "modify"
80                }
81
82                // load a study to modify
83                modify {
84                        render(view: "_modify")
85                        onRender {
86                                flow.page = 1
87                                flash.cancel = true
88                        }
89                        on("cancel") {
90                                flow.study = null
91                        }.to "start"
92                        on("next") {
93                                // TODO: loading a study is not yet implemented
94                                //       create a error stating this feature is
95                                //       not yet implemented
96                                flash.errors = [:]
97                                this.appendErrorMap(
98                                        ['study': 'Loading a study and modifying it has not yet been implemented. Please press \'cancel\' to go back to the initial page...'],
99                                        flash.errors
100                                )
101                        }.to "modify"
102                }
103
104                // render and handle the study page
105                // TODO: make sure both template as well as logic will
106                //       handle Study templates as well!!!
107                study {
108                        render(view: "_study")
109                        onRender {
110                                flow.page = 2
111                        }
112                        on("refresh") {
113                                flash.values = params
114
115                                // handle study data
116                                this.handleStudy(flow, flash, params)
117
118                                // remove errors as we don't want any warnings now
119                                flash.errors = [:]                             
120                        }.to "study"
121                        on("switchTemplate") {
122                                flash.values = params
123
124                                // handle study data
125                                this.handleStudy(flow, flash, params)
126
127                                // remove errors as we don't want any warnings now
128                                flash.errors = [:]
129                        }.to "study"
130                        on("previous") {
131                                flash.errors = [:]
132
133                                // handle the study
134                                this.handleStudy(flow, flash, params)
135
136                                // reset errors
137                                flash.errors = [:]
138
139                                success()
140                        }.to "start"
141                        on("next") {
142                                flash.errors = [:]
143
144                                if (this.handleStudy(flow, flash, params)) {
145                                        success()
146                                } else {
147                                        error()
148                                }
149                        }.to "subjects"
150                }
151
152                // render and handle subjects page
153                subjects {
154                        render(view: "_subjects")
155                        onRender {
156                                flow.page = 3
157
158                                if (!flow.subjects) {
159                                        flow.subjects = []
160                                        flow.subjectTemplates = [:]
161                                }
162                        }
163                        on("refresh") {
164                                flash.values = params
165                        }.to "subjects"
166                        on("add") {
167                                flash.values = params
168                                def speciesTerm = Term.findByName(params.species);
169                                def subjectTemplateName = params.get('template');
170                                def subjectTemplate = Template.findByName(subjectTemplateName);
171
172                                // add this subject template to the subject template array
173                                if (!flow.subjectTemplates[ subjectTemplateName ]) {
174                                        flow.subjectTemplates[ subjectTemplateName ] = [
175                                                name: subjectTemplateName,
176                                                template: subjectTemplate,
177                                                subjects: []
178                                        ]
179                                }
180
181                                // add x subjects of species y
182                                (params.addNumber as int).times {
183                                        def increment = flow.subjects.size()
184                                        def subject = new Subject(
185                                                name: 'Subject ' + (increment + 1),
186                                                species: speciesTerm,
187                                                template: subjectTemplate
188                                        )
189
190                                        // instantiate a new Subject
191                                        flow.subjects[ increment ] = subject
192
193                                        // and remember the subject id with the template
194                                        def subjectsSize = flow.subjectTemplates[ subjectTemplateName ]['subjects'].size()
195                                        flow.subjectTemplates[ subjectTemplateName ]['subjects'][ subjectsSize ] = increment
196                                }
197                        }.to "subjects"
198                        on("next") {
199                                flash.errors = [:]
200
201                                // check if we have at least one subject
202                                // and check form data
203                                if (flow.subjects.size() < 1) {
204                                        // append error map
205                                        this.appendErrorMap(['subjects': 'You need at least to create one subject for your study'], flash.errors)
206                                        error()
207                                } else if (!this.handleSubjects(flow, flash, params)) {
208                                        error()
209                                } else {
210                                        success()
211                                }
212                        }.to "events"
213                        on("delete") {
214                                flash.errors = [:]
215                                def delete = params.get('do') as int;
216
217                                // remove subject
218                                if (flow.subjects[ delete ] && flow.subjects[ delete ] instanceof Subject) {
219                                        flow.subjectTemplates.each() { templateName, templateData ->
220                                                templateData.subjects.remove(delete)
221                                        }
222
223                                        flow.subjects.remove( delete )
224                                }
225                        }.to "subjects"
226                        on("previous") {
227                                flash.errors = [:]
228
229                                // handle form data
230                                if (!this.handleSubjects(flow, flash, params)) {
231                                        error()
232                                } else {
233                                        success()
234                                }
235                        }.to "study"
236                }
237
238                // render events page
239                events {
240                        render(view: "_events")
241                        onRender {
242                                flow.page = 4
243
244                                /*
245                                if (!flow.event) flow.event = new Event()
246                                if (!flow.events) flow.events = []
247                                if (!flow.eventGroups) {
248                                        flow.eventGroups = []
249                                        flow.eventGroups[0] = new EventGroup(name: 'Group 1')   // 1 group by default
250                                }
251                                */
252
253                                if (!flow.event) {
254                                        flow.event                      = new Event()
255                                        flow.events                     = []
256                                        flow.eventGroups        = []
257                                        flow.eventGroups[0]     = new EventGroup(name: 'Group 1')       // 1 group by default
258                                        flow.eventTemplates     = [:]
259                                }
260                        }
261                        on("switchTemplate") {
262                                flash.values = params
263
264                                // handle study data
265                                this.handleEvents(flow, flash, params)
266
267                                // remove errors as we don't want any warnings now
268                                flash.errors = [:]
269                        }.to "events"
270                        on("add") {
271                                /*
272                                def startTime   = (params.get('startTime')) ? params.startTime = new Date().parse("d/M/yyyy HH:mm", params.get('startTime').toString()) : null
273                                def endTime             = (params.get('endTime')) ? new Date().parse("d/M/yyyy HH:mm", params.get('endTime').toString()) : null
274                                def template    = params.get('template')
275
276                                // handle template
277                                if (template instanceof String && template.size() > 0) {
278                                        template = Template.findByName(template)
279                                } else if (!template instanceof Template) {
280                                        template = null
281                                }
282
283                                // handle data
284                                if (template && startTime && endTime) {
285                                        // add an event instance
286                                        def event = new Event(
287                                                template        : template,
288                                                startTime       : startTime,
289                                                endTime         : endTime
290                                        )
291
292                                        // validate event
293                                        if (event.validate()) {
294                                                // add event to event list
295                                                flow.events[ flow.events.size() ] = event
296                                                success()
297                                        } else {
298                                                // validation failed, feedback errors
299                                                flash.errors = [:]
300                                                flash.values = params
301                                                this.appendErrors(event, flash.errors)
302                                                error()
303                                        }
304                                } else {
305                                        // validation failed, feedback errors
306                                        flash.errors    = [:]
307                                        flash.values    = params
308
309                                        if (!template)  this.appendErrorMap(['template': 'You need to select an event template'], flash.errors)
310                                        if (!startTime) this.appendErrorMap(['startTime': 'You need to define the start time of your study event'], flash.errors)
311                                        if (!endTime)   this.appendErrorMap(['endTime': 'You need to define the end time of your study event'], flash.errors)
312                                        error()
313                                }
314                                */
315                                flash.values                    = params
316                                def eventTemplateName   = params.get('template')
317                                def eventTemplate               = Template.findByName(eventTemplateName)
318
319                                // add this event template to the event template array
320                                if (!flow.eventTemplates[ eventTemplateName ]) {
321                                        flow.eventTemplates[ eventTemplateName ] = [
322                                                name: eventTemplateName,
323                                                template: eventTemplate,
324                                                events: []
325                                        ]
326                                }
327
328                                // handle study data
329                                this.handleEvents(flow, flash, params)
330
331                                // validate event object
332                                if (flow.event.validate()) {
333
334flow.event.template.fields.each() {
335        println "["+it.name+"] = "+flow.event.getFieldValue(it.name)   
336}
337                                        // it validated! Duplicate the event object...
338                                        def newEvent    = flow.event
339                                        def increment   = flow.events.size()
340
341                                        // ...store it in the events map in the flow scope...
342                                        flow.events[ increment ] = newEvent
343
344                                        // ...and 'reset' the event object in the flow scope
345                                        flow.event = new Event(template: newEvent.template)
346                                       
347                                        // remember the event id with the template
348                                        def eventSize = flow.eventTemplates[ eventTemplateName ]['events'].size()
349                                        flow.eventTemplates[ eventTemplateName ]['events'][ eventSize ] = increment
350
351                                        success()
352                                } else {
353                                        // it does not validate, show error feedback
354                                        flash.errors = [:]
355                                        this.appendErrors(flow.event, flash.errors)
356                                        error()
357                                }
358                        }.to "events"
359                        on("deleteEvent") {
360                                flash.values = params
361                                def delete = params.get('do') as int;
362
363                                // handle event groupings
364                                this.handleEventGrouping(flow, flash, params)
365
366                                // remove event
367                                if (flow.events[ delete ] && flow.events[ delete ] instanceof Event) {
368                                        flow.events.remove(delete)
369                                }
370                        }.to "events"
371                        on("addEventGroup") {
372                                flash.values = params
373                               
374                                // handle event groupings
375                                this.handleEventGrouping(flow, flash, params)
376
377                                def increment = flow.eventGroups.size()
378                                def groupName = "Group " + (increment + 1)
379
380                                // check if group name exists
381                                def nameExists = true
382                                def u = 0
383
384                                // make sure a unique name is generated
385                                while (nameExists) {
386                                        u++
387                                        def count = 0
388                                       
389                                        flow.eventGroups.each() {
390                                                if (it.name == groupName) {
391                                                        groupName = "Group " + (increment + 1) + "," + u
392                                                } else {
393                                                        count++
394                                                }
395                                        }
396
397                                        nameExists = !(count == flow.eventGroups.size())
398                                }
399
400                                flow.eventGroups[increment] = new EventGroup(name: groupName)
401                        }.to "events"
402                        on("deleteEventGroup") {
403                                flash.values = params
404                               
405                                def delete = params.get('do') as int;
406
407                                // handle event groupings
408                                this.handleEventGrouping(flow, flash, params)
409
410                                // remove the group with this specific id
411                                if (flow.eventGroups[delete] && flow.eventGroups[delete] instanceof EventGroup) {
412                                        // remove this eventGroup
413                                        flow.eventGroups.remove(delete)
414                                }
415                        }.to "events"
416                        on("previous") {
417                                // handle event groupings
418                                this.handleEventGrouping(flow, flash, params)
419                        }.to "subjects"
420                        on("next") {
421                                flash.values = params
422                                flash.errors = [:]
423                                /*
424
425                                // handle event groupings
426                                this.handleEventGrouping(flow, flash, params)
427
428                                // check if we have at least one subject
429                                // and check form data
430                                if (flow.events.size() < 1) {
431                                        // append error map
432                                        flash.values = params
433                                        this.appendErrorMap(['events': 'You need at least to create one event for your study'], flash.errors)
434                                        error()
435                                }
436                                */
437                        }.to "events"
438                }
439
440                confirm {
441                        render(view: "_confirmation")
442                        onRender {
443                                flow.page = 5
444                        }
445                        on("toStudy").to "study"
446                        on("toSubjects").to "subjects"
447                        on("toEvents").to "events"
448                        on("previous").to "events"
449                        on("next").to "save"
450                }
451
452                // store all study data
453                save {
454                        action {
455                                println "saving..."
456                                flash.errors = [:]
457
458                                // start transaction
459                                def transaction = sessionFactory.getCurrentSession().beginTransaction()
460
461                                // persist data to the database
462                                try {
463                                        // save EventDescriptions
464                                        flow.eventDescriptions.each() {
465                                                if (!it.save(flush:true)) {
466                                                        this.appendErrors(it, flash.errors)
467                                                        throw new Exception('error saving eventDescription')
468                                                }
469                                                println "saved eventdescription "+it
470                                        }
471
472                                        // TODO: eventDescriptions that are not linked to an event are currently
473                                        //               stored but end up in a black hole. We should either decide to
474                                        //               NOT store these eventDescriptions, or add "hasmany eventDescriptions"
475                                        //               to Study domain class
476
477                                        // save events
478                                        flow.events.each() {
479                                                if (!it.save(flush:true)) {
480                                                        this.appendErrors(it, flash.errors)
481                                                        throw new Exception('error saving event')
482                                                }
483                                                println "saved event "+it
484
485                                                // add to study
486                                                if (it instanceof SamplingEvent) {
487                                                        flow.study.addToSamplingEvents(it)
488                                                } else {
489                                                        flow.study.addToEvents(it)
490                                                }
491                                        }
492
493                                        // save eventGroups
494                                        flow.eventGroups.each() {
495                                                if (!it.save(flush:true)) {
496                                                        this.appendErrors(it, flash.errors)
497                                                        throw new Exception('error saving eventGroup')
498                                                }
499                                                println "saved eventGroup "+it
500
501                                                // add to study
502                                                flow.study.addToEventGroups(it)
503                                        }
504                                       
505                                        // save subjects
506                                        flow.subjects.each() {
507                                                if (!it.save(flush:true)) {
508                                                        this.appendErrors(it, flash.errors)
509                                                        throw new Exception('error saving subject')
510                                                }
511                                                println "saved subject "+it
512
513                                                // add this subject to the study
514                                                flow.study.addToSubjects(it)
515                                        }
516
517                                        // save study
518                                        if (!flow.study.save(flush:true)) {
519                                                this.appendErrors(flow.study, flash.errors)
520                                                throw new Exception('error saving study')
521                                        }
522                                        println "saved study "+flow.study+" (id: "+flow.study.id+")"
523
524                                        // commit transaction
525                                        println "commit"
526                                        transaction.commit()
527                                        success()
528                                } catch (Exception e) {
529                                        // rollback
530                                        this.appendErrorMap(['exception': e.toString() + ', see log for stacktrace' ], flash.errors)
531
532                                        // stacktrace in flash scope
533                                        flash.debug = e.getStackTrace()
534
535                                        println "rollback"
536                                        transaction.rollback()
537                                        error()
538                                }
539                        }
540                        on("error").to "error"
541                        on(Exception).to "error"
542                        on("success").to "done"
543                }
544
545                // error storing data
546                error {
547                        render(view: "_error")
548                        onRender {
549                                flow.page = 6
550                        }
551                        on("next").to "save"
552                        on("previous").to "events"
553                }
554
555                // render page three
556                done {
557                        render(view: "_done")
558                        onRender {
559                                flow.page = 7
560                        }
561                        on("previous") {
562                                // TODO
563                        }.to "confirm"
564                }
565        }
566
567        /**
568         * re-usable code for handling study form data in a web flow
569         * @param Map LocalAttributeMap (the flow scope)
570         * @param Map localAttributeMap (the flash scope)
571         * @param Map GrailsParameterMap (the flow parameters = form data)
572         * @returns boolean
573         */
574        def handleStudy(flow, flash, params) {
575                // create study instance if we have none
576                if (!flow.study) flow.study = new Study();
577
578                // create date instance from date string?
579                // @see WizardTagLibrary::dateElement{...}
580                if (params.get('startDate')) {
581                        params.startDate = new Date().parse("d/M/yyyy", params.get('startDate').toString())
582                } else {
583                        params.remove('startDate')
584                }
585
586                // if a template is selected, get template instance
587                def template = params.remove('template')
588                if (template instanceof String && template.size() > 0) {
589                        flow.study.template = Template.findByName(template)
590                } else if (template instanceof Template) {
591                        flow.study.template = template
592                }
593
594//println flow.study.giveFields()
595/*
596                // update study instance with parameters
597                params.each() { key, value ->
598                        if (flow.study.hasProperty(key)) {
599println ".set property ["+key+"] with value ["+value+"]"
600                                flow.study.setProperty(key, value);
601                        }
602                }
603
604                // walk through template fields
605                if (params.template) {
606                        params.template.fields.each() { field ->
607println ".set field ["+field.name+"] with value ["+params.get(field.escapedName())+"]"
608                                flow.study.setFieldValue(field.name, params.get(field.escapedName()))
609                        }
610                }
611*/
612                // iterate through fields
613                if (flow.study.template) {
614                        flow.study.giveFields().each() {
615                                flow.study.setFieldValue(it.name, params.get(it.escapedName()))
616                        }
617                }
618println "study = " + flow.study
619println flow.study.templateDateFields
620               
621                // validate study
622                if (flow.study.validate()) {
623                        return true
624                } else {
625                        // validation failed, feedback errors
626                        flash.errors = [:]
627                        this.appendErrors(flow.study, flash.errors)
628                        return false
629                }
630        }
631
632        /**
633         * re-usable code for handling subject form data in a web flow
634         * @param Map LocalAttributeMap (the flow scope)
635         * @param Map localAttributeMap (the flash scope)
636         * @param Map GrailsParameterMap (the flow parameters = form data)
637         * @returns boolean
638         */
639        def handleSubjects(flow, flash, params) {
640                def names = [:];
641                def errors = false;
642                def id = 0;
643
644                // iterate through subject templates
645                flow.subjectTemplates.each() {
646                        def subjectTemplate = it.getValue().template
647                        def templateFields      = subjectTemplate.fields
648
649                        // iterate through subjects
650                        it.getValue().subjects.each() { subjectId ->
651                                /*
652                                flow.subjects[ subjectId ].name = params.get('subject_' + subjectId + '_name')
653                                flow.subjects[ subjectId ].species = Term.findByName(params.get('subject_' + subjectId + '_species'))
654
655                                // remember name and check for duplicates
656                                if (!names[ flow.subjects[ subjectId ].name ]) {
657                                        names[ flow.subjects[ subjectId ].name ] = [count: 1, first: 'subject_' + subjectId + '_name', firstId: subjectId]
658                                } else {
659                                        // duplicate name found, set error flag
660                                        names[ flow.subjects[ subjectId ].name ]['count']++
661
662                                        // second occurence?
663                                        if (names[ flow.subjects[ subjectId ].name ]['count'] == 2) {
664                                                // yeah, also mention the first
665                                                // occurrence in the error message
666                                                this.appendErrorMap(name: 'The subject name needs to be unique!', flash.errors, 'subject_' + names[ flow.subjects[ subjectId ].name ]['firstId'] + '_')
667                                        }
668
669                                        // add to error map
670                                        this.appendErrorMap([name: 'The subject name needs to be unique!'], flash.errors, 'subject_' + subjectId + '_')
671                                        errors = true
672                                }
673                                */
674
675                                // iterate through template fields
676                                //templateFields.each() { subjectField ->
677                                flow.subjects[ subjectId ].giveFields().each() { subjectField ->
678                                        flow.subjects[ subjectId ].setFieldValue(
679                                                subjectField.name,
680                                                params.get( 'subject_' + subjectId + '_' + subjectField.escapedName() )
681                                        )
682                                }
683
684                                // validate subject
685                                if (!flow.subjects[ subjectId ].validate()) {
686                                        errors = true
687                                        this.appendErrors(flow.subjects[ subjectId ], flash.errors, 'subject_' + subjectId + '_')
688                                }
689                        }
690                }
691
692                return !errors
693        }
694
695        /**
696         * re-usable code for handling event form data in a web flow
697         * @param Map LocalAttributeMap (the flow scope)
698         * @param Map localAttributeMap (the flash scope)
699         * @param Map GrailsParameterMap (the flow parameters = form data)
700         * @returns boolean
701         */
702        def handleEvents(flow, flash, params) {
703                // got an event in the flash scope?
704                if (!flow.event) flow.event = new Event()
705
706                // if a template is selected, get template instance
707                def template = params.remove('template')
708                if (template instanceof String && template.size() > 0) {
709                        params.template = Template.findByName(template)
710                } else if (template instanceof Template) {
711                        params.template = template
712                } else {
713                        params.template = null
714                }
715
716                // set template
717                if (params.template) flow.event.template = params.template
718
719                // update event instance with parameters
720                params.each() { key, value ->
721                        // does this event have such a property or (if
722                        // a template is set) such a template field?
723                        if (flow.event.fieldExists(key)) {
724                                // yes, set it
725                                flow.event.setFieldValue(key, value)
726                        }
727                }
728
729                // handle event objects
730                flow.eventTemplates.each() {
731                        def eventTemplate       = it.getValue().template
732                        def templateFields      = eventTemplate.fields
733
734                        // iterate through events
735                        it.getValue().events.each() { eventId ->
736                                // iterate through template fields
737                                templateFields.each() { eventField ->
738                                        flow.events[ eventId ].setFieldValue(
739                                                eventField.name,
740                                                params.get( 'event_' + eventId + '_' + eventField.escapedName() )
741                                        )
742                                }
743
744                                // validate event
745                                if (!flow.events[ eventId ].validate()) {
746                                        errors = true
747                                        this.appendErrors(flow.events[ eventId ], flash.errors, 'event_' + eventId + '_')
748                                }
749
750
751                        }
752                }
753
754                // handle event grouping
755                handleEventGrouping(flow, flash, params)
756
757println flow.event
758
759                return !errors
760        }
761
762        /**
763         * re-usable code for handling event grouping in a web flow
764         * @param Map LocalAttributeMap (the flow scope)
765         * @param Map localAttributeMap (the flash scope)
766         * @param Map GrailsParameterMap (the flow parameters = form data)
767         * @returns boolean
768         */
769        def handleEventGrouping(flow, flash, params) {
770                // walk through eventGroups
771                def g = 0
772                flow.eventGroups.each() {
773                        def e = 0
774                        def eventGroup = it
775
776                        // reset events
777                        eventGroup.events = new HashSet()
778
779                        // walk through events
780                        flow.events.each() {
781                                if (params.get('event_' + e + '_group_' + g) == 'on') {
782                                        eventGroup.addToEvents(it)
783                                }
784                                e++
785                        }
786                        g++
787                }
788        }
789
790        /**
791         * return the object from a map of objects by searching for a name
792         * @param String name
793         * @param Map map of objects
794         * @return Object
795         */
796        def getObjectByName(name, map) {
797                def result = null
798                map.each() {
799                        if (it.name == name) {
800                                result = it
801                        }
802                }
803
804                return result
805        }
806
807        /**
808         * transform domain class validation errors into a human readable
809         * linked hash map
810         * @param object validated domain class
811         * @returns object  linkedHashMap
812         */
813        def getHumanReadableErrors(object) {
814                def errors = [:]
815                object.errors.getAllErrors().each() {
816                        errors[it.getArguments()[0]] = it.getDefaultMessage()
817                }
818
819                return errors
820        }
821
822        /**
823         * append errors of a particular object to a map
824         * @param object
825         * @param map linkedHashMap
826         * @void
827         */
828        def appendErrors(object, map) {
829                this.appendErrorMap(this.getHumanReadableErrors(object), map)
830        }
831
832        def appendErrors(object, map, prepend) {
833                this.appendErrorMap(this.getHumanReadableErrors(object), map, prepend)
834        }
835
836        /**
837         * append errors of one map to another map
838         * @param map linkedHashMap
839         * @param map linkedHashMap
840         * @void
841         */
842        def appendErrorMap(map, mapToExtend) {
843                map.each() {key, value ->
844                        mapToExtend[key] = ['key': key, 'value': value, 'dynamic': false]
845                }
846        }
847
848        def appendErrorMap(map, mapToExtend, prepend) {
849                map.each() {key, value ->
850                        mapToExtend[prepend + key] = ['key': key, 'value': value, 'dynamic': true]
851                }
852        }
853}
Note: See TracBrowser for help on using the repository browser.