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
.name
;
12 import eu
.etaxonomy
.cdm
.model
.occurrence
.Specimen
;
13 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
14 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
15 import eu
.etaxonomy
.cdm
.model
.reference
.StrictReferenceBase
;
16 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
17 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
18 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
19 import eu
.etaxonomy
.cdm
.model
.common
.IParsable
;
20 import eu
.etaxonomy
.cdm
.model
.common
.IRelated
;
21 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
22 import eu
.etaxonomy
.cdm
.model
.common
.IReferencedEntity
;
23 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
24 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
25 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
28 import org
.apache
.log4j
.Logger
;
29 import org
.hibernate
.annotations
.Cascade
;
30 import org
.hibernate
.annotations
.CascadeType
;
31 import org
.hibernate
.annotations
.Index
;
32 import org
.hibernate
.annotations
.Table
;
33 import org
.hibernate
.annotations
.Target
;
35 import eu
.etaxonomy
.cdm
.strategy
.cache
.name
.INameCacheStrategy
;
39 import java
.lang
.reflect
.Method
;
42 import javax
.persistence
.*;
43 import javax
.xml
.bind
.annotation
.XmlAccessType
;
44 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
45 import javax
.xml
.bind
.annotation
.XmlAnyElement
;
46 import javax
.xml
.bind
.annotation
.XmlAttribute
;
47 import javax
.xml
.bind
.annotation
.XmlElement
;
48 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
49 import javax
.xml
.bind
.annotation
.XmlIDREF
;
50 import javax
.xml
.bind
.annotation
.XmlRootElement
;
51 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
52 import javax
.xml
.bind
.annotation
.XmlTransient
;
53 import javax
.xml
.bind
.annotation
.XmlType
;
56 * The upmost (abstract) class for scientific taxon names regardless of any
57 * particular nomenclature code. The scientific taxon name does not depend
58 * on the use made of it in a publication or a treatment
59 * ({@link taxon.TaxonBase taxon concept respectively potential taxon})
60 * as an {@link taxon.Taxon "accepted" respectively "correct" (taxon) name}
61 * or as a {@link taxon.Synonym synonym}.
65 * @created 08-Nov-2007 13:06:57
67 @XmlAccessorType(XmlAccessType
.FIELD
)
68 @XmlType(name
= "TaxonNameBase", propOrder
= {
70 "nomenclaturalMicroReference",
71 "nomenclaturalReference",
74 "nameTypeDesignations",
75 "specimenTypeDesignations",
76 "relationsFromThisName",
77 "relationsToThisName",
83 @Inheritance(strategy
=InheritanceType
.SINGLE_TABLE
)
84 @Table(appliesTo
="TaxonNameBase", indexes
= { @Index(name
= "taxonNameBaseTitleCacheIndex", columnNames
= { "persistentTitleCache" }) })
85 public abstract class TaxonNameBase
<T
extends TaxonNameBase
, S
extends INameCacheStrategy
> extends IdentifiableEntity
<TaxonNameBase
> implements IReferencedEntity
, IParsable
, IRelated
{
87 static Logger logger
= Logger
.getLogger(TaxonNameBase
.class);
89 private static Method methodDescriptionSetTaxonName
;
91 @XmlElementWrapper(name
= "Descriptions")
92 @XmlElement(name
= "Description")
93 private Set
<TaxonNameDescription
> descriptions
= new HashSet
<TaxonNameDescription
>();
95 @XmlElement(name
= "AppendedPhrase")
96 private String appendedPhrase
;
98 @XmlElement(name
= "NomenclaturalMicroReference")
99 private String nomenclaturalMicroReference
;
102 private boolean hasProblem
= false;
104 @XmlElementWrapper(name
= "NameTypeDesignations")
105 @XmlElement(name
= "NameTypeDesignation")
106 protected Set
<NameTypeDesignation
> nameTypeDesignations
= new HashSet
<NameTypeDesignation
>();
108 @XmlElementWrapper(name
= "SpecimenTypeDesignations")
109 @XmlElement(name
= "SpecimenTypeDesignation")
110 private Set
<SpecimenTypeDesignation
> specimenTypeDesignations
= new HashSet
<SpecimenTypeDesignation
>();
112 // List homotypical groups here in TaxonomicNames or separately?
113 // FIXME: Stack overflow if listed here.
114 @XmlElement(name
= "HomotypicalGroup")
116 @XmlSchemaType(name
= "IDREF")
117 private HomotypicalGroup homotypicalGroup
= new HomotypicalGroup();
119 @XmlElementWrapper(name
= "RelationsFromThisName")
120 @XmlElement(name
= "RelationFromThisName")
122 private Set
<NameRelationship
> relationsFromThisName
= new HashSet
<NameRelationship
>();
124 @XmlElementWrapper(name
= "RelationsToThisName")
125 @XmlElement(name
= "RelationToThisName")
127 private Set
<NameRelationship
> relationsToThisName
= new HashSet
<NameRelationship
>();
129 @XmlElementWrapper(name
= "Statuses")
130 @XmlElement(name
= "Status")
132 private Set
<NomenclaturalStatus
> status
= new HashSet
<NomenclaturalStatus
>();
135 //@XmlElementWrapper(name = "TaxonBases")
136 //@XmlElement(name = "TaxonBase")
137 private Set
<TaxonBase
> taxonBases
= new HashSet
<TaxonBase
>();
139 @XmlElement(name
= "Rank")
141 @XmlSchemaType(name
= "IDREF")
144 // FIXME: This must be an IDREF to the corresponding nomenclatural reference.
146 private INomenclaturalReference nomenclaturalReference
;
148 static Method methodTaxonBaseSetName
;
150 // ************* CONSTRUCTORS *************/
152 * Class constructor: creates a new empty taxon name.
154 * @see #TaxonNameBase(Rank)
155 * @see #TaxonNameBase(HomotypicalGroup)
156 * @see #TaxonNameBase(Rank, HomotypicalGroup)
158 public TaxonNameBase() {
162 * Class constructor: creates a new taxon name
163 * only containing its {@link common.Rank rank}.
165 * @param rank the rank to be assigned to this taxon name
166 * @see #TaxonNameBase()
167 * @see #TaxonNameBase(HomotypicalGroup)
168 * @see #TaxonNameBase(Rank, HomotypicalGroup)
170 public TaxonNameBase(Rank rank
) {
174 * Class constructor: creates a new taxon name
175 * only containing its {@link HomotypicalGroup homotypical group}.
176 * The new taxon name will be also added to the set of taxon names
177 * belonging to this homotypical group.
179 * @param homotypicalGroup the homotypical group to which this taxon name belongs
180 * @see #TaxonNameBase()
181 * @see #TaxonNameBase(Rank)
182 * @see #TaxonNameBase(Rank, HomotypicalGroup)
184 public TaxonNameBase(HomotypicalGroup homotypicalGroup
) {
185 this(null, homotypicalGroup
);
188 * Class constructor: creates a new taxon name
189 * only containing its {@link common.Rank rank} and
190 * its {@link HomotypicalGroup homotypical group}.
191 * The new taxon name will be also added to the set of taxon names
192 * belonging to this homotypical group.
194 * @param rank the rank to be assigned to this taxon name
195 * @param homotypicalGroup the homotypical group to which this taxon name belongs
196 * @see #TaxonNameBase()
197 * @see #TaxonNameBase(Rank)
198 * @see #TaxonNameBase(HomotypicalGroup)
200 public TaxonNameBase(Rank rank
, HomotypicalGroup homotypicalGroup
) {
203 if (homotypicalGroup
== null){
204 homotypicalGroup
= new HomotypicalGroup();
206 homotypicalGroup
.addTypifiedName(this);
209 //********* METHODS **************************************/
211 //@Index(name="TaxonNameBaseTitleCacheIndex")
212 // public String getTitleCache(){
213 // return super.getTitleCache();
217 * Returns the boolean value "false" since the components of this taxon name
218 * cannot follow the rules of a corresponding {@link NomenclaturalCode nomenclatural code}
219 * which is not defined for this class. The nomenclature code depends on
220 * the concrete name subclass ({@link BacterialName BacterialName},
221 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName},
222 * {@link ZoologicalName ZoologicalName} or {@link ViralName ViralName})
223 * to which a taxon name belongs.
228 public abstract boolean isCodeCompliant();
232 * Returns the set of all {@link NameRelationship name relationships}
233 * in which this taxon name is involved. A taxon name can be both source
234 * in some name relationships or target in some others.
236 * @see #getRelationsToThisName()
237 * @see #getRelationsFromThisName()
238 * @see #addNameRelationship(NameRelationship)
239 * @see #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
240 * @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
243 public Set
<NameRelationship
> getNameRelations() {
244 Set
<NameRelationship
> rels
= new HashSet
<NameRelationship
>();
245 rels
.addAll(getRelationsFromThisName());
246 rels
.addAll(getRelationsToThisName());
250 * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from this taxon name to another taxon name
251 * and adds it both to the set of {@link #getRelationsFromThisName() relations from this taxon name} and
252 * to the set of {@link #getRelationsToThisName() relations to the other taxon name}.
254 * @param toName the taxon name of the target for this new name relationship
255 * @param type the type of this new name relationship
256 * @param ruleConsidered the string which specifies the rule on which this name relationship is based
257 * @see #getRelationsToThisName()
258 * @see #getNameRelations()
259 * @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
260 * @see #addNameRelationship(NameRelationship)
262 public void addRelationshipToName(TaxonNameBase toName
, NameRelationshipType type
, String ruleConsidered
){
263 NameRelationship rel
= new NameRelationship(toName
, this, type
, ruleConsidered
);
266 * Creates a new {@link NameRelationship#NameRelationship(TaxonNameBase, TaxonNameBase, NameRelationshipType, String) name relationship} from another taxon name to this taxon name
267 * and adds it both to the set of {@link #getRelationsToThisName() relations to this taxon name} and
268 * to the set of {@link #getRelationsFromThisName() relations from the other taxon name}.
270 * @param fromName the taxon name of the source for this new name relationship
271 * @param type the type of this new name relationship
272 * @param ruleConsidered the string which specifies the rule on which this name relationship is based
273 * @see #getRelationsFromThisName()
274 * @see #getNameRelations()
275 * @see #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
276 * @see #addNameRelationship(NameRelationship)
278 public void addRelationshipFromName(TaxonNameBase fromName
, NameRelationshipType type
, String ruleConsidered
){
279 NameRelationship rel
= new NameRelationship(this, fromName
, type
, ruleConsidered
);
282 * Adds an existing {@link NameRelationship name relationship} either to the set of
283 * {@link #getRelationsToThisName() relations to this taxon name} or to the set of
284 * {@link #getRelationsFromThisName() relations from this taxon name}. If neither the
285 * source nor the target of the name relationship match with this taxon
286 * no addition will be carried out.
288 * @param rel the name relationship to be added to one of this taxon name's name relationships sets
289 * @see #getNameRelations()
290 * @see #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
291 * @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
293 protected void addNameRelationship(NameRelationship rel
) {
294 if (rel
!=null && rel
.getToName().equals(this)){
295 this.relationsToThisName
.add(rel
);
296 }else if(rel
!=null && rel
.getFromName().equals(this)){
297 this.relationsFromThisName
.add(rel
);
299 //TODO: raise error???
303 * Removes one {@link NameRelationship name relationship} from one of both sets of
304 * {@link #getNameRelations() name relationships} in which this taxon name is involved.
305 * The name relationship will also be removed from one of both sets belonging
306 * to the second taxon name involved. Furthermore the fromName and toName
307 * attributes of the name relationship object will be nullified.
309 * @param nameRelation the name relationship which should be deleted from one of both sets
310 * @see #getNameRelations()
312 public void removeNameRelationship(NameRelationship nameRelation
) {
313 //TODO to be implemented?
314 logger
.warn("not yet fully implemented?");
315 this.relationsToThisName
.remove(nameRelation
);
316 this.relationsFromThisName
.remove(nameRelation
);
321 * Does exactly the same as the addNameRelationship method provided that
322 * the given relationship is a name relationship.
324 * @param relation the relationship to be added to one of this taxon name's name relationships sets
325 * @see #addNameRelationship(NameRelationship)
326 * @see #getNameRelations()
327 * @see NameRelationship
328 * @see common.RelationshipBase
330 public void addRelationship(RelationshipBase relation
) {
331 if (relation
instanceof NameRelationship
){
332 addNameRelationship((NameRelationship
)relation
);
333 if (relation
.getType() != null &&
334 ( relation
.getType().equals(NameRelationshipType
.BASIONYM()) ||
335 relation
.getType().equals(NameRelationshipType
.REPLACED_SYNONYM())
337 TaxonNameBase fromName
= ((NameRelationship
)relation
).getFromName();
338 TaxonNameBase toName
= ((NameRelationship
)relation
).getToName();
339 fromName
.getHomotypicalGroup().merge(toName
.getHomotypicalGroup());
342 logger
.warn("Relationship not of type NameRelationship!");
343 //TODO exception handling
349 * Returns the set of all {@link NameRelationship name relationships}
350 * in which this taxon name is involved as a source.
352 * @see #getNameRelations()
353 * @see #getRelationsToThisName()
354 * @see #addRelationshipFromName(TaxonNameBase, NameRelationshipType, String)
356 @OneToMany(mappedBy
="relatedFrom", fetch
= FetchType
.LAZY
)
357 @Cascade({CascadeType
.SAVE_UPDATE
})
358 public Set
<NameRelationship
> getRelationsFromThisName() {
359 return relationsFromThisName
;
361 private void setRelationsFromThisName(Set
<NameRelationship
> relationsFromThisName
) {
362 this.relationsFromThisName
= relationsFromThisName
;
366 * Returns the set of all {@link NameRelationship name relationships}
367 * in which this taxon name is involved as a target.
369 * @see #getNameRelations()
370 * @see #getRelationsFromThisName()
371 * @see #addRelationshipToName(TaxonNameBase, NameRelationshipType, String)
373 @OneToMany(mappedBy
="relatedTo", fetch
= FetchType
.LAZY
)
374 @Cascade({CascadeType
.SAVE_UPDATE
})
375 public Set
<NameRelationship
> getRelationsToThisName() {
376 return relationsToThisName
;
378 private void setRelationsToThisName(Set
<NameRelationship
> relationsToThisName
) {
379 this.relationsToThisName
= relationsToThisName
;
384 * Returns the set of {@link NomenclaturalStatus nomenclatural status} assigned
385 * to this taxon name according to its corresponding nomenclature code.
386 * This includes the {@link NomenclaturalStatusType type} of the nomenclatural status
387 * and the nomenclatural code rule considered.
389 * @see NomenclaturalStatus
390 * @see NomenclaturalStatusType
392 @OneToMany(fetch
= FetchType
.LAZY
)
393 @Cascade({CascadeType
.SAVE_UPDATE
})
394 public Set
<NomenclaturalStatus
> getStatus() {
400 protected void setStatus(Set
<NomenclaturalStatus
> nomStatus
) {
401 this.status
= nomStatus
;
404 * Adds a new {@link NomenclaturalStatus nomenclatural status}
405 * to this taxon name's set of nomenclatural status.
407 * @param nomStatus the nomenclatural status to be added
410 public void addStatus(NomenclaturalStatus nomStatus
) {
411 this.status
.add(nomStatus
);
414 * Removes one element from the set of nomenclatural status of this taxon name.
415 * Type and ruleConsidered attributes of the nomenclatural status object
418 * @param nomStatus the nomenclatural status of this taxon name which should be deleted
421 public void removeStatus(NomenclaturalStatus nomStatus
) {
422 //TODO to be implemented?
423 logger
.warn("not yet fully implemented?");
424 this.status
.remove(nomStatus
);
429 * Indicates whether this taxon name is a {@link NameRelationshipType.BASIONYM() basionym}
430 * or a {@link NameRelationshipType.REPLACED_SYNONYM() replaced synonym}
431 * of any other taxon name. Returns "true", if a basionym or a replaced
432 * synonym relationship from this taxon name to another taxon name exists,
433 * false otherwise (also in case this taxon name is the only one in the
434 * homotypical group).
437 public boolean isOriginalCombination(){
438 Set
<NameRelationship
> relationsFromThisName
= this.getRelationsFromThisName();
439 for (NameRelationship relation
: relationsFromThisName
) {
440 if (relation
.getType().equals(NameRelationshipType
.BASIONYM()) ||
441 relation
.getType().equals(NameRelationshipType
.REPLACED_SYNONYM())) {
449 * Returns the taxon name which is the {@link NameRelationshipType.BASIONYM() basionym} of this taxon name.
450 * The basionym of a taxon name is its epithet-bringing synonym.
451 * For instance Pinus abies L. was published by Linnaeus and the botanist
452 * Karsten transferred later this taxon to the genus Picea. Therefore,
453 * Pinus abies L. is the basionym of the new combination Picea abies (L.) H. Karst.
456 public T
getBasionym(){
457 //TODO: pick the right name relationships...
458 logger
.warn("get Basionym not yet implemented");
462 * Assigns another taxon name as {@link NameRelationshipType.BASIONYM() basionym} of this taxon name.
463 * The basionym relationship will be added to this taxon name
464 * and to the basionym. The basionym cannot have itself a basionym.
465 * The homotypical group of this taxon name will be changed the basionyms homotypical group.
466 * @see #getBasionym()
467 * @see #addBasionym(TaxonNameBase, String)
469 public void addBasionym(T basionym
){
470 addBasionym(basionym
, null);
473 * Assigns another taxon name as {@link NameRelationshipType.BASIONYM() basionym} of this taxon name
474 * and keeps the nomenclatural rule considered for it. The basionym
475 * relationship will be added to this taxon name and to the basionym.
476 * The basionym cannot have itself as a basionym.
477 * The homotypical group of this taxon name will be changed the basionyms homotypical group.
478 * @see #getBasionym()
479 * @see #setBasionym(TaxonNameBase)
481 public void addBasionym(T basionym
, String ruleConsidered
){
482 if (basionym
!= null){
483 basionym
.addRelationshipToName(this, NameRelationshipType
.BASIONYM(), ruleConsidered
);
487 public void removeBasionym(){
489 logger
.warn("not yet implemented");
495 public abstract S
getCacheStrategy();
496 public abstract void setCacheStrategy(S cacheStrategy
);
499 * Returns the taxonomic {@link Rank rank} of this taxon name.
504 //@Cascade({CascadeType.SAVE_UPDATE})
505 public Rank
getRank(){
511 public void setRank(Rank rank
){
516 * Returns the {@link reference.INomenclaturalReference nomenclatural reference} of this taxon name.
517 * The nomenclatural reference is here meant to be the one publication
518 * this taxon name was originally published in while fulfilling the formal
519 * requirements as specified by the corresponding nomenclatural code.
521 * @see reference.INomenclaturalReference
522 * @see reference.ReferenceBase
525 @Cascade({CascadeType
.SAVE_UPDATE
})
526 @Target(ReferenceBase
.class)
527 public INomenclaturalReference
getNomenclaturalReference(){
528 return (INomenclaturalReference
) this.nomenclaturalReference
;
531 * Assigns a nomenclatural {@link reference.INomenclaturalReference nomenclatural reference} to this taxon name.
532 * The corresponding {@link reference.ReferenceBase.isNomenclaturallyRelevant nomenclaturally relevant flag} will be set to true
533 * as it is obviously used for nomenclatural purposes.
535 * @see #getNomenclaturalReference()
537 public void setNomenclaturalReference(INomenclaturalReference nomenclaturalReference
){
538 this.nomenclaturalReference
= nomenclaturalReference
;
542 * Returns the appended phrase string assigned to this taxon name.
543 * The appended phrase is a non-atomised addition to a name. It is
544 * not ruled by a nomenclatural code.
546 public String
getAppendedPhrase(){
547 return this.appendedPhrase
;
550 * @see #getAppendedPhrase()
552 public void setAppendedPhrase(String appendedPhrase
){
553 this.appendedPhrase
= appendedPhrase
;
557 * Returns the details string of the nomenclatural reference assigned
558 * to this taxon name. The details describe the exact localisation within
559 * the publication used as nomenclature reference. These are mostly
560 * (implicitly) pages but can also be figures or tables or any other
561 * element of a publication. A nomenclatural micro reference (details)
562 * requires the existence of a nomenclatural reference.
564 //Details of the nomenclatural reference (protologue).
565 public String
getNomenclaturalMicroReference(){
566 return this.nomenclaturalMicroReference
;
569 * @see #getNomenclaturalMicroReference()
571 public void setNomenclaturalMicroReference(String nomenclaturalMicroReference
){
572 this.nomenclaturalMicroReference
= nomenclaturalMicroReference
;
576 * Returns the boolean value of the flag indicating whether the used {@link eu.etaxonomy.cdm.strategy.parser.INonViralNameParser parser}
577 * method was able to parse the taxon name string successfully (false)
578 * or not (true). The parser itself may also depend on the {@link NomenclaturalCode nomenclatural code}
579 * governing the construction of this taxon name.
581 * @return the boolean value of the hasProblem flag
582 * @see #getNameCache()
584 public boolean getHasProblem(){
585 return this.hasProblem
;
588 * @see #getHasProblem()
590 public void setHasProblem(boolean hasProblem
){
591 this.hasProblem
= hasProblem
;
594 * Returns exactly the same boolean value as the {@link #getHasProblem() getHasProblem} method.
596 * @see #getHasProblem()
598 public boolean hasProblem(){
599 return getHasProblem();
604 * Returns the set of {@link NameTypeDesignation name type designations} assigned
605 * to this taxon name the rank of which must be above "species".
606 * The name type designations include all the taxon names used to typify
607 * this name and eventually the rejected or conserved status
608 * of these designations.
610 * @see NameTypeDesignation
611 * @see SpecimenTypeDesignation
614 //TODO @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN})
615 @Cascade(CascadeType
.SAVE_UPDATE
)
616 public Set
<NameTypeDesignation
> getNameTypeDesignations() {
617 return nameTypeDesignations
;
620 * @see #getNameTypeDesignations()
622 protected void setNameTypeDesignations(Set
<NameTypeDesignation
> nameTypeDesignations
) {
623 this.nameTypeDesignations
= nameTypeDesignations
;
628 * Creates and adds a new {@link NameTypeDesignation name type designation}
629 * to this taxon name's set of name type designations.
631 * @param typeSpecies the taxon name to be used as type of this taxon name
632 * @param citation the reference for this new designation
633 * @param citationMicroReference the string with the details (generally pages) within the reference
634 * @param originalNameString the taxon name string used in the reference to assert this designation
635 * @param isRejectedType the boolean status for rejected
636 * @param isConservedType the boolean status for conserved
637 * @see #getNameTypeDesignations()
638 * @see #addTypeDesignation(Specimen, TypeDesignationStatus, ReferenceBase, String, String)
640 public void addNameTypeDesignation(TaxonNameBase typeSpecies
, ReferenceBase citation
, String citationMicroReference
, String originalNameString
, boolean isRejectedType
, boolean isConservedType
) {
641 NameTypeDesignation td
= new NameTypeDesignation(this, typeSpecies
, citation
, citationMicroReference
, originalNameString
, isRejectedType
, isConservedType
);
645 * Removes one element from the set of {@link NameTypeDesignation name type designations} of this taxon name.
646 * The name type designation itself will be nullified.
648 * @param typeDesignation the name type designation of this taxon name which should be deleted
649 * @see #getNameTypeDesignations()
650 * @see #removeTypeDesignation(SpecimenTypeDesignation)
652 public void removeNameTypeDesignation(NameTypeDesignation typeDesignation
) {
654 logger
.warn("not yet fully implemented: nullify the name type designation itself?");
655 this.nameTypeDesignations
.remove(typeDesignation
);
659 * Returns the set of {@link SpecimenTypeDesignation specimen type designations}
660 * that typify this taxon name.
663 @Cascade(CascadeType
.SAVE_UPDATE
)
664 public Set
<SpecimenTypeDesignation
> getSpecimenTypeDesignations() {
665 return specimenTypeDesignations
;
668 * @see #getSpecimenTypeDesignations()
670 protected void setSpecimenTypeDesignations(Set
<SpecimenTypeDesignation
> specimenTypeDesignations
) {
671 this.specimenTypeDesignations
= specimenTypeDesignations
;
675 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} assigned
676 * indirectly to this taxon name through its {@link HomotypicalGroup homotypical group}.
677 * The rank of this taxon name is generally "species" or below.
678 * The specimen type designations include all the specimens on which
679 * the typification of this name is based (and which are common to all
680 * taxon names belonging to the homotypical group) and eventually
681 * the status of these designations.
683 * @see SpecimenTypeDesignation
684 * @see NameTypeDesignation
687 public Set
<SpecimenTypeDesignation
> getSpecimenTypeDesignationsOfHomotypicalGroup() {
688 return this.getHomotypicalGroup().getTypeDesignations();
692 * Adds a new {@link SpecimenTypeDesignation specimen type designation}
693 * (using its attributes as parameters) to the set of specimen type designations assigned to the
694 * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
696 * @param typeSpecimen the specimen to be used as a type for this taxon name's homotypical group
697 * @param status the specimen type designation status
698 * @param citation the reference for this new specimen type designation
699 * @param citationMicroReference the string with the details (generally pages) within the reference
700 * @param originalNameString the taxon name used in the reference to assert this designation
701 * @see HomotypicalGroup#getTypeDesignations()
702 * @see #addTypeDesignation(TaxonNameBase, ReferenceBase, String, String, boolean, boolean)
703 * @see TypeDesignationStatus
705 public void addSpecimenTypeDesignation(Specimen typeSpecimen
, TypeDesignationStatus status
, ReferenceBase citation
, String citationMicroReference
, String originalNameString
, boolean addToAllNames
) {
706 SpecimenTypeDesignation specimenTypeDesignation
=
707 SpecimenTypeDesignation
.NewInstance(typeSpecimen
, status
, citation
, citationMicroReference
, originalNameString
);
708 this.getHomotypicalGroup().addTypeDesignation(specimenTypeDesignation
, addToAllNames
);
711 //only to be used for xxx
713 * Adds a new {@link SpecimenTypeDesignation specimen type designation}
714 * to the set of specimen type designations assigned to the
715 * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
717 * @param specimenTypeDesignation the specimen type designation to be added for this taxon name's homotypical group
718 * @see #addSpecimenTypeDesignation(Specimen, TypeDesignationStatus, ReferenceBase, String, String, boolean)
719 * @see HomotypicalGroup#getTypeDesignations()
720 * @see #addTypeDesignation(TaxonNameBase, ReferenceBase, String, String, boolean, boolean)
722 protected void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation
) {
723 this.specimenTypeDesignations
.add(specimenTypeDesignation
);
726 //only to be used for xxx
728 * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
729 * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
731 * @param SpecimenTypeDesignation the specimen type designation which should be deleted
732 * @see HomotypicalGroup#getTypeDesignations()
733 * @see #removeTypeDesignation(SpecimenTypeDesignation)
734 * @see #removeNameTypeDesignation(NameTypeDesignation)
736 protected void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation
) {
737 this.specimenTypeDesignations
.remove(specimenTypeDesignation
);
741 * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
742 * {@link HomotypicalGroup homotypical group} to which this taxon name belongs.
743 * The specimen type designation itself will be nullified.
745 * @param typeDesignation the specimen type designation which should be deleted
746 * @see HomotypicalGroup#getTypeDesignations()
747 * @see #removeSpecimenTypeDesignation(SpecimenTypeDesignation)
748 * @see #removeNameTypeDesignation(NameTypeDesignation)
750 public void removeTypeDesignation(SpecimenTypeDesignation typeDesignation
) {
751 logger
.warn("not yet fully implemented: nullify the specimen type designation itself?");
752 this.homotypicalGroup
.removeTypeDesignation(typeDesignation
);
756 * Returns the {@link HomotypicalGroup homotypical group} to which
757 * this taxon name belongs. A homotypical group represents all taxon names
758 * that share the same type specimens.
760 * @see HomotypicalGroup
763 @Cascade({CascadeType
.SAVE_UPDATE
})
764 public HomotypicalGroup
getHomotypicalGroup() {
765 return homotypicalGroup
;
767 @Deprecated //only for bidirectional and persistence use
768 protected void setHomotypicalGroup(HomotypicalGroup newHomotypicalGroup
) {
769 this.homotypicalGroup
= newHomotypicalGroup
;
773 * @see #getNomenclaturalReference()
776 public StrictReferenceBase
getCitation(){
777 //TODO What is the purpose of this method differing from the getNomenclaturalReference method?
778 logger
.warn("getCitation not yet implemented");
783 * Returns the complete string containing the
784 * {@link reference.INomenclaturalReference#getNomenclaturalCitation() nomenclatural reference citation}
785 * (including {@link #getNomenclaturalMicroReference() details}) assigned to this taxon name.
787 * @return the string containing the nomenclatural reference of this taxon name
788 * @see reference.INomenclaturalReference#getNomenclaturalCitation()
789 * @see #getNomenclaturalReference()
790 * @see #getNomenclaturalMicroReference()
793 public String
getCitationString(){
794 logger
.warn("getCitationString not yet implemented");
799 public String
[] getProblems(){
800 logger
.warn("getProblems not yet implemented");
805 * Returns the string containing the publication date (generally only year)
806 * of the nomenclatural reference for this taxon name, null if there is
807 * no nomenclatural reference.
809 * @return the string containing the publication date of this taxon name
810 * @see reference.INomenclaturalReference#getYear()
813 public String
getReferenceYear(){
814 if (this.getNomenclaturalReference() != null ){
815 return this.getNomenclaturalReference().getYear();
822 * Returns the set of {@link taxon.TaxonBase taxon bases} that refer to this taxon name.
823 * In this context a taxon base means the use of a taxon name by a reference
824 * either as a taxon ("accepted/correct" name) or as a (junior) synonym.
825 * A taxon name can be used by several distinct references but only once
826 * within a taxonomic treatment (identified by one reference).
828 * @see taxon.TaxonBase
830 * @see #getSynonyms()
832 @OneToMany(mappedBy
="name", fetch
= FetchType
.LAZY
)
833 public Set
<TaxonBase
> getTaxonBases() {
834 return this.taxonBases
;
837 * @see #getTaxonBases()
839 protected void setTaxonBases(Set
<TaxonBase
> taxonBases
) {
840 if (taxonBases
== null){
841 taxonBases
= new HashSet
<TaxonBase
>();
843 this.taxonBases
= taxonBases
;
847 * Adds a new {@link taxon.TaxonBase taxon base}
848 * to the set of taxon bases using this taxon name.
850 * @param taxonBase the taxon base to be added
851 * @see #getTaxonBases()
852 * @see #removeTaxonBase(TaxonBase)
855 public void addTaxonBase(TaxonBase taxonBase
){
856 taxonBases
.add(taxonBase
);
858 invokeSetMethod(methodTaxonBaseSetName
, taxonBase
);
861 * Removes one element from the set of {@link taxon.TaxonBase taxon bases} that refer to this taxon name.
863 * @param taxonBase the taxon base which should be removed from the corresponding set
864 * @see #addTaxonBase(TaxonBase)
866 public void removeTaxonBase(TaxonBase taxonBase
){
867 taxonBases
.remove(taxonBase
);
869 invokeSetMethodWithNull(methodTaxonBaseSetName
, taxonBase
);
872 private void initMethods(){
873 if (methodTaxonBaseSetName
== null){
875 methodTaxonBaseSetName
= TaxonBase
.class.getDeclaredMethod("setName", TaxonNameBase
.class);
876 methodTaxonBaseSetName
.setAccessible(true);
877 } catch (Exception e
) {
879 //TODO handle exception
882 if (methodDescriptionSetTaxonName
== null){
884 methodDescriptionSetTaxonName
= TaxonNameDescription
.class.getDeclaredMethod("setTaxonName", TaxonNameBase
.class);
885 methodDescriptionSetTaxonName
.setAccessible(true);
886 } catch (Exception e
) {
888 //TODO handle exception
896 * Returns the set of {@link taxon.Taxon taxa} ("accepted/correct" names according to any
897 * reference) that are based on this taxon name. This set is a subset of
898 * the set returned by getTaxonBases().
901 * @see #getTaxonBases()
902 * @see #getSynonyms()
905 public Set
<Taxon
> getTaxa(){
906 Set
<Taxon
> result
= new HashSet
<Taxon
>();
907 for (TaxonBase taxonBase
: this.taxonBases
){
908 if (taxonBase
instanceof Taxon
){
909 result
.add((Taxon
)taxonBase
);
916 * Returns the set of {@link taxon.Synonym (junior) synonyms} (according to any
917 * reference) that are based on this taxon name. This set is a subset of
918 * the set returned by getTaxonBases().
921 * @see #getTaxonBases()
925 public Set
<Synonym
> getSynonyms() {
926 Set
<Synonym
> result
= new HashSet
<Synonym
>();
927 for (TaxonBase taxonBase
: this.taxonBases
){
928 if (taxonBase
instanceof Synonym
){
929 result
.add((Synonym
)taxonBase
);
936 // *********** DESCRIPTIONS *************************************
938 @OneToMany(mappedBy
="taxonName", fetch
= FetchType
.LAZY
)
939 @Cascade({CascadeType
.SAVE_UPDATE
})
940 public Set
<TaxonNameDescription
> getDescriptions() {
943 protected void setDescriptions(Set
<TaxonNameDescription
> descriptions
) {
944 this.descriptions
= descriptions
;
947 * Adds a description to this taxon. Set the taxon property of description to this taxon.
950 public void addDescription(TaxonNameDescription description
) {
952 this.invokeSetMethod(methodDescriptionSetTaxonName
, description
);
953 descriptions
.add(description
);
955 public void removeDescription(TaxonNameDescription description
) {
957 this.invokeSetMethod(methodDescriptionSetTaxonName
, null);
958 descriptions
.remove(description
);
968 * Returns the boolean value indicating whether a given taxon name belongs
969 * to the same {@link HomotypicalGroup homotypical group} as this taxon name (true)
970 * or not (false). Returns "true" only if the homotypical groups of both
971 * taxon names exist and if they are identical.
973 * @param homoTypicName the taxon name the homotypical group of which is to be checked
974 * @return the boolean value of the check
975 * @see HomotypicalGroup
977 public boolean isHomotypic(TaxonNameBase homoTypicName
) {
978 if (homoTypicName
== null) {
981 HomotypicalGroup homotypicGroup
= homoTypicName
.getHomotypicalGroup();
982 if (homotypicGroup
== null || this.getHomotypicalGroup() == null) {
985 if (homotypicGroup
.equals(this.getHomotypicalGroup())) {
993 //********* Rank comparison shortcuts ********************//
995 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of this
996 * taxon name is higher than the genus rank (true) or not (false).
997 * Suprageneric non viral names are monomials.
998 * Returns false if rank is null.
1001 * @see #isInfraGeneric()
1003 * @see #isInfraSpecific()
1006 public boolean isSupraGeneric() {
1010 return getRank().isSupraGeneric();
1013 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of this
1014 * taxon name is the genus rank (true) or not (false). Non viral names with
1015 * genus rank are monomials.
1016 * Returns false if rank is null.
1018 * @see #isSupraGeneric()
1019 * @see #isInfraGeneric()
1021 * @see #isInfraSpecific()
1024 public boolean isGenus() {
1028 return getRank().isGenus();
1031 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of this
1032 * taxon name is higher than the species aggregate rank and lower than
1033 * the genus rank (true) or not (false). Infrageneric non viral names
1035 * Returns false if rank is null.
1037 * @see #isSupraGeneric()
1040 * @see #isInfraSpecific()
1043 public boolean isInfraGeneric() {
1047 return getRank().isInfraGeneric();
1050 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of this
1051 * taxon name is the species or species aggregate rank (true) or not (false). Non viral names
1052 * with species rank are binomials.
1053 * Returns false if rank is null.
1055 * @see #isSupraGeneric()
1057 * @see #isInfraGeneric()
1058 * @see #isInfraSpecific()
1061 public boolean isSpecies() {
1065 return getRank().isSpecies();
1068 * Returns the boolean value indicating whether the taxonomic {@link Rank rank} of this
1069 * taxon name is lower than the species rank (true) or not (false).
1070 * Infraspecific non viral names are trinomials.
1071 * Returns false if rank is null.
1073 * @see #isSupraGeneric()
1075 * @see #isInfraGeneric()
1079 public boolean isInfraSpecific() {
1083 return getRank().isInfraSpecific();
1088 * Returns null as the {@link NomenclaturalCode nomenclatural code} that governs
1089 * the construction of this taxon name since there is no specific
1090 * nomenclatural code defined. The real implementention takes place in the
1091 * subclasses {@link ViralName ViralName}, {@link BacterialName BacterialName},
1092 * {@link BotanicalName BotanicalName}, {@link CultivarPlantName CultivarPlantName} and
1093 * {@link ZoologicalName ZoologicalName}. Each taxon name is governed by one
1094 * and only one nomenclatural code.
1097 * @see #isCodeCompliant()
1098 * @see #getHasProblem()
1101 abstract public NomenclaturalCode
getNomenclaturalCode();
1103 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
1106 * Generates and returns the string with the scientific name of this
1108 * This string may be stored in the inherited
1109 * {@link common.IdentifiableEntity#getTitleCache() titleCache} attribute.
1110 * This method overrides the generic and inherited
1111 * IdentifiableEntity#generateTitle() method.
1113 * @return the string with the composed name of this non viral taxon name with authorship (and maybe year)
1114 * @see common.IdentifiableEntity#generateTitle()
1115 * @see common.IdentifiableEntity#getTitleCache()
1118 public String
generateTitle() {
1119 // TODO Auto-generated method stub
1120 logger
.warn("not yet implemented");