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
.taxon
;
13 import java
.lang
.reflect
.Field
;
14 import java
.util
.ArrayList
;
15 import java
.util
.Collections
;
16 import java
.util
.HashMap
;
17 import java
.util
.HashSet
;
18 import java
.util
.Iterator
;
19 import java
.util
.List
;
23 import javax
.persistence
.Entity
;
24 import javax
.persistence
.FetchType
;
25 import javax
.persistence
.ManyToOne
;
26 import javax
.persistence
.OneToMany
;
27 import javax
.persistence
.Transient
;
28 import javax
.validation
.Valid
;
29 import javax
.validation
.constraints
.NotNull
;
30 import javax
.xml
.bind
.annotation
.XmlAccessType
;
31 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
32 import javax
.xml
.bind
.annotation
.XmlAttribute
;
33 import javax
.xml
.bind
.annotation
.XmlElement
;
34 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
35 import javax
.xml
.bind
.annotation
.XmlIDREF
;
36 import javax
.xml
.bind
.annotation
.XmlRootElement
;
37 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
38 import javax
.xml
.bind
.annotation
.XmlType
;
40 import org
.apache
.log4j
.Logger
;
41 import org
.hibernate
.annotations
.Cascade
;
42 import org
.hibernate
.annotations
.CascadeType
;
43 import org
.hibernate
.envers
.Audited
;
44 import org
.hibernate
.search
.annotations
.ClassBridge
;
45 import org
.hibernate
.search
.annotations
.ClassBridges
;
46 import org
.hibernate
.search
.annotations
.ContainedIn
;
47 import org
.hibernate
.search
.annotations
.Indexed
;
48 import org
.hibernate
.search
.annotations
.IndexedEmbedded
;
49 import org
.springframework
.beans
.factory
.annotation
.Configurable
;
50 import org
.springframework
.util
.ReflectionUtils
;
52 import eu
.etaxonomy
.cdm
.hibernate
.search
.GroupByTaxonClassBridge
;
53 import eu
.etaxonomy
.cdm
.hibernate
.search
.TaxonRelationshipClassBridge
;
54 import eu
.etaxonomy
.cdm
.model
.common
.IPublishable
;
55 import eu
.etaxonomy
.cdm
.model
.common
.IRelated
;
56 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
57 import eu
.etaxonomy
.cdm
.model
.description
.IDescribable
;
58 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
59 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
60 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
61 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
62 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
63 import eu
.etaxonomy
.cdm
.strategy
.cache
.taxon
.TaxonBaseDefaultCacheStrategy
;
66 * The class for "accepted/correct" {@link TaxonBase taxa} (only these taxa according to
67 * the opinion of the {@link eu.etaxonomy.cdm.model.reference.Reference reference} can build a classification).
68 * An {@link java.lang.Iterable interface} is supported to iterate through taxonomic children.<BR>
69 * Splitting taxa in "accepted/correct" and {@link Synonym "synonyms"} makes it easier to handle
70 * particular relationships between ("accepted/correct") taxa on the one hand
71 * and between ("synonym") taxa and ("accepted/correct") taxa on the other.
75 * @created 08-Nov-2007 13:06:56
77 @XmlAccessorType(XmlAccessType
.FIELD
)
78 @XmlType(name
= "Taxon", propOrder
= {
79 "taxonomicParentCache",
81 "taxonomicChildrenCount",
83 "relationsFromThisTaxon",
84 "relationsToThisTaxon",
88 @XmlRootElement(name
= "Taxon")
90 @Indexed(index
= "eu.etaxonomy.cdm.model.taxon.TaxonBase")
94 @ClassBridge(impl
= GroupByTaxonClassBridge
.class),
95 @ClassBridge(impl
= TaxonRelationshipClassBridge
.class)
97 public class Taxon
extends TaxonBase
<IIdentifiableEntityCacheStrategy
<Taxon
>>
98 implements IRelated
<RelationshipBase
>, IDescribable
<TaxonDescription
>, IPublishable
, Cloneable
{
99 private static final long serialVersionUID
= -584946869762749006L;
100 private static final Logger logger
= Logger
.getLogger(Taxon
.class);
102 @XmlElementWrapper(name
= "Descriptions")
103 @XmlElement(name
= "Description")
104 @OneToMany(mappedBy
="taxon", fetch
= FetchType
.LAZY
)
105 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
108 private Set
<TaxonDescription
> descriptions
= new HashSet
<TaxonDescription
>();
110 // all related synonyms
111 @XmlElementWrapper(name
= "SynonymRelations")
112 @XmlElement(name
= "SynonymRelationship")
113 @OneToMany(mappedBy
="relatedTo", fetch
=FetchType
.LAZY
, orphanRemoval
=true)
114 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
117 private Set
<SynonymRelationship
> synonymRelations
= new HashSet
<SynonymRelationship
>();
119 // all taxa relations with rel.fromTaxon==this
120 @XmlElementWrapper(name
= "RelationsFromThisTaxon")
121 @XmlElement(name
= "FromThisTaxonRelationship")
122 @OneToMany(mappedBy
="relatedFrom", fetch
=FetchType
.LAZY
, orphanRemoval
=true)
123 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
126 private Set
<TaxonRelationship
> relationsFromThisTaxon
= new HashSet
<TaxonRelationship
>();
128 // all taxa relations with rel.toTaxon==this
129 @XmlElementWrapper(name
= "RelationsToThisTaxon")
130 @XmlElement(name
= "ToThisTaxonRelationship")
132 @XmlSchemaType(name
= "IDREF")
133 @OneToMany(mappedBy
="relatedTo", fetch
=FetchType
.LAZY
, orphanRemoval
=true)
134 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
, CascadeType
.DELETE
})
137 private Set
<TaxonRelationship
> relationsToThisTaxon
= new HashSet
<TaxonRelationship
>();
139 @XmlAttribute(name
= "taxonStatusUnknown")
140 private boolean taxonStatusUnknown
= false;
142 @XmlAttribute(name
= "unplaced")
143 private boolean unplaced
= false;
145 @XmlAttribute(name
= "excluded")
146 private boolean excluded
= false;
148 // shortcut to the taxonomicIncluded (parent) taxon. Managed by the taxonRelations setter
149 @XmlElement(name
= "TaxonomicParentCache")
151 @XmlSchemaType(name
= "IDREF")
152 @ManyToOne(fetch
= FetchType
.LAZY
)
153 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
154 private Taxon taxonomicParentCache
;
157 @XmlElementWrapper(name
= "taxonNodes")
158 @XmlElement(name
= "taxonNode")
160 @XmlSchemaType(name
= "IDREF")
161 @OneToMany(mappedBy
="taxon", fetch
=FetchType
.LAZY
)
162 @Cascade({CascadeType
.SAVE_UPDATE
, CascadeType
.MERGE
})
164 private Set
<TaxonNode
> taxonNodes
= new HashSet
<TaxonNode
>();
166 //cached number of taxonomic children
167 @XmlElement(name
= "TaxonomicChildrenCount")
168 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
169 private int taxonomicChildrenCount
;
172 @XmlAttribute(name
= "publish")
173 private boolean publish
= true;
175 // ************************* FACTORY METHODS ********************************/
178 * Creates a new (accepted/correct) taxon instance with
179 * the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
182 * @param taxonNameBase the taxon name used
183 * @param sec the reference using the taxon name
184 * @see #Taxon(TaxonNameBase, Reference)
186 public static Taxon
NewInstance(TaxonNameBase taxonNameBase
, Reference sec
){
187 Taxon result
= new Taxon(taxonNameBase
, sec
);
192 * Creates a new taxon instance with an unknown status (accepted/synonym) and with
193 * the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
196 * @param taxonNameBase the taxon name used
197 * @param sec the reference using the taxon name
198 * @see #Taxon(TaxonNameBase, Reference)
200 public static Taxon
NewUnknownStatusInstance(TaxonNameBase taxonNameBase
, Reference sec
){
201 Taxon result
= new Taxon(taxonNameBase
, sec
);
202 result
.setTaxonStatusUnknown(true);
205 // ************* CONSTRUCTORS *************/
207 //TODO should be private, but still produces Spring init errors
210 this.cacheStrategy
= new TaxonBaseDefaultCacheStrategy
<Taxon
>();
214 * Class constructor: creates a new (accepted/correct) taxon instance with
215 * the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} used and the {@link eu.etaxonomy.cdm.model.reference.Reference reference}
218 * @param taxonNameBase the taxon name used
219 * @param sec the reference using the taxon name
220 * @see TaxonBase#TaxonBase(TaxonNameBase, Reference)
222 public Taxon(TaxonNameBase taxonNameBase
, Reference sec
){
223 super(taxonNameBase
, sec
);
224 this.cacheStrategy
= new TaxonBaseDefaultCacheStrategy
<Taxon
>();
227 //********* METHODS **************************************/
232 * Returns the set of {@link eu.etaxonomy.cdm.model.description.TaxonDescription taxon descriptions}
233 * concerning <i>this</i> taxon.
235 * @see #removeDescription(TaxonDescription)
236 * @see #addDescription(TaxonDescription)
237 * @see eu.etaxonomy.cdm.model.description.TaxonDescription#getTaxon()
240 public Set
<TaxonDescription
> getDescriptions() {
241 if(descriptions
== null) {
242 descriptions
= new HashSet
<TaxonDescription
>();
248 * Adds a new {@link eu.etaxonomy.cdm.model.description.TaxonDescription taxon description} to the set
249 * of taxon descriptions assigned to <i>this</i> (accepted/correct) taxon.
250 * Due to bidirectionality the content of the {@link eu.etaxonomy.cdm.model.description.TaxonDescription#getTaxon() taxon attribute} of the
251 * taxon description itself will be replaced with <i>this</i> taxon. The taxon
252 * description will also be removed from the set of taxon descriptions
253 * assigned to its previous taxon.
255 * @param description the taxon description to be added for <i>this</i> taxon
256 * @see #getDescriptions()
257 * @see #removeDescription(TaxonDescription)
258 * @see eu.etaxonomy.cdm.model.description.TaxonDescription#getTaxon()
261 public void addDescription(TaxonDescription description
) {
262 if (description
.getTaxon() != null){
263 description
.getTaxon().removeDescription(description
);
265 Field field
= ReflectionUtils
.findField(TaxonDescription
.class, "taxon", Taxon
.class);
266 ReflectionUtils
.makeAccessible(field
);
267 ReflectionUtils
.setField(field
, description
, this);
268 descriptions
.add(description
);
272 * Removes one element from the set of {@link eu.etaxonomy.cdm.model.description.TaxonDescription taxon descriptions} assigned
273 * to <i>this</i> (accepted/correct) taxon. Due to bidirectionality the content of
274 * the {@link eu.etaxonomy.cdm.model.description.TaxonDescription#getTaxon() taxon attribute} of the taxon description
275 * itself will be set to "null".
277 * @param description the taxon description which should be removed
278 * @see #getDescriptions()
279 * @see #addDescription(TaxonDescription)
280 * @see eu.etaxonomy.cdm.model.description.TaxonDescription#getTaxon()
283 public void removeDescription(TaxonDescription description
) {
284 //description.setTaxon(null) for not visible method
285 Field field
= ReflectionUtils
.findField(TaxonDescription
.class, "taxon", Taxon
.class);
286 ReflectionUtils
.makeAccessible(field
);
287 ReflectionUtils
.setField(field
, description
, null);
288 descriptions
.remove(description
);
292 * Returns the image gallery for a taxon. If there are multiple taxon descriptions
293 * marked as image galleries an arbitrary one is chosen.
294 * If no image gallery exists, a new one is created if <code>createNewIfNotExists</code>
295 * is <code>true</code>.
296 * @param createNewIfNotExists
299 public TaxonDescription
getImageGallery(boolean createNewIfNotExists
) {
300 TaxonDescription result
= null;
301 Set
<TaxonDescription
> descriptions
= getDescriptions();
302 for (TaxonDescription description
: descriptions
){
303 if (description
.isImageGallery()){
304 result
= description
;
308 if (result
== null && createNewIfNotExists
){
309 result
= TaxonDescription
.NewInstance(this);
310 result
.setImageGallery(true);
317 public Set
<TaxonNode
> getTaxonNodes() {
320 // protected void setTaxonNodes(Set<TaxonNode> taxonNodes) {
321 // this.taxonNodes = taxonNodes;
323 protected void addTaxonNode(TaxonNode taxonNode
){
324 taxonNodes
.add(taxonNode
);
327 public boolean removeTaxonNode(TaxonNode taxonNode
){
328 if (!taxonNodes
.contains(taxonNode
)){
331 TaxonNode parent
= taxonNode
.getParent();
333 parent
.removeChildNode(taxonNode
);
335 taxonNode
.setTaxon(null);
336 return taxonNodes
.remove(taxonNode
);
340 public boolean removeTaxonNode(TaxonNode taxonNode
, boolean deleteChildren
){
341 TaxonNode parent
= taxonNode
.getParent();
342 boolean success
= true;
344 if ((!taxonNode
.getChildNodes().isEmpty() && deleteChildren
) || (taxonNode
.getChildNodes().isEmpty()) ){
348 } else if (!taxonNode
.isTopmostNode()){
349 List
<TaxonNode
> children
= taxonNode
.getChildNodes();
351 for (TaxonNode childNode
: children
){
353 children
.remove(childNode
);
354 parent
.addChildNode(childNode
, null, null);
360 } else if (taxonNode
.isTopmostNode()){
366 public boolean removeTaxonNodes(boolean deleteChildren
){
367 Iterator
<TaxonNode
> nodesIterator
= taxonNodes
.iterator();
370 boolean success
= false;
371 List
<TaxonNode
> removeNodes
= new ArrayList
<TaxonNode
>();
372 while (nodesIterator
.hasNext()){
373 node
= nodesIterator
.next();
374 if (!deleteChildren
){
375 List
<TaxonNode
> children
= node
.getChildNodes();
376 Iterator
<TaxonNode
> childrenIterator
= children
.iterator();
377 parent
= node
.getParent();
378 while (childrenIterator
.hasNext()){
379 TaxonNode childNode
= childrenIterator
.next();
381 parent
.addChildNode(childNode
, null, null);
383 childNode
.setParent(null);
387 for (int i
= 0; i
<node
.getChildNodes().size(); i
++){
394 removeNodes
.add(node
);
396 for (int i
= 0; i
<removeNodes
.size(); i
++){
397 TaxonNode removeNode
= removeNodes
.get(i
);
398 success
= removeNode
.delete(deleteChildren
);
399 removeNode
.setTaxon(null);
400 removeTaxonNode(removeNode
);
410 * Returns the set of all {@link SynonymRelationship synonym relationships}
411 * in which <i>this</i> ("accepted/correct") taxon is involved. <i>This</i> taxon can only
412 * be the target of these synonym relationships.
414 * @see #addSynonymRelation(SynonymRelationship)
415 * @see #removeSynonymRelation(SynonymRelationship)
416 * @see #getSynonyms()
418 public Set
<SynonymRelationship
> getSynonymRelations() {
419 if(synonymRelations
== null) {
420 this.synonymRelations
= new HashSet
<SynonymRelationship
>();
422 return synonymRelations
;
426 * Adds an existing {@link SynonymRelationship synonym relationship} to the set of
427 * {@link #getSynonymRelations() synonym relationships} assigned to <i>this</i> taxon. If
428 * the target of the synonym relationship does not match with <i>this</i> taxon
429 * no addition will be carried out.
431 * @param synonymRelation the synonym relationship to be added to <i>this</i> taxon's
432 * synonym relationships set
433 * @see #getSynonymRelations()
434 * @see #addSynonym(Synonym, SynonymRelationshipType)
435 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
436 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
437 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
439 protected void addSynonymRelation(SynonymRelationship synonymRelation
) {
440 this.synonymRelations
.add(synonymRelation
);
443 * Removes one element from the set of {@link SynonymRelationship synonym relationships} assigned
444 * to <i>this</i> (accepted/correct) taxon. Due to bidirectionality the given
445 * synonym relationship will also be removed from the set of synonym
446 * relationships assigned to the {@link Synonym#getSynonymRelations() synonym} involved in the
447 * relationship. Furthermore the content of
448 * the {@link SynonymRelationship#getAcceptedTaxon() accepted taxon} attribute and of the
449 * {@link SynonymRelationship#getSynonym() synonym} attribute within the synonym relationship
450 * itself will be set to "null".
452 * @param synonymRelation the synonym relationship which should be deleted
453 * @param removeSynonymNameFromHomotypicalGroup
454 * if <code>true</code> the synonym name will also be deleted from its homotypical group if the
455 * group contains other names
456 * @see #getSynonymRelations()
457 * @see #addSynonymRelation(SynonymRelationship)
458 * @see #removeSynonym(Synonym)
460 public void removeSynonymRelation(SynonymRelationship synonymRelation
, boolean removeSynonymNameFromHomotypicalGroup
) {
461 synonymRelation
.setAcceptedTaxon(null);
462 Synonym synonym
= synonymRelation
.getSynonym();
463 if (synonym
!= null){
464 synonymRelation
.setSynonym(null);
465 synonym
.removeSynonymRelation(synonymRelation
);
466 if(removeSynonymNameFromHomotypicalGroup
){
467 HomotypicalGroup synHG
= synonym
.getName().getHomotypicalGroup();
468 if (synHG
.getTypifiedNames().size() > 1){
469 synHG
.removeTypifiedName(synonym
.getName());
473 this.synonymRelations
.remove(synonymRelation
);
477 * Like {@link Taxon#removeSynonymRelation(SynonymRelationship, boolean)} but synonym name
478 * will be deleted from homotypical group by default
480 * @param synonymRelation the synonym relationship which should be deleted
482 * @see #removeSynonymRelation(SynonymRelationship, boolean)
484 public void removeSynonymRelation(SynonymRelationship synonymRelation
){
485 removeSynonymRelation(synonymRelation
, true);
490 * Returns the set of all {@link TaxonRelationship taxon relationships}
491 * between two taxa in which <i>this</i> taxon is involved as a source.
493 * @see #getRelationsToThisTaxon()
494 * @see #getTaxonRelations()
496 public Set
<TaxonRelationship
> getRelationsFromThisTaxon() {
497 if(relationsFromThisTaxon
== null) {
498 this.relationsFromThisTaxon
= new HashSet
<TaxonRelationship
>();
500 return relationsFromThisTaxon
;
505 * Returns the set of all {@link TaxonRelationship taxon relationships}
506 * between two taxa in which <i>this</i> taxon is involved as a target.
508 * @see #getRelationsFromThisTaxon()
509 * @see #getTaxonRelations()
511 public Set
<TaxonRelationship
> getRelationsToThisTaxon() {
512 if(relationsToThisTaxon
== null) {
513 this.relationsToThisTaxon
= new HashSet
<TaxonRelationship
>();
515 return relationsToThisTaxon
;
518 * Returns the set of all {@link TaxonRelationship taxon relationships}
519 * between two taxa in which <i>this</i> taxon is involved either as a source or
522 * @see #getRelationsFromThisTaxon()
523 * @see #getRelationsToThisTaxon()
526 public Set
<TaxonRelationship
> getTaxonRelations() {
527 Set
<TaxonRelationship
> rels
= new HashSet
<TaxonRelationship
>();
528 rels
.addAll(getRelationsToThisTaxon());
529 rels
.addAll(getRelationsFromThisTaxon());
534 * @see #getRelationsToThisTaxon()
536 protected void setRelationsToThisTaxon(Set
<TaxonRelationship
> relationsToThisTaxon
) {
537 this.relationsToThisTaxon
= relationsToThisTaxon
;
541 * @see #getRelationsFromThisTaxon()
543 protected void setRelationsFromThisTaxon(Set
<TaxonRelationship
> relationsFromThisTaxon
) {
544 this.relationsFromThisTaxon
= relationsFromThisTaxon
;
548 * If a relationships between <i>this</i> and the given taxon exists they will be returned.
549 * <i>This</i> taxon is involved either as a source or as a target in the relationships.
550 * The method will return <code>null</code> if no relations exist between the two taxa.
552 * @param possiblyRelatedTaxon
553 * a taxon to check for a relationship
555 * a set of <code>TaxonRelationship</code>s or <code>null</null> if none exists.
557 public Set
<TaxonRelationship
> getTaxonRelations(Taxon possiblyRelatedTaxon
){
558 Set
<TaxonRelationship
> relations
= new HashSet
<TaxonRelationship
>();
560 for(TaxonRelationship relationship
: getTaxonRelations()){
561 if(relationship
.getFromTaxon().equals(possiblyRelatedTaxon
)) {
562 relations
.add(relationship
);
564 if(relationship
.getToTaxon().equals(possiblyRelatedTaxon
)) {
565 relations
.add(relationship
);
569 return relations
.size() > 0 ? relations
: null;
573 * Removes one {@link TaxonRelationship taxon relationship} from one of both sets of
574 * {@link #getTaxonRelations() taxon relationships} in which <i>this</i> taxon is involved
575 * either as a {@link #getRelationsFromThisTaxon() source} or as a {@link #getRelationsToThisTaxon() target}.
576 * The taxon relationship will also be removed from one of both sets
577 * belonging to the second taxon involved. Furthermore the inherited RelatedFrom and
578 * RelatedTo attributes of the given taxon relationship will be nullified.<P>
579 * If the taxon relationship concerns the classification possible
580 * modifications of the {@link #getTaxonomicParent() parent taxon} or of the number of
581 * {@link #getTaxonomicChildrenCount() childrens} will be stored.
583 * @param rel the taxon relationship which should be removed from one
585 * @see #getTaxonRelations()
586 * @see #getTaxonomicParent()
587 * @see #getTaxonomicChildrenCount()
588 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
589 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
592 public void removeTaxonRelation(TaxonRelationship rel
) {
593 this.relationsToThisTaxon
.remove(rel
);
594 this.relationsFromThisTaxon
.remove(rel
);
595 Taxon fromTaxon
= rel
.getFromTaxon();
596 Taxon toTaxon
= rel
.getToTaxon();
597 // check if this removes the taxonomical parent. If so, also remove shortcut to the higher taxon
598 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) ){
599 if (fromTaxon
!= null && fromTaxon
.equals(this)){
600 this.taxonomicParentCache
= null;
601 }else if (toTaxon
!= null && toTaxon
.equals(this)){
602 this.setTaxonomicChildrenCount(computeTaxonomicChildrenCount());
605 //delete Relationship from other related Taxon
606 if (fromTaxon
!= this){
607 rel
.setToTaxon(null); //remove this Taxon from relationship
608 if (fromTaxon
!= null){
609 if (fromTaxon
.getTaxonRelations().contains(rel
)){
610 fromTaxon
.removeTaxonRelation(rel
);
614 if (toTaxon
!= this ){
615 rel
.setFromTaxon(null); //remove this Taxon from relationship
616 if (toTaxon
!= null){
617 if (toTaxon
.getTaxonRelations().contains(rel
)) {
618 toTaxon
.removeTaxonRelation(rel
);
625 * Adds an existing {@link TaxonRelationship taxon relationship} either to the set of
626 * {@link #getRelationsToThisTaxon() taxon relationships to <i>this</i> taxon} or to the set of
627 * {@link #getRelationsFromThisTaxon() taxon relationships from <i>this</i> taxon}. If neither the
628 * source nor the target of the taxon relationship match with <i>this</i> taxon
629 * no addition will be carried out. The taxon relationship will also be
630 * added to the second taxon involved in the given relationship.<P>
631 * If the taxon relationship concerns the classification possible
632 * modifications of the {@link #getTaxonomicParent() parent taxon} or of the number of
633 * {@link #getTaxonomicChildrenCount() childrens} will be stored.
635 * @param rel the taxon relationship to be added to one of <i>this</i> taxon's taxon relationships sets
636 * @see #addTaxonRelation(Taxon, TaxonRelationshipType, Reference, String)
637 * @see #getTaxonRelations()
638 * @see #getRelationsFromThisTaxon()
639 * @see #getRelationsToThisTaxon()
640 * @see #getTaxonomicParent()
641 * @see #getTaxonomicChildrenCount()
643 public void addTaxonRelation(TaxonRelationship rel
) {
644 if (rel
!=null && rel
.getType()!=null && !getTaxonRelations().contains(rel
) ){
645 Taxon toTaxon
=rel
.getToTaxon();
646 Taxon fromTaxon
=rel
.getFromTaxon();
647 if ( this.equals(toTaxon
) || this.equals(fromTaxon
) ){
648 if (this.equals(fromTaxon
)){
649 relationsFromThisTaxon
.add(rel
);
650 // also add relation to other taxon object
652 toTaxon
.addTaxonRelation(rel
);
654 // check if this sets the taxonomical parent. If so, remember a shortcut to this taxon
655 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) && toTaxon
!=null ){
656 this.taxonomicParentCache
= toTaxon
;
658 }else if (this.equals(toTaxon
)){
659 relationsToThisTaxon
.add(rel
);
660 // also add relation to other taxon object
661 if (fromTaxon
!=null){
662 fromTaxon
.addTaxonRelation(rel
);
664 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) && fromTaxon
!=null ){
665 this.taxonomicChildrenCount
++;
669 }else if (toTaxon
== null || fromTaxon
== null){
670 if (toTaxon
== null){
672 relationsToThisTaxon
.add(rel
);
673 if (fromTaxon
!= null){
674 fromTaxon
.addTaxonRelation(rel
);
676 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) && fromTaxon
!=null ){
677 this.taxonomicChildrenCount
++;
679 }else if (fromTaxon
== null && toTaxon
!= null){
681 relationsFromThisTaxon
.add(rel
);
683 toTaxon
.addTaxonRelation(rel
);
685 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) && toTaxon
!=null ){
686 this.taxonomicParentCache
= toTaxon
;
694 * @see eu.etaxonomy.cdm.model.common.IRelated#addRelationship(eu.etaxonomy.cdm.model.common.RelationshipBase)
697 @Deprecated //for inner use by RelationshipBase only
698 public void addRelationship(RelationshipBase rel
){
699 if (rel
instanceof TaxonRelationship
){
700 addTaxonRelation((TaxonRelationship
)rel
);
701 }else if (rel
instanceof SynonymRelationship
){
702 addSynonymRelation((SynonymRelationship
)rel
);
704 throw new ClassCastException("Wrong Relationsship type for Taxon.addRelationship");
709 * Creates a new {@link TaxonRelationship taxon relationship} instance where <i>this</i> taxon
710 * plays the source role and adds it to the set of
711 * {@link #getRelationsFromThisTaxon() "taxon relationships from"} belonging to <i>this</i> taxon.
712 * The taxon relationship will also be added to the set of taxon
713 * relationships to the second taxon involved in the created relationship.<P>
714 * If the taxon relationship concerns the classification possible
715 * modifications of the {@link #getTaxonomicParent() parent taxon} or of the number of
716 * {@link #getTaxonomicChildrenCount() childrens} will be stored.
718 * @param toTaxon the taxon which plays the target role in the new taxon relationship
719 * @param type the taxon relationship type for the new taxon relationship
720 * @param citation the reference source for the new taxon relationship
721 * @param microcitation the string with the details describing the exact localisation within the reference
723 * @see #addTaxonRelation(TaxonRelationship)
724 * @see #getTaxonRelations()
725 * @see #getRelationsFromThisTaxon()
726 * @see #getRelationsToThisTaxon()
727 * @see #getTaxonomicParent()
728 * @see #getTaxonomicChildrenCount()
730 public TaxonRelationship
addTaxonRelation(Taxon toTaxon
, TaxonRelationshipType type
, Reference citation
, String microcitation
) {
731 return new TaxonRelationship(this, toTaxon
, type
, citation
, microcitation
);
734 * Creates a new {@link TaxonRelationship taxon relationship} (with {@link TaxonRelationshipType taxon relationship type}
735 * "misapplied name for") instance where <i>this</i> taxon plays the target role
736 * and adds it to the set of {@link #getRelationsToThisTaxon() taxon relationships to <i>this</i> taxon}.
737 * The taxon relationship will also be added to the set of taxon
738 * relationships to the other (misapplied name) taxon involved in the created relationship.
740 * @param misappliedNameTaxon the taxon which plays the target role in the new taxon relationship
741 * @param citation the reference source for the new taxon relationship
742 * @param microcitation the string with the details describing the exact localisation within the reference
744 * @see #getMisappliedNames()
745 * @see #addTaxonRelation(Taxon, TaxonRelationshipType, Reference, String)
746 * @see #addTaxonRelation(TaxonRelationship)
747 * @see #getTaxonRelations()
748 * @see #getRelationsFromThisTaxon()
749 * @see #getRelationsToThisTaxon()
751 public TaxonRelationship
addMisappliedName(Taxon misappliedNameTaxon
, Reference citation
, String microcitation
) {
752 return misappliedNameTaxon
.addTaxonRelation(this, TaxonRelationshipType
.MISAPPLIED_NAME_FOR(), citation
, microcitation
);
755 // public void removeMisappliedName(Taxon misappliedNameTaxon){
756 // Set<TaxonRelationship> taxRels = this.getTaxonRelations();
757 // for (TaxonRelationship taxRel : taxRels ){
758 // if (taxRel.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())
759 // && taxRel.getFromTaxon().equals(misappliedNameTaxon)){
760 // this.removeTaxonRelation(taxRel);
766 * TODO update documentation
767 * Removes one {@link TaxonRelationship taxon relationship} with {@link TaxonRelationshipType taxon relationship type}
768 * taxonRelType and with the given child taxon playing the
769 * source role from the set of {@link #getRelationsToThisTaxon() "taxon relationships to"} belonging
770 * to <i>this</i> taxon. The taxon relationship will also be removed from the set
771 * of {@link #getRelationsFromThisTaxon() "taxon relationships from"} belonging to the other side taxon.
772 * Furthermore, the inherited RelatedFrom and RelatedTo attributes of the
773 * taxon relationship will be nullified.<P>
775 * @param taxon the taxon which plays the source role in the taxon relationship
776 * @param taxonRelType the taxon relationship type
778 public void removeTaxon(Taxon taxon
, TaxonRelationshipType taxonRelType
){
779 Set
<TaxonRelationship
> taxRels
= this.getTaxonRelations();
780 for (TaxonRelationship taxRel
: taxRels
){
781 if (taxRel
.getType().equals(taxonRelType
)
782 && taxRel
.getFromTaxon().equals(taxon
)){
783 this.removeTaxonRelation(taxRel
);
789 * Creates a new {@link TaxonRelationship taxon relationship} (with {@link TaxonRelationshipType taxon relationship type}
790 * "taxonomically included in") instance where <i>this</i> taxon plays the target
791 * role (parent) and adds it to the set of
792 * {@link #getRelationsToThisTaxon() "taxon relationships to"} belonging to <i>this</i> taxon.
793 * The taxon relationship will also be added to the set of
794 * {@link #getRelationsFromThisTaxon() "taxon relationships from"} belonging to the second taxon
795 * (child) involved in the created relationship.<P>
796 * Since the taxon relationship concerns the modifications
797 * of the number of {@link #getTaxonomicChildrenCount() childrens} for <i>this</i> taxon and
798 * of the {@link #getTaxonomicParent() parent taxon} for the child taxon will be stored.
799 * The {@link name.Rank rank} of the taxon name used as a parent taxon must be higher
800 * than the rank of the taxon name used as a child taxon.
802 * @param child the taxon which plays the source role (child) in the new taxon relationship
803 * @param citation the reference source for the new taxon relationship
804 * @param microcitation the string with the details describing the exact localisation within the reference
805 * @see #setTaxonomicParent(Taxon, Reference, String)
806 * @see #addTaxonRelation(Taxon, TaxonRelationshipType, Reference, String)
807 * @see #addTaxonRelation(TaxonRelationship)
808 * @see #getTaxonRelations()
809 * @see #getRelationsFromThisTaxon()
810 * @see #getRelationsToThisTaxon()
811 * @see #getTaxonomicParent()
812 * @see #getTaxonomicChildrenCount()
814 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
815 public void addTaxonomicChild(Taxon child
, Reference citation
, String microcitation
){
817 throw new NullPointerException("Child Taxon is 'null'");
819 child
.setTaxonomicParent(this, citation
, microcitation
);
824 * Removes one {@link TaxonRelationship taxon relationship} with {@link TaxonRelationshipType taxon relationship type}
825 * "taxonomically included in" and with the given child taxon playing the
826 * source role from the set of {@link #getRelationsToThisTaxon() "taxon relationships to"} belonging
827 * to <i>this</i> taxon. The taxon relationship will also be removed from the set
828 * of {@link #getRelationsFromThisTaxon() "taxon relationships from"} belonging to the child taxon.
829 * Furthermore the inherited RelatedFrom and RelatedTo attributes of the
830 * taxon relationship will be nullified.<P>
831 * Since the taxon relationship concerns the classification modifications
832 * of the number of {@link #getTaxonomicChildrenCount() childrens} for <i>this</i> taxon and
833 * of the {@link #getTaxonomicParent() parent taxon} for the child taxon will be stored.
835 * @param child the taxon playing the source role in the relationship to be removed
836 * @see #removeTaxonRelation(TaxonRelationship)
837 * @see #getRelationsToThisTaxon()
838 * @see #getRelationsFromThisTaxon()
839 * @see #getTaxonomicParent()
840 * @see #getTaxonomicChildrenCount()
841 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
842 * @see eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedTo()
845 @Deprecated //will be removed in future versions. Use classification/TaxonNode instead
846 public void removeTaxonomicChild(Taxon child
){
847 Set
<TaxonRelationship
> taxRels
= this.getTaxonRelations();
848 for (TaxonRelationship taxRel
: taxRels
){
849 if (taxRel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())
850 && taxRel
.getFromTaxon().equals(child
)){
851 this.removeTaxonRelation(taxRel
);
857 * Returns the taxon which is the next higher taxon (parent) of <i>this</i> taxon
858 * within the classification and which is stored in the
859 * TaxonomicParentCache attribute. Each taxon can have only one parent taxon.
860 * The child taxon and the parent taxon play the source respectively the
861 * target role in one {@link TaxonRelationship taxon relationship} with
862 * {@link TaxonRelationshipType taxon relationship type} "taxonomically included in".
863 * The {@link name.Rank rank} of the taxon name used as a parent taxon must be higher
864 * than the rank of the taxon name used as a child taxon.
866 * @see #setTaxonomicParent(Taxon, Reference, String)
867 * @see #getTaxonomicChildren()
868 * @see #getTaxonomicChildrenCount()
869 * @see #getRelationsFromThisTaxon()
871 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
872 public Taxon
getTaxonomicParent() {
873 return this.taxonomicParentCache
;
877 * Sets the taxononomic parent of <i>this</i> taxon to null.
878 * Note that this method does not handle taxonomic relationships.
880 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
881 public void nullifyTaxonomicParent() {
882 this.taxonomicParentCache
= null;
886 * Replaces both the taxonomic parent cache with the given new parent taxon
887 * and the corresponding taxon relationship with a new {@link TaxonRelationship taxon relationship}
888 * (with {@link TaxonRelationshipType taxon relationship type} "taxonomically included in") instance.
889 * In the new taxon relationship <i>this</i> taxon plays the source role (child).
890 * This method creates and adds the new taxon relationship to the set of
891 * {@link #getRelationsFromThisTaxon() "taxon relationships from"} belonging to <i>this</i> taxon.
892 * The taxon relationship will also be added to the set of
893 * {@link #getRelationsToThisTaxon() "taxon relationships to"} belonging to the second taxon
894 * (parent) involved in the new relationship.<P>
895 * Since the taxon relationship concerns the classification modifications
896 * of the {@link #getTaxonomicParent() parent taxon} for <i>this</i> taxon and of the number of
897 * {@link #getTaxonomicChildrenCount() childrens} for the child taxon will be stored.
899 * @param newParent the taxon which plays the target role (parent) in the new taxon relationship
900 * @param citation the reference source for the new taxon relationship
901 * @param microcitation the string with the details describing the exact localisation within the reference
902 * @see #removeTaxonRelation(TaxonRelationship)
903 * @see #getTaxonomicParent()
904 * @see #addTaxonRelation(Taxon, TaxonRelationshipType, Reference, String)
905 * @see #addTaxonRelation(TaxonRelationship)
906 * @see #getTaxonRelations()
907 * @see #getRelationsFromThisTaxon()
908 * @see #getRelationsToThisTaxon()
909 * @see #getTaxonomicChildrenCount()
911 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
912 public void setTaxonomicParent(Taxon newParent
, Reference citation
, String microcitation
){
913 //remove previously existing parent relationship!!!
914 Taxon oldParent
= this.getTaxonomicParent();
915 Set
<TaxonRelationship
> taxRels
= this.getTaxonRelations();
916 for (TaxonRelationship taxRel
: taxRels
){
917 if (taxRel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN()) && taxRel
.getToTaxon().equals(oldParent
)){
918 this.removeTaxonRelation(taxRel
);
922 if (newParent
!= null){
923 addTaxonRelation(newParent
, TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN(),citation
,microcitation
);
928 * Returns the set of taxa which have <i>this</i> taxon as next higher taxon
929 * (parent) within the classification. Each taxon can have several child
930 * taxa. The child taxon and the parent taxon play the source respectively
931 * the target role in one {@link TaxonRelationship taxon relationship} with
932 * {@link TaxonRelationshipType taxon relationship type} "taxonomically included in".
933 * The {@link name.Rank rank} of the taxon name used as a parent taxon must be higher
934 * than the rank of the taxon name used as a child taxon.
936 * @see #getTaxonomicParent()
937 * @see #addTaxonomicChild(Taxon, Reference, String)
938 * @see #getTaxonomicChildrenCount()
939 * @see #getRelationsToThisTaxon()
942 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
943 public Set
<Taxon
> getTaxonomicChildren() {
944 Set
<Taxon
> taxa
= new HashSet
<Taxon
>();
945 Set
<TaxonRelationship
> rels
= this.getRelationsToThisTaxon();
946 for (TaxonRelationship rel
: rels
){
947 TaxonRelationshipType tt
= rel
.getType();
948 TaxonRelationshipType incl
= TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN();
949 if (tt
.equals(incl
)){
950 taxa
.add(rel
.getFromTaxon());
957 * Returns the number of taxa which have <i>this</i> taxon as next higher taxon
958 * (parent) within the classification and the number of which is stored in
959 * the TaxonomicChildrenCount attribute. Each taxon can have several child
960 * taxa. The child taxon and the parent taxon play the source respectively
961 * the target role in one {@link TaxonRelationship taxon relationship} with
962 * {@link TaxonRelationshipType taxon relationship type} "taxonomically included in".
963 * The {@link name.Rank rank} of the taxon name used as a parent taxon must be higher
964 * than the rank of the taxon name used as a child taxon.
966 * @see #getTaxonomicChildren()
967 * @see #getRelationsToThisTaxon()
969 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
970 public int getTaxonomicChildrenCount(){
971 return taxonomicChildrenCount
;
975 * @see #getTaxonomicChildrenCount()
977 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
978 public void setTaxonomicChildrenCount(int taxonomicChildrenCount
) {
979 this.taxonomicChildrenCount
= taxonomicChildrenCount
;
983 * Returns the boolean value indicating whether <i>this</i> taxon has at least one
984 * taxonomic child taxon within the classification (true) or not (false).
986 * @see #getTaxonomicChildrenCount()
987 * @see #getTaxonomicChildren()
989 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
990 public boolean hasTaxonomicChildren(){
991 return this.taxonomicChildrenCount
> 0;
994 @Deprecated //will be removed in future versions. Use Classification/TaxonNode instead
995 private int computeTaxonomicChildrenCount(){
997 for (TaxonRelationship rel
: this.getRelationsToThisTaxon()){
998 if (rel
.getType().equals(TaxonRelationshipType
.TAXONOMICALLY_INCLUDED_IN())){
1007 * Returns the boolean value indicating whether <i>this</i> taxon is a misaplication
1008 * (misapplied name) for at least one other taxon.
1010 // TODO cache as for #hasTaxonomicChildren
1012 public boolean isMisapplication(){
1013 return computeMisapliedNameRelations() > 0;
1017 * Counts the number of misaplied names relationships where this taxon represents the
1018 * misaplied name for another taxon.
1021 private int computeMisapliedNameRelations(){
1023 for (TaxonRelationship rel
: this.getRelationsFromThisTaxon()){
1024 if (rel
.getType().equals(TaxonRelationshipType
.MISAPPLIED_NAME_FOR())){
1032 * Returns the boolean value indicating whether <i>this</i> taxon is a related
1033 * concept for at least one other taxon.
1036 public boolean isRelatedConcept(){
1037 return computeConceptRelations() > 0;
1041 * Counts the number of concept relationships where this taxon represents the
1042 * related concept for another taxon.
1045 private int computeConceptRelations(){
1047 for (TaxonRelationship rel
: this.getRelationsFromThisTaxon()){
1048 TaxonRelationshipType type
= rel
.getType();
1049 if (type
.isConceptRelationship()){
1057 * Returns the boolean value indicating whether <i>this</i> taxon has at least one
1058 * {@link Synonym synonym} (true) or not (false). If true the {@link #getSynonymRelations() set of synonym relationships}
1059 * belonging to <i>this</i> ("accepted/correct") taxon is not empty .
1061 * @see #getSynonymRelations()
1062 * @see #getSynonyms()
1063 * @see #getSynonymNames()
1064 * @see #removeSynonym(Synonym)
1065 * @see SynonymRelationship
1067 public boolean hasSynonyms(){
1068 return this.getSynonymRelations().size() > 0;
1073 * Returns the boolean value indicating whether <i>this</i> taxon is at least
1074 * involved in one {@link #getTaxonRelations() taxon relationship} between
1075 * two taxa (true), either as a source or as a target, or not (false).
1077 * @see #getTaxonRelations()
1078 * @see #getRelationsToThisTaxon()
1079 * @see #getRelationsFromThisTaxon()
1080 * @see #removeTaxonRelation(TaxonRelationship)
1081 * @see TaxonRelationship
1083 public boolean hasTaxonRelationships(){
1084 return this.getTaxonRelations().size() > 0;
1091 * Returns the set of taxa playing the source role in {@link TaxonRelationship taxon relationships}
1092 * (with {@link TaxonRelationshipType taxon relationship type} "misapplied name for") where
1093 * <i>this</i> taxon plays the target role. A misapplied name is a taxon the
1094 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} of which has been erroneously used
1095 * by its {@link TaxonBase#getSec() taxon reference} to denominate the same real taxon
1096 * as the one meant by <i>this</i> ("accepted/correct") taxon.
1098 * @see #getTaxonRelations()
1099 * @see #getRelationsToThisTaxon()
1100 * @see #addMisappliedName(Taxon, Reference, String)
1103 public Set
<Taxon
> getMisappliedNames(){
1104 Set
<Taxon
> taxa
= new HashSet
<Taxon
>();
1105 Set
<TaxonRelationship
> rels
= this.getRelationsToThisTaxon();
1106 for (TaxonRelationship rel
: rels
){
1107 TaxonRelationshipType tt
= rel
.getType();
1108 TaxonRelationshipType incl
= TaxonRelationshipType
.MISAPPLIED_NAME_FOR();
1109 if (tt
.equals(incl
)){
1110 taxa
.add(rel
.getFromTaxon());
1116 * Returns the set of taxa playing the target role in {@link TaxonRelationship taxon relationships}
1117 * (with {@link TaxonRelationshipType taxon relationship type} "misapplied name for") where
1118 * <i>this</i> taxon plays the source role. A misapplied name is a taxon the
1119 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name} of which has been erroneously used
1120 * by its {@link TaxonBase#getSec() taxon reference} to denominate the same real taxon
1121 * as the one meant by <i>this</i> ("accepted/correct") taxon.
1123 * @see #getTaxonRelations()
1124 * @see #getRelationsToThisTaxon()
1125 * @see #addMisappliedName(Taxon, Reference, String)
1128 public Set
<Taxon
> getTaxonForMisappliedName(){
1129 Set
<Taxon
> taxa
= new HashSet
<Taxon
>();
1130 Set
<TaxonRelationship
> rels
= this.getRelationsFromThisTaxon();
1131 for (TaxonRelationship rel
: rels
){
1132 TaxonRelationshipType tt
= rel
.getType();
1133 TaxonRelationshipType incl
= TaxonRelationshipType
.MISAPPLIED_NAME_FOR();
1134 if (tt
.equals(incl
)){
1135 taxa
.add(rel
.getToTaxon());
1143 * DEALING WITH SYNONYMS
1146 * Returns the set of all {@link Synonym synonyms} of <i>this</i> ("accepted/correct") taxon.
1147 * Each synonym is the source and <i>this</i> taxon is the target of a {@link SynonymRelationship synonym relationship}
1148 * belonging to the {@link #getSynonymRelations() set of synonym relationships} assigned to <i>this</i> taxon.
1149 * For a particular synonym and for a particular ("accepted/correct") taxon
1150 * there can be several synonym relationships (if two or more
1151 * {@link SynonymRelationshipType synonym relationship types} - for instance
1152 * "pro parte synonym of" and "is homotypic synonym of" - must be combined).
1154 * @see #getSynonymsSortedByType()
1155 * @see #getSynonymNames()
1156 * @see #getSynonymRelations()
1157 * @see #addSynonym(Synonym, SynonymRelationshipType)
1158 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1159 * @see #removeSynonymRelation(SynonymRelationship)
1160 * @see #removeSynonym(Synonym)
1163 public Set
<Synonym
> getSynonyms(){
1164 Set
<Synonym
> syns
= new HashSet
<Synonym
>();
1165 for (SynonymRelationship rel
: this.getSynonymRelations()){
1166 syns
.add(rel
.getSynonym());
1171 * Returns the set of all {@link Synonym synonyms} of <i>this</i> ("accepted/correct") taxon
1172 * sorted by the different {@link SynonymRelationshipType categories of synonym relationships}.
1173 * Each synonym is the source and <i>this</i> taxon is the target of a {@link SynonymRelationship synonym relationship}
1174 * belonging to the {@link #getSynonymRelations() set of synonym relationships} assigned to <i>this</i> taxon.
1176 * @see #getSynonyms()
1177 * @see #getSynonymNames()
1178 * @see #getSynonymRelations()
1179 * @see #addSynonym(Synonym, SynonymRelationshipType)
1180 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1181 * @see #removeSynonymRelation(SynonymRelationship)
1182 * @see #removeSynonym(Synonym)
1185 public Set
<Synonym
> getSynonymsSortedByType(){
1186 // FIXME: need to sort synonyms according to type!!!
1187 logger
.warn("getSynonymsSortedByType() not yet implemented");
1188 return getSynonyms();
1191 * Returns the set of all {@link name.TaxonNameBase taxon names} used as {@link Synonym synonyms}
1192 * of <i>this</i> ("accepted/correct") taxon. Each synonym is the source and
1193 * <i>this</i> taxon is the target of a {@link SynonymRelationship synonym relationship} belonging
1194 * to the {@link #getSynonymRelations() set of synonym relationships} assigned to <i>this</i> taxon.
1196 * @see #getSynonyms()
1197 * @see #getSynonymsSortedByType()
1198 * @see #getSynonymRelations()
1199 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1200 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1201 * @see #removeSynonymRelation(SynonymRelationship)
1202 * @see #removeSynonym(Synonym)
1205 public Set
<TaxonNameBase
> getSynonymNames(){
1206 Set
<TaxonNameBase
> names
= new HashSet
<TaxonNameBase
>();
1207 for (SynonymRelationship rel
: this.getSynonymRelations()){
1208 names
.add(rel
.getSynonym().getName());
1213 * Creates a new {@link SynonymRelationship synonym relationship} (with the given {@link Synonym synonym}
1214 * and with the given {@link SynonymRelationshipType synonym relationship type}), returns it and adds it
1215 * to the set of {@link #getSynonymRelations() synonym relationships} assigned to <i>this</i> taxon.
1216 * The new synonym relationship will also be added to the set of
1217 * {@link Synonym#getSynonymRelations() synonym relationships} belonging to the synonym
1218 * involved in this synonym relationship.<BR>
1219 * The returned synonym relationship allows to add further information to it.
1221 * @param synonym the synonym involved in the relationship to be created
1222 * and added to <i>this</i> taxon's synonym relationships set
1223 * @param synonymType the synonym relationship category of the synonym
1224 * relationship to be added
1225 * @return the created synonym relationship
1226 * @see #addSynonymRelation(SynonymRelationship)
1227 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1228 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1229 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1230 * @see #addHomotypicSynonym(Synonym, Reference, String)
1231 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1232 * @see #addHeterotypicSynonymName(TaxonNameBase)
1233 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1234 * @see #getSynonymRelations()
1235 * @see #removeSynonym(Synonym)
1236 * @see Synonym#getSynonymRelations()
1238 public SynonymRelationship
addSynonym(Synonym synonym
, SynonymRelationshipType synonymType
){
1239 return addSynonym(synonym
, synonymType
, null, null);
1242 * Creates a new {@link SynonymRelationship synonym relationship} (with the given {@link Synonym synonym},
1243 * with the given {@link SynonymRelationshipType synonym relationship type} and with the
1244 * {@link eu.etaxonomy.cdm.model.reference.Reference reference source} on which the relationship assertion is based),
1245 * returns it and adds it to the set of {@link #getSynonymRelations() synonym relationships}
1246 * assigned to <i>this</i> taxon. The new synonym relationship will also be
1247 * added to the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging to the synonym
1248 * involved in this synonym relationship.<BR>
1249 * The returned synonym relationship allows to add further information to it.
1251 * @param synonym the synonym involved in the relationship to be created
1252 * and added to <i>this</i> taxon's synonym relationships set
1253 * @param synonymType the synonym relationship category of the synonym
1254 * relationship to be added
1255 * @param citation the reference source for the new synonym relationship
1256 * @param microcitation the string with the details describing the exact localisation within the reference
1257 * @return the created synonym relationship
1258 * @see #addSynonymRelation(SynonymRelationship)
1259 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1260 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1261 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1262 * @see #addHomotypicSynonym(Synonym, Reference, String)
1263 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1264 * @see #addHeterotypicSynonymName(TaxonNameBase)
1265 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1266 * @see #getSynonymRelations()
1267 * @see #removeSynonym(Synonym)
1268 * @see Synonym#getSynonymRelations()
1270 public SynonymRelationship
addSynonym(Synonym synonym
, SynonymRelationshipType synonymType
, Reference citation
, String citationMicroReference
){
1271 SynonymRelationship synonymRelationship
= new SynonymRelationship(synonym
, this, synonymType
, citation
, citationMicroReference
);
1272 return synonymRelationship
;
1276 * Creates a new {@link Synonym synonym} (with the given {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}),
1277 * a new {@link SynonymRelationship synonym relationship} (with the new synonym and with the given
1278 * {@link SynonymRelationshipType synonym relationship type}), returns the relationship and adds it
1279 * to the set of {@link #getSynonymRelations() synonym relationships} assigned to <i>this</i> taxon.
1280 * The new synonym will have the same {@link TaxonBase#getSec() concept reference}
1281 * as <i>this</i> taxon. The new synonym relationship will also be added to
1282 * the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging
1283 * to the created synonym.<BR>
1284 * The returned synonym relationship allows to add further information to it.
1286 * @param synonymName the taxon name to be used as a synonym to be added
1287 * to <i>this</i> taxon's set of synonyms
1288 * @param synonymType the synonym relationship category of the synonym
1289 * relationship to be added
1290 * @return the created synonym relationship
1291 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1292 * @see #addSynonym(Synonym, SynonymRelationshipType)
1293 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1294 * @see #addSynonymRelation(SynonymRelationship)
1295 * @see #addHomotypicSynonym(Synonym, Reference, String)
1296 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1297 * @see #addHeterotypicSynonymName(TaxonNameBase)
1298 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1299 * @see #getSynonymRelations()
1300 * @see #removeSynonym(Synonym)
1301 * @see Synonym#getSynonymRelations()
1303 public SynonymRelationship
addSynonymName(TaxonNameBase synonymName
, SynonymRelationshipType synonymType
){
1304 return addSynonymName(synonymName
, synonymType
, null, null);
1307 * Creates a new {@link Synonym synonym} (with the given {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}),
1308 * a new {@link SynonymRelationship synonym relationship} (with the new synonym, with the given
1309 * {@link SynonymRelationshipType synonym relationship type} and with the {@link eu.etaxonomy.cdm.model.reference.Reference reference source}
1310 * on which the relationship assertion is based), returns the relationship
1311 * and adds it to the set of {@link #getSynonymRelations() synonym relationships} assigned
1312 * to <i>this</i> taxon. The new synonym will have the same {@link TaxonBase#getSec() concept reference}
1313 * as <i>this</i> taxon. The new synonym relationship will also be added to
1314 * the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging
1315 * to the created synonym.<BR>
1316 * The returned synonym relationship allows to add further information to it.
1318 * @param synonymName the taxon name to be used as a synonym to be added
1319 * to <i>this</i> taxon's set of synonyms
1320 * @param synonymType the synonym relationship category of the synonym
1321 * relationship to be added
1322 * @param citation the reference source for the new synonym relationship
1323 * @param microcitation the string with the details describing the exact localisation within the reference
1324 * @return the created synonym relationship
1325 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1326 * @see #addSynonym(Synonym, SynonymRelationshipType)
1327 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1328 * @see #addSynonymRelation(SynonymRelationship)
1329 * @see #addHomotypicSynonym(Synonym, Reference, String)
1330 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1331 * @see #addHeterotypicSynonymName(TaxonNameBase)
1332 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1333 * @see #getSynonymRelations()
1334 * @see #removeSynonym(Synonym)
1335 * @see Synonym#getSynonymRelations()
1337 public SynonymRelationship
addSynonymName(TaxonNameBase synonymName
, SynonymRelationshipType synonymType
, Reference citation
, String citationMicroReference
){
1338 Synonym synonym
= Synonym
.NewInstance(synonymName
, this.getSec());
1339 return addSynonym(synonym
, synonymType
, citation
, citationMicroReference
);
1343 * Creates a new {@link Synonym synonym} (with the given {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}),
1344 * a new {@link SynonymRelationship synonym relationship} (with the new synonym and with the
1345 * {@link SynonymRelationshipType#HETEROTYPIC_SYNONYM_OF() "is heterotypic synonym of" relationship type}),
1346 * returns the relationship and adds it to the set of
1347 * {@link #getSynonymRelations() synonym relationships} assigned to <i>this</i> taxon.
1348 * The new synonym will have the same {@link TaxonBase#getSec() concept reference}
1349 * as <i>this</i> taxon. The new synonym relationship will also be added to
1350 * the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging
1351 * to the created synonym.<BR>
1352 * The returned synonym relationship allows to add further information to it.
1354 * @param synonymName the taxon name to be used as an heterotypic synonym
1355 * to be added to <i>this</i> taxon's set of synonyms
1356 * @return the created synonym relationship
1357 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1358 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1359 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1360 * @see #addSynonym(Synonym, SynonymRelationshipType)
1361 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1362 * @see #addSynonymRelation(SynonymRelationship)
1363 * @see #addHomotypicSynonym(Synonym, Reference, String)
1364 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1365 * @see #getSynonymRelations()
1366 * @see #removeSynonym(Synonym)
1367 * @see Synonym#getSynonymRelations()
1369 public SynonymRelationship
addHeterotypicSynonymName(TaxonNameBase synonymName
){
1370 return addHeterotypicSynonymName(synonymName
, null, null, null);
1374 * Creates a new {@link Synonym synonym} (with the given {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}),
1375 * a new {@link SynonymRelationship synonym relationship} (with the new synonym, with the
1376 * {@link SynonymRelationshipType#HETEROTYPIC_SYNONYM_OF() "is heterotypic synonym of" relationship type}
1377 * and with the {@link eu.etaxonomy.cdm.model.reference.Reference reference source}
1378 * on which the relationship assertion is based), returns the relationship
1379 * and adds it to the set of {@link #getSynonymRelations() synonym relationships} assigned
1380 * to <i>this</i> taxon. The new synonym will have the same {@link TaxonBase#getSec() concept reference}
1381 * as <i>this</i> taxon. Furthermore the new synonym relationship will be
1382 * added to the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging
1383 * to the created synonym and the taxon name used as synonym will be added
1384 * to the given {@link name.HomotypicalGroup homotypical group}.<BR>
1385 * The returned synonym relationship allows to add further information to it.
1387 * @param synonymName the taxon name to be used as an heterotypic synonym
1388 * to be added to <i>this</i> taxon's set of synonyms
1389 * @param homotypicalGroup the homotypical group to which the taxon name
1390 * of the synonym will be added
1391 * @param citation the reference source for the new synonym relationship
1392 * @param microcitation the string with the details describing the exact localisation
1393 * within the reference
1394 * @return the created synonym relationship
1395 * @see #addHeterotypicSynonymName(TaxonNameBase)
1396 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1397 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1398 * @see #addSynonym(Synonym, SynonymRelationshipType)
1399 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1400 * @see #addSynonymRelation(SynonymRelationship)
1401 * @see #addHomotypicSynonym(Synonym, Reference, String)
1402 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1403 * @see #getSynonymRelations()
1404 * @see #removeSynonym(Synonym)
1405 * @see Synonym#getSynonymRelations()
1407 public SynonymRelationship
addHeterotypicSynonymName(TaxonNameBase synonymName
, HomotypicalGroup homotypicalGroup
, Reference citation
, String microCitation
){
1408 Synonym synonym
= Synonym
.NewInstance(synonymName
, this.getSec());
1409 if (homotypicalGroup
!= null){
1410 homotypicalGroup
.addTypifiedName(synonymName
);
1412 return addSynonym(synonym
, SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF(), citation
, microCitation
);
1416 * Creates a new {@link Synonym synonym} (with the given {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}),
1417 * a new {@link SynonymRelationship synonym relationship} (with the new synonym, with the
1418 * {@link SynonymRelationshipType#HOMOTYPIC_SYNONYM_OF() "is homotypic synonym of" relationship type})
1419 * and with the {@link eu.etaxonomy.cdm.model.reference.Reference reference source}
1420 * on which the relationship assertion is based), returns the relationship
1421 * and adds it to the set of {@link #getSynonymRelations() synonym relationships} assigned
1422 * to <i>this</i> taxon. The new synonym will have the same {@link TaxonBase#getSec() concept reference}
1423 * as <i>this</i> taxon. Furthermore the new synonym relationship will be
1424 * added to the set of {@link Synonym#getSynonymRelations() synonym relationships} belonging
1425 * to the created synonym and the taxon name used as synonym will be added
1426 * to the same {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group} to which the taxon name
1427 * of <i>this</i> taxon belongs.<BR>
1428 * The returned synonym relationship allows to add further information to it.
1430 * @param synonymName the taxon name to be used as an homotypic synonym
1431 * to be added to <i>this</i> taxon's set of synonyms
1432 * @param citation the reference source for the new synonym relationship
1433 * @param microcitation the string with the details describing the exact localisation
1434 * within the reference
1435 * @return the created synonym relationship
1436 * @see #addHomotypicSynonym(Synonym, Reference, String)
1437 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1438 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1439 * @see #addSynonym(Synonym, SynonymRelationshipType)
1440 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1441 * @see #addSynonymRelation(SynonymRelationship)
1442 * @see #addHeterotypicSynonymName(TaxonNameBase)
1443 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1444 * @see #getSynonymRelations()
1445 * @see #removeSynonym(Synonym)
1446 * @see Synonym#getSynonymRelations()
1448 public SynonymRelationship
addHomotypicSynonymName(TaxonNameBase synonymName
, Reference citation
, String microCitation
){
1449 Synonym synonym
= Synonym
.NewInstance(synonymName
, this.getSec());
1450 return addHomotypicSynonym(synonym
, citation
, microCitation
);
1454 * Creates a new {@link SynonymRelationship synonym relationship} (with the given {@link Synonym synonym},
1455 * with the {@link SynonymRelationshipType#HOMOTYPIC_SYNONYM_OF() "is homotypic synonym of" relationship type}
1456 * and with the {@link eu.etaxonomy.cdm.model.reference.Reference reference source} on which the relationship
1457 * assertion is based), returns it and adds it to the set of
1458 * {@link #getSynonymRelations() synonym relationships} assigned to <i>this</i> taxon.
1459 * Furthermore the new synonym relationship will be added to the set of
1460 * {@link Synonym#getSynonymRelations() synonym relationships} belonging to the synonym
1461 * involved in this synonym relationship and the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon name}
1462 * used as synonym will be added to the same {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group}
1463 * to which the taxon name of <i>this</i> taxon belongs.<BR>
1464 * The returned synonym relationship allows to add further information to it.
1466 * @param synonym the synonym involved in the "is homotypic synonym of" relationship to be created
1467 * and added to <i>this</i> taxon's synonym relationships set
1468 * @param citation the reference source for the new synonym relationship
1469 * @param microcitation the string with the details describing the exact localisation within the reference
1470 * @return the created synonym relationship
1471 * @see #addHomotypicSynonymName(TaxonNameBase, Reference, String)
1472 * @see #addSynonym(Synonym, SynonymRelationshipType)
1473 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1474 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType, Reference, String)
1475 * @see #addSynonymName(TaxonNameBase, SynonymRelationshipType)
1476 * @see #addSynonymRelation(SynonymRelationship)
1477 * @see #addHeterotypicSynonymName(TaxonNameBase)
1478 * @see #addHeterotypicSynonymName(TaxonNameBase, HomotypicalGroup, Reference, String)
1479 * @see #getSynonymRelations()
1480 * @see #removeSynonym(Synonym)
1481 * @see Synonym#getSynonymRelations()
1483 public SynonymRelationship
addHomotypicSynonym(Synonym synonym
, Reference citation
, String microCitation
){
1484 if (this.getName() != null){
1485 if (this.getName().getHomotypicalGroup().getTypifiedNames().isEmpty()){
1486 this.getName().getHomotypicalGroup().getTypifiedNames().add(this.getName());
1489 this.getName().getHomotypicalGroup().addTypifiedName(synonym
.getName());
1492 SynonymRelationship synRel
= addSynonym(synonym
, SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF(), citation
, microCitation
);
1497 * Like {@link #removeSynonym(Synonym, boolean)} with <code>removeSynonymNameFromHomotypicalGroup</code> set to true.
1498 * @see #removeSynonym(Synonym, boolean)
1500 public void removeSynonym(Synonym synonym
){
1501 removeSynonym(synonym
, true);
1505 * Removes the element(s) from the set of {@link SynonymRelationship synonym relationships}
1506 * assigned to <i>this</i> ("accepted/valid") taxon in which the given synonym is involved.
1507 * Due to bidirectionality the same synonym relationships will also be
1508 * removed from the set of synonym relationships assigned to the
1509 * {@link Synonym#getSynonymRelations() synonym} involved in the relationship. Furthermore the content of
1510 * the {@link SynonymRelationship#getAcceptedTaxon() accepted taxon} attribute and of the
1511 * {@link SynonymRelationship#getSynonym() synonym} attribute within the synonym relationships
1512 * themselves will be set to "null".
1514 * @param synonym the synonym involved in the synonym relationship which should be deleted
1515 * @param removeSynonymNameFromHomotypicalGroup if <code>true</code> the removed synonyms
1516 * name will get a new homotypic group in case it is together with other names in a group.
1517 * @see #getSynonymRelations()
1518 * @see #addSynonym(Synonym, SynonymRelationshipType)
1519 * @see #addSynonym(Synonym, SynonymRelationshipType, Reference, String)
1520 * @see #removeSynonymRelation(SynonymRelationship)
1521 * @see #removeSynonymRelation(SynonymRelationship, boolean)
1523 public void removeSynonym(Synonym synonym
, boolean removeSynonymNameFromHomotypicalGroup
){
1524 Set
<SynonymRelationship
> synonymRelationships
= new HashSet
<SynonymRelationship
>();
1525 synonymRelationships
.addAll(this.getSynonymRelations());
1526 for(SynonymRelationship synonymRelationship
: synonymRelationships
){
1527 if (synonymRelationship
.getAcceptedTaxon().equals(this) && synonymRelationship
.getSynonym().equals(synonym
)){
1528 this.removeSynonymRelation(synonymRelationship
, removeSynonymNameFromHomotypicalGroup
);
1535 * Retrieves the ordered list (depending on the date of publication) of
1536 * homotypic {@link Synonym synonyms} (according to the same {@link eu.etaxonomy.cdm.model.reference.Reference reference}
1537 * as for <i>this</i> taxon) under the condition that the {@link eu.etaxonomy.cdm.model.name.TaxonNameBase taxon names}
1538 * of these synonyms and the taxon name of <i>this</i> taxon belong to the
1539 * same {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical group}.
1541 * @return the ordered list of homotypic synonyms
1542 * @see #getHomotypicSynonymsByHomotypicRelationship()
1543 * @see #getSynonyms()
1544 * @see #getHomotypicSynonymyGroups()
1545 * @see eu.etaxonomy.cdm.model.name.HomotypicalGroup
1546 * @see eu.etaxonomy.cdm.model.name.HomotypicalGroup#getSynonymsInGroup(Reference)
1549 public List
<Synonym
> getHomotypicSynonymsByHomotypicGroup(){
1550 if (this.getHomotypicGroup() == null){
1553 return this.getSynonymsInGroup(this.getHomotypicGroup());
1558 * Retrieves the ordered list (depending on the date of publication) of
1559 * homotypic {@link Synonym synonyms} (according to the same {@link eu.etaxonomy.cdm.model.reference.Reference reference}
1560 * as for <i>this</i> taxon) under the condition that these synonyms and
1561 * <i>this</i> taxon are involved in {@link SynonymRelationship synonym relationships} with an
1562 * "is homotypic synonym of" {@link SynonymRelationshipType#HOMOTYPIC_SYNONYM_OF() synonym relationship type}.
1564 * @return the ordered list of homotypic synonyms
1565 * @see #getHomotypicSynonymsByHomotypicGroup()
1566 * @see #getSynonyms()
1567 * @see #getHomotypicSynonymyGroups()
1568 * @see SynonymRelationshipType
1571 public List
<Synonym
> getHomotypicSynonymsByHomotypicRelationship(){
1572 Set
<SynonymRelationship
> synonymRelations
= this.getSynonymRelations();
1573 List
<Synonym
> result
= new ArrayList
<Synonym
>();
1574 for(SynonymRelationship synonymRelation
: synonymRelations
) {
1575 if(synonymRelation
.getType().equals(SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF())){
1576 result
.add(synonymRelation
.getSynonym());
1583 * Returns the ordered list of all {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical groups} {@link Synonym synonyms} of
1584 * <i>this</i> taxon belong to. {@link eu.etaxonomy.cdm.model.name.TaxonNameBase Taxon names} of homotypic synonyms
1585 * belong to the same homotypical group as the taxon name of <i>this</i>
1586 * taxon. Taxon names of heterotypic synonyms belong to at least one other
1587 * homotypical group. <BR>
1588 * The list returned is ordered according to the date of publication of the
1589 * first published name within each homotypical group.
1591 * @see #getHeterotypicSynonymyGroups()
1592 * @see #getSynonyms()
1593 * @see eu.etaxonomy.cdm.model.name.HomotypicalGroup
1596 public List
<HomotypicalGroup
> getHomotypicSynonymyGroups(){
1597 List
<HomotypicalGroup
> result
= new ArrayList
<HomotypicalGroup
>();
1598 result
.add(this.getHomotypicGroup());
1599 for (TaxonNameBase taxonNameBase
:this.getSynonymNames()){
1600 if (taxonNameBase
!= null) {
1601 if (!result
.contains(taxonNameBase
.getHomotypicalGroup())){
1602 result
.add(taxonNameBase
.getHomotypicalGroup());
1604 } // TODO: give error message to user
1606 // TODO: sort list according to date of first published name within each group
1613 * The status of this taxon is unknown it could also be some kind of synonym.
1614 * @return the taxonStatusUnknown
1616 public boolean isTaxonStatusUnknown() {
1617 return taxonStatusUnknown
;
1621 * @param taxonStatusUnknown the taxonStatusUnknown to set
1623 public void setTaxonStatusUnknown(boolean taxonStatusUnknown
) {
1624 this.taxonStatusUnknown
= taxonStatusUnknown
;
1630 public boolean isUnplaced() {
1636 public boolean isOrphaned() {
1638 if(taxonNodes
== null || taxonNodes
.isEmpty()) {
1639 if(getRelationsFromThisTaxon().isEmpty() && getRelationsToThisTaxon().isEmpty()) {
1646 public void setUnplaced(boolean unplaced
) {
1647 this.unplaced
= unplaced
;
1650 public boolean isExcluded() {
1654 public void setExcluded(boolean excluded
) {
1655 this.excluded
= excluded
;
1660 * Returns the boolean value indicating if this taxon should be withheld (<code>publish=false</code>) or not
1661 * (<code>publish=true</code>) during any publication process to the general public.
1662 * This publish flag implementation is preliminary and may be replaced by a more general
1663 * implementation of READ rights in future.<BR>
1664 * The default value is <code>true</code>.
1667 public boolean isPublish() {
1672 public void setPublish(boolean publish
) {
1673 this.publish
= publish
;
1677 * Returns the ordered list of all {@link eu.etaxonomy.cdm.model.name.HomotypicalGroup homotypical groups}
1678 * that contain {@link Synonym synonyms} that are heterotypic to <i>this</i> taxon.
1679 * {@link eu.etaxonomy.cdm.model.name.TaxonNameBase Taxon names} of heterotypic synonyms
1680 * belong to a homotypical group which cannot be the homotypical group to which the
1681 * taxon name of <i>this</i> taxon belongs. This method returns the same
1682 * list as the {@link #getHomotypicSynonymyGroups() getHomotypicSynonymyGroups} method
1683 * but without the homotypical group to which the taxon name of <i>this</i> taxon
1685 * The list returned is ordered according to the date of publication of the
1686 * first published name within each homotypical group.
1688 * @see #getHeterotypicSynonymyGroups()
1689 * @see #getSynonyms()
1690 * @see SynonymRelationshipType#HETEROTYPIC_SYNONYM_OF()
1691 * @see eu.etaxonomy.cdm.model.name.HomotypicalGroup
1694 public List
<HomotypicalGroup
> getHeterotypicSynonymyGroups(){
1695 List
<HomotypicalGroup
> list
= getHomotypicSynonymyGroups();
1696 list
.remove(this.getHomotypicGroup());
1698 Map
<Synonym
, HomotypicalGroup
> map
= new HashMap
<Synonym
, HomotypicalGroup
>();
1699 for (HomotypicalGroup homotypicalGroup
: list
){
1700 List
<Synonym
> synonymList
= getSynonymsInGroup(homotypicalGroup
);
1701 if (synonymList
.size() > 0){
1702 map
.put(synonymList
.get(0), homotypicalGroup
);
1705 List
<Synonym
> keyList
= new ArrayList
<Synonym
>();
1706 keyList
.addAll(map
.keySet());
1707 Collections
.sort(keyList
, new TaxonComparator());
1709 List
<HomotypicalGroup
> result
= new ArrayList
<HomotypicalGroup
>();
1710 for(Synonym synonym
: keyList
){
1711 result
.add(map
.get(synonym
));
1718 * Retrieves the ordered list (depending on the date of publication) of
1719 * {@link taxon.Synonym synonyms} (according to a given reference)
1720 * the {@link TaxonNameBase taxon names} of which belong to the homotypical group.
1721 * If other names are part of the group that are not considered synonyms of
1722 * <i>this</i> taxon, then they will not be included in
1726 * @see TaxonNameBase#getSynonyms()
1727 * @see TaxonNameBase#getTaxa()
1728 * @see taxon.Synonym
1731 public List
<Synonym
> getSynonymsInGroup(HomotypicalGroup homotypicGroup
){
1732 List
<Synonym
> result
= new ArrayList
<Synonym
>();
1734 for (TaxonNameBase
<?
, ?
>name
: homotypicGroup
.getTypifiedNames()){
1735 for (Synonym synonym
: name
.getSynonyms()){
1736 for(SynonymRelationship synRel
: synonym
.getSynonymRelations()){
1737 if (synRel
.getAcceptedTaxon().equals(this)){
1738 result
.add(synRel
.getSynonym());
1743 Collections
.sort(result
, new TaxonComparator());
1749 * Returns the image gallery description. If no image gallery exists, a new one is created using the
1750 * defined title and adds the string "-Image Gallery" to the title.</BR>
1751 * If multiple image galleries exist an arbitrary one is choosen.
1756 public TaxonDescription
getOrCreateImageGallery(String title
){
1757 return getOrCreateImageGallery(title
, true, false);
1761 * Returns the image gallery description. If no image gallery exists, a new one is created using the
1762 * defined title.</BR>
1763 * If onlyTitle == true we look only for an image gallery with this title, create a new one otherwise.
1764 * If multiple image galleries exist that match the conditions an arbitrary one is choosen.
1767 * @param if true, the String "Image Gallery
1771 public TaxonDescription
getOrCreateImageGallery(String title
, boolean addImageGalleryToTitle
, boolean onlyTitle
){
1772 TaxonDescription result
= null;
1773 String titleCache
= (title
== null) ?
"Image Gallery" : title
;
1774 if (title
!= null && addImageGalleryToTitle
){
1775 titleCache
= titleCache
+ "-Image Gallery";
1777 Set
<TaxonDescription
> descriptionSet
= this.getDescriptions();
1778 for (TaxonDescription desc
: descriptionSet
){
1779 if (desc
.isImageGallery()){
1780 if (onlyTitle
&& ! titleCache
.equals(desc
.getTitleCache())){
1784 if (onlyTitle
&& titleCache
.equals(desc
.getTitleCache())){
1789 if (result
== null){
1790 result
= TaxonDescription
.NewInstance();
1791 result
.setTitleCache(titleCache
, true);
1792 this.addDescription(result
);
1793 result
.setImageGallery(true);
1797 //*********************** CLONE ********************************************************/
1801 * Clones <i>this</i> taxon. This is a shortcut that enables to create
1802 * a new instance that differs only slightly from <i>this</i> taxon by
1803 * modifying only some of the attributes.<BR><BR>
1804 * The TaxonNodes are not cloned, the list is empty.<BR>
1805 * (CAUTION: this behaviour needs to be discussed and may change in future).<BR><BR>
1806 * The taxon relationships and synonym relationships are cloned <BR>
1808 * @see eu.etaxonomy.cdm.model.taxon.TaxonBase#clone()
1809 * @see eu.etaxonomy.cdm.model.media.IdentifiableEntity#clone()
1810 * @see java.lang.Object#clone()
1813 public Object
clone() {
1815 result
= (Taxon
)super.clone();
1817 result
.setRelationsFromThisTaxon(new HashSet
<TaxonRelationship
>());
1819 for (TaxonRelationship fromRelationship
: this.getRelationsFromThisTaxon()){
1820 TaxonRelationship newRelationship
= (TaxonRelationship
)fromRelationship
.clone();
1821 newRelationship
.setRelatedFrom(result
);
1822 result
.relationsFromThisTaxon
.add(newRelationship
);
1825 result
.setRelationsToThisTaxon(new HashSet
<TaxonRelationship
>());
1826 for (TaxonRelationship toRelationship
: this.getRelationsToThisTaxon()){
1827 TaxonRelationship newRelationship
= (TaxonRelationship
)toRelationship
.clone();
1828 newRelationship
.setRelatedTo(result
);
1829 result
.relationsToThisTaxon
.add(newRelationship
);
1833 result
.synonymRelations
= new HashSet
<SynonymRelationship
>();
1834 for (SynonymRelationship synRelationship
: this.getSynonymRelations()){
1835 SynonymRelationship newRelationship
= (SynonymRelationship
)synRelationship
.clone();
1836 newRelationship
.setRelatedTo(result
);
1837 result
.synonymRelations
.add(newRelationship
);
1841 result
.taxonNodes
= new HashSet
<TaxonNode
>();
1843 /*for (TaxonNode taxonNode : this.getTaxonNodes()){
1844 TaxonNode newTaxonNode = (TaxonNode)taxonNode.clone();
1845 newTaxonNode.setTaxon(result);
1846 result.addTaxonNode(newTaxonNode);