Project

General

Profile

Download (35 KB) Statistics
| Branch: | Tag: | Revision:
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

    
10
package eu.etaxonomy.cdm.model.description;
11

    
12

    
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import javax.persistence.Entity;
21
import javax.persistence.FetchType;
22
import javax.persistence.JoinTable;
23
import javax.persistence.ManyToMany;
24
import javax.xml.bind.annotation.XmlAccessType;
25
import javax.xml.bind.annotation.XmlAccessorType;
26
import javax.xml.bind.annotation.XmlElement;
27
import javax.xml.bind.annotation.XmlElementWrapper;
28
import javax.xml.bind.annotation.XmlIDREF;
29
import javax.xml.bind.annotation.XmlRootElement;
30
import javax.xml.bind.annotation.XmlSchemaType;
31
import javax.xml.bind.annotation.XmlType;
32

    
33
import org.apache.log4j.Logger;
34
import org.hibernate.envers.Audited;
35

    
36
import eu.etaxonomy.cdm.model.common.DefinedTerm;
37
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
38
import eu.etaxonomy.cdm.model.common.Language;
39
import eu.etaxonomy.cdm.model.common.TermType;
40
import eu.etaxonomy.cdm.model.common.TermVocabulary;
41
import eu.etaxonomy.cdm.model.name.BotanicalName;
42
import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
43
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
44
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
45
import eu.etaxonomy.cdm.model.taxon.Taxon;
46

    
47

    
48
/**
49
 * The class for individual properties (also designed as character, type or
50
 * category) of observed phenomena able to be described or measured. It also
51
 * covers categories of informations on {@link TaxonNameBase taxon names} not
52
 * taken in account in {@link NomenclaturalCode nomenclature}.<BR>
53
 * Descriptions require features in order to be structured and disaggregated
54
 * in {@link DescriptionElementBase description elements}.<BR>
55
 * Experts do not use the word feature for the actual description
56
 * but only for the property itself. Therefore naming this class FeatureType
57
 * would have leaded to confusion.
58
 * <P>
59
 * Since features are {@link DefinedTermBase defined terms} they have a hierarchical
60
 * structure that allows to specify ("kind of") or generalize
61
 * ("generalization of") features. "Kind of" / "generalization of" relations
62
 * are bidirectional (a feature F1 is a "Kind of" a feature F2 if and only
63
 * if the feature F2 is a "generalization of" the feature F1. This hierarchical
64
 * structure has nothing in common with {@link FeatureTree feature trees} used for determination.
65
 * <P>
66
 * A standard set of feature instances will be automatically
67
 * created as the project starts. But this class allows to extend this standard
68
 * set by creating new instances of additional features if needed.<BR>
69
 * <P>
70
 * This class corresponds to DescriptionsSectionType according to the SDD
71
 * schema.
72
 *
73
 * @author m.doering
74
 * @created 08-Nov-2007 13:06:24
75
 */
