Project

General

Profile

Download (33 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.HashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Set;
17
import java.util.UUID;
18

    
19
import javax.persistence.Entity;
20
import javax.persistence.FetchType;
21
import javax.persistence.JoinTable;
22
import javax.persistence.ManyToMany;
23
import javax.persistence.OneToMany;
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
import org.hibernate.search.annotations.Indexed;
36

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

    
47
/**
48
 * The class for individual properties (also designed as character, type or
49
 * category) of observed phenomena able to be described or measured. It also
50
 * covers categories of informations on {@link TaxonNameBase taxon names} not
51
 * taken in account in {@link NomenclaturalCode nomenclature}.<BR>
52
 * Descriptions require features in order to be structured and disaggregated 
53
 * in {@link DescriptionElementBase description elements}.<BR>
54
 * Experts do not use the word feature for the actual description
55
 * but only for the property itself. Therefore naming this class FeatureType
56
 * would have leaded to confusion.
57
 * <P>
58
 * Since features are {@link DefinedTermBase defined terms} they have a hierarchical
59
 * structure that allows to specify ("kind of") or generalize
60
 * ("generalization of") features. "Kind of" / "generalization of" relations
61
 * are bidirectional (a feature F1 is a "Kind of" a feature F2 if and only
62
 * if the feature F2 is a "generalization of" the feature F1. This hierarchical
63
 * structure has nothing in common with {@link FeatureTree feature trees} used for determination.
64
 * <P> 
65
 * A standard set of feature instances will be automatically
66
 * created as the project starts. But this class allows to extend this standard
67
 * set by creating new instances of additional features if needed.<BR>
68
 * <P>
69
 * This class corresponds to DescriptionsSectionType according to the SDD
70
 * schema.
71
 * 
72
 * @author m.doering
73
 * @version 1.0
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(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
97
@Audited
98
public class Feature extends DefinedTermBase<Feature> {
99
	private static final long serialVersionUID = 6754598791831848704L;
100
	private static final Logger logger = Logger.getLogger(Feature.class);
101
	private static Feature IMAGE;
102
	private static Feature CULTIVATION;
103
	private static Feature CONSERVATION;
104
	private static Feature USES;
105
	private static Feature ADDITIONAL_PUBLICATION;
106
	private static Feature CITATION;
107
	private static Feature OCCURRENCE;
108
	private static Feature PHENOLOGY;
109
	private static Feature COMMON_NAME;
110
	private static Feature PROTOLOG;
111
	private static Feature INTRODUCTION;
112
	private static Feature DIAGNOSIS;
113
	private static Feature ETYMOLOGY;
114
	private static Feature MATERIALS_METHODS;
115
	private static Feature MATERIALS_EXAMINED;
116
	private static Feature KEY;
117
	private static Feature BIOLOGY_ECOLOGY;
118
	private static Feature ECOLOGY;
119
	private static Feature DISCUSSION;
120
	private static Feature DISTRIBUTION;
121
	private static Feature DESCRIPTION;
122
	private static Feature UNKNOWN;
123

    
124
	@XmlElement(name = "SupportsTextData")
125
	private boolean supportsTextData;
126
	
127
	@XmlElement(name = "SupportsQuantitativeData")
128
	private boolean supportsQuantitativeData;
129
	
130
	@XmlElement(name = "SupportsDistribution")
131
	private boolean supportsDistribution;
132
	
133
	@XmlElement(name = "SupportsIndividualAssociation")
134
	private boolean supportsIndividualAssociation;
135
	
136
	@XmlElement(name = "SupportsTaxonInteraction")
137
	private boolean supportsTaxonInteraction;
138
	
139
	@XmlElement(name = "SupportsCategoricalData")
140
	private boolean supportsCategoricalData;
141
	
142
	/*
143
	 * FIXME Should this be Many-To-Many or do we expect each Feature to have its own unique modifier enums?
144
	 */
145
	@XmlElementWrapper(name = "RecommendedModifierEnumerations")
146
	@XmlElement(name = "RecommendedModifierEnumeration")
147
	@XmlIDREF
148
	@XmlSchemaType(name = "IDREF")
149
	@OneToMany(fetch = FetchType.LAZY)
150
    @JoinTable(name="DefinedTermBase_RecommendedModifierEnumeration")
151
	private Set<TermVocabulary<Modifier>> recommendedModifierEnumeration = new HashSet<TermVocabulary<Modifier>>();
152
	
153
	@XmlElementWrapper(name = "RecommendedStatisticalMeasures")
154
	@XmlElement(name = "RecommendedStatisticalMeasure")
155
	@XmlIDREF
156
	@XmlSchemaType(name = "IDREF")
157
	@ManyToMany(fetch = FetchType.LAZY)
158
    @JoinTable(name="DefinedTermBase_StatisticalMeasure")
159
	private Set<StatisticalMeasure> recommendedStatisticalMeasures = new HashSet<StatisticalMeasure>();
160
	
161
	/*
162
	 * FIXME Should this be Many-To-Many or do we expect each Feature to have its own unique state enums?
163
	 */
164
	@XmlElementWrapper(name = "SupportedCategoricalEnumerations")
165
	@XmlElement(name = "SupportedCategoricalEnumeration")
166
	@XmlIDREF
167
	@XmlSchemaType(name = "IDREF")
168
	@OneToMany(fetch = FetchType.LAZY)
169
    @JoinTable(name="DefinedTermBase_SupportedCategoricalEnumeration")
170
	private Set<TermVocabulary<State>> supportedCategoricalEnumerations = new HashSet<TermVocabulary<State>>();
171
	@XmlElement(name = "SupportsCommonTaxonName")
172
	private boolean supportsCommonTaxonName;
173
	
174
	@XmlElementWrapper(name = "RecommendedMeasurementUnits")
175
	@XmlElement(name = "RecommendedMeasurementUnit")
176
	@XmlIDREF
177
	@XmlSchemaType(name = "IDREF")
178
	@ManyToMany(fetch = FetchType.LAZY)
179
    @JoinTable(name="DefinedTermBase_MeasurementUnit")
180
	private Set<MeasurementUnit> recommendedMeasurementUnits = new HashSet<MeasurementUnit>();
181
	
182
/* ***************** CONSTRUCTOR AND FACTORY METHODS **********************************/
183
	
184

    
185
	/** 
186
	 * Class constructor: creates a new empty feature instance.
187
	 * 
188
	 * @see #Feature(String, String, String)
189
	 */
190
	public Feature() {
191
		super();
192
	}
193
	
194
	/** 
195
	 * Class constructor: creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
196
	 * a label and a label abbreviation.
197
	 * 
198
	 * @param	term  		 the string (in the default language) describing the
199
	 * 						 new feature to be created 
200
	 * @param	label  		 the string identifying the new feature to be created
201
	 * @param	labelAbbrev  the string identifying (in abbreviated form) the
202
	 * 						 new feature to be created
203
	 * @see 				 #Feature()
204
	 */
205
	protected Feature(String term, String label, String labelAbbrev) {
206
		super(term, label, labelAbbrev);
207
	}
208

    
209
	/** 
210
	 * Creates a new empty feature instance.
211
	 * 
212
	 * @see #NewInstance(String, String, String)
213
	 */
214
	public static Feature NewInstance() {
215
		return new Feature();
216
	}
217
	
218
	/** 
219
	 * Creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
220
	 * a label and a label abbreviation.
221
	 * 
222
	 * @param	term  		 the string (in the default language) describing the
223
	 * 						 new feature to be created 
224
	 * @param	label  		 the string identifying the new feature to be created
225
	 * @param	labelAbbrev  the string identifying (in abbreviated form) the
226
	 * 						 new feature to be created
227
	 * @see 				 #readCsvLine(List, Language)
228
	 * @see 				 #NewInstance()
229
	 */
230
	public static Feature NewInstance(String term, String label, String labelAbbrev){
231
		return new Feature(term, label, labelAbbrev);
232
	}
233

    
234
/* *************************************************************************************/
235
	
236
	/**
237
	 * Returns the boolean value of the flag indicating whether <i>this</i>
238
	 * feature can be described with {@link QuantitativeData quantitative data} (true)
239
	 * or not (false). If this flag is set <i>this</i> feature can only apply to
240
	 * {@link TaxonDescription taxon descriptions} or {@link SpecimenDescription specimen descriptions}.
241
	 *  
242
	 * @return  the boolean value of the supportsQuantitativeData flag
243
	 */
244
	public boolean supportsQuantitativeData() {
245
		return supportsQuantitativeData;
246
	}
247

    
248
	/**
249
	 * @see	#isSupportsQuantitativeData() 
250
	 */
251
	public void setSupportsQuantitativeData(boolean supportsQuantitativeData) {
252
		this.supportsQuantitativeData = supportsQuantitativeData;
253
	}
254

    
255
	/**
256
	 * Returns the boolean value of the flag indicating whether <i>this</i>
257
	 * feature can be described with {@link TextData text data} (true)
258
	 * or not (false).
259
	 *  
260
	 * @return  the boolean value of the supportsTextData flag
261
	 */
262
	public boolean supportsTextData() {
263
		return supportsTextData;
264
	}
265

    
266
	/**
267
	 * @see	#isSupportsTextData() 
268
	 */
269
	public void setSupportsTextData(boolean supportsTextData) {
270
		this.supportsTextData = supportsTextData;
271
	}
272

    
273
	/**
274
	 * Returns the boolean value of the flag indicating whether <i>this</i>
275
	 * feature can be described with {@link Distribution distribution} objects
276
	 * (true) or not (false). This flag is set if and only if <i>this</i> feature
277
	 * is the {@link #DISTRIBUTION() distribution feature}.
278
	 *  
279
	 * @return  the boolean value of the supportsDistribution flag
280
	 */
281
	public boolean supportsDistribution() {
282
		return supportsDistribution;
283
	}
284

    
285
	/**
286
	 * @see	#isSupportsDistribution() 
287
	 */
288
	public void setSupportsDistribution(boolean supportsDistribution) {
289
		this.supportsDistribution = supportsDistribution;
290
	}
291

    
292
	/**
293
	 * Returns the boolean value of the flag indicating whether <i>this</i>
294
	 * feature can be described with {@link IndividualsAssociation individuals associations}
295
	 * (true) or not (false).
296
	 *  
297
	 * @return  the boolean value of the supportsIndividualAssociation flag
298
	 */
299
	public boolean supportsIndividualAssociation() {
300
		return supportsIndividualAssociation;
301
	}
302

    
303
	/**
304
	 * @see	#isSupportsIndividualAssociation() 
305
	 */
306
	public void setSupportsIndividualAssociation(
307
			boolean supportsIndividualAssociation) {
308
		this.supportsIndividualAssociation = supportsIndividualAssociation;
309
	}
310

    
311
	/**
312
	 * Returns the boolean value of the flag indicating whether <i>this</i>
313
	 * feature can be described with {@link TaxonInteraction taxon interactions}
314
	 * (true) or not (false).
315
	 *  
316
	 * @return  the boolean value of the supportsTaxonInteraction flag
317
	 */
318
	public boolean supportsTaxonInteraction() {
319
		return supportsTaxonInteraction;
320
	}
321

    
322
	/**
323
	 * @see	#isSupportsTaxonInteraction() 
324
	 */
325
	public void setSupportsTaxonInteraction(boolean supportsTaxonInteraction) {
326
		this.supportsTaxonInteraction = supportsTaxonInteraction;
327
	}
328

    
329
	/**
330
	 * Returns the boolean value of the flag indicating whether <i>this</i>
331
	 * feature can be described with {@link CommonTaxonName common names}
332
	 * (true) or not (false). This flag is set if and only if <i>this</i> feature
333
	 * is the {@link #COMMON_NAME() common name feature}.
334
	 *  
335
	 * @return  the boolean value of the supportsCommonTaxonName flag
336
	 */
337
	public boolean supportsCommonTaxonName() {
338
		return supportsCommonTaxonName;
339
	}
340

    
341
	/**
342
	 * @see	#isSupportsTaxonInteraction() 
343
	 */
344
	public void setSupportsCommonTaxonName(boolean supportsCommonTaxonName) {
345
		this.supportsCommonTaxonName = supportsCommonTaxonName;
346
	}
347

    
348
	/**
349
	 * Returns the boolean value of the flag indicating whether <i>this</i>
350
	 * feature can be described with {@link CategoricalData categorical data}
351
	 * (true) or not (false).
352
	 *  
353
	 * @return  the boolean value of the supportsCategoricalData flag
354
	 */
355
	public boolean supportsCategoricalData() {
356
		return supportsCategoricalData;
357
	}
358

    
359
	/**
360
	 * @see	#supportsCategoricalData() 
361
	 */
362
	public void setSupportsCategoricalData(boolean supportsCategoricalData) {
363
		this.supportsCategoricalData = supportsCategoricalData;
364
	}
365

    
366
	
367
	/**
368
	 * Returns the set of {@link TermVocabulary term vocabularies} containing the
369
	 * {@link Modifier modifiers} recommended to be used for {@link DescriptionElementBase description elements}
370
	 * with <i>this</i> feature.
371
	 *  
372
	 */
373
	public Set<TermVocabulary<Modifier>> getRecommendedModifierEnumeration() {
374
		return recommendedModifierEnumeration;
375
	}
376

    
377
	/**
378
	 * Adds a {@link TermVocabulary term vocabulary} (with {@link Modifier modifiers}) to the set of
379
	 * {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies} assigned
380
	 * to <i>this</i> feature.
381
	 * 
382
	 * @param recommendedModifierEnumeration	the term vocabulary to be added
383
	 * @see    	   								#getRecommendedModifierEnumeration()
384
	 */
385
	public void addRecommendedModifierEnumeration(
386
			TermVocabulary<Modifier> recommendedModifierEnumeration) {
387
		this.recommendedModifierEnumeration.add(recommendedModifierEnumeration);
388
	}
389
	/** 
390
	 * Removes one element from the set of {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies}
391
	 * assigned to <i>this</i> feature.
392
	 *
393
	 * @param  recommendedModifierEnumeration	the term vocabulary which should be removed
394
	 * @see     								#getRecommendedModifierEnumeration()
395
	 * @see     								#addRecommendedModifierEnumeration(TermVocabulary)
396
	 */
397
	public void removeRecommendedModifierEnumeration(
398
			TermVocabulary<Modifier> recommendedModifierEnumeration) {
399
		this.recommendedModifierEnumeration.remove(recommendedModifierEnumeration);
400
	}
401

    
402
	/**
403
	 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
404
	 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
405
	 */
406
	public Set<StatisticalMeasure> getRecommendedStatisticalMeasures() {
407
		return recommendedStatisticalMeasures;
408
	}
409

    
410
	/**
411
	 * Adds a {@link StatisticalMeasure statistical measure} to the set of
412
	 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
413
	 * to <i>this</i> feature.
414
	 * 
415
	 * @param recommendedStatisticalMeasure	the statistical measure to be added
416
	 * @see    	   							#getRecommendedStatisticalMeasures()
417
	 */
418
	public void addRecommendedStatisticalMeasure(
419
			StatisticalMeasure recommendedStatisticalMeasure) {
420
		this.recommendedStatisticalMeasures.add(recommendedStatisticalMeasure);
421
	}
422
	/** 
423
	 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
424
	 * assigned to <i>this</i> feature.
425
	 *
426
	 * @param  recommendedStatisticalMeasure	the statistical measure which should be removed
427
	 * @see     								#getRecommendedStatisticalMeasures()
428
	 * @see     								#addRecommendedStatisticalMeasure(StatisticalMeasure)
429
	 */
430
	public void removeRecommendedStatisticalMeasure(
431
			StatisticalMeasure recommendedStatisticalMeasure) {
432
		this.recommendedStatisticalMeasures.remove(recommendedStatisticalMeasure);
433
	}
434

    
435
	/**
436
	 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
437
	 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
438
	 */
439
	public Set<MeasurementUnit> getRecommendedMeasurementUnits() {
440
		return recommendedMeasurementUnits;
441
	}
442

    
443
	/**
444
	 * Adds a {@link StatisticalMeasure statistical measure} to the set of
445
	 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
446
	 * to <i>this</i> feature.
447
	 * 
448
	 * @param recommendedStatisticalMeasure	the statistical measure to be added
449
	 * @see    	   							#getRecommendedStatisticalMeasures()
450
	 */
451
	public void addRecommendedMeasurementUnit(
452
			MeasurementUnit recommendedMeasurementUnit) {
453
		this.recommendedMeasurementUnits.add(recommendedMeasurementUnit);
454
	}
455
	/** 
456
	 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
457
	 * assigned to <i>this</i> feature.
458
	 *
459
	 * @param  recommendedStatisticalMeasure	the statistical measure which should be removed
460
	 * @see     								#getRecommendedStatisticalMeasures()
461
	 * @see     								#addRecommendedStatisticalMeasure(StatisticalMeasure)
462
	 */
463
	public void removeRecommendedMeasurementUnit(
464
			MeasurementUnit recommendedMeasurementUnit) {
465
		this.recommendedMeasurementUnits.remove(recommendedMeasurementUnit);
466
	}
467
	
468
	/**
469
	 * Returns the set of {@link TermVocabulary term vocabularies} containing the list of
470
	 * possible {@link State states} to be used in {@link CategoricalData categorical data}
471
	 * with <i>this</i> feature.
472
	 * 
473
	 */
474
	public Set<TermVocabulary<State>> getSupportedCategoricalEnumerations() {
475
		return supportedCategoricalEnumerations;
476
	}
477

    
478
	/**
479
	 * Adds a {@link TermVocabulary term vocabulary} to the set of
480
	 * {@link #getSupportedCategoricalEnumerations() supported state vocabularies} assigned
481
	 * to <i>this</i> feature.
482
	 * 
483
	 * @param supportedCategoricalEnumeration	the term vocabulary which should be removed
484
	 * @see    	   								#getSupportedCategoricalEnumerations()
485
	 */
486
	public void addSupportedCategoricalEnumeration(
487
			TermVocabulary<State> supportedCategoricalEnumeration) {
488
		this.supportedCategoricalEnumerations.add(supportedCategoricalEnumeration);
489
	}
490
	/** 
491
	 * Removes one element from the set of {@link #getSupportedCategoricalEnumerations() supported state vocabularies}
492
	 * assigned to <i>this</i> feature.
493
	 *
494
	 * @param  supportedCategoricalEnumeration	the term vocabulary which should be removed
495
	 * @see     								#getSupportedCategoricalEnumerations()
496
	 * @see     								#addSupportedCategoricalEnumeration(TermVocabulary)
497
	 */
498
	public void removeSupportedCategoricalEnumeration(
499
			TermVocabulary<State> supportedCategoricalEnumeration) {
500
		this.supportedCategoricalEnumerations.remove(supportedCategoricalEnumeration);
501
	}
502
	
503
	@XmlElement(name = "KindOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
504
    @XmlIDREF
505
    @XmlSchemaType(name = "IDREF")
506
	public Feature getKindOf(){
507
		return super.getKindOf();
508
	}
509

    
510
	public void setKindOf(Feature kindOf){
511
		super.setKindOf(kindOf);
512
	}
513
	
514
	@XmlElement(name = "PartOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
515
	@XmlIDREF
516
    @XmlSchemaType(name = "IDREF")
517
	public Feature getPartOf(){
518
		return super.getPartOf();
519
	}
520
	
521
	public void setPartOf(Feature partOf){
522
		super.setPartOf(partOf);
523
	}
524
	
525
	@XmlElementWrapper(name = "Generalizations", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
526
	@XmlElement(name = "GeneralizationOf", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
527
    @XmlIDREF
528
    @XmlSchemaType(name = "IDREF")
529
	public Set<Feature> getGeneralizationOf(){
530
		return super.getGeneralizationOf();
531
	}
532
	
533
	protected void setGeneralizationOf(Set<Feature> value){
534
		super.setGeneralizationOf(value);
535
	}
536
	
537
	@XmlElementWrapper(name = "Includes", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
538
	@XmlElement(name = "Include", namespace = "http://etaxonomy.eu/cdm/model/common/1.0")
539
	@XmlIDREF
540
    @XmlSchemaType(name = "IDREF")
541
	public Set<Feature> getIncludes(){
542
		return super.getIncludes();
543
	}
544
	
545
	protected void setIncludes(Set<Feature> includes) {
546
		super.setIncludes(includes);
547
	}
548
	
549
	private static final UUID uuidUnknown = UUID.fromString("910307f1-dc3c-452c-a6dd-af5ac7cd365c");
550
	private static final UUID uuidDescription = UUID.fromString("9087cdcd-8b08-4082-a1de-34c9ba9fb493");
551
	private static final UUID uuidDistribution = UUID.fromString("9fc9d10c-ba50-49ee-b174-ce83fc3f80c6");
552
	private static final UUID uuidEcology = UUID.fromString("aa923827-d333-4cf5-9a5f-438ae0a4746b");
553
	private static final UUID uuidBiologyEcology = UUID.fromString("9832e24f-b670-43b4-ac7c-20a7261a1d8c");
554
	private static final UUID uuidKey = UUID.fromString("a677f827-22b9-4205-bb37-11cb48dd9106");
555
	private static final UUID uuidMaterialsExamined = UUID.fromString("7c0c7571-a864-47c1-891d-01f59000dae1");
556
	private static final UUID uuidMaterialsMethods = UUID.fromString("1e87d9c3-0844-4a03-9686-773e2ccb3ab6");
557
	private static final UUID uuidEtymology = UUID.fromString("dd653d48-355c-4aec-a4e7-724f6eb29f8d");
558
	private static final UUID uuidDiagnosis = UUID.fromString("d43d8501-ceab-4caa-9e51-e87138528fac");
559
	private static final UUID uuidProtolog = UUID.fromString("7f1fd111-fc52-49f0-9e75-d0097f576b2d");
560
	private static final UUID uuidCommonName = UUID.fromString("fc810911-51f0-4a46-ab97-6562fe263ae5");
561
	private static final UUID uuidPhenology = UUID.fromString("a7786d3e-7c58-4141-8416-346d4c80c4a2");
562
	private static final UUID uuidOccurrence = UUID.fromString("5deff505-1a32-4817-9a74-50e6936fd630");
563
	private static final UUID uuidCitation = UUID.fromString("99b2842f-9aa7-42fa-bd5f-7285311e0101");
564
	private static final UUID uuidAdditionalPublication = UUID.fromString("cb2eab09-6d9d-4e43-8ad2-873f23400930");
565
	private static final UUID uuidUses = UUID.fromString("e5374d39-b210-47c7-bec1-bee05b5f1cb6");
566
	private static final UUID uuidConservation = UUID.fromString("4518fc20-2492-47de-b345-777d2b83c9cf");
567
	private static final UUID uuidCultivation = UUID.fromString("e28965b2-a367-48c5-b954-8afc8ac2c69b");
568
	private static final UUID uuidIntroduction = UUID.fromString("e75255ca-8ff4-4905-baad-f842927fe1d3");
569
	private static final UUID uuidDiscussion = UUID.fromString("d3c4cbb6-0025-4322-886b-cd0156753a25");
570
	private static final UUID uuidImage = UUID.fromString("84193b2c-327f-4cce-90ef-c8da18fd5bb5");
571
	
572
	
573
//	private static final UUID uuidDistribution = UUID.fromString("");
574
//	private static final UUID uuidDistribution = UUID.fromString("");
575
//	private static final UUID uuidDistribution = UUID.fromString("");
576

    
577
//	"86bd920d-f8c5-48b9-af1d-03f63c31de5c",,"Abstract","Abstract"
578
//	"489bf358-b78a-45e2-a691-f9f3f10446ce",,"Synopsis","Synopsis"
579
//	"89d3b005-9876-4923-89d9-60eb75b9583b",,"Multiple","Multiple"
580
//	"555a46bc-211a-476f-a022-c472970d6f8b",,"Acknowledgments","Acknowledgments"
581
	
582
	
583
	/** 
584
	 * Creates and returns a new feature instance on the basis of a given string
585
	 * list (containing an UUID, an URI, a label and a description) and a given
586
	 * {@link Language language} to be associated with the description. Furthermore
587
	 * the flags concerning the supported subclasses of {@link DescriptionElementBase description elements}
588
	 * are set according to a particular string belonging to the given
589
	 * string list.<BR>
590
	 * This method overrides the readCsvLine method from {@link DefinedTermBase#readCsvLine(List, Language) DefinedTermBase}.
591
	 *
592
	 * @param  csvLine	the string list with elementary information for attributes
593
	 * @param  lang		the language in which the description has been formulated
594
	 * @see     		#NewInstance(String, String, String)
595
	 */
596
	@Override
597
	public Feature readCsvLine(Class<Feature> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
598
		Feature newInstance = super.readCsvLine(termClass, csvLine, terms); 
599
		String text = (String)csvLine.get(4);
600
		if (text != null && text.length() >= 6){
601
			if ("1".equals(text.substring(0, 1))){newInstance.setSupportsTextData(true);};
602
			if ("1".equals(text.substring(1, 2))){newInstance.setSupportsQuantitativeData(true);};
603
			if ("1".equals(text.substring(2, 3))){newInstance.setSupportsDistribution(true);};
604
			if ("1".equals(text.substring(3, 4))){newInstance.setSupportsIndividualAssociation(true);};
605
			if ("1".equals(text.substring(4, 5))){newInstance.setSupportsTaxonInteraction(true);};
606
			if ("1".equals(text.substring(5, 6))){newInstance.setSupportsCommonTaxonName(true);};
607
			// if ("1".equals(text.substring(6, 7))){newInstance.setSupportsCategoricalData(true);};
608
		}
609
		return newInstance;
610
	}
611
	
612
	/**
613
	 * Returns the "unknown" feature. This feature allows to store values of
614
	 * {@link DescriptionElementBase description elements} even if it is momentarily
615
	 * not known what they mean.
616
	 */
617
	public static final Feature UNKNOWN(){
618
		return UNKNOWN;
619
	}
620
	
621
	/**
622
	 * Returns the "description" feature. This feature allows to handle global
623
	 * {@link DescriptionElementBase description elements} for a global {@link DescriptionBase description}.<BR>
624
	 * The "description" feature is the highest level feature. 
625
	 */
626
	public static final Feature DESCRIPTION(){
627
		return DESCRIPTION;
628
	}
629

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

    
640
	/**
641
	 * Returns the "discussion" feature. This feature can only be described
642
	 * with {@link TextData text data}.
643
	 * 
644
	 * @see	#isSupportsTextData()
645
	 */
646
	public static final Feature DISCUSSION(){
647
		return DISCUSSION;
648
	}
649
	
650
	/**
651
	 * Returns the "ecology" feature. This feature only applies
652
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
653
	 * The "ecology" feature generalizes all other possible features concerning
654
	 * ecological matters.
655
	 */
656
	public static final Feature ECOLOGY(){
657
		return ECOLOGY;
658
	}	
659
	
660
	/**
661
	 * Returns the "biology_ecology" feature. This feature only applies
662
	 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
663
	 * The "biology_ecology" feature generalizes all possible features concerning
664
	 * biological aspects of ecological matters.
665
	 * 
666
	 * @see #ECOLOGY()
667
	 */
668
	public static final Feature BIOLOGY_ECOLOGY(){
669
		return BIOLOGY_ECOLOGY;
670
	}
671
	
672
	/**
673
	 * Returns the "key" feature. This feature is the "upper" feature generalizing
674
	 * all features being used within an identification key.
675
	 */
676
	public static final Feature KEY(){
677
		return KEY;
678
	}		
679
	
680
	
681
	/**
682
	 * Returns the "materials_examined" feature. This feature can only be described
683
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
684
	 * mentioning which material has been examined in order to accomplish
685
	 * the description. This feature applies only to
686
	 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
687
	 */
688
	public static final Feature MATERIALS_EXAMINED(){
689
		return MATERIALS_EXAMINED;
690
	}
691
	
692
	/**
693
	 * Returns the "materials_methods" feature. This feature can only be described
694
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
695
	 * mentioning which methods have been adopted to analyze the material in
696
	 * order to accomplish the description. This feature applies only to
697
	 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
698
	 */
699
	public static final Feature MATERIALS_METHODS(){
700
		return MATERIALS_METHODS;
701
	}
702
	
703
	/**
704
	 * Returns the "etymology" feature. This feature can only be described
705
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
706
	 * giving some information about the history of the taxon name. This feature applies only to
707
	 * {@link TaxonNameDescription taxon name descriptions}.
708
	 */
709
	public static final Feature ETYMOLOGY(){
710
		return ETYMOLOGY;
711
	}
712
		
713
	/**
714
	 * Returns the "diagnosis" feature. This feature can only be described
715
	 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}.
716
	 * This feature applies only to {@link SpecimenDescription specimen descriptions} or to
717
	 * {@link TaxonDescription taxon descriptions}.
718
	 */
719
	public static final Feature DIAGNOSIS(){
720
		return DIAGNOSIS;
721
	}
722

    
723
	
724
	/**
725
	 * Returns the "introduction" feature. This feature can only be described
726
	 * with {@link TextData text data}.
727
	 * 
728
	 * @see	#isSupportsTextData()
729
	 */
730
	public static final Feature INTRODUCTION(){
731
		return INTRODUCTION;
732
	}
733

    
734
	/**
735
	 * Returns the "protologue" feature. This feature can only be described
736
	 * with {@link TextData text data} reproducing the content of the protologue 
737
	 * (or some information about it) of the taxon name. This feature applies only to
738
	 * {@link TaxonNameDescription taxon name descriptions}.
739
	 * 
740
	 * @see	#isSupportsTextData()
741
	 */
742
	public static final Feature PROTOLOG(){
743
		return PROTOLOG;
744
	}
745
	/**
746
	 * Returns the "common_name" feature. This feature allows to handle only
747
	 * {@link CommonTaxonName common names}.
748
	 * 
749
	 * @see	#isSupportsCommonTaxonName()
750
	 */
751
	public static final Feature COMMON_NAME(){
752
		return COMMON_NAME;
753
	}
754
	
755
	/**
756
	 * Returns the "phenology" feature. This feature can only be described
757
	 * with {@link CategoricalData categorical data} or eventually with {@link TextData text data}
758
	 * containing information time about recurring natural phenomena.
759
	 * This feature only applies to {@link TaxonDescription taxon descriptions}.<BR>
760
	 * The "phenology" feature generalizes all other possible features
761
	 * concerning time information about particular natural phenomena
762
	 * (such as "first flight of butterflies").
763
	 */
764
	public static final Feature PHENOLOGY(){
765
		return PHENOLOGY;
766
	}
767

    
768
	/**
769
	 * Returns the "occurrence" feature.
770
	 */
771
	public static final Feature OCCURRENCE(){
772
		return OCCURRENCE;
773
	}
774
	
775
	/**
776
	 * Returns the "citation" feature. This feature can only be described
777
	 * with {@link TextData text data}.
778
	 * 
779
	 * @see	#isSupportsTextData()
780
	 */
781
	public static final Feature CITATION(){
782
		return CITATION;
783
	}
784
	
785
	/**
786
	 * Returns the "additional_publication" feature. This feature can only be
787
	 * described with {@link TextData text data} with information about a
788
	 * publication where a {@link TaxonNameBase taxon name} has also been published
789
	 * but which is not the {@link TaxonNameBase#getNomenclaturalReference() nomenclatural reference}.
790
	 * This feature applies only to {@link TaxonNameDescription taxon name descriptions}.
791
	 * 
792
	 * @see	#isSupportsTextData()
793
	 */
794
	public static final Feature ADDITIONAL_PUBLICATION(){
795
		return ADDITIONAL_PUBLICATION;
796
	}
797
	
798
	
799
	/**
800
	 * Returns the "uses" feature. This feature only applies
801
	 * to {@link TaxonDescription taxon descriptions}.<BR>
802
	 * The "uses" feature generalizes all other possible features concerning
803
	 * particular uses (for instance "industrial use of seeds").
804
	 */
805
	public static final Feature USES(){
806
		return USES;
807
	}
808
	
809
	
810
	/**
811
	 * Returns the "conservation" feature. This feature only applies
812
	 * to {@link SpecimenDescription specimen descriptions} and generalizes
813
	 * methods and conditions for the conservation of {@link Specimen specimens}.<BR>
814
	 */
815
	public static final Feature CONSERVATION(){
816
		return CONSERVATION;
817
	}
818
	
819
	
820
	/**
821
	 * Returns the "cultivation" feature.
822
	 */
823
	public static final Feature CULTIVATION(){
824
		return CULTIVATION;
825
	}
826
	
827
	
828
	/**
829
	 * Returns the "cultivation" feature.
830
	 */
831
	public static final Feature IMAGE(){
832
		return IMAGE;
833
	}
834
	
835
	/**
836
	 * Returns the "hybrid_parent" feature. This feature can only be used
837
	 * by {@link TaxonInteraction taxon interactions}.<BR>
838
	 * <P>
839
	 * Note: It must be distinguished between hybrid relationships as
840
	 * relevant nomenclatural relationships between {@link BotanicalName plant names}
841
	 * on the one side and the biological relation between two {@link Taxon taxa}
842
	 * as it is here the case on the other one. 
843
	 * 
844
	 * @see	#isSupportsTaxonInteraction()
845
	 * @see	HybridRelationshipType
846
	 */
847
	public static final Feature HYBRID_PARENT(){
848
		//TODO
849
		logger.warn("HYBRID_PARENT not yet implemented");
850
		return null;
851
	}
852

    
853
	@Override
854
	protected void setDefaultTerms(TermVocabulary<Feature> termVocabulary) {
855
		Feature.ADDITIONAL_PUBLICATION = termVocabulary.findTermByUuid(Feature.uuidAdditionalPublication);
856
		Feature.BIOLOGY_ECOLOGY = termVocabulary.findTermByUuid(Feature.uuidBiologyEcology);
857
		Feature.CITATION = termVocabulary.findTermByUuid(Feature.uuidCitation);
858
		Feature.COMMON_NAME = termVocabulary.findTermByUuid(Feature.uuidCommonName);
859
		Feature.CONSERVATION = termVocabulary.findTermByUuid(Feature.uuidConservation);
860
		Feature.CULTIVATION = termVocabulary.findTermByUuid(Feature.uuidCultivation);
861
		Feature.DESCRIPTION = termVocabulary.findTermByUuid(Feature.uuidDescription);
862
		Feature.DIAGNOSIS = termVocabulary.findTermByUuid(Feature.uuidDiagnosis);
863
		Feature.DISCUSSION = termVocabulary.findTermByUuid(Feature.uuidDiscussion);
864
		Feature.DISTRIBUTION = termVocabulary.findTermByUuid(Feature.uuidDistribution);
865
		Feature.ECOLOGY = termVocabulary.findTermByUuid(Feature.uuidEcology);
866
		Feature.ETYMOLOGY = termVocabulary.findTermByUuid(Feature.uuidEtymology);
867
		Feature.IMAGE = termVocabulary.findTermByUuid(Feature.uuidImage);
868
		Feature.INTRODUCTION = termVocabulary.findTermByUuid(Feature.uuidIntroduction);
869
		Feature.KEY = termVocabulary.findTermByUuid(Feature.uuidKey);
870
		Feature.MATERIALS_EXAMINED = termVocabulary.findTermByUuid(Feature.uuidMaterialsExamined);
871
		Feature.MATERIALS_METHODS = termVocabulary.findTermByUuid(Feature.uuidMaterialsMethods);
872
		Feature.OCCURRENCE = termVocabulary.findTermByUuid(Feature.uuidOccurrence);
873
		Feature.PHENOLOGY = termVocabulary.findTermByUuid(Feature.uuidPhenology);
874
		Feature.PROTOLOG = termVocabulary.findTermByUuid(Feature.uuidProtolog);
875
		Feature.UNKNOWN = termVocabulary.findTermByUuid(Feature.uuidUnknown);
876
		Feature.USES = termVocabulary.findTermByUuid(Feature.uuidUses);
877
	}
878

    
879

    
880
}
(7-7/31)