source: trunk/grails-app/domain/dbnp/studycapturing/Template.groovy @ 1027

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

Implemented compare templates feature and fixed show studies overview (tickets #7 and #137)

  • Property svn:keywords set to Author Date Rev
File size: 5.7 KB
Line 
1package dbnp.studycapturing
2
3import dbnp.authentication.SecUser
4import dbnp.authentication.AuthenticationService
5
6/**
7 * The Template class describes a TemplateEntity template, which is basically an extension of the study capture entities
8 * in terms of extra fields (which are described by classes that extend the TemplateField class).
9 * Study, Subject, Sample and Event are all TemplateEntities.
10 *
11 * Within a Template, we have two different types of fields: 'domain fields' and 'template fields'.
12 * The domain fields are TemplateFields which are given by the TemplateEntity itself and therefore always present
13 * in any instance of that TemplateEntity. They are specified by implementing TemplateEntity.giveDomainFields()
14 * The template fields are TemplateFields which are added specifically by the Template. They are specified
15 * in the fields property of the Template object which is referenced by the TemplateEntity.template property.
16 *
17 * Revision information:
18 * $Rev: 1027 $
19 * $Author: robert@isdat.nl $
20 * $Date: 2010-11-01 11:42:49 +0000 (ma, 01 nov 2010) $
21 */
22class Template extends Identity {
23
24        /** The name of the template */
25        String name
26
27        /** A string describing the template to other users */
28        String description
29
30        /** The target TemplateEntity for this template */
31        Class entity
32
33        /** The owner of the template. If the owner is not defined, it is a shared/public template */
34        SecUser owner
35
36        /** The template fields which are the members of this template. This is a List to preserve the field order */
37        List fields
38
39        static hasMany = [fields: TemplateField]
40        static mapping = {
41        }
42
43        // constraints
44        static constraints = {
45                owner(nullable: true, blank: true)
46                description(nullable: true, blank: true)
47
48                fields(validator: { fields, obj, errors ->
49                        // 'obj' refers to the actual Template object
50
51                        // define a boolean
52                        def error = false
53
54                        // iterate through fields
55                        fields.each { field ->
56                                // check if the field entity is the same as the template entity
57                                if (!field.entity.equals(obj.entity)) {
58                                        error = true
59                                        errors.rejectValue(
60                                                'fields',
61                                                'templateEntity.entityMismatch',
62                                                [field.name, obj.entity, field.entity] as Object[],
63                                                'Template field {0} must be of entity {1} and is currently of entity {2}'
64                                                )
65                                }
66                        }
67
68                        // got an error, or not?
69                        return (!error)
70                })
71
72                // outcommented for now due to bug in Grails / Hibernate
73                // see http://jira.codehaus.org/browse/GRAILS-6020
74                // This is to verify that the template name is unique with respect to the parent entity.
75                // TODO: this probably has to change in the case of private templates of different users,
76                // which can co-exist with the same name. See also TemplateField
77                // name(unique:['entity'])
78
79        }
80
81        public Template() {
82                super()
83        }
84
85        /**
86         * Creates a clone of the given other template and also copies its owner
87         *
88         * @param       otherTemplate
89         */
90        public Template( Template otherTemplate) {
91                this( otherTemplate, otherTemplate.owner )
92        }
93
94        /**
95         * Creates a clone of the given other template. The currently logged in user
96         * is set as the owner
97         * @param       otherTemplate
98         */
99        public Template( Template otherTemplate, SecUser owner ) {
100                this()
101
102                //authenticationService = new AuthenticationService()
103
104                this.name = otherTemplate.name + " (Copy)"
105                this.description = otherTemplate.description
106                this.entity = otherTemplate.entity
107                this.owner = owner
108
109                // The fields are copied by reference
110                this.fields = []
111                otherTemplate.fields.each {
112                        this.fields.add( it )
113                }
114        }
115
116        /**
117         * overloaded toString method
118         * @return String
119         */
120        def String toString() {
121                return this.name;
122        }
123
124        /**
125         * Look up the type of a certain template subject field
126         * @param String fieldName The name of the template field
127         * @return String       The type (static member of TemplateFieldType) of the field, or null of the field does not exist
128         */
129        def TemplateFieldType getFieldType(String fieldName) {
130                def field = fields.find {
131                        it.name == fieldName
132                }
133                field?.type
134        }
135
136        /**
137         * get all field of a particular type
138         * @param Class fieldType
139         * @return Set < TemplateField >
140         */
141        def getFieldsByType(TemplateFieldType fieldType) {
142                def result = fields.findAll {
143                        it.type == fieldType
144                }
145                return result;
146        }
147
148        /**
149         * get all required fields
150         * @param Class fieldType
151         * @return Set < TemplateField >
152         */
153        def getRequiredFields() {
154                def result = fields.findAll {
155                        it.required == true
156                }
157                return result;
158        }
159
160        /**
161         * Checks whether this template is used by any object
162         *
163         * @returns             true iff this template is used by any object, false otherwise
164         */
165        def inUse() {
166                return (numUses() > 0 );
167        }
168
169        /**
170         * The number of objects that use this template
171         *
172         * @returns             the number of objects that use this template.
173         */
174        def numUses() {
175                // This template can only be used in objects of the right entity. Find objects of that
176                // entity and see whether they use this method.
177                //
178                // Unfortunately, due to the grails way of creating classes, we can not use reflection for this
179                def elements;
180                switch( this.entity ) {
181                        case Event:
182                                elements = Event.findAllByTemplate( this ); break;
183                        case Sample:
184                                elements = Sample.findAllByTemplate( this ); break;
185                        case Study:
186                                elements = Study.findAllByTemplate( this ); break;
187                        case Subject:
188                                elements = Subject.findAllByTemplate( this ); break;
189                        default:
190                                return 0;
191                }
192
193                return elements.size();
194        }
195
196        /**
197         * overloading the findAllByEntity method to make it function as expected
198         * @param Class entity (for example: dbnp.studycapturing.Subject)
199         * @return ArrayList
200         */
201        public static findAllByEntity(java.lang.Class entity) {
202                def results = []
203                // 'this' should not work in static context, so taking Template instead of this
204                Template.findAll().each() {
205                        if (entity.equals(it.entity)) {
206                                results[results.size()] = it
207                        }
208                }
209
210                return results
211        }
212}
Note: See TracBrowser for help on using the repository browser.