76
@XmlAccessorType(XmlAccessType.PROPERTY)
77
@XmlType(name="Feature", factoryMethod="NewInstance", propOrder = {
78
		"kindOf",
79
		"generalizationOf",
80
		"partOf",
81
		"includes",
82
	    "supportsTextData",
83
	    "supportsQuantitativeData",
84
	    "supportsDistribution",
85
	    "supportsIndividualAssociation",
86
	    "supportsTaxonInteraction",
87
	    "supportsCommonTaxonName",
88
	    "supportsCategoricalData",
89
	    "recommendedModifierEnumeration",
90
	    "recommendedStatisticalMeasures",
91
	    "supportedCategoricalEnumerations",
92
	    "recommendedMeasurementUnits"
93
})
94
@XmlRootElement(name = "Feature")
95
@Entity
96
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
97
//@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
98
@Audited
99
public class Feature extends DefinedTermBase<Feature> {
100
	private static final long serialVersionUID = 6754598791831848704L;
101
	private static final Logger logger = Logger.getLogger(Feature.class);
102

    
103
	protected static Map<UUID, Feature> termMap = null;
104

    
105
	private boolean supportsTextData = true;   //by default text data should be always supported
106

    
107
	private boolean supportsQuantitativeData;
108

    
109
	private boolean supportsDistribution;
110

    
111
	private boolean supportsIndividualAssociation;
112

    
113
	private boolean supportsTaxonInteraction;
114

    
115
	private boolean supportsCategoricalData;
116

    
117
	private boolean supportsCommonTaxonName;
118

    
119
    /* for M:M see #4843 */
120
	@ManyToMany(fetch = FetchType.LAZY)
121
    @JoinTable(name="DefinedTermBase_RecommendedModifierEnumeration")
122
	private final Set<TermVocabulary<DefinedTerm>> recommendedModifierEnumeration = new HashSet<TermVocabulary<DefinedTerm>>();
123

    
124
	@ManyToMany(fetch = FetchType.LAZY)
125
    @JoinTable(name="DefinedTermBase_StatisticalMeasure")
126
	private final Set<StatisticalMeasure> recommendedStatisticalMeasures = new HashSet<StatisticalMeasure>();
127

    
128
	/* for M:M see #4843 */
129
	@ManyToMany(fetch = FetchType.LAZY)
130
	@JoinTable(name="DefinedTermBase_SupportedCategoricalEnumeration")
131
	private final Set<TermVocabulary<State>> supportedCategoricalEnumerations = new HashSet<TermVocabulary<State>>();
132

    
133

    
134
	@ManyToMany(fetch = FetchType.LAZY)
135
    @JoinTable(name="DefinedTermBase_MeasurementUnit")
136
	private final Set<MeasurementUnit> recommendedMeasurementUnits = new HashSet<MeasurementUnit>();
137

    
138
/* ***************** CONSTRUCTOR AND FACTORY METHODS **********************************/
139

    
140
	//for hibernate use only
141
	@Deprecated
142
	protected Feature() {
143
		super(TermType.Feature);
144
	}
145

    
146
	/**
147
	 * Class constructor: creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
148
	 * a label and a label abbreviation.
149
	 *
150
	 * @param	term  		 the string (in the default language) describing the
151
	 * 						 new feature to be created
152
	 * @param	label  		 the string identifying the new feature to be created
153
	 * @param	labelAbbrev  the string identifying (in abbreviated form) the
154
	 * 						 new feature to be created
155
	 * @see 				 #Feature()
156
	 */
157
	protected Feature(String term, String label, String labelAbbrev) {
158
		super(TermType.Feature, term, label, labelAbbrev);
159
	}
160

    
161
	/**
162
	 * Creates a new empty feature instance.
163
	 *
164
	 * @see #NewInstance(String, String, String)
165
	 */
166
	public static Feature NewInstance() {
167
		return new Feature();
168
	}
169

    
170
	/**
171
	 * Creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
172
	 * a label and a label abbreviation.
173
	 *
174
	 * @param	term  		 the string (in the default language) describing the
175
	 * 						 new feature to be created
176
	 * @param	label  		 the string identifying the new feature to be created
177
	 * @param	labelAbbrev  the string identifying (in abbreviated form) the
178
	 * 						 new feature to be created
179
	 * @see 				 #readCsvLine(List, Language)
180
	 * @see 				 #NewInstance()
181
	 */
182
	public static Feature NewInstance(String term, String label, String labelAbbrev){
183
		return new Feature(term, label, labelAbbrev);
184
	}
185

    
186
/* *************************************************************************************/
187

    
188
	@Override
189
	public void resetTerms(){
190
		termMap = null;
191
	}
192

    
193

    
194
	/**
195
	 * Returns the boolean value of the flag indicating whether <i>this</i>
196
	 * feature can be described with {@link QuantitativeData quantitative data} (true)
197
	 * or not (false). If this flag is set <i>this</i> feature can only apply to
198
	 * {@link TaxonDescription taxon descriptions} or {@link SpecimenDescription specimen descriptions}.
199
	 *
200
	 * @return  the boolean value of the supportsQuantitativeData flag
201
	 */
202
	@XmlElement(name = "SupportsQuantitativeData")
203
	public boolean isSupportsQuantitativeData() {
204
		return supportsQuantitativeData;
205
	}
206

    
207
	/**
208
	 * @see	#isSupportsQuantitativeData()
209
	 */
210
	public void setSupportsQuantitativeData(boolean supportsQuantitativeData) {
211
		this.supportsQuantitativeData = supportsQuantitativeData;
212
	}
213

    
214
	/**
215
	 * Returns the boolean value of the flag indicating whether <i>this</i>
216
	 * feature can be described with {@link TextData text data} (true)
217
	 * or not (false).
218
	 *
219
	 * @return  the boolean value of the supportsTextData flag
220
	 */
221
	@XmlElement(name = "SupportsTextData")
222
	public boolean isSupportsTextData() {
223
		return supportsTextData;
224
	}
225

    
226
	/**
227
	 * @see	#isSupportsTextData()
228
	 */
229
	public void setSupportsTextData(boolean supportsTextData) {
230
		this.supportsTextData = supportsTextData;
231
	}
232

    
233
	/**
234
	 * Returns the boolean value of the flag indicating whether <i>this</i>
235
	 * feature can be described with {@link Distribution distribution} objects
236
	 * (true) or not (false). This flag is set if and only if <i>this</i> feature
237
	 * is the {@link #DISTRIBUTION() distribution feature}.
238
	 *
239
	 * @return  the boolean value of the supportsDistribution flag
240
	 */
241
	@XmlElement(name = "SupportsDistribution")
242
	public boolean isSupportsDistribution() {
243
		return supportsDistribution;
244
	}
245

    
246
	/**
247
	 * @see	#isSupportsDistribution()
248
	 */
249
	public void setSupportsDistribution(boolean supportsDistribution) {
250
		this.supportsDistribution = supportsDistribution;
251
	}
252

    
253
	/**
254
	 * Returns the boolean value of the flag indicating whether <i>this</i>
255
	 * feature can be described with {@link IndividualsAssociation individuals associations}
256
	 * (true) or not (false).
257
	 *
258
	 * @return  the boolean value of the supportsIndividualAssociation flag
259
	 */
260
	@XmlElement(name = "SupportsIndividualAssociation")
261
	public boolean isSupportsIndividualAssociation() {
262
		return supportsIndividualAssociation;
263
	}
264

    
265
	/**
266
	 * @see	#isSupportsIndividualAssociation()
267
	 */
268
	public void setSupportsIndividualAssociation(
269
			boolean supportsIndividualAssociation) {
270
		this.supportsIndividualAssociation = supportsIndividualAssociation;
271
	}
272

    
273
	/**
274
	 * Returns the boolean value of the flag indicating whether <i>this</i>
275
	 * feature can be described with {@link TaxonInteraction taxon interactions}
276
	 * (true) or not (false).
277
	 *
278
	 * @return  the boolean value of the supportsTaxonInteraction flag
279
	 */
280
	@XmlElement(name = "SupportsTaxonInteraction")
281
	public boolean isSupportsTaxonInteraction() {
282
		return supportsTaxonInteraction;
283
	}
284

    
285
	/**
286
	 * @see	#isSupportsTaxonInteraction()
287
	 */
288
	public void setSupportsTaxonInteraction(boolean supportsTaxonInteraction) {
289
		this.supportsTaxonInteraction = supportsTaxonInteraction;
290
	}
291

    
292
	/**
293
	 * Returns the boolean value of the flag indicating whether <i>this</i>
294
	 * feature can be described with {@link CommonTaxonName common names}
295
	 * (true) or not (false). This flag is set if and only if <i>this</i> feature
296
	 * is the {@link #COMMON_NAME() common name feature}.
297
	 *
298
	 * @return  the boolean value of the supportsCommonTaxonName flag
299
	 */
300
	@XmlElement(name = "SupportsCommonTaxonName")
301
	public boolean isSupportsCommonTaxonName() {
302
		return supportsCommonTaxonName;
303
	}
304

    
305
	/**
306
	 * @see	#isSupportsTaxonInteraction()
307
	 */
308
	public void setSupportsCommonTaxonName(boolean supportsCommonTaxonName) {
309
		this.supportsCommonTaxonName = supportsCommonTaxonName;
310
	}
311

    
312
	/**
313
	 * Returns the boolean value of the flag indicating whether <i>this</i>
314
	 * feature can be described with {@link CategoricalData categorical data}
315
	 * (true) or not (false).
316
	 *
317
	 * @return  the boolean value of the supportsCategoricalData flag
318
	 */
319
	@XmlElement(name = "SupportsCategoricalData")
320
	public boolean isSupportsCategoricalData() {
321
		return supportsCategoricalData;
322
	}
323

    
324
	/**
325
	 * @see	#supportsCategoricalData()
326
	 */
327
	public void setSupportsCategoricalData(boolean supportsCategoricalData) {
328
		this.supportsCategoricalData = supportsCategoricalData;
329
	}
330

    
331

    
332
	/**
333
	 * Returns the set of {@link TermVocabulary term vocabularies} containing the
334
	 * {@link Modifier modifiers} recommended to be used for {@link DescriptionElementBase description elements}
335
	 * with <i>this</i> feature.
336
	 *
337
	 */
338
	@XmlElementWrapper(name = "RecommendedModifierEnumerations")
339
	@XmlElement(name = "RecommendedModifierEnumeration")
340
	@XmlIDREF
341
	@XmlSchemaType(name = "IDREF")
342
	public Set<TermVocabulary<DefinedTerm>> getRecommendedModifierEnumeration() {
343
		return recommendedModifierEnumeration;
344
	}
345

    
346
	/**
347
	 * Adds a {@link TermVocabulary term vocabulary} (with {@link Modifier modifiers}) to the set of
348
	 * {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies} assigned
349
	 * to <i>this</i> feature.
350
	 *
351
	 * @param recommendedModifierEnumeration	the term vocabulary to be added
352
	 * @see    	   								#getRecommendedModifierEnumeration()
353
	 */
354
	public void addRecommendedModifierEnumeration(
355
			TermVocabulary<DefinedTerm> recommendedModifierEnumeration) {
356
		this.recommendedModifierEnumeration.add(recommendedModifierEnumeration);
357
	}
358
	/**
359
	 * Removes one element from the set of {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies}
360
	 * assigned to <i>this</i> feature.
361
	 *
362
	 * @param  recommendedModifierEnumeration	the term vocabulary which should be removed
363
	 * @see     								#getRecommendedModifierEnumeration()
364
	 * @see     								#addRecommendedModifierEnumeration(TermVocabulary)
365
	 */
366
	public void removeRecommendedModifierEnumeration(
367
			TermVocabulary<DefinedTerm> recommendedModifierEnumeration) {
368
		this.recommendedModifierEnumeration.remove(recommendedModifierEnumeration);
369
	}
370

    
371
	/**
372
	 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
373
	 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
374
	 */
375
	@XmlElementWrapper(name = "RecommendedStatisticalMeasures")
376
	@XmlElement(name = "RecommendedStatisticalMeasure")
377
	@XmlIDREF
378
	@XmlSchemaType(name = "IDREF")
379
	public Set<StatisticalMeasure> getRecommendedStatisticalMeasures() {
380
		return recommendedStatisticalMeasures;
381
	}
382

    
383
	/**
384
	 * Adds a {@link StatisticalMeasure statistical measure} to the set of
385
	 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
386
	 * to <i>this</i> feature.
387
	 *
388
	 * @param recommendedStatisticalMeasure	the statistical measure to be added
389
	 * @see    	   							#getRecommendedStatisticalMeasures()
390
	 */
391
	public void addRecommendedStatisticalMeasure(
392
			StatisticalMeasure recommendedStatisticalMeasure) {
393
		this.recommendedStatisticalMeasures.add(recommendedStatisticalMeasure);
394
	}
395
	/**
396
	 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
397
	 * assigned to <i>this</i> feature.
398
	 *
399
	 * @param  recommendedStatisticalMeasure	the statistical measure which should be removed
400
	 * @see     								#getRecommendedStatisticalMeasures()
401
	 * @see     								#addRecommendedStatisticalMeasure(StatisticalMeasure)
402
	 */
403
	public void removeRecommendedStatisticalMeasure(
404
			StatisticalMeasure recommendedStatisticalMeasure) {
405
		this.recommendedStatisticalMeasures.remove(recommendedStatisticalMeasure);
406
	}
407

    
408
	/**
409
	 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
410
	 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
411
	 */
412
	@XmlElementWrapper(name = "RecommendedMeasurementUnits")
413
	@XmlElement(name = "RecommendedMeasurementUnit")
414
	@XmlIDREF
415
	@XmlSchemaType(name = "IDREF")
416
	public Set<MeasurementUnit> getRecommendedMeasurementUnits() {
417
		return recommendedMeasurementUnits;
418
	}
419

    
420
	/**
421
	 * Adds a {@link StatisticalMeasure statistical measure} to the set of
422
	 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
423
	 * to <i>this</i> feature.
424
	 *
425
	 * @param recommendedStatisticalMeasure	the statistical measure to be added
426
	 * @see    	   							#getRecommendedStatisticalMeasures()
427
	 */
428
	public void addRecommendedMeasurementUnit(
429
			MeasurementUnit recommendedMeasurementUnit) {
430
		this.recommendedMeasurementUnits.add(recommendedMeasurementUnit);
431
	}
432
	/**
433
	 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
434
	 * assigned to <i>this</i> feature.
435
	 *
436
	 * @param  recommendedStatisticalMeasure	the statistical measure which should be removed
437
	 * @see     								#getRecommendedStatisticalMeasures()
438
	 * @see     								#addRecommendedStatisticalMeasure(StatisticalMeasure)
439
	 */
440
	public void removeRecommendedMeasurementUnit(
441
			MeasurementUnit recommendedMeasurementUnit) {
442
		this.recommendedMeasurementUnits.remove(recommendedMeasurementUnit);
443
	}
444

    
445
	/**
446
	 * Returns the set of {@link TermVocabulary term vocabularies} containing the list of
447
	 * possible {@link State states} to be used in {@link CategoricalData categorical data}
448
	 * with <i>this</i> feature.
449
	 *
450
	 */
451
	@XmlElementWrapper(name = "SupportedCategoricalEnumerations")
452
	@XmlElement(name = "SupportedCategoricalEnumeration")
453
	@XmlIDREF
454
	@XmlSchemaType(name = "IDREF")
455
	public Set<TermVocabulary<State>> getSupportedCategoricalEnumerations() {
456
		return supportedCategoricalEnumerations;
457
	}
458

    
459
	/**
460
	 * Adds a {@link TermVocabulary term vocabulary} to the set of
461
	 * {@link #getSupportedCategoricalEnumerations() supported state vocabularies} assigned
462
	 * to <i>this</i> feature.
463
	 *
464
	 * @param supportedCategoricalEnumeration	the term vocabulary which should be removed
465
	 * @see    	   								#getSupportedCategoricalEnumerations()
466
	 */
467
	public void addSupportedCategoricalEnumeration(
468
			TermVocabulary<State> supportedCategoricalEnumeration) {
469
		this.supportedCategoricalEnumerations.add(supportedCategoricalEnumeration);
470
	}
471
	/**
472
	 * Removes one element from the set of {@link #getSupportedCategoricalEnumerations() supported state vocabularies}
473
	 * assigned to <i>this</i> feature.
474
	 *
475
	 * @param  supportedCategoricalEnumeration	the term vocabulary which should be removed
476
	 * @see     								#getSupportedCategoricalEnumerations()
477
	 * @see     								#addSupportedCategoricalEnumeration(TermVocabulary)
478
	 */
479
	public void removeSupportedCategoricalEnumeration(
480
			TermVocabulary<State> supportedCategoricalEnumeration) {
481
		this.supportedCategoricalEnumerations.remove(supportedCategoricalEnumeration);
482
	}
483

    
484
	@XmlElement(name = "KindOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
485
    @XmlIDREF
486
    @XmlSchemaType(name = "IDREF")
487
    @Override
488
	public Feature getKindOf(){
489
		return super.getKindOf();
490
	}
491

    
492
	@Override
493
    public void setKindOf(Feature kindOf){
494
		super.setKindOf(kindOf);
495
	}
496

    
497
	@Override
498
    @XmlElement(name = "PartOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
499
	@XmlIDREF
500
    @XmlSchemaType(name = "IDREF")
501
	public Feature getPartOf(){
502
		return super.getPartOf();
503
	}
504

    
505
	@Override
506
    public void setPartOf(Feature partOf){
507
		super.setPartOf(partOf);
508
	}
509

    
510
	@Override
511
    @XmlElementWrapper(name = "Generalizations", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
512
	@XmlElement(name = "GeneralizationOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
513
    @XmlIDREF
514
    @XmlSchemaType(name = "IDREF")
515
	public Set<Feature> getGeneralizationOf(){
516
		return super.getGeneralizationOf();
517
	}
518

    
519
	@Override
520
    protected void setGeneralizationOf(Set<Feature> value){
521
		super.setGeneralizationOf(value);
522
	}
523

    
524
	@Override
525
    @XmlElementWrapper(name = "Includes", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
526
	@XmlElement(name = "Include", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
527
	@XmlIDREF
528
    @XmlSchemaType(name = "IDREF")
529
	public Set<Feature> getIncludes(){
530
		return super.getIncludes();
531
	}
532

    
533
	@Override
534
    protected void setIncludes(Set<Feature> includes) {
535
		super.setIncludes(includes);
536
	}
537

    
538
	private static final UUID uuidUnknown = UUID.fromString("910307f1-dc3c-452c-a6dd-af5ac7cd365c");
539
	private static final UUID uuidDescription = UUID.fromString("9087cdcd-8b08-4082-a1de-34c9ba9fb493");
540
	private static final UUID uuidDistribution = UUID.fromString("9fc9d10c-ba50-49ee-b174-ce83fc3f80c6");
541
	private static final UUID uuidEcology = UUID.fromString("aa923827-d333-4cf5-9a5f-438ae0a4746b");
542
	private static final UUID uuidHabitat = UUID.fromString("fb16929f-bc9c-456f-9d40-dec987b36438");
543
	private static final UUID uuidHabitatAndEcology = UUID.fromString("9fdc4663-4d56-47d0-90b5-c0bf251bafbb");
544
	private static final UUID uuidChromosomeNumber = UUID.fromString("6f677e98-d8d5-4bc5-80bf-affdb7e3945a");
545

    
546
	private static final UUID uuidBiologyEcology = UUID.fromString("9832e24f-b670-43b4-ac7c-20a7261a1d8c");
547
	private static final UUID uuidKey = UUID.fromString("a677f827-22b9-4205-bb37-11cb48dd9106");
548
	private static final UUID uuidMaterialsExamined = UUID.fromString("7c0c7571-a864-47c1-891d-01f59000dae1");
549
	private static final UUID uuidMaterialsMethods = UUID.fromString("1e87d9c3-0844-4a03-9686-773e2ccb3ab6");
550
	private static final UUID uuidEtymology = UUID.fromString("dd653d48-355c-4aec-a4e7-724f6eb29f8d");
551
	private static final UUID uuidDiagnosis = UUID.fromString("d43d8501-ceab-4caa-9e51-e87138528fac");
552
	private static final UUID uuidProtologue = UUID.fromString("71b356c5-1e3f-4f5d-9b0f-c2cf8ae7779f");
553
	private static final UUID uuidCommonName = UUID.fromString("fc810911-51f0-4a46-ab97-6562fe263ae5");
554
	private static final UUID uuidPhenology = UUID.fromString("a7786d3e-7c58-4141-8416-346d4c80c4a2");
555
	private static final UUID uuidOccurrence = UUID.fromString("5deff505-1a32-4817-9a74-50e6936fd630");
556
	private static final UUID uuidCitation = UUID.fromString("99b2842f-9aa7-42fa-bd5f-7285311e0101");
557
	private static final UUID uuidAdditionalPublication = UUID.fromString("2c355c16-cb04-4858-92bf-8da8d56dea95");
558
	private static final UUID uuidUses = UUID.fromString("e5374d39-b210-47c7-bec1-bee05b5f1cb6");
559
	private static final UUID uuidConservation = UUID.fromString("4518fc20-2492-47de-b345-777d2b83c9cf");
560
	private static final UUID uuidCultivation = UUID.fromString("e28965b2-a367-48c5-b954-8afc8ac2c69b");
561
	private static final UUID uuidIntroduction = UUID.fromString("e75255ca-8ff4-4905-baad-f842927fe1d3");
562
	private static final UUID uuidDiscussion = UUID.fromString("d3c4cbb6-0025-4322-886b-cd0156753a25");
563
	private static final UUID uuidImage = UUID.fromString("84193b2c-327f-4cce-90ef-c8da18fd5bb5");
564
	private static final UUID uuidAnatomy = UUID.fromString("94213b2c-e67a-4d37-25ef-e8d316edfba1");
565
	private static final UUID uuidHostPlant = UUID.fromString("6e9de1d5-05f0-40d5-8786-2fe30d0d894d");
566
	private static final UUID uuidPathogenAgent = UUID.fromString("002d05f2-fd72-49f1-ba4d-196cf09240b5");
567
	private static final UUID uuidIndividualsAssociation = UUID.fromString("e2308f37-ddc5-447d-b483-5e2171dd85fd");
568
	private static final UUID uuidSpecimen = UUID.fromString("8200e050-d5fd-4cac-8a76-4b47afb13809");
569
	private static final UUID uuidObservation = UUID.fromString("f59e747d-0b4f-4bf7-b69a-cbd50bc78595");
570
	private static final UUID uuidStatus = UUID.fromString("86d40635-2a63-4ad6-be75-9faa4a6a57fb");
571
	private static final UUID uuidSystematics = UUID.fromString("bd9aca17-cd0e-4418-a3a1-1a4b80dbc162");
572
	private static final UUID uuidUseRecord = UUID.fromString("8125a59d-b4d5-4485-89ea-67306297b599");
573

    
574
	/**
575
	 * Creates and returns a new feature instance on the basis of a given string
576
	 * list (containing an UUID, an URI, a label and a description) and a given
577
	 * {@link Language language} to be associated with the description. Furthermore
578
	 * the flags concerning the supported subclasses of {@link DescriptionElementBase description elements}
579
	 * are set according to a particular string belonging to the given
580
	 * string list.<BR>
581
	 * This method overrides the readCsvLine method from {@link DefinedTermBase#readCsvLine(List, Language) DefinedTermBase}.
582
	 *
583
	 * @param  csvLine	the string list with elementary information for attributes
584
	 * @param  lang		the language in which the description has been formulated
585
	 * @see     		#NewInstance(String, String, String)
586
	 */
587
	@Override
588
	public Feature readCsvLine(Class<Feature> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) {
589
		Feature newInstance = super.readCsvLine(termClass, csvLine, terms, abbrevAsId);
590
		String text = csvLine.get(4);
591
		if (text != null && text.length() >= 6){
592
			if ("1".equals(text.substring(0, 1))){newInstance.setSupportsTextData(true);};
593
			if ("1".equals(text.substring(1, 2))){newInstance.setSupportsQuantitativeData(true);};
594
			if ("1".equals(text.substring(2, 3))){newInstance.setSupportsDistribution(true);};
595
			if ("1".equals(text.substring(3, 4))){newInstance.setSupportsIndividualAssociation(true);};
596
			if ("1".equals(text.substring(4, 5))){newInstance.setSupportsTaxonInteraction(true);};
597
			if ("1".equals(text.substring(5, 6))){newInstance.setSupportsCommonTaxonName(true);};
598
			// if ("1".equals(text.substring(6, 7))){newInstance.setSupportsCategoricalData(true);};
599
			//there is no abbreviated label for features yet, if there is one in future we need to increment the index for supportXXX form 4 to 5
600
			newInstance.getRepresentation(Language.DEFAULT()).setAbbreviatedLabel(null);
601
		}
602
		return newInstance;
603
	}
604

    
605
//******************************* STATIC METHODS *****************************************
606

    
607
	protected static Feature getTermByUuid(UUID uuid){
608
	    if (termMap == null || termMap.isEmpty()){
609
            return getTermByClassAndUUID(Feature.class, uuid);
610
        } else {
611
			return termMap.get(uuid);
612
        }
613
	}
614

    
615
	/**
616
	 * Returns the "unknown" feature. This feature allows to store values of
617
	 * {@link DescriptionElementBase description elements} even if it is momentarily
618
	 * not known what they mean.
619
	 */
620
	public static final Feature UNKNOWN(){
621
		return getTermByUuid(uuidUnknown);
622
	}
623

    
624
	/**
625
	 * Returns the "description" feature. This feature allows to handle global
626
	 * {@link DescriptionElementBase description elements} for a global {@link DescriptionBase description}.<BR>
627
	 * The "description" feature is the highest level feature.
628
	 */
629
	public static final Feature DESCRIPTION(){
630
		return getTermByUuid(uuidDescription);
631
	}
632

    
633
	/**
634
	 * Returns the "distribution" feature. This feature allows to handle only
635
	 * {@link Distribution distributions}.
636
	 *
637
	 * @see	#isSupportsDistribution()
638
	 */
639
	public static final Feature DISTRIBUTION(){
640
		return getTermByUuid(uuidDistribution);
641
	}
642

    
643
	/**
644
	 * Returns the "discussion" feature. This feature can only be described
645
	 * with {@link TextData text data}.
646
	 *
647
	 * @see	#isSupportsTextData()
648
	 */
649
	public static final Feature DISCUSSION(){
650
		return getTermByUuid(uuidDiscussion);
651
	}
652

    
653
	/**
654
	 * Returns the "ecology" feature. This feature only applies
655
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
656
	 * The "ecology" feature generalizes all other possible features concerning
657
	 * ecological matters.
658
	 */
659
	public static final Feature ECOLOGY(){
660
		return getTermByUuid(uuidEcology);
661
	}
662

    
663
	/**
664
	 * Returns the "habitat" feature. This feature only applies
665
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
666
	 * The "habitat" feature generalizes all other possible features concerning
667
	 * habitat matters.
668
	 */
669
	public static final Feature HABITAT(){
670
		return getTermByUuid(uuidHabitat);
671
	}
672

    
673

    
674
	/**
675
	 * Returns the "habitat & ecology" feature. This feature only applies
676
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
677
	 * The "habitat & ecology" feature generalizes all other possible features concerning
678
	 * habitat and ecology matters.
679
	 */
680
	public static final Feature HABITAT_ECOLOGY(){
681
		return getTermByUuid(uuidHabitatAndEcology);
682
	}
683

    
684
	/**
685
	 * Returns the "biology_ecology" feature. This feature only applies
686
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
687
	 * The "biology_ecology" feature generalizes all possible features concerning
688
	 * biological aspects of ecological matters.
689
	 *
690
	 * @see #ECOLOGY()
691
	 */
692
	public static final Feature BIOLOGY_ECOLOGY(){
693
		return getTermByUuid(uuidBiologyEcology);
694
	}
695

    
696
	/**
697
	 * Returns the "chromosome number" feature. This feature only applies
698
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
699
	 */
700
	public static final Feature CHROMOSOME_NUMBER(){
701
		return getTermByUuid(uuidChromosomeNumber);
702
	}
703

    
704

    
705
	/**
706
	 * Returns the "key" feature. This feature is the "upper" feature generalizing
707
	 * all features being used within an identification key.
708
	 */
709
	public static final Feature KEY(){
710
		return getTermByUuid(uuidKey);
711
	}
712

    
713

    
714
	/**
715
	 * Returns the "materials_examined" feature. This feature can only be described
716
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
717
	 * mentioning which material has been examined in order to accomplish
718
	 * the description. This feature applies only to
719
	 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
720
	 */
721
	public static final Feature MATERIALS_EXAMINED(){
722
		return getTermByUuid(uuidMaterialsExamined);
723
	}
724

    
725
	/**
726
	 * Returns the "materials_methods" feature. This feature can only be described
727
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
728
	 * mentioning which methods have been adopted to analyze the material in
729
	 * order to accomplish the description. This feature applies only to
730
	 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
731
	 */
732
	public static final Feature MATERIALS_METHODS(){
733
		return getTermByUuid(uuidMaterialsMethods);
734
	}
735

    
736
	/**
737
	 * Returns the "etymology" feature. This feature can only be described
738
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
739
	 * giving some information about the history of the taxon name. This feature applies only to
740
	 * {@link TaxonNameDescription taxon name descriptions}.
741
	 */
742
	public static final Feature ETYMOLOGY(){
743
		return getTermByUuid(uuidEtymology);
744
	}
745

    
746
	/**
747
	 * Returns the "diagnosis" feature. This feature can only be described
748
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}.
749
	 * This feature applies only to {@link SpecimenDescription specimen descriptions} or to
750
	 * {@link TaxonDescription taxon descriptions}.
751
	 */
752
	public static final Feature DIAGNOSIS(){
753
		return getTermByUuid(uuidDiagnosis);
754
	}
755

    
756

    
757
	/**
758
	 * Returns the "introduction" feature. This feature can only be described
759
	 * with {@link TextData text data}.
760
	 *
761
	 * @see	#isSupportsTextData()
762
	 */
763
	public static final Feature INTRODUCTION(){
764
		return getTermByUuid(uuidIntroduction);
765
	}
766

    
767
	/**
768
	 * Returns the "protologue" feature. This feature can only be described
769
	 * with {@link TextData text data} reproducing the content of the protologue
770
	 * (or some information about it) of the taxon name. This feature applies only to
771
	 * {@link TaxonNameDescription taxon name descriptions}.
772
	 *
773
	 * @see	#isSupportsTextData()
774
	 */
775
	public static final Feature PROTOLOGUE(){
776
		return getTermByUuid(uuidProtologue);
777
	}
778

    
779
	/**
780
	 * Returns the "common_name" feature. This feature allows to handle only
781
	 * {@link CommonTaxonName common names}.
782
	 *
783
	 * @see	#isSupportsCommonTaxonName()
784
	 */
785
	public static final Feature COMMON_NAME(){
786
		return getTermByUuid(uuidCommonName);
787
	}
788

    
789
	/**
790
	 * Returns the "phenology" feature. This feature can only be described
791
	 * with {@link CategoricalData categorical data} or eventually with {@link TextData text data}
792
	 * containing information time about recurring natural phenomena.
793
	 * This feature only applies to {@link TaxonDescription taxon descriptions}.<BR>
794
	 * The "phenology" feature generalizes all other possible features
795
	 * concerning time information about particular natural phenomena
796
	 * (such as "first flight of butterflies").
797
	 */
798
	public static final Feature PHENOLOGY(){
799
		return getTermByUuid(uuidPhenology);
800
	}
801

    
802
	/**
803
	 * Returns the "occurrence" feature.
804
	 */
805
	public static final Feature OCCURRENCE(){
806
		return getTermByUuid(uuidOccurrence);
807
	}
808

    
809
	/**
810
	 * Returns the "anatomy" feature.
811
	 */
812
	public static final Feature ANATOMY(){
813
		return getTermByUuid(uuidAnatomy);
814
	}
815
	/**
816
	 * Returns the "hostplant" feature.
817
	 */
818
	public static final Feature HOSTPLANT(){
819
		return getTermByUuid(uuidHostPlant);
820
	}
821
	/**
822
	 * Returns the "pathogen agent" feature.
823
	 */
824
	public static final Feature PATHOGEN_AGENT(){
825
		return getTermByUuid(uuidPathogenAgent);
826
	}
827

    
828
	/**
829
	 * Returns the "citation" feature. This feature can only be described
830
	 * with {@link TextData text data}.
831
	 *
832
	 * @see	#isSupportsTextData()
833
	 */
834
	public static final Feature CITATION(){
835
		return getTermByUuid(uuidCitation);
836
	}
837

    
838
	/**
839
	 * Returns the "additional_publication" feature. This feature can only be
840
	 * described with {@link TextData text data} with information about a
841
	 * publication where a {@link TaxonNameBase taxon name} has also been published
842
	 * but which is not the {@link TaxonNameBase#getNomenclaturalReference() nomenclatural reference}.
843
	 * This feature applies only to {@link TaxonNameDescription taxon name descriptions}.
844
	 *
845
	 * @see	#isSupportsTextData()
846
	 */
847
	public static final Feature ADDITIONAL_PUBLICATION(){
848
		return getTermByUuid(uuidAdditionalPublication);
849
	}
850

    
851

    
852
	/**
853
	 * Returns the "uses" feature. This feature only applies
854
	 * to {@link TaxonDescription taxon descriptions}.<BR>
855
	 * The "uses" feature generalizes all other possible features concerning
856
	 * particular uses (for instance "industrial use of seeds").
857
	 */
858
	public static final Feature USES(){
859
		return getTermByUuid(uuidUses);
860
	}
861

    
862
	public static final Feature USERECORD(){
863
		return getTermByUuid(uuidUseRecord);
864
	}
865

    
866

    
867
	/**
868
	 * Returns the "conservation" feature. This feature only applies
869
	 * to {@link SpecimenDescription specimen descriptions} and generalizes
870
	 * methods and conditions for the conservation of {@link Specimen specimens}.<BR>
871
	 */
872
	public static final Feature CONSERVATION(){
873
		return getTermByUuid(uuidConservation);
874
	}
875

    
876

    
877
	/**
878
	 * Returns the "cultivation" feature.
879
	 */
880
	public static final Feature CULTIVATION(){
881
		return getTermByUuid(uuidCultivation);
882
	}
883

    
884

    
885
	/**
886
	 * Returns the "image" feature.
887
	 */
888
	public static final Feature IMAGE(){
889
		return getTermByUuid(uuidImage);
890
	}
891

    
892
	/**
893
	 * Returns the "individuals association" feature.
894
	 */
895
	public static final Feature INDIVIDUALS_ASSOCIATION(){
896
		Feature individuals_association =  getTermByUuid(uuidIndividualsAssociation);
897
		Set<Feature> generalizationOf = new HashSet<Feature>();
898
		generalizationOf.add(SPECIMEN());
899
		generalizationOf.add(OBSERVATION());
900
		individuals_association.setGeneralizationOf(generalizationOf);
901
		return individuals_association;
902

    
903
	}
904

    
905
	public static final Feature SPECIMEN(){
906
		return getTermByUuid(uuidSpecimen);
907
	}
908

    
909
	public static final Feature OBSERVATION(){
910
		return getTermByUuid(uuidObservation);
911
	}
912

    
913
	/**
914
	 * The status of a taxon. Usually the status should be determined within a {@link Distribution distribution}.
915
	 * If this is not possible for some reason (e.g. the area is not well defined) the status feature
916
	 * may be used.
917
	 * @return
918
	 */
919
	public static final Feature STATUS(){
920
		return getTermByUuid(uuidStatus);
921
	}
922

    
923
	public static final Feature SYSTEMATICS(){
924
		return getTermByUuid(uuidSystematics);
925
	}
926

    
927
	/**
928
	 * Returns the "hybrid_parent" feature. This feature can only be used
929
	 * by {@link TaxonInteraction taxon interactions}.<BR>
930
	 * <P>
931
	 * Note: It must be distinguished between hybrid relationships as
932
	 * relevant nomenclatural relationships between {@link BotanicalName plant names}
933
	 * on the one side and the biological relation between two {@link Taxon taxa}
934
	 * as it is here the case on the other one.
935
	 *
936
	 * @see	#isSupportsTaxonInteraction()
937
	 * @see	HybridRelationshipType
938
	 */
939
	public static final Feature HYBRID_PARENT(){
940
		//TODO
941
		logger.warn("HYBRID_PARENT not yet implemented");
942
		return null;
943
	}
944

    
945
	@Override
946
	protected void setDefaultTerms(TermVocabulary<Feature> termVocabulary) {
947
		if (termMap == null){  //needed because there are multiple feature vocabularies
948
			termMap = new HashMap<UUID, Feature>();
949
		}
950
		for (Feature term : termVocabulary.getTerms()){
951
			termMap.put(term.getUuid(), term);
952
		}
953
	}
954

    
955
}
(8-8/36)