2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.model
.description
;
13 import java
.util
.HashMap
;
14 import java
.util
.HashSet
;
15 import java
.util
.List
;
18 import java
.util
.UUID
;
20 import javax
.persistence
.Entity
;
21 import javax
.persistence
.FetchType
;
22 import javax
.persistence
.JoinColumn
;
23 import javax
.persistence
.JoinTable
;
24 import javax
.persistence
.ManyToMany
;
25 import javax
.persistence
.OneToMany
;
26 import javax
.persistence
.Transient
;
27 import javax
.xml
.bind
.annotation
.XmlAccessType
;
28 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
29 import javax
.xml
.bind
.annotation
.XmlElement
;
30 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
31 import javax
.xml
.bind
.annotation
.XmlIDREF
;
32 import javax
.xml
.bind
.annotation
.XmlRootElement
;
33 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
34 import javax
.xml
.bind
.annotation
.XmlType
;
36 import org
.apache
.log4j
.Logger
;
37 import org
.hibernate
.annotations
.Cascade
;
38 import org
.hibernate
.annotations
.CascadeType
;
39 import org
.hibernate
.envers
.Audited
;
41 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTerm
;
42 import eu
.etaxonomy
.cdm
.model
.common
.DefinedTermBase
;
43 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
44 import eu
.etaxonomy
.cdm
.model
.common
.Representation
;
45 import eu
.etaxonomy
.cdm
.model
.common
.TermType
;
46 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
47 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationshipType
;
48 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
49 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
54 * The class for individual properties (also designed as character, type or
55 * category) of observed phenomena able to be described or measured. It also
56 * covers categories of informations on {@link TaxonName taxon names} not
57 * taken in account in {@link NomenclaturalCode nomenclature}.<BR>
58 * Descriptions require features in order to be structured and disaggregated
59 * in {@link DescriptionElementBase description elements}.<BR>
60 * Experts do not use the word feature for the actual description
61 * but only for the property itself. Therefore naming this class FeatureType
62 * would have leaded to confusion.
64 * Since features are {@link DefinedTermBase defined terms} they have a hierarchical
65 * structure that allows to specify ("kind of") or generalize
66 * ("generalization of") features. "Kind of" / "generalization of" relations
67 * are bidirectional (a feature F1 is a "Kind of" a feature F2 if and only
68 * if the feature F2 is a "generalization of" the feature F1. This hierarchical
69 * structure has nothing in common with {@link FeatureTree feature trees} used for determination.
71 * A standard set of feature instances will be automatically
72 * created as the project starts. But this class allows to extend this standard
73 * set by creating new instances of additional features if needed.<BR>
75 * This class corresponds to DescriptionsSectionType according to the SDD
79 * @since 08-Nov-2007 13:06:24
81 @XmlAccessorType(XmlAccessType
.PROPERTY
)
82 @XmlType(name
="Feature", factoryMethod
="NewInstance", propOrder
= {
88 "supportsQuantitativeData",
89 "supportsDistribution",
90 "supportsIndividualAssociation",
91 "supportsTaxonInteraction",
92 "supportsCommonTaxonName",
93 "supportsCategoricalData",
94 "recommendedModifierEnumeration",
95 "recommendedStatisticalMeasures",
96 "supportedCategoricalEnumerations",
97 "recommendedMeasurementUnits",
98 "inverseRepresentations"
100 @XmlRootElement(name
= "Feature")
102 //@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
103 //@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
105 public class Feature
extends DefinedTermBase
<Feature
> {
106 private static final long serialVersionUID
= 6754598791831848704L;
107 private static final Logger logger
= Logger
.getLogger(Feature
.class);
109 protected static Map
<UUID
, Feature
> termMap
= null;
111 private boolean supportsTextData
= true; //by default text data should be always supported
113 private boolean supportsQuantitativeData
;
115 private boolean supportsDistribution
;
117 private boolean supportsIndividualAssociation
;
119 private boolean supportsTaxonInteraction
;
121 private boolean supportsCategoricalData
;
123 private boolean supportsCommonTaxonName
;
125 /* for M:M see #4843 */
126 @ManyToMany(fetch
= FetchType
.LAZY
)
127 @JoinTable(name
="DefinedTermBase_RecommendedModifierEnumeration")
128 private final Set
<TermVocabulary
<DefinedTerm
>> recommendedModifierEnumeration
= new HashSet
<>();
130 @ManyToMany(fetch
= FetchType
.LAZY
)
131 @JoinTable(name
="DefinedTermBase_StatisticalMeasure")
132 private final Set
<StatisticalMeasure
> recommendedStatisticalMeasures
= new HashSet
<>();
134 /* for M:M see #4843 */
135 @ManyToMany(fetch
= FetchType
.LAZY
)
136 @JoinTable(name
="DefinedTermBase_SupportedCategoricalEnumeration")
137 private final Set
<TermVocabulary
<State
>> supportedCategoricalEnumerations
= new HashSet
<>();
140 @ManyToMany(fetch
= FetchType
.LAZY
)
141 @JoinTable(name
="DefinedTermBase_MeasurementUnit")
142 private final Set
<MeasurementUnit
> recommendedMeasurementUnits
= new HashSet
<>();
145 //copy from RelationshipTermBase
146 @XmlElementWrapper(name
= "InverseRepresentations")
147 @XmlElement(name
= "Representation")
148 @OneToMany(fetch
= FetchType
.LAZY
, orphanRemoval
=true)
149 @JoinTable(name
="DefinedTermBase_InverseRepresentation", //see also RelationshipTermBase.inverseRepresentations
150 joinColumns
=@JoinColumn(name
="DefinedTermBase_id")
151 // inverseJoinColumns
153 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
154 // @IndexedEmbedded(depth = 2)
155 private Set
<Representation
> inverseRepresentations
= new HashSet
<>();
157 private static final UUID uuidUnknown
= UUID
.fromString("910307f1-dc3c-452c-a6dd-af5ac7cd365c");
158 public static final UUID uuidDescription
= UUID
.fromString("9087cdcd-8b08-4082-a1de-34c9ba9fb493");
159 private static final UUID uuidDistribution
= UUID
.fromString("9fc9d10c-ba50-49ee-b174-ce83fc3f80c6");
160 private static final UUID uuidDistributionGeneral
= UUID
.fromString("fd8c64f0-6ea5-44b0-9f70-e95833d6076e");
161 private static final UUID uuidEcology
= UUID
.fromString("aa923827-d333-4cf5-9a5f-438ae0a4746b");
162 private static final UUID uuidHabitat
= UUID
.fromString("fb16929f-bc9c-456f-9d40-dec987b36438");
163 private static final UUID uuidHabitatAndEcology
= UUID
.fromString("9fdc4663-4d56-47d0-90b5-c0bf251bafbb");
164 private static final UUID uuidChromosomeNumber
= UUID
.fromString("6f677e98-d8d5-4bc5-80bf-affdb7e3945a");
166 private static final UUID uuidBiologyEcology
= UUID
.fromString("9832e24f-b670-43b4-ac7c-20a7261a1d8c");
167 private static final UUID uuidKey
= UUID
.fromString("a677f827-22b9-4205-bb37-11cb48dd9106");
168 private static final UUID uuidMaterialsExamined
= UUID
.fromString("7c0c7571-a864-47c1-891d-01f59000dae1");
169 private static final UUID uuidMaterialsMethods
= UUID
.fromString("1e87d9c3-0844-4a03-9686-773e2ccb3ab6");
170 private static final UUID uuidEtymology
= UUID
.fromString("dd653d48-355c-4aec-a4e7-724f6eb29f8d");
171 private static final UUID uuidDiagnosis
= UUID
.fromString("d43d8501-ceab-4caa-9e51-e87138528fac");
172 private static final UUID uuidProtologue
= UUID
.fromString("71b356c5-1e3f-4f5d-9b0f-c2cf8ae7779f");
173 public static final UUID uuidCommonName
= UUID
.fromString("fc810911-51f0-4a46-ab97-6562fe263ae5");
174 private static final UUID uuidPhenology
= UUID
.fromString("a7786d3e-7c58-4141-8416-346d4c80c4a2");
175 private static final UUID uuidOccurrence
= UUID
.fromString("5deff505-1a32-4817-9a74-50e6936fd630");
176 private static final UUID uuidCitation
= UUID
.fromString("99b2842f-9aa7-42fa-bd5f-7285311e0101");
177 private static final UUID uuidAdditionalPublication
= UUID
.fromString("2c355c16-cb04-4858-92bf-8da8d56dea95");
178 public static final UUID uuidUses
= UUID
.fromString("e5374d39-b210-47c7-bec1-bee05b5f1cb6");
179 private static final UUID uuidConservation
= UUID
.fromString("4518fc20-2492-47de-b345-777d2b83c9cf");
180 private static final UUID uuidCultivation
= UUID
.fromString("e28965b2-a367-48c5-b954-8afc8ac2c69b");
181 private static final UUID uuidIntroduction
= UUID
.fromString("e75255ca-8ff4-4905-baad-f842927fe1d3");
182 private static final UUID uuidDiscussion
= UUID
.fromString("d3c4cbb6-0025-4322-886b-cd0156753a25");
183 public static final UUID uuidImage
= UUID
.fromString("84193b2c-327f-4cce-90ef-c8da18fd5bb5");
184 private static final UUID uuidAnatomy
= UUID
.fromString("94213b2c-e67a-4d37-25ef-e8d316edfba1");
185 private static final UUID uuidHostPlant
= UUID
.fromString("6e9de1d5-05f0-40d5-8786-2fe30d0d894d");
186 private static final UUID uuidPathogenAgent
= UUID
.fromString("002d05f2-fd72-49f1-ba4d-196cf09240b5");
187 private static final UUID uuidIndividualsAssociation
= UUID
.fromString("e2308f37-ddc5-447d-b483-5e2171dd85fd");
188 public static final UUID uuidSpecimen
= UUID
.fromString("8200e050-d5fd-4cac-8a76-4b47afb13809");
189 private static final UUID uuidObservation
= UUID
.fromString("f59e747d-0b4f-4bf7-b69a-cbd50bc78595");
190 private static final UUID uuidStatus
= UUID
.fromString("86d40635-2a63-4ad6-be75-9faa4a6a57fb");
191 private static final UUID uuidSystematics
= UUID
.fromString("bd9aca17-cd0e-4418-a3a1-1a4b80dbc162");
192 private static final UUID uuidUseRecord
= UUID
.fromString("8125a59d-b4d5-4485-89ea-67306297b599");
193 private static final UUID uuidNotes
= UUID
.fromString("b5780b45-6439-4f3c-9818-d89d26d36eb2");
194 public static final UUID uuidLifeform
= UUID
.fromString("db9228d3-8bbf-4460-abfe-0b1326c82f8e");
197 /* ***************** CONSTRUCTOR AND FACTORY METHODS **********************************/
201 * Creates a new empty feature instance.
203 * @see #NewInstance(String, String, String)
205 public static Feature
NewInstance() {
206 return new Feature();
210 * Creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
211 * a label and a label abbreviation.
213 * @param description the string (in the default language) describing the
214 * new feature to be created
215 * @param label the string identifying the new feature to be created
216 * @param labelAbbrev the string identifying (in abbreviated form) the
217 * new feature to be created
218 * @see #readCsvLine(List, Language)
219 * @see #NewInstance()
221 public static Feature
NewInstance(String description
, String label
, String labelAbbrev
){
222 return new Feature(description
, label
, labelAbbrev
);
226 //for hibernate use only
228 protected Feature() {
229 super(TermType
.Feature
);
233 * Class constructor: creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
234 * a label and a label abbreviation.
236 * @param term the string (in the default language) describing the
237 * new feature to be created
238 * @param label the string identifying the new feature to be created
239 * @param labelAbbrev the string identifying (in abbreviated form) the
240 * new feature to be created
243 protected Feature(String term
, String label
, String labelAbbrev
) {
244 super(TermType
.Feature
, term
, label
, labelAbbrev
);
247 /* *************************************************************************************/
250 public void resetTerms(){
256 * Returns the boolean value of the flag indicating whether <i>this</i>
257 * feature can be described with {@link QuantitativeData quantitative data} (true)
258 * or not (false). If this flag is set <i>this</i> feature can only apply to
259 * {@link TaxonDescription taxon descriptions} or {@link SpecimenDescription specimen descriptions}.
261 * @return the boolean value of the supportsQuantitativeData flag
263 @XmlElement(name
= "SupportsQuantitativeData")
264 public boolean isSupportsQuantitativeData() {
265 return supportsQuantitativeData
;
269 * @see #isSupportsQuantitativeData()
271 public void setSupportsQuantitativeData(boolean supportsQuantitativeData
) {
272 this.supportsQuantitativeData
= supportsQuantitativeData
;
276 * Returns the boolean value of the flag indicating whether <i>this</i>
277 * feature can be described with {@link TextData text data} (true)
280 * @return the boolean value of the supportsTextData flag
282 @XmlElement(name
= "SupportsTextData")
283 public boolean isSupportsTextData() {
284 return supportsTextData
;
288 * @see #isSupportsTextData()
290 public void setSupportsTextData(boolean supportsTextData
) {
291 this.supportsTextData
= supportsTextData
;
295 * Returns the boolean value of the flag indicating whether <i>this</i>
296 * feature can be described with {@link Distribution distribution} objects
297 * (true) or not (false). This flag is set if and only if <i>this</i> feature
298 * is the {@link #DISTRIBUTION() distribution feature}.
300 * @return the boolean value of the supportsDistribution flag
302 @XmlElement(name
= "SupportsDistribution")
303 public boolean isSupportsDistribution() {
304 return supportsDistribution
;
308 * @see #isSupportsDistribution()
310 public void setSupportsDistribution(boolean supportsDistribution
) {
311 this.supportsDistribution
= supportsDistribution
;
315 * Returns the boolean value of the flag indicating whether <i>this</i>
316 * feature can be described with {@link IndividualsAssociation individuals associations}
317 * (true) or not (false).
319 * @return the boolean value of the supportsIndividualAssociation flag
321 @XmlElement(name
= "SupportsIndividualAssociation")
322 public boolean isSupportsIndividualAssociation() {
323 return supportsIndividualAssociation
;
327 * @see #isSupportsIndividualAssociation()
329 public void setSupportsIndividualAssociation(
330 boolean supportsIndividualAssociation
) {
331 this.supportsIndividualAssociation
= supportsIndividualAssociation
;
335 * Returns the boolean value of the flag indicating whether <i>this</i>
336 * feature can be described with {@link TaxonInteraction taxon interactions}
337 * (true) or not (false).
339 * @return the boolean value of the supportsTaxonInteraction flag
341 @XmlElement(name
= "SupportsTaxonInteraction")
342 public boolean isSupportsTaxonInteraction() {
343 return supportsTaxonInteraction
;
347 * @see #isSupportsTaxonInteraction()
349 public void setSupportsTaxonInteraction(boolean supportsTaxonInteraction
) {
350 this.supportsTaxonInteraction
= supportsTaxonInteraction
;
354 * Returns the boolean value of the flag indicating whether <i>this</i>
355 * feature can be described with {@link CommonTaxonName common names}
356 * (true) or not (false). This flag is set if and only if <i>this</i> feature
357 * is the {@link #COMMON_NAME() common name feature}.
359 * @return the boolean value of the supportsCommonTaxonName flag
361 @XmlElement(name
= "SupportsCommonTaxonName")
362 public boolean isSupportsCommonTaxonName() {
363 return supportsCommonTaxonName
;
367 * @see #isSupportsTaxonInteraction()
369 public void setSupportsCommonTaxonName(boolean supportsCommonTaxonName
) {
370 this.supportsCommonTaxonName
= supportsCommonTaxonName
;
374 * Returns the boolean value of the flag indicating whether <i>this</i>
375 * feature can be described with {@link CategoricalData categorical data}
376 * (true) or not (false).
378 * @return the boolean value of the supportsCategoricalData flag
380 @XmlElement(name
= "SupportsCategoricalData")
381 public boolean isSupportsCategoricalData() {
382 return supportsCategoricalData
;
386 * @see #supportsCategoricalData()
388 public void setSupportsCategoricalData(boolean supportsCategoricalData
) {
389 this.supportsCategoricalData
= supportsCategoricalData
;
394 * Returns the set of {@link TermVocabulary term vocabularies} containing the
395 * {@link Modifier modifiers} recommended to be used for {@link DescriptionElementBase description elements}
396 * with <i>this</i> feature.
399 @XmlElementWrapper(name
= "RecommendedModifierEnumerations")
400 @XmlElement(name
= "RecommendedModifierEnumeration")
402 @XmlSchemaType(name
= "IDREF")
403 public Set
<TermVocabulary
<DefinedTerm
>> getRecommendedModifierEnumeration() {
404 return recommendedModifierEnumeration
;
408 * Adds a {@link TermVocabulary term vocabulary} (with {@link Modifier modifiers}) to the set of
409 * {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies} assigned
410 * to <i>this</i> feature.
412 * @param recommendedModifierEnumeration the term vocabulary to be added
413 * @see #getRecommendedModifierEnumeration()
415 public void addRecommendedModifierEnumeration(
416 TermVocabulary
<DefinedTerm
> recommendedModifierEnumeration
) {
417 this.recommendedModifierEnumeration
.add(recommendedModifierEnumeration
);
420 * Removes one element from the set of {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies}
421 * assigned to <i>this</i> feature.
423 * @param recommendedModifierEnumeration the term vocabulary which should be removed
424 * @see #getRecommendedModifierEnumeration()
425 * @see #addRecommendedModifierEnumeration(TermVocabulary)
427 public void removeRecommendedModifierEnumeration(
428 TermVocabulary
<DefinedTerm
> recommendedModifierEnumeration
) {
429 this.recommendedModifierEnumeration
.remove(recommendedModifierEnumeration
);
433 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
434 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
436 @XmlElementWrapper(name
= "RecommendedStatisticalMeasures")
437 @XmlElement(name
= "RecommendedStatisticalMeasure")
439 @XmlSchemaType(name
= "IDREF")
440 public Set
<StatisticalMeasure
> getRecommendedStatisticalMeasures() {
441 return recommendedStatisticalMeasures
;
445 * Adds a {@link StatisticalMeasure statistical measure} to the set of
446 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
447 * to <i>this</i> feature.
449 * @param recommendedStatisticalMeasure the statistical measure to be added
450 * @see #getRecommendedStatisticalMeasures()
452 public void addRecommendedStatisticalMeasure(
453 StatisticalMeasure recommendedStatisticalMeasure
) {
454 this.recommendedStatisticalMeasures
.add(recommendedStatisticalMeasure
);
457 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
458 * assigned to <i>this</i> feature.
460 * @param recommendedStatisticalMeasure the statistical measure which should be removed
461 * @see #getRecommendedStatisticalMeasures()
462 * @see #addRecommendedStatisticalMeasure(StatisticalMeasure)
464 public void removeRecommendedStatisticalMeasure(
465 StatisticalMeasure recommendedStatisticalMeasure
) {
466 this.recommendedStatisticalMeasures
.remove(recommendedStatisticalMeasure
);
470 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
471 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
473 @XmlElementWrapper(name
= "RecommendedMeasurementUnits")
474 @XmlElement(name
= "RecommendedMeasurementUnit")
476 @XmlSchemaType(name
= "IDREF")
477 public Set
<MeasurementUnit
> getRecommendedMeasurementUnits() {
478 return recommendedMeasurementUnits
;
482 * Adds a {@link StatisticalMeasure statistical measure} to the set of
483 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
484 * to <i>this</i> feature.
486 * @param recommendedStatisticalMeasure the statistical measure to be added
487 * @see #getRecommendedStatisticalMeasures()
489 public void addRecommendedMeasurementUnit(
490 MeasurementUnit recommendedMeasurementUnit
) {
491 this.recommendedMeasurementUnits
.add(recommendedMeasurementUnit
);
494 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
495 * assigned to <i>this</i> feature.
497 * @param recommendedStatisticalMeasure the statistical measure which should be removed
498 * @see #getRecommendedStatisticalMeasures()
499 * @see #addRecommendedStatisticalMeasure(StatisticalMeasure)
501 public void removeRecommendedMeasurementUnit(
502 MeasurementUnit recommendedMeasurementUnit
) {
503 this.recommendedMeasurementUnits
.remove(recommendedMeasurementUnit
);
507 * Returns the set of {@link TermVocabulary term vocabularies} containing the list of
508 * possible {@link State states} to be used in {@link CategoricalData categorical data}
509 * with <i>this</i> feature.
512 @XmlElementWrapper(name
= "SupportedCategoricalEnumerations")
513 @XmlElement(name
= "SupportedCategoricalEnumeration")
515 @XmlSchemaType(name
= "IDREF")
516 public Set
<TermVocabulary
<State
>> getSupportedCategoricalEnumerations() {
517 return supportedCategoricalEnumerations
;
521 * Adds a {@link TermVocabulary term vocabulary} to the set of
522 * {@link #getSupportedCategoricalEnumerations() supported state vocabularies} assigned
523 * to <i>this</i> feature.
525 * @param supportedCategoricalEnumeration the term vocabulary which should be removed
526 * @see #getSupportedCategoricalEnumerations()
528 public void addSupportedCategoricalEnumeration(
529 TermVocabulary
<State
> supportedCategoricalEnumeration
) {
530 this.supportedCategoricalEnumerations
.add(supportedCategoricalEnumeration
);
533 * Removes one element from the set of {@link #getSupportedCategoricalEnumerations() supported state vocabularies}
534 * assigned to <i>this</i> feature.
536 * @param supportedCategoricalEnumeration the term vocabulary which should be removed
537 * @see #getSupportedCategoricalEnumerations()
538 * @see #addSupportedCategoricalEnumeration(TermVocabulary)
540 public void removeSupportedCategoricalEnumeration(
541 TermVocabulary
<State
> supportedCategoricalEnumeration
) {
542 this.supportedCategoricalEnumerations
.remove(supportedCategoricalEnumeration
);
545 @XmlElement(name
= "KindOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
547 @XmlSchemaType(name
= "IDREF")
549 public Feature
getKindOf(){
550 return super.getKindOf();
554 public void setKindOf(Feature kindOf
){
555 super.setKindOf(kindOf
);
559 @XmlElement(name
= "PartOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
561 @XmlSchemaType(name
= "IDREF")
562 public Feature
getPartOf(){
563 return super.getPartOf();
567 public void setPartOf(Feature partOf
){
568 super.setPartOf(partOf
);
572 @XmlElementWrapper(name
= "Generalizations", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
573 @XmlElement(name
= "GeneralizationOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
575 @XmlSchemaType(name
= "IDREF")
576 public Set
<Feature
> getGeneralizationOf(){
577 return super.getGeneralizationOf();
581 protected void setGeneralizationOf(Set
<Feature
> value
){
582 super.setGeneralizationOf(value
);
586 @XmlElementWrapper(name
= "Includes", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
587 @XmlElement(name
= "Include", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
589 @XmlSchemaType(name
= "IDREF")
590 public Set
<Feature
> getIncludes(){
591 return super.getIncludes();
595 protected void setIncludes(Set
<Feature
> includes
) {
596 super.setIncludes(includes
);
599 // ***************** Invers Label *****************************************/
601 public Set
<Representation
> getInverseRepresentations() {
602 return inverseRepresentations
;
604 public void addInverseRepresentation(Representation inverseRepresentation
) {
605 this.inverseRepresentations
.add(inverseRepresentation
);
607 public void removeInverseRepresentation(Representation inverseRepresentation
) {
608 this.inverseRepresentations
.remove(inverseRepresentation
);
611 * Inverse representation convenience methods similar to TermBase.xxx
612 * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
615 public String
getInverseLabel() {
616 if(getInverseLabel(Language
.DEFAULT()) != null){
617 return this.getInverseRepresentation(Language
.DEFAULT()).getLabel();
619 for (Representation r
: inverseRepresentations
){
623 return super.getUuid().toString();
625 public String
getInverseLabel(Language lang
) {
626 Representation r
= this.getInverseRepresentation(lang
);
633 public Representation
getInverseRepresentation(Language lang
) {
634 Representation result
= null;
635 for (Representation repr
: this.getInverseRepresentations()){
636 if (lang
.equals(repr
.getLanguage())){
642 // ****************** END INVERS REPRESENTATION **************************/
645 * Creates and returns a new feature instance on the basis of a given string
646 * list (containing an UUID, an URI, a label and a description) and a given
647 * {@link Language language} to be associated with the description. Furthermore
648 * the flags concerning the supported subclasses of {@link DescriptionElementBase description elements}
649 * are set according to a particular string belonging to the given
651 * This method overrides the readCsvLine method from {@link DefinedTermBase#readCsvLine(List, Language) DefinedTermBase}.
653 * @param csvLine the string list with elementary information for attributes
654 * @param lang the language in which the description has been formulated
655 * @see #NewInstance(String, String, String)
658 public Feature
readCsvLine(Class
<Feature
> termClass
, List
<String
> csvLine
, TermType termType
,
659 Map
<UUID
,DefinedTermBase
> terms
, boolean abbrevAsId
) {
660 Feature newInstance
= super.readCsvLine(termClass
, csvLine
, termType
, terms
, abbrevAsId
);
661 String text
= csvLine
.get(4);
662 if (text
!= null && text
.length() >= 6){
663 if ("1".equals(text
.substring(0, 1))){newInstance
.setSupportsTextData(true);}
664 if ("1".equals(text
.substring(1, 2))){newInstance
.setSupportsQuantitativeData(true);}
665 if ("1".equals(text
.substring(2, 3))){newInstance
.setSupportsDistribution(true);}
666 if ("1".equals(text
.substring(3, 4))){newInstance
.setSupportsIndividualAssociation(true);}
667 if ("1".equals(text
.substring(4, 5))){newInstance
.setSupportsTaxonInteraction(true);}
668 if ("1".equals(text
.substring(5, 6))){newInstance
.setSupportsCommonTaxonName(true);}
669 if (text
.length() > 6 && "1".equals(text
.substring(6, 7))){newInstance
.setSupportsCategoricalData(true);}
670 //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
671 newInstance
.getRepresentation(Language
.DEFAULT()).setAbbreviatedLabel(null);
676 //******************************* STATIC METHODS *****************************************
678 protected static Feature
getTermByUuid(UUID uuid
){
679 if (termMap
== null || termMap
.isEmpty()){
680 return getTermByClassAndUUID(Feature
.class, uuid
);
682 return termMap
.get(uuid
);
687 * Returns the "unknown" feature. This feature allows to store values of
688 * {@link DescriptionElementBase description elements} even if it is momentarily
689 * not known what they mean.
691 public static final Feature
UNKNOWN(){
692 return getTermByUuid(uuidUnknown
);
696 * Returns the "description" feature. This feature allows to handle global
697 * {@link DescriptionElementBase description elements} for a global {@link DescriptionBase description}.<BR>
698 * The "description" feature is the highest level feature.
700 public static final Feature
DESCRIPTION(){
701 return getTermByUuid(uuidDescription
);
705 * Returns the "distribution" feature. This feature allows to handle only
706 * {@link Distribution distributions}.
708 * @see #isSupportsDistribution()
710 public static final Feature
DISTRIBUTION(){
711 return getTermByUuid(uuidDistribution
);
715 * Returns the feature for general text-based
718 public static final Feature
DISTRIBUTION_GENERAL(){
719 return getTermByUuid(uuidDistributionGeneral
);
723 * Returns the "discussion" feature. This feature can only be described
724 * with {@link TextData text data}.
726 * @see #isSupportsTextData()
728 public static final Feature
DISCUSSION(){
729 return getTermByUuid(uuidDiscussion
);
733 * Returns the "ecology" feature. This feature only applies
734 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
735 * The "ecology" feature generalizes all other possible features concerning
736 * ecological matters.
738 public static final Feature
ECOLOGY(){
739 return getTermByUuid(uuidEcology
);
743 * Returns the "habitat" feature. This feature only applies
744 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
745 * The "habitat" feature generalizes all other possible features concerning
748 public static final Feature
HABITAT(){
749 return getTermByUuid(uuidHabitat
);
754 * Returns the "habitat & ecology" feature. This feature only applies
755 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
756 * The "habitat & ecology" feature generalizes all other possible features concerning
757 * habitat and ecology matters.
759 public static final Feature
HABITAT_ECOLOGY(){
760 return getTermByUuid(uuidHabitatAndEcology
);
764 * Returns the "biology_ecology" feature. This feature only applies
765 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
766 * The "biology_ecology" feature generalizes all possible features concerning
767 * biological aspects of ecological matters.
771 public static final Feature
BIOLOGY_ECOLOGY(){
772 return getTermByUuid(uuidBiologyEcology
);
776 * Returns the "chromosome number" feature. This feature only applies
777 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
779 public static final Feature
CHROMOSOME_NUMBER(){
780 return getTermByUuid(uuidChromosomeNumber
);
785 * Returns the "key" feature. This feature is the "upper" feature generalizing
786 * all features being used within an identification key.
788 public static final Feature
KEY(){
789 return getTermByUuid(uuidKey
);
794 * Returns the "materials_examined" feature. This feature can only be described
795 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
796 * mentioning which material has been examined in order to accomplish
797 * the description. This feature applies only to
798 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
800 public static final Feature
MATERIALS_EXAMINED(){
801 return getTermByUuid(uuidMaterialsExamined
);
805 * Returns the "materials_methods" feature. This feature can only be described
806 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
807 * mentioning which methods have been adopted to analyze the material in
808 * order to accomplish the description. This feature applies only to
809 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
811 public static final Feature
MATERIALS_METHODS(){
812 return getTermByUuid(uuidMaterialsMethods
);
816 * Returns the "etymology" feature. This feature can only be described
817 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
818 * giving some information about the history of the taxon name. This feature applies only to
819 * {@link TaxonNameDescription taxon name descriptions}.
821 public static final Feature
ETYMOLOGY(){
822 return getTermByUuid(uuidEtymology
);
826 * Returns the "diagnosis" feature. This feature can only be described
827 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}.
828 * This feature applies only to {@link SpecimenDescription specimen descriptions} or to
829 * {@link TaxonDescription taxon descriptions}.
831 public static final Feature
DIAGNOSIS(){
832 return getTermByUuid(uuidDiagnosis
);
837 * Returns the "introduction" feature. This feature can only be described
838 * with {@link TextData text data}.
840 * @see #isSupportsTextData()
842 public static final Feature
INTRODUCTION(){
843 return getTermByUuid(uuidIntroduction
);
847 * Returns the "protologue" feature. This feature can only be described
848 * with {@link TextData text data} reproducing the content of the protologue
849 * (or some information about it) of the taxon name. This feature applies only to
850 * {@link TaxonNameDescription taxon name descriptions}.
852 * @see #isSupportsTextData()
854 public static final Feature
PROTOLOGUE(){
855 return getTermByUuid(uuidProtologue
);
859 * Returns the "common_name" feature. This feature allows to handle only
860 * {@link CommonTaxonName common names}.
862 * @see #isSupportsCommonTaxonName()
864 public static final Feature
COMMON_NAME(){
865 return getTermByUuid(uuidCommonName
);
869 * Returns the "phenology" feature. This feature can only be described
870 * with {@link CategoricalData categorical data} or eventually with {@link TextData text data}
871 * containing information time about recurring natural phenomena.
872 * This feature only applies to {@link TaxonDescription taxon descriptions}.<BR>
873 * The "phenology" feature generalizes all other possible features
874 * concerning time information about particular natural phenomena
875 * (such as "first flight of butterflies").
877 public static final Feature
PHENOLOGY(){
878 return getTermByUuid(uuidPhenology
);
882 * Returns the "occurrence" feature.
884 public static final Feature
OCCURRENCE(){
885 return getTermByUuid(uuidOccurrence
);
889 * Returns the "anatomy" feature.
891 public static final Feature
ANATOMY(){
892 return getTermByUuid(uuidAnatomy
);
895 * Returns the "hostplant" feature.
897 public static final Feature
HOSTPLANT(){
898 return getTermByUuid(uuidHostPlant
);
901 * Returns the "pathogen agent" feature.
903 public static final Feature
PATHOGEN_AGENT(){
904 return getTermByUuid(uuidPathogenAgent
);
908 * Returns the "citation" feature. This feature can only be described
909 * with {@link TextData text data}.
911 * @see #isSupportsTextData()
913 public static final Feature
CITATION(){
914 return getTermByUuid(uuidCitation
);
918 * Returns the "additional_publication" feature. This feature can only be
919 * described with {@link TextData text data} with information about a
920 * publication where a {@link TaxonName taxon name} has also been published
921 * but which is not the {@link TaxonName#getNomenclaturalReference() nomenclatural reference}.
922 * This feature applies only to {@link TaxonNameDescription taxon name descriptions}.
924 * @see #isSupportsTextData()
926 public static final Feature
ADDITIONAL_PUBLICATION(){
927 return getTermByUuid(uuidAdditionalPublication
);
932 * Returns the "uses" feature. This feature only applies
933 * to {@link TaxonDescription taxon descriptions}.<BR>
934 * The "uses" feature generalizes all other possible features concerning
935 * particular uses (for instance "industrial use of seeds").
937 public static final Feature
USES(){
938 return getTermByUuid(uuidUses
);
941 public static final Feature
USERECORD(){
942 return getTermByUuid(uuidUseRecord
);
946 * Returns the "notes" feature. Used for
949 public static final Feature
NOTES(){
950 return getTermByUuid(uuidNotes
);
954 * Returns the "conservation" feature. This feature only applies
955 * to {@link SpecimenDescription specimen descriptions} and generalizes
956 * methods and conditions for the conservation of {@link Specimen specimens}.<BR>
958 public static final Feature
CONSERVATION(){
959 return getTermByUuid(uuidConservation
);
964 * Returns the "cultivation" feature.
966 public static final Feature
CULTIVATION(){
967 return getTermByUuid(uuidCultivation
);
972 * Returns the "image" feature.
974 public static final Feature
IMAGE(){
975 return getTermByUuid(uuidImage
);
979 * Returns the "individuals association" feature.
981 public static final Feature
INDIVIDUALS_ASSOCIATION(){
982 Feature individuals_association
= getTermByUuid(uuidIndividualsAssociation
);
983 Set
<Feature
> generalizationOf
= new HashSet
<>();
984 generalizationOf
.add(SPECIMEN());
985 generalizationOf
.add(OBSERVATION());
986 individuals_association
.setGeneralizationOf(generalizationOf
);
987 return individuals_association
;
991 public static final Feature
SPECIMEN(){
992 return getTermByUuid(uuidSpecimen
);
995 public static final Feature
OBSERVATION(){
996 return getTermByUuid(uuidObservation
);
1000 * The status of a taxon. Usually the status should be determined within a {@link Distribution distribution}.
1001 * If this is not possible for some reason (e.g. the area is not well defined) the status feature
1005 public static final Feature
STATUS(){
1006 return getTermByUuid(uuidStatus
);
1009 public static final Feature
SYSTEMATICS(){
1010 return getTermByUuid(uuidSystematics
);
1013 public static final Feature
LIFEFORM(){
1014 return getTermByUuid(uuidLifeform
);
1018 * Returns the "hybrid_parent" feature. This feature can only be used
1019 * by {@link TaxonInteraction taxon interactions}.<BR>
1021 * Note: It must be distinguished between hybrid relationships as
1022 * relevant nomenclatural relationships between {@link BotanicalName plant names}
1023 * on the one side and the biological relation between two {@link Taxon taxa}
1024 * as it is here the case on the other one.
1026 * @see #isSupportsTaxonInteraction()
1027 * @see HybridRelationshipType
1029 public static final Feature
HYBRID_PARENT(){
1031 logger
.warn("HYBRID_PARENT not yet implemented");
1036 protected void setDefaultTerms(TermVocabulary
<Feature
> termVocabulary
) {
1037 if (termMap
== null){ //needed because there are multiple feature vocabularies
1038 termMap
= new HashMap
<UUID
, Feature
>();
1040 for (Feature term
: termVocabulary
.getTerms()){
1041 termMap
.put(term
.getUuid(), term
);
1045 //*********************************** CLONE *********************************************************/
1048 public Object
clone() {
1049 Feature result
= (Feature
)super.clone();
1051 result
.inverseRepresentations
= new HashSet
<Representation
>();
1052 for (Representation rep
: this.inverseRepresentations
){
1053 result
.addInverseRepresentation((Representation
)rep
.clone());
1056 //no changes to: symmetric, transitiv