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

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

moved gdt package to org.dbnp, moved tests for RelTime?, TemplateEntity?, Template etc. to gdt plugin

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