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

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