source: trunk/grails-app/domain/dbnp/studycapturing/TemplateField.groovy @ 1159

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

Improved the template editor so that template fields can be removed from templates, even if the templates are in use, but only if the template fields are never filled. (see ticket #74)

Also changed the user registration so that the administrator confirmation mails will be sent to the administrators in production environment, but still to gscfproject@… in other environments.

  • Property svn:keywords set to Author Date Rev
File size: 8.2 KB
Line 
1package dbnp.studycapturing
2
3import dbnp.data.Ontology
4
5/**
6 * A TemplateField is a specification for either a 'domain field' of a subclass of TemplateEntity or a
7 * 'template field' for a specific Template. See the Template class for an explanation of these terms.
8 * The TemplateField class contains all information which is needed to specify what kind of data can be stored
9 * in this particular field, such as the TemplateFieldType, the name, the ontologies from which terms can derive
10 * in case of an ONTOLOGYTERM field, the list entries in case of a STRINGLIST fields, and so on.
11 * The actual values of the template fields are stored in instances of subclasses of the TemplateEntity class.
12 * For example, if there exists a Study template with a 'description' TemplateField as a member of Template.fields,
13 * the actual description for each Study would be stored in the inherited templateStringFields map of that Study instance.
14 *
15 * One TemplateField can belong to many Templates, but they have to be the same entity as the TemplateField itself.
16 *
17 * Revision information:
18 * $Rev: 1159 $
19 * $Author: robert@isdat.nl $
20 * $Date: 2010-11-17 15:20:33 +0000 (wo, 17 nov 2010) $
21 */
22class TemplateField implements Serializable {
23
24        /** The name of the TemplateField, by which it is represented to the user.  */
25        String name
26
27        /** The type of this TemplateField, such as STRING, ONTOLOGYTERM etc. */
28        TemplateFieldType type
29
30        /** The entity for which this TemplateField is meant. Only Templates for this entity can contain this TemplateField */
31        Class entity
32
33        /** The unit of the values of this TemplateField (optional) */
34        String unit
35
36        /** The help string which is shown in the user interface to describe this template field (optional, TEXT) */
37        String comment
38
39        /** The different list entries for a STRINGLIST TemplateField. This property is only used if type == TemplateFieldType.STRINGLIST */
40        List listEntries
41
42        /** Indicates whether this field is required to be filled out or not */
43        boolean required
44
45        /** Indicates whether this field is the preferred identifier for the resulting templated entity.
46                This is for example used when importing to match entries in the database against the ones that are being imported. */
47        boolean preferredIdentifier
48
49        static hasMany = [
50                listEntries: TemplateFieldListItem,     // to store the entries to choose from when the type is 'item from predefined list'
51                ontologies: Ontology                            // to store the ontologies to choose from when the type is 'ontology term'
52        ]
53
54        static constraints = {
55                // outcommented for now due to bug in Grails / Hibernate
56                // see http://jira.codehaus.org/browse/GRAILS-6020
57                // This is to verify that TemplateField names are unique within templates of each super entity
58                // TODO: this probably has to change in the case of private templates of different users,
59                // which can co-exist with the same name. See also Template
60                // name(unique:['entity'])
61
62                name(nullable: false, blank: false)
63                type(nullable: false, blank: false)
64                entity(nullable: false, blank: false)
65                unit(nullable: true, blank: true)
66                comment(nullable: true, blank: true)
67                required(default: false)
68                preferredIdentifier(default: false)
69        }
70
71        static mapping = {
72                // Make sure the comments can be Strings of arbitrary length
73                comment type: 'text'
74                name column:"templatefieldname"
75                type column:"templatefieldtype"
76                entity column:"templatefieldentity"
77                unit column:"templatefieldunit"
78                comment column:"templatefieldcomment"               
79        }
80
81        String toString() {
82                return name
83        }
84
85        /**
86         * return an escaped name which can be used in business logic
87         * @return String
88         */
89        def String escapedName() {
90                return name.toLowerCase().replaceAll("([^a-z0-9])", "_")
91        }
92
93        /**
94         * overloading the findAllByEntity method to make it function as expected
95         * @param Class entity (for example: dbnp.studycapturing.Subject)
96         * @return ArrayList
97         */
98        public static findAllByEntity(java.lang.Class entity) {
99                def results = []
100                // 'this' should not work in static context, so taking Template instead of this
101                TemplateField.findAll().each() {
102                        if (entity.equals(it.entity)) {
103                                results[results.size()] = it
104                        }
105                }
106
107                return results
108        }
109
110        /**
111         * Checks whether this template field is used in a template
112         *
113         * @returns             true iff this template field is used in a template (even if the template is never used), false otherwise
114         */
115        def inUse() {
116                return numUses() > 0;
117        }
118
119        /**
120         * The number of templates that use this template field
121         *
122         * @returns             the number of templates that use this template field.
123         */
124        def numUses() {
125                return getUses().size();
126        }
127
128        /**
129         * Retrieves the templates that use this template field
130         *
131         * @returns             a list of templates that use this template field.
132         */
133        def getUses() {
134                def templates = Template.findAll();
135                def elements;
136
137                if( templates && templates.size() > 0 ) {
138                        elements = templates.findAll { template -> template.fields.contains( this ) };
139                } else {
140                        return [];
141                }
142
143                return elements;
144        }
145
146        /**
147         * Checks whether this template field is used in a template and also filled in any instance of that template
148         *
149         * @returns             true iff this template field is used in a template, the template is instantiated
150         *                              and an instance has a value for this field. false otherwise
151         */
152        def isFilled() {
153                // Find all entities that use this template
154                def templates = getUses();
155
156                if( templates.size() == 0 )
157                        return false;
158
159                def c = this.entity.createCriteria()
160                def entities = c {
161                        'in'("template",templates)
162                }
163
164                def filledEntities = entities.findAll { entity -> entity.getFieldValue( this.name ) }
165
166                return filledEntities.size() > 0;
167        }
168
169        /**
170         * Checks whether this template field is used in the given template and also filled in an instance of that template
171         *
172         * @returns             true iff this template field is used in the given template, the template is instantiated
173         *                              and an instance has a value for this field. false otherwise
174         */
175        def isFilledInTemplate(Template t) {
176                println( "Checking field " + this.name )
177                println( "Filled in template: " + t)
178                if( t == null ) 
179                        return false;
180                       
181                // If the template is not used, if can never be filled
182                if( !t.fields.contains( this ) )
183                        return false;
184
185                // Find all entities that use this template
186                def entities = entity.findAllByTemplate( t );
187
188                println( "Num entities: " + entities.size() )
189
190                def filledEntities = entities.findAll { entity -> entity.getFieldValue( this.name ) }
191
192                println( "Num filled entities: " + filledEntities.size() )
193                println( "Values: " + filledEntities*.getFieldValue( this.name ).join( ', ' ) )
194                return filledEntities.size() > 0;
195        }
196
197        /**
198         * Check whether a templatefield that is used in a template may still be edited or deleted.
199         * That is possible if the templatefield is never filled and the template is only used in one template
200         *
201         * This method should only be used for templatefields used in a template that is currently shown. Otherwise
202         * the user may edit this template field, while it is also in use in another template than is currently shown.
203         * That lead to confusion.
204         *
205         * @returns true iff this template may still be edited or deleted.
206         */
207        def isEditable() {
208                return !isFilled() && numUses() == 1;
209        }
210
211        /**
212         * Checks whether the given list item is selected in an entity where this template field is used
213         *
214         * @param       item    ListItem to check.
215         * @returns                     true iff the list item is part of this template field and the given list
216         *                                      item is selected in an entity where this template field is used. false otherwise
217         *                                      Returns false if the type of this template field is other than STRINGLIST
218         */
219        def entryUsed(TemplateFieldListItem item) {
220                //return numUses() > 0;
221        }
222
223        /**
224         * Checks whether a term from the given ontology is selected in an entity where this template field is used
225         *
226         * @param       item    ListItem to check.
227         * @returns                     true iff the ontology is part of this template field and a term from the given
228         *                                      ontology is selected in an entity where this template field is used. false otherwise
229         *                                      Returns false if the type of this template field is other than ONTOLOGY
230         */
231        def entryUsed(Ontology item) {
232                //return numUses() > 0;
233        }
234
235}
Note: See TracBrowser for help on using the repository browser.