source: trunk/grails-app/domain/dbnp/studycapturing/Sample.groovy @ 1430

Last change on this file since 1430 was 1430, checked in by work@…, 10 years ago
  • set keyword expansion
  • Property svn:keywords set to Rev Author Date
File size: 4.0 KB
Line 
1package dbnp.studycapturing
2
3import nl.grails.plugins.gdt.*
4
5/**
6 * The Sample class describes an actual sample which results from a SamplingEvent.
7 *
8 * Revision information:
9 * $Rev: 1430 $
10 * $Author: work@osx.eu $
11 * $Date: 2011-01-21 20:05:36 +0000 (vr, 21 jan 2011) $
12 */
13class Sample extends nl.grails.plugins.gdt.TemplateEntity {
14        // uncommented due to searchable issue
15        // @see http://jira.codehaus.org/browse/GRAILSPLUGINS-1577
16        //static searchable = { [only: ['name']] }
17
18        static belongsTo = [
19                // A Sample always belongs to one study.
20                parent                  : Study,
21
22                // A Sample optionally has a parent Subject from which it was taken, this Subject should be in the same parent study.
23                parentSubject   : Subject,
24
25                // Also, it has a parent SamplingEvent describing the actual sampling, also within the same parent study.
26                parentEvent             : SamplingEvent,
27
28                // And it has a parent EventGroup which tied it to its parent subject and parent event
29                parentEventGroup: EventGroup
30
31                // We can't have parentAssay since a Sample can belong to multiple Assays
32        ]
33
34        String name             // should be unique with respect to the parent study (which can be inferred)
35        Term material           // material of the sample (should normally be bound to the BRENDA ontology)
36
37        /**
38         * return the domain fields for this domain class
39         * @return List
40         */
41        static List<TemplateField> giveDomainFields() { return Sample.domainFields }
42
43        // We have to specify an ontology list for the material property. However, at compile time, this ontology does of course not exist.
44        // Therefore, the ontology is added at runtime in the bootstrap, possibly downloading the ontology properties if it is not present in the database yet.
45        static List<TemplateField> domainFields = [
46                new TemplateField(
47                        name: 'name',
48                        type: TemplateFieldType.STRING,
49                        preferredIdentifier: true,
50                        required: true
51                ),
52                new TemplateField(
53                        name: 'material',
54                        type: TemplateFieldType.ONTOLOGYTERM,
55                        comment: "The material is based on the BRENDA tissue / enzyme source ontology, a structured controlled vocabulary for the source of an enzyme. It comprises terms for tissues, cell lines, cell types and cell cultures from uni- and multicellular organisms. If a material is missing, please add it by using 'add more'"
56                )
57        ]
58
59        static constraints = {
60                // The parent subject is optional, e.g. in a biobank of samples the subject could be unknown or non-existing.
61                parentSubject(nullable:true)
62
63                // The same holds for parentEvent
64                parentEvent(nullable:true)
65
66                // and for parentEventGroup
67                parentEventGroup(nullable:true)
68
69                // The material domain field is optional
70                material(nullable: true)
71
72                // Check if the externalSampleId (currently defined as name) is really unique within each parent study of this sample.
73                // This feature is tested by integration test SampleTests.testSampleUniqueNameConstraint
74                name(unique:['parent'])
75
76                // Same, but also when the other sample is not even in the database
77                // This feature is tested by integration test SampleTests.testSampleUniqueNameConstraintAtValidate
78                name(validator: { field, obj, errors ->
79                        // 'obj' refers to the actual Sample object
80
81                        // define a boolean
82                        def error = false
83
84                        // check whether obj.parent.samples is not null at this stage to avoid null pointer exception
85                        if (obj.parent) {
86
87                                if (obj.parent.samples) {
88
89                                        // check if there is exactly one sample with this name in the study (this one)
90                                        if (obj.parent.samples.findAll{ it.name == obj.name}.size() > 1) {
91                                                error = true
92                                                errors.rejectValue(
93                                                        'name',
94                                                        'sample.UniqueNameViolation',
95                                                        [obj.name, obj.parent] as Object[],
96                                                        'Sample name {0} appears multiple times in study {1}'
97                                                        )
98                                        }
99                                }
100                        }
101                        else {
102                                // if there is no parent study defined, fail immediately
103                                error = true
104                        }
105
106                        // got an error, or not?
107                        return (!error)
108                })
109        }
110
111    static mapping = {
112        sort "name"
113
114        // Workaround for bug http://jira.codehaus.org/browse/GRAILS-6754
115        templateTextFields type: 'text'
116    }
117
118        static getSamplesFor( event ) {
119                return  Sample.findAll( 'from Sample s where s.parentEvent =:event', [event:event] )
120        }
121
122        def String toString() {
123                return name
124        }
125}
Note: See TracBrowser for help on using the repository browser.