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
.BotanicalName
;
48 import eu
.etaxonomy
.cdm
.model
.name
.HybridRelationshipType
;
49 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
50 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
55 * The class for individual properties (also designed as character, type or
56 * category) of observed phenomena able to be described or measured. It also
57 * covers categories of informations on {@link TaxonNameBase taxon names} not
58 * taken in account in {@link NomenclaturalCode nomenclature}.<BR>
59 * Descriptions require features in order to be structured and disaggregated
60 * in {@link DescriptionElementBase description elements}.<BR>
61 * Experts do not use the word feature for the actual description
62 * but only for the property itself. Therefore naming this class FeatureType
63 * would have leaded to confusion.
65 * Since features are {@link DefinedTermBase defined terms} they have a hierarchical
66 * structure that allows to specify ("kind of") or generalize
67 * ("generalization of") features. "Kind of" / "generalization of" relations
68 * are bidirectional (a feature F1 is a "Kind of" a feature F2 if and only
69 * if the feature F2 is a "generalization of" the feature F1. This hierarchical
70 * structure has nothing in common with {@link FeatureTree feature trees} used for determination.
72 * A standard set of feature instances will be automatically
73 * created as the project starts. But this class allows to extend this standard
74 * set by creating new instances of additional features if needed.<BR>
76 * This class corresponds to DescriptionsSectionType according to the SDD
80 * @created 08-Nov-2007 13:06:24
82 @XmlAccessorType(XmlAccessType
.PROPERTY
)
83 @XmlType(name
="Feature", factoryMethod
="NewInstance", propOrder
= {
89 "supportsQuantitativeData",
90 "supportsDistribution",
91 "supportsIndividualAssociation",
92 "supportsTaxonInteraction",
93 "supportsCommonTaxonName",
94 "supportsCategoricalData",
95 "recommendedModifierEnumeration",
96 "recommendedStatisticalMeasures",
97 "supportedCategoricalEnumerations",
98 "recommendedMeasurementUnits",
99 "inverseRepresentations"
101 @XmlRootElement(name
= "Feature")
103 //@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
104 //@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
106 public class Feature
extends DefinedTermBase
<Feature
> {
107 private static final long serialVersionUID
= 6754598791831848704L;
108 private static final Logger logger
= Logger
.getLogger(Feature
.class);
110 protected static Map
<UUID
, Feature
> termMap
= null;
112 private boolean supportsTextData
= true; //by default text data should be always supported
114 private boolean supportsQuantitativeData
;
116 private boolean supportsDistribution
;
118 private boolean supportsIndividualAssociation
;
120 private boolean supportsTaxonInteraction
;
122 private boolean supportsCategoricalData
;
124 private boolean supportsCommonTaxonName
;
126 /* for M:M see #4843 */
127 @ManyToMany(fetch
= FetchType
.LAZY
)
128 @JoinTable(name
="DefinedTermBase_RecommendedModifierEnumeration")
129 private final Set
<TermVocabulary
<DefinedTerm
>> recommendedModifierEnumeration
= new HashSet
<TermVocabulary
<DefinedTerm
>>();
131 @ManyToMany(fetch
= FetchType
.LAZY
)
132 @JoinTable(name
="DefinedTermBase_StatisticalMeasure")
133 private final Set
<StatisticalMeasure
> recommendedStatisticalMeasures
= new HashSet
<StatisticalMeasure
>();
135 /* for M:M see #4843 */
136 @ManyToMany(fetch
= FetchType
.LAZY
)
137 @JoinTable(name
="DefinedTermBase_SupportedCategoricalEnumeration")
138 private final Set
<TermVocabulary
<State
>> supportedCategoricalEnumerations
= new HashSet
<TermVocabulary
<State
>>();
141 @ManyToMany(fetch
= FetchType
.LAZY
)
142 @JoinTable(name
="DefinedTermBase_MeasurementUnit")
143 private final Set
<MeasurementUnit
> recommendedMeasurementUnits
= new HashSet
<MeasurementUnit
>();
146 //copy from RelationshipTermBase
147 @XmlElementWrapper(name
= "InverseRepresentations")
148 @XmlElement(name
= "Representation")
149 @OneToMany(fetch
= FetchType
.LAZY
, orphanRemoval
=true)
150 @JoinTable(name
="RelationshipTermBase_inverseRepresentation",
151 joinColumns
=@JoinColumn(name
="relationshiptermbase_id")
153 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
154 // @IndexedEmbedded(depth = 2)
155 private Set
<Representation
> inverseRepresentations
= new HashSet
<Representation
>();
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 uuidEcology
= UUID
.fromString("aa923827-d333-4cf5-9a5f-438ae0a4746b");
161 private static final UUID uuidHabitat
= UUID
.fromString("fb16929f-bc9c-456f-9d40-dec987b36438");
162 private static final UUID uuidHabitatAndEcology
= UUID
.fromString("9fdc4663-4d56-47d0-90b5-c0bf251bafbb");
163 private static final UUID uuidChromosomeNumber
= UUID
.fromString("6f677e98-d8d5-4bc5-80bf-affdb7e3945a");
165 private static final UUID uuidBiologyEcology
= UUID
.fromString("9832e24f-b670-43b4-ac7c-20a7261a1d8c");
166 private static final UUID uuidKey
= UUID
.fromString("a677f827-22b9-4205-bb37-11cb48dd9106");
167 private static final UUID uuidMaterialsExamined
= UUID
.fromString("7c0c7571-a864-47c1-891d-01f59000dae1");
168 private static final UUID uuidMaterialsMethods
= UUID
.fromString("1e87d9c3-0844-4a03-9686-773e2ccb3ab6");
169 private static final UUID uuidEtymology
= UUID
.fromString("dd653d48-355c-4aec-a4e7-724f6eb29f8d");
170 private static final UUID uuidDiagnosis
= UUID
.fromString("d43d8501-ceab-4caa-9e51-e87138528fac");
171 private static final UUID uuidProtologue
= UUID
.fromString("71b356c5-1e3f-4f5d-9b0f-c2cf8ae7779f");
172 public static final UUID uuidCommonName
= UUID
.fromString("fc810911-51f0-4a46-ab97-6562fe263ae5");
173 private static final UUID uuidPhenology
= UUID
.fromString("a7786d3e-7c58-4141-8416-346d4c80c4a2");
174 private static final UUID uuidOccurrence
= UUID
.fromString("5deff505-1a32-4817-9a74-50e6936fd630");
175 private static final UUID uuidCitation
= UUID
.fromString("99b2842f-9aa7-42fa-bd5f-7285311e0101");
176 private static final UUID uuidAdditionalPublication
= UUID
.fromString("2c355c16-cb04-4858-92bf-8da8d56dea95");
177 public static final UUID uuidUses
= UUID
.fromString("e5374d39-b210-47c7-bec1-bee05b5f1cb6");
178 private static final UUID uuidConservation
= UUID
.fromString("4518fc20-2492-47de-b345-777d2b83c9cf");
179 private static final UUID uuidCultivation
= UUID
.fromString("e28965b2-a367-48c5-b954-8afc8ac2c69b");
180 private static final UUID uuidIntroduction
= UUID
.fromString("e75255ca-8ff4-4905-baad-f842927fe1d3");
181 private static final UUID uuidDiscussion
= UUID
.fromString("d3c4cbb6-0025-4322-886b-cd0156753a25");
182 public static final UUID uuidImage
= UUID
.fromString("84193b2c-327f-4cce-90ef-c8da18fd5bb5");
183 private static final UUID uuidAnatomy
= UUID
.fromString("94213b2c-e67a-4d37-25ef-e8d316edfba1");
184 private static final UUID uuidHostPlant
= UUID
.fromString("6e9de1d5-05f0-40d5-8786-2fe30d0d894d");
185 private static final UUID uuidPathogenAgent
= UUID
.fromString("002d05f2-fd72-49f1-ba4d-196cf09240b5");
186 private static final UUID uuidIndividualsAssociation
= UUID
.fromString("e2308f37-ddc5-447d-b483-5e2171dd85fd");
187 public static final UUID uuidSpecimen
= UUID
.fromString("8200e050-d5fd-4cac-8a76-4b47afb13809");
188 private static final UUID uuidObservation
= UUID
.fromString("f59e747d-0b4f-4bf7-b69a-cbd50bc78595");
189 private static final UUID uuidStatus
= UUID
.fromString("86d40635-2a63-4ad6-be75-9faa4a6a57fb");
190 private static final UUID uuidSystematics
= UUID
.fromString("bd9aca17-cd0e-4418-a3a1-1a4b80dbc162");
191 private static final UUID uuidUseRecord
= UUID
.fromString("8125a59d-b4d5-4485-89ea-67306297b599");
192 private static final UUID uuidNotes
= UUID
.fromString("b5780b45-6439-4f3c-9818-d89d26d36eb2");
193 public static final UUID uuidLifeform
= UUID
.fromString("db9228d3-8bbf-4460-abfe-0b1326c82f8e");
196 /* ***************** CONSTRUCTOR AND FACTORY METHODS **********************************/
199 * Class constructor: creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
200 * a label and a label abbreviation.
202 * @param term the string (in the default language) describing the
203 * new feature to be created
204 * @param label the string identifying the new feature to be created
205 * @param labelAbbrev the string identifying (in abbreviated form) the
206 * new feature to be created
209 protected Feature(String description
, String label
, String labelAbbrev
) {
210 super(TermType
.Feature
, description
, label
, labelAbbrev
);
214 * Creates a new empty feature instance.
216 * @see #NewInstance(String, String, String)
218 public static Feature
NewInstance() {
219 return new Feature();
223 * Creates a new feature instance with a description (in the {@link Language#DEFAULT() default language}),
224 * a label and a label abbreviation.
226 * @param term the string (in the default language) describing the
227 * new feature to be created
228 * @param label the string identifying the new feature to be created
229 * @param labelAbbrev the string identifying (in abbreviated form) the
230 * new feature to be created
231 * @see #readCsvLine(List, Language)
232 * @see #NewInstance()
234 public static Feature
NewInstance(String term
, String label
, String labelAbbrev
){
235 return new Feature(term
, label
, labelAbbrev
);
239 //for hibernate use only
241 protected Feature() {
242 super(TermType
.Feature
);
245 /* *************************************************************************************/
248 public void resetTerms(){
254 * Returns the boolean value of the flag indicating whether <i>this</i>
255 * feature can be described with {@link QuantitativeData quantitative data} (true)
256 * or not (false). If this flag is set <i>this</i> feature can only apply to
257 * {@link TaxonDescription taxon descriptions} or {@link SpecimenDescription specimen descriptions}.
259 * @return the boolean value of the supportsQuantitativeData flag
261 @XmlElement(name
= "SupportsQuantitativeData")
262 public boolean isSupportsQuantitativeData() {
263 return supportsQuantitativeData
;
267 * @see #isSupportsQuantitativeData()
269 public void setSupportsQuantitativeData(boolean supportsQuantitativeData
) {
270 this.supportsQuantitativeData
= supportsQuantitativeData
;
274 * Returns the boolean value of the flag indicating whether <i>this</i>
275 * feature can be described with {@link TextData text data} (true)
278 * @return the boolean value of the supportsTextData flag
280 @XmlElement(name
= "SupportsTextData")
281 public boolean isSupportsTextData() {
282 return supportsTextData
;
286 * @see #isSupportsTextData()
288 public void setSupportsTextData(boolean supportsTextData
) {
289 this.supportsTextData
= supportsTextData
;
293 * Returns the boolean value of the flag indicating whether <i>this</i>
294 * feature can be described with {@link Distribution distribution} objects
295 * (true) or not (false). This flag is set if and only if <i>this</i> feature
296 * is the {@link #DISTRIBUTION() distribution feature}.
298 * @return the boolean value of the supportsDistribution flag
300 @XmlElement(name
= "SupportsDistribution")
301 public boolean isSupportsDistribution() {
302 return supportsDistribution
;
306 * @see #isSupportsDistribution()
308 public void setSupportsDistribution(boolean supportsDistribution
) {
309 this.supportsDistribution
= supportsDistribution
;
313 * Returns the boolean value of the flag indicating whether <i>this</i>
314 * feature can be described with {@link IndividualsAssociation individuals associations}
315 * (true) or not (false).
317 * @return the boolean value of the supportsIndividualAssociation flag
319 @XmlElement(name
= "SupportsIndividualAssociation")
320 public boolean isSupportsIndividualAssociation() {
321 return supportsIndividualAssociation
;
325 * @see #isSupportsIndividualAssociation()
327 public void setSupportsIndividualAssociation(
328 boolean supportsIndividualAssociation
) {
329 this.supportsIndividualAssociation
= supportsIndividualAssociation
;
333 * Returns the boolean value of the flag indicating whether <i>this</i>
334 * feature can be described with {@link TaxonInteraction taxon interactions}
335 * (true) or not (false).
337 * @return the boolean value of the supportsTaxonInteraction flag
339 @XmlElement(name
= "SupportsTaxonInteraction")
340 public boolean isSupportsTaxonInteraction() {
341 return supportsTaxonInteraction
;
345 * @see #isSupportsTaxonInteraction()
347 public void setSupportsTaxonInteraction(boolean supportsTaxonInteraction
) {
348 this.supportsTaxonInteraction
= supportsTaxonInteraction
;
352 * Returns the boolean value of the flag indicating whether <i>this</i>
353 * feature can be described with {@link CommonTaxonName common names}
354 * (true) or not (false). This flag is set if and only if <i>this</i> feature
355 * is the {@link #COMMON_NAME() common name feature}.
357 * @return the boolean value of the supportsCommonTaxonName flag
359 @XmlElement(name
= "SupportsCommonTaxonName")
360 public boolean isSupportsCommonTaxonName() {
361 return supportsCommonTaxonName
;
365 * @see #isSupportsTaxonInteraction()
367 public void setSupportsCommonTaxonName(boolean supportsCommonTaxonName
) {
368 this.supportsCommonTaxonName
= supportsCommonTaxonName
;
372 * Returns the boolean value of the flag indicating whether <i>this</i>
373 * feature can be described with {@link CategoricalData categorical data}
374 * (true) or not (false).
376 * @return the boolean value of the supportsCategoricalData flag
378 @XmlElement(name
= "SupportsCategoricalData")
379 public boolean isSupportsCategoricalData() {
380 return supportsCategoricalData
;
384 * @see #supportsCategoricalData()
386 public void setSupportsCategoricalData(boolean supportsCategoricalData
) {
387 this.supportsCategoricalData
= supportsCategoricalData
;
392 * Returns the set of {@link TermVocabulary term vocabularies} containing the
393 * {@link Modifier modifiers} recommended to be used for {@link DescriptionElementBase description elements}
394 * with <i>this</i> feature.
397 @XmlElementWrapper(name
= "RecommendedModifierEnumerations")
398 @XmlElement(name
= "RecommendedModifierEnumeration")
400 @XmlSchemaType(name
= "IDREF")
401 public Set
<TermVocabulary
<DefinedTerm
>> getRecommendedModifierEnumeration() {
402 return recommendedModifierEnumeration
;
406 * Adds a {@link TermVocabulary term vocabulary} (with {@link Modifier modifiers}) to the set of
407 * {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies} assigned
408 * to <i>this</i> feature.
410 * @param recommendedModifierEnumeration the term vocabulary to be added
411 * @see #getRecommendedModifierEnumeration()
413 public void addRecommendedModifierEnumeration(
414 TermVocabulary
<DefinedTerm
> recommendedModifierEnumeration
) {
415 this.recommendedModifierEnumeration
.add(recommendedModifierEnumeration
);
418 * Removes one element from the set of {@link #getRecommendedModifierEnumeration() recommended modifier vocabularies}
419 * assigned to <i>this</i> feature.
421 * @param recommendedModifierEnumeration the term vocabulary which should be removed
422 * @see #getRecommendedModifierEnumeration()
423 * @see #addRecommendedModifierEnumeration(TermVocabulary)
425 public void removeRecommendedModifierEnumeration(
426 TermVocabulary
<DefinedTerm
> recommendedModifierEnumeration
) {
427 this.recommendedModifierEnumeration
.remove(recommendedModifierEnumeration
);
431 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
432 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
434 @XmlElementWrapper(name
= "RecommendedStatisticalMeasures")
435 @XmlElement(name
= "RecommendedStatisticalMeasure")
437 @XmlSchemaType(name
= "IDREF")
438 public Set
<StatisticalMeasure
> getRecommendedStatisticalMeasures() {
439 return recommendedStatisticalMeasures
;
443 * Adds a {@link StatisticalMeasure statistical measure} to the set of
444 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
445 * to <i>this</i> feature.
447 * @param recommendedStatisticalMeasure the statistical measure to be added
448 * @see #getRecommendedStatisticalMeasures()
450 public void addRecommendedStatisticalMeasure(
451 StatisticalMeasure recommendedStatisticalMeasure
) {
452 this.recommendedStatisticalMeasures
.add(recommendedStatisticalMeasure
);
455 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
456 * assigned to <i>this</i> feature.
458 * @param recommendedStatisticalMeasure the statistical measure which should be removed
459 * @see #getRecommendedStatisticalMeasures()
460 * @see #addRecommendedStatisticalMeasure(StatisticalMeasure)
462 public void removeRecommendedStatisticalMeasure(
463 StatisticalMeasure recommendedStatisticalMeasure
) {
464 this.recommendedStatisticalMeasures
.remove(recommendedStatisticalMeasure
);
468 * Returns the set of {@link StatisticalMeasure statistical measures} recommended to be used
469 * in case of {@link QuantitativeData quantitative data} with <i>this</i> feature.
471 @XmlElementWrapper(name
= "RecommendedMeasurementUnits")
472 @XmlElement(name
= "RecommendedMeasurementUnit")
474 @XmlSchemaType(name
= "IDREF")
475 public Set
<MeasurementUnit
> getRecommendedMeasurementUnits() {
476 return recommendedMeasurementUnits
;
480 * Adds a {@link StatisticalMeasure statistical measure} to the set of
481 * {@link #getRecommendedStatisticalMeasures() recommended statistical measures} assigned
482 * to <i>this</i> feature.
484 * @param recommendedStatisticalMeasure the statistical measure to be added
485 * @see #getRecommendedStatisticalMeasures()
487 public void addRecommendedMeasurementUnit(
488 MeasurementUnit recommendedMeasurementUnit
) {
489 this.recommendedMeasurementUnits
.add(recommendedMeasurementUnit
);
492 * Removes one element from the set of {@link #getRecommendedStatisticalMeasures() recommended statistical measures}
493 * assigned to <i>this</i> feature.
495 * @param recommendedStatisticalMeasure the statistical measure which should be removed
496 * @see #getRecommendedStatisticalMeasures()
497 * @see #addRecommendedStatisticalMeasure(StatisticalMeasure)
499 public void removeRecommendedMeasurementUnit(
500 MeasurementUnit recommendedMeasurementUnit
) {
501 this.recommendedMeasurementUnits
.remove(recommendedMeasurementUnit
);
505 * Returns the set of {@link TermVocabulary term vocabularies} containing the list of
506 * possible {@link State states} to be used in {@link CategoricalData categorical data}
507 * with <i>this</i> feature.
510 @XmlElementWrapper(name
= "SupportedCategoricalEnumerations")
511 @XmlElement(name
= "SupportedCategoricalEnumeration")
513 @XmlSchemaType(name
= "IDREF")
514 public Set
<TermVocabulary
<State
>> getSupportedCategoricalEnumerations() {
515 return supportedCategoricalEnumerations
;
519 * Adds a {@link TermVocabulary term vocabulary} to the set of
520 * {@link #getSupportedCategoricalEnumerations() supported state vocabularies} assigned
521 * to <i>this</i> feature.
523 * @param supportedCategoricalEnumeration the term vocabulary which should be removed
524 * @see #getSupportedCategoricalEnumerations()
526 public void addSupportedCategoricalEnumeration(
527 TermVocabulary
<State
> supportedCategoricalEnumeration
) {
528 this.supportedCategoricalEnumerations
.add(supportedCategoricalEnumeration
);
531 * Removes one element from the set of {@link #getSupportedCategoricalEnumerations() supported state vocabularies}
532 * assigned to <i>this</i> feature.
534 * @param supportedCategoricalEnumeration the term vocabulary which should be removed
535 * @see #getSupportedCategoricalEnumerations()
536 * @see #addSupportedCategoricalEnumeration(TermVocabulary)
538 public void removeSupportedCategoricalEnumeration(
539 TermVocabulary
<State
> supportedCategoricalEnumeration
) {
540 this.supportedCategoricalEnumerations
.remove(supportedCategoricalEnumeration
);
543 @XmlElement(name
= "KindOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
545 @XmlSchemaType(name
= "IDREF")
547 public Feature
getKindOf(){
548 return super.getKindOf();
552 public void setKindOf(Feature kindOf
){
553 super.setKindOf(kindOf
);
557 @XmlElement(name
= "PartOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
559 @XmlSchemaType(name
= "IDREF")
560 public Feature
getPartOf(){
561 return super.getPartOf();
565 public void setPartOf(Feature partOf
){
566 super.setPartOf(partOf
);
570 @XmlElementWrapper(name
= "Generalizations", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
571 @XmlElement(name
= "GeneralizationOf", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
573 @XmlSchemaType(name
= "IDREF")
574 public Set
<Feature
> getGeneralizationOf(){
575 return super.getGeneralizationOf();
579 protected void setGeneralizationOf(Set
<Feature
> value
){
580 super.setGeneralizationOf(value
);
584 @XmlElementWrapper(name
= "Includes", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
585 @XmlElement(name
= "Include", namespace
= "http://etaxonomy.eu/cdm/model/common/1.0")
587 @XmlSchemaType(name
= "IDREF")
588 public Set
<Feature
> getIncludes(){
589 return super.getIncludes();
593 protected void setIncludes(Set
<Feature
> includes
) {
594 super.setIncludes(includes
);
597 // ***************** Invers Label *****************************************/
599 public Set
<Representation
> getInverseRepresentations() {
600 return inverseRepresentations
;
602 public void addInverseRepresentation(Representation inverseRepresentation
) {
603 this.inverseRepresentations
.add(inverseRepresentation
);
605 public void removeInverseRepresentation(Representation inverseRepresentation
) {
606 this.inverseRepresentations
.remove(inverseRepresentation
);
609 * Inverse representation convenience methods similar to TermBase.xxx
610 * @see eu.etaxonomy.cdm.model.common.TermBase#getLabel()
613 public String
getInverseLabel() {
614 if(getInverseLabel(Language
.DEFAULT()) != null){
615 return this.getInverseRepresentation(Language
.DEFAULT()).getLabel();
617 for (Representation r
: inverseRepresentations
){
621 return super.getUuid().toString();
623 public String
getInverseLabel(Language lang
) {
624 Representation r
= this.getInverseRepresentation(lang
);
631 public Representation
getInverseRepresentation(Language lang
) {
632 Representation result
= null;
633 for (Representation repr
: this.getInverseRepresentations()){
634 if (lang
.equals(repr
.getLanguage())){
640 // ****************** END INVERS REPRESENTATION **************************/
643 * Creates and returns a new feature instance on the basis of a given string
644 * list (containing an UUID, an URI, a label and a description) and a given
645 * {@link Language language} to be associated with the description. Furthermore
646 * the flags concerning the supported subclasses of {@link DescriptionElementBase description elements}
647 * are set according to a particular string belonging to the given
649 * This method overrides the readCsvLine method from {@link DefinedTermBase#readCsvLine(List, Language) DefinedTermBase}.
651 * @param csvLine the string list with elementary information for attributes
652 * @param lang the language in which the description has been formulated
653 * @see #NewInstance(String, String, String)
656 public Feature
readCsvLine(Class
<Feature
> termClass
, List
<String
> csvLine
, Map
<UUID
,DefinedTermBase
> terms
, boolean abbrevAsId
) {
657 Feature newInstance
= super.readCsvLine(termClass
, csvLine
, terms
, abbrevAsId
);
658 String text
= csvLine
.get(4);
659 if (text
!= null && text
.length() >= 6){
660 if ("1".equals(text
.substring(0, 1))){newInstance
.setSupportsTextData(true);}
661 if ("1".equals(text
.substring(1, 2))){newInstance
.setSupportsQuantitativeData(true);}
662 if ("1".equals(text
.substring(2, 3))){newInstance
.setSupportsDistribution(true);}
663 if ("1".equals(text
.substring(3, 4))){newInstance
.setSupportsIndividualAssociation(true);}
664 if ("1".equals(text
.substring(4, 5))){newInstance
.setSupportsTaxonInteraction(true);}
665 if ("1".equals(text
.substring(5, 6))){newInstance
.setSupportsCommonTaxonName(true);}
666 if (text
.length() > 6 && "1".equals(text
.substring(6, 7))){newInstance
.setSupportsCategoricalData(true);}
667 //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
668 newInstance
.getRepresentation(Language
.DEFAULT()).setAbbreviatedLabel(null);
673 //******************************* STATIC METHODS *****************************************
675 protected static Feature
getTermByUuid(UUID uuid
){
676 if (termMap
== null || termMap
.isEmpty()){
677 return getTermByClassAndUUID(Feature
.class, uuid
);
679 return termMap
.get(uuid
);
684 * Returns the "unknown" feature. This feature allows to store values of
685 * {@link DescriptionElementBase description elements} even if it is momentarily
686 * not known what they mean.
688 public static final Feature
UNKNOWN(){
689 return getTermByUuid(uuidUnknown
);
693 * Returns the "description" feature. This feature allows to handle global
694 * {@link DescriptionElementBase description elements} for a global {@link DescriptionBase description}.<BR>
695 * The "description" feature is the highest level feature.
697 public static final Feature
DESCRIPTION(){
698 return getTermByUuid(uuidDescription
);
702 * Returns the "distribution" feature. This feature allows to handle only
703 * {@link Distribution distributions}.
705 * @see #isSupportsDistribution()
707 public static final Feature
DISTRIBUTION(){
708 return getTermByUuid(uuidDistribution
);
712 * Returns the "discussion" feature. This feature can only be described
713 * with {@link TextData text data}.
715 * @see #isSupportsTextData()
717 public static final Feature
DISCUSSION(){
718 return getTermByUuid(uuidDiscussion
);
722 * Returns the "ecology" feature. This feature only applies
723 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
724 * The "ecology" feature generalizes all other possible features concerning
725 * ecological matters.
727 public static final Feature
ECOLOGY(){
728 return getTermByUuid(uuidEcology
);
732 * Returns the "habitat" feature. This feature only applies
733 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
734 * The "habitat" feature generalizes all other possible features concerning
737 public static final Feature
HABITAT(){
738 return getTermByUuid(uuidHabitat
);
743 * Returns the "habitat & ecology" feature. This feature only applies
744 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
745 * The "habitat & ecology" feature generalizes all other possible features concerning
746 * habitat and ecology matters.
748 public static final Feature
HABITAT_ECOLOGY(){
749 return getTermByUuid(uuidHabitatAndEcology
);
753 * Returns the "biology_ecology" feature. This feature only applies
754 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
755 * The "biology_ecology" feature generalizes all possible features concerning
756 * biological aspects of ecological matters.
760 public static final Feature
BIOLOGY_ECOLOGY(){
761 return getTermByUuid(uuidBiologyEcology
);
765 * Returns the "chromosome number" feature. This feature only applies
766 * to {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.<BR>
768 public static final Feature
CHROMOSOME_NUMBER(){
769 return getTermByUuid(uuidChromosomeNumber
);
774 * Returns the "key" feature. This feature is the "upper" feature generalizing
775 * all features being used within an identification key.
777 public static final Feature
KEY(){
778 return getTermByUuid(uuidKey
);
783 * Returns the "materials_examined" feature. This feature can only be described
784 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
785 * mentioning which material has been examined in order to accomplish
786 * the description. This feature applies only to
787 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
789 public static final Feature
MATERIALS_EXAMINED(){
790 return getTermByUuid(uuidMaterialsExamined
);
794 * Returns the "materials_methods" feature. This feature can only be described
795 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
796 * mentioning which methods have been adopted to analyze the material in
797 * order to accomplish the description. This feature applies only to
798 * {@link SpecimenDescription specimen descriptions} or to {@link TaxonDescription taxon descriptions}.
800 public static final Feature
MATERIALS_METHODS(){
801 return getTermByUuid(uuidMaterialsMethods
);
805 * Returns the "etymology" feature. This feature can only be described
806 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}
807 * giving some information about the history of the taxon name. This feature applies only to
808 * {@link TaxonNameDescription taxon name descriptions}.
810 public static final Feature
ETYMOLOGY(){
811 return getTermByUuid(uuidEtymology
);
815 * Returns the "diagnosis" feature. This feature can only be described
816 * with {@link TextData text data} or eventually with {@link CategoricalData categorical data}.
817 * This feature applies only to {@link SpecimenDescription specimen descriptions} or to
818 * {@link TaxonDescription taxon descriptions}.
820 public static final Feature
DIAGNOSIS(){
821 return getTermByUuid(uuidDiagnosis
);
826 * Returns the "introduction" feature. This feature can only be described
827 * with {@link TextData text data}.
829 * @see #isSupportsTextData()
831 public static final Feature
INTRODUCTION(){
832 return getTermByUuid(uuidIntroduction
);
836 * Returns the "protologue" feature. This feature can only be described
837 * with {@link TextData text data} reproducing the content of the protologue
838 * (or some information about it) of the taxon name. This feature applies only to
839 * {@link TaxonNameDescription taxon name descriptions}.
841 * @see #isSupportsTextData()
843 public static final Feature
PROTOLOGUE(){
844 return getTermByUuid(uuidProtologue
);
848 * Returns the "common_name" feature. This feature allows to handle only
849 * {@link CommonTaxonName common names}.
851 * @see #isSupportsCommonTaxonName()
853 public static final Feature
COMMON_NAME(){
854 return getTermByUuid(uuidCommonName
);
858 * Returns the "phenology" feature. This feature can only be described
859 * with {@link CategoricalData categorical data} or eventually with {@link TextData text data}
860 * containing information time about recurring natural phenomena.
861 * This feature only applies to {@link TaxonDescription taxon descriptions}.<BR>
862 * The "phenology" feature generalizes all other possible features
863 * concerning time information about particular natural phenomena
864 * (such as "first flight of butterflies").
866 public static final Feature
PHENOLOGY(){
867 return getTermByUuid(uuidPhenology
);
871 * Returns the "occurrence" feature.
873 public static final Feature
OCCURRENCE(){
874 return getTermByUuid(uuidOccurrence
);
878 * Returns the "anatomy" feature.
880 public static final Feature
ANATOMY(){
881 return getTermByUuid(uuidAnatomy
);
884 * Returns the "hostplant" feature.
886 public static final Feature
HOSTPLANT(){
887 return getTermByUuid(uuidHostPlant
);
890 * Returns the "pathogen agent" feature.
892 public static final Feature
PATHOGEN_AGENT(){
893 return getTermByUuid(uuidPathogenAgent
);
897 * Returns the "citation" feature. This feature can only be described
898 * with {@link TextData text data}.
900 * @see #isSupportsTextData()
902 public static final Feature
CITATION(){
903 return getTermByUuid(uuidCitation
);
907 * Returns the "additional_publication" feature. This feature can only be
908 * described with {@link TextData text data} with information about a
909 * publication where a {@link TaxonNameBase taxon name} has also been published
910 * but which is not the {@link TaxonNameBase#getNomenclaturalReference() nomenclatural reference}.
911 * This feature applies only to {@link TaxonNameDescription taxon name descriptions}.
913 * @see #isSupportsTextData()
915 public static final Feature
ADDITIONAL_PUBLICATION(){
916 return getTermByUuid(uuidAdditionalPublication
);
921 * Returns the "uses" feature. This feature only applies
922 * to {@link TaxonDescription taxon descriptions}.<BR>
923 * The "uses" feature generalizes all other possible features concerning
924 * particular uses (for instance "industrial use of seeds").
926 public static final Feature
USES(){
927 return getTermByUuid(uuidUses
);
930 public static final Feature
USERECORD(){
931 return getTermByUuid(uuidUseRecord
);
935 * Returns the "notes" feature. Used for
938 public static final Feature
NOTES(){
939 return getTermByUuid(uuidNotes
);
943 * Returns the "conservation" feature. This feature only applies
944 * to {@link SpecimenDescription specimen descriptions} and generalizes
945 * methods and conditions for the conservation of {@link Specimen specimens}.<BR>
947 public static final Feature
CONSERVATION(){
948 return getTermByUuid(uuidConservation
);
953 * Returns the "cultivation" feature.
955 public static final Feature
CULTIVATION(){
956 return getTermByUuid(uuidCultivation
);
961 * Returns the "image" feature.
963 public static final Feature
IMAGE(){
964 return getTermByUuid(uuidImage
);
968 * Returns the "individuals association" feature.
970 public static final Feature
INDIVIDUALS_ASSOCIATION(){
971 Feature individuals_association
= getTermByUuid(uuidIndividualsAssociation
);
972 Set
<Feature
> generalizationOf
= new HashSet
<Feature
>();
973 generalizationOf
.add(SPECIMEN());
974 generalizationOf
.add(OBSERVATION());
975 individuals_association
.setGeneralizationOf(generalizationOf
);
976 return individuals_association
;
980 public static final Feature
SPECIMEN(){
981 return getTermByUuid(uuidSpecimen
);
984 public static final Feature
OBSERVATION(){
985 return getTermByUuid(uuidObservation
);
989 * The status of a taxon. Usually the status should be determined within a {@link Distribution distribution}.
990 * If this is not possible for some reason (e.g. the area is not well defined) the status feature
994 public static final Feature
STATUS(){
995 return getTermByUuid(uuidStatus
);
998 public static final Feature
SYSTEMATICS(){
999 return getTermByUuid(uuidSystematics
);
1002 public static final Feature
LIFEFORM(){
1003 return getTermByUuid(uuidLifeform
);
1007 * Returns the "hybrid_parent" feature. This feature can only be used
1008 * by {@link TaxonInteraction taxon interactions}.<BR>
1010 * Note: It must be distinguished between hybrid relationships as
1011 * relevant nomenclatural relationships between {@link BotanicalName plant names}
1012 * on the one side and the biological relation between two {@link Taxon taxa}
1013 * as it is here the case on the other one.
1015 * @see #isSupportsTaxonInteraction()
1016 * @see HybridRelationshipType
1018 public static final Feature
HYBRID_PARENT(){
1020 logger
.warn("HYBRID_PARENT not yet implemented");
1025 protected void setDefaultTerms(TermVocabulary
<Feature
> termVocabulary
) {
1026 if (termMap
== null){ //needed because there are multiple feature vocabularies
1027 termMap
= new HashMap
<UUID
, Feature
>();
1029 for (Feature term
: termVocabulary
.getTerms()){
1030 termMap
.put(term
.getUuid(), term
);
1034 //*********************************** CLONE *********************************************************/
1037 public Object
clone() {
1038 Feature result
= (Feature
)super.clone();
1040 result
.inverseRepresentations
= new HashSet
<Representation
>();
1041 for (Representation rep
: this.inverseRepresentations
){
1042 result
.addInverseRepresentation((Representation
)rep
.clone());
1045 //no changes to: symmetric, transitiv