ref #1444, ref #8509 adapt IncludedInMapper and TaxonRelationshipType uuid access...
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / molecular / Amplification.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.model.molecular;
10
11 import javax.persistence.Column;
12 import javax.persistence.Entity;
13 import javax.persistence.FetchType;
14 import javax.persistence.JoinColumn;
15 import javax.persistence.ManyToOne;
16 import javax.xml.bind.annotation.XmlAccessType;
17 import javax.xml.bind.annotation.XmlAccessorType;
18 import javax.xml.bind.annotation.XmlElement;
19 import javax.xml.bind.annotation.XmlIDREF;
20 import javax.xml.bind.annotation.XmlRootElement;
21 import javax.xml.bind.annotation.XmlSchemaType;
22 import javax.xml.bind.annotation.XmlType;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.log4j.Logger;
26 import org.hibernate.annotations.Cascade;
27 import org.hibernate.annotations.CascadeType;
28 import org.hibernate.envers.Audited;
29 import org.hibernate.search.annotations.Analyze;
30 import org.hibernate.search.annotations.Field;
31 import org.hibernate.search.annotations.IndexedEmbedded;
32 import org.hibernate.search.annotations.NumericField;
33
34 import eu.etaxonomy.cdm.common.CdmUtils;
35 import eu.etaxonomy.cdm.model.agent.Institution;
36 import eu.etaxonomy.cdm.model.common.EventBase;
37 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
38 import eu.etaxonomy.cdm.model.occurrence.MaterialOrMethodEvent;
39 import eu.etaxonomy.cdm.model.term.DefinedTerm;
40 import eu.etaxonomy.cdm.model.term.TermType;
41
42 /**
43 * The physical process of amplification (also called PCR) extracts and replicates parts of the DNA of
44 * a given {@link #getDnaSample() DNA Sample} . The part of the DNA being replicated is defined by the
45 * {@link Amplification#getDnaMarker() marker} (also called locus) - implemented in CDM as a {@link DefinedTerm}
46 * of term type {@link TermType#DnaMarker}.
47 *
48 * <BR>
49 * To execute the replication {@link Primer primers} (short DNA fractions) are
50 * used. They may work in both directions of the DNA part therefore we do have a
51 * {@link #getForwardPrimer() forward primer} and a {@link #getReversePrimer() reverse primer}.
52 * Most (or all?) amplifications require a {@link #getPurification() purification process}. Additionally
53 * some use {@link #getCloning()} for replication.
54 *
55 * <H3>Quality control</H3>
56 * <BR>
57 * For quality control the resulting product (PCR) is tested using a chromatographic method called
58 * electrophoresis. The parameters (voltage, ladder used, running time, and gel concentration) used
59 * for this electrophoresis as well as the resulting
60 * {@link #getGelPhoto() photo} are also relevant for an amplification.
61 *
62 * We have 2 classes to store the core data for an amplification: {@link Amplification} and {@link AmplificationResult}.
63 * <BR>
64 * In {@link Amplification} we store all data that is equal for an amplification event which includes amplification
65 * of many {@link DnaSample dna samples}. Those data which are relevant only for a specific dna sample are
66 * stored in {@link AmplificationResult}. Theoretically this includes data on the resulting PCR. However, as the
67 * PCR itself is not persistent we do not store further information on it in the CDM and do not handle
68 * {@link AmplificationResult} as a {@link DerivedUnit}.
69 * <BR>
70 * This may change in future: http://dev.e-taxonomy.eu/trac/ticket/3717.
71 * <BR>
72 *
73 * @author a.mueller
74 * @since 2013-07-05
75 *
76 * @see AmplificationResult
77 */
78 @XmlAccessorType(XmlAccessType.FIELD)
79 @XmlType(name = "Amplification", propOrder = {
80 "dnaMarker",
81 "forwardPrimer",
82 "reversePrimer",
83 "purification",
84 "institution",
85 "ladderUsed",
86 "electrophoresisVoltage",
87 "gelRunningTime",
88 "gelConcentration",
89 "labelCache"
90 })
91 @XmlRootElement(name = "Amplification")
92 @Entity
93 @Audited
94 public class Amplification extends EventBase implements Cloneable{
95 private static final long serialVersionUID = -6382383300974316261L;
96
97 private static final Logger logger = Logger.getLogger(Amplification.class);
98
99 /** @see #getDnaMarker()*/
100 @XmlElement(name = "DnaMarker")
101 @XmlIDREF
102 @XmlSchemaType(name = "IDREF")
103 //TODO why is this eager?
104 @ManyToOne(fetch=FetchType.EAGER)
105 private DefinedTerm dnaMarker;
106
107 /** @see #getForwardPrimer() */
108 @XmlElement(name = "ForwardPrimer")
109 @XmlIDREF
110 @XmlSchemaType(name = "IDREF")
111 @ManyToOne(fetch=FetchType.LAZY)
112 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
113 private Primer forwardPrimer;
114
115 /** @see #getReversePrimer()*/
116 @XmlElement(name = "ReversePrimer")
117 @XmlIDREF
118 @XmlSchemaType(name = "IDREF")
119 @ManyToOne(fetch=FetchType.LAZY)
120 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
121 private Primer reversePrimer;
122
123
124 @XmlElement(name = "Purification")
125 @XmlIDREF
126 @XmlSchemaType(name = "IDREF")
127 @ManyToOne(fetch=FetchType.LAZY)
128 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
129 private MaterialOrMethodEvent purification;
130
131 @XmlElement(name = "Institution")
132 @XmlIDREF
133 @XmlSchemaType(name = "IDREF")
134 @ManyToOne(fetch = FetchType.LAZY)
135 @IndexedEmbedded
136 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
137 @JoinColumn(name="institution_id")
138 private Institution institution;
139
140 /** @see #getLadderUsed() */
141 @XmlElement(name = "ladderUsed")
142 @Field
143 @Column(length=255)
144 private String ladderUsed;
145
146 /** @see #getElectrophoresisVoltage()*/
147 @XmlElement(name = "electrophoresisVoltage")
148 @Field(analyze = Analyze.NO)
149 @NumericField
150 private Double electrophoresisVoltage;
151
152 /** @see #getGelRunningTime() */
153 @XmlElement(name = "gelRunningTime")
154 @Field(analyze = Analyze.NO)
155 @NumericField
156 private Double gelRunningTime;
157
158 /** @see #getGelConcentration() */
159 @XmlElement(name = "gelConcentration")
160 @Field(analyze = Analyze.NO)
161 @NumericField
162 private Double gelConcentration;
163
164 //automatically created
165 private String labelCache;
166
167
168 // ********************* FACTORY METHODS ************************/
169
170 public static Amplification NewInstance(){
171 return new Amplification();
172 }
173
174
175 // ******************* CONSTRUCTOR *******************************/
176
177 protected Amplification(){}
178
179
180 //********************* GETTER / SETTER ************/
181
182
183 /**
184 * The {@link TermType#DnaMarker DNA marker} used for this amplification.
185 * The DNA marker also defines the part (locality) of the DNA/RNA examined.
186 * It may also be called <i>locus</i>
187 */
188 public DefinedTerm getDnaMarker() {
189 return dnaMarker;
190 }
191 /** @see #getDnaMarker()*/
192 public void setDnaMarker(DefinedTerm marker) {
193 this.dnaMarker = marker;
194 }
195
196 /**
197 * The primer used for forward amplification.
198 * @see #getReversePrimer()
199 */
200 public Primer getForwardPrimer() {
201 return forwardPrimer;
202 }
203 /**
204 * @see #getForwardPrimer()
205 * @see #getReversePrimer()
206 */
207 public void setForwardPrimer(Primer forwardPrimer) {
208 this.forwardPrimer = forwardPrimer;
209 }
210
211 /**
212 * The primer used for reverse amplification.
213 * @see #getForwardPrimer()
214 */
215 public Primer getReversePrimer() {
216 return reversePrimer;
217 }
218 /**
219 * @see #getReversePrimer()
220 * @see #getForwardPrimer()
221 */
222 public void setReversePrimer(Primer reversePrimer) {
223 this.reversePrimer = reversePrimer;
224 }
225
226
227 /**
228 * The material and/or method used for purification.
229 */
230 public MaterialOrMethodEvent getPurification() {
231 return purification;
232 }
233 /**
234 * @see #getPurification()
235 */
236 public void setPurification(MaterialOrMethodEvent purification) {
237 this.purification = purification;
238 }
239
240 /**
241 * The institution in which the amplification event took place.
242 * Usually the {@link Amplification#getActor()} should be a person
243 * or team that works for this institution at the given time
244 * @return the institution
245 */
246 // #4498
247 public Institution getInstitution() {
248 return institution;
249 }
250 /**
251 * @see #getInstitution()
252 */
253 public void setInstitution(Institution institution) {
254 this.institution = institution;
255 }
256
257 /**
258 * The voltage used for running the electrophoresis quality check.
259 * Base unit is voltage [V].
260 * @see #getGelRunningTime()
261 * @see #getGelPhoto()
262 * @see #getLadderUsed()
263 * @see #getGelConcentration()
264
265 */
266 public Double getElectrophoresisVoltage() {
267 return electrophoresisVoltage;
268 }
269 /**
270 * @see #getElectrophoresisVoltage()
271 */
272 public void setElectrophoresisVoltage(Double electrophoresisVoltage) {
273 this.electrophoresisVoltage = electrophoresisVoltage;
274 }
275
276 /**
277 * The time for running the electrophoresis quality check.
278 * Base unit is minutes [min].
279 */
280 public Double getGelRunningTime() {
281 return gelRunningTime;
282 }
283 /**
284 * @see #getGelRunningTime()
285 */
286 public void setGelRunningTime(Double gelRunningTime) {
287 this.gelRunningTime = gelRunningTime;
288 }
289
290
291 /**
292 * The gel concentration used for the electrophoresis.
293 * Base unit is [%]
294 * @see #getElectrophoresisVoltage()
295 * @see #getGelRunningTime()
296 * @see #getGelPhoto()
297 * @see #getLadderUsed()
298 */
299 public Double getGelConcentration() {
300 return gelConcentration;
301 }
302 /**
303 * @see #getGelConcentration()
304 */
305 public void setGelConcentration(Double gelConcentration) {
306 this.gelConcentration = gelConcentration;
307 }
308
309 /**
310 * Material and method used for testing quality of this amplification.
311 * @see #getElectrophoresisVoltage()
312 * @see #getGelPhoto()
313 * @see #getGelConcentration()
314 * @see #getGelRunningTime()
315 */
316 public String getLadderUsed() {
317 return ladderUsed;
318 }
319 /**
320 * @see #getLadderUsed()
321 */
322 public void setLadderUsed(String ladderUsed) {
323 this.ladderUsed = ladderUsed;
324 }
325
326
327
328 /**
329 * Returns the labelCache
330 * @return
331 */
332 public String getLabelCache() {
333 return labelCache;
334 }
335
336
337 /**
338 * This method pushes the {@link Amplification#labelCache label cache} update.
339 * The cache is otherwise updated during persist in CacheStrategyUpdater.
340 */
341 public void updateCache(){
342 //retrieve data
343 String institutionName = getInstitution() == null ? "" :getInstitution().getTitleCache();
344 String staffName = getActor() == null ? "" :getActor().getTitleCache();
345 String dnaMarkerString = getDnaMarker() == null ? "" :getDnaMarker().getTitleCache();
346 String dateString = getTimeperiod() == null ? "" :getTimeperiod().toString();
347
348 //assemble string
349 String designation = CdmUtils.concat("_", new String[]{institutionName, staffName, dnaMarkerString, dateString});
350
351 this.labelCache = StringUtils.isBlank(designation) ? "<Amplification:" + getUuid() + ">" : designation ;
352 }
353
354
355
356 // ********************** CLONE ***********************************/
357 /**
358 * Clones <i>this</i> amplification. This is a shortcut that enables to create
359 * a new instance that differs only slightly from <i>this</i> amplification by
360 * modifying only some of the attributes.<BR><BR>
361 *
362 *
363 * @see EventBase#clone()
364 * @see java.lang.Object#clone()
365 */
366 @Override
367 public Object clone() {
368 try{
369 Amplification result = (Amplification)super.clone();
370
371 //don't change marker, forwardPrimer, reversePrimer,
372 //purifiaction, ladderUsed, electrophoresisVoltage,
373 //gelRunningTime, gelConcentration
374 return result;
375 }catch (CloneNotSupportedException e) {
376 logger.warn("Object does not implement cloneable");
377 e.printStackTrace();
378 return null;
379 }
380 }
381
382
383 }