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 java
.util
.ArrayList
;
13 import java
.util
.Collections
;
14 import java
.util
.HashSet
;
15 import java
.util
.List
;
18 import javax
.persistence
.Entity
;
19 import javax
.persistence
.FetchType
;
20 import javax
.persistence
.OneToMany
;
21 import javax
.persistence
.Transient
;
22 import javax
.xml
.bind
.annotation
.XmlAccessType
;
23 import javax
.xml
.bind
.annotation
.XmlAccessorType
;
24 import javax
.xml
.bind
.annotation
.XmlElement
;
25 import javax
.xml
.bind
.annotation
.XmlElementWrapper
;
26 import javax
.xml
.bind
.annotation
.XmlIDREF
;
27 import javax
.xml
.bind
.annotation
.XmlSchemaType
;
28 import javax
.xml
.bind
.annotation
.XmlType
;
30 import org
.apache
.log4j
.Logger
;
31 import org
.hibernate
.envers
.Audited
;
33 import eu
.etaxonomy
.cdm
.model
.common
.AnnotatableEntity
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceBase
;
35 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
36 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonComparator
;
40 * The homotypical group class represents a set of {@link TaxonNameBase taxon names} associated
41 * on the base of their typifications. Since it can be asserted that two taxon
42 * names are typified by the same type without mentioning the type itself, even
43 * taxon names without explicit {@link TypeDesignationBase type designation} can belong
44 * to an homotypical group.<BR>
45 * Taxon names belonging to an homotypical group and the taxon names or
46 * {@link eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase specimens} used as types for their
47 * {@link TypeDesignationBase type designations} have the following properties: <ul>
48 * <li> A taxon name belongs exactly to one homotypical group
49 * <li> A type specimen or a type name can be used as a type only for taxon
50 * names belonging to the same homotypical group<BR>
51 * - therefore an homotypical group circumscribes a set of types<BR>
52 * - each taxon name shares a subset of these types<BR>
53 * - each type is used by a subset of these taxon names
54 * within the homotypical group
55 * <li> Names that share at least one common type must belong to the same
57 * <li> Names that share the same basionym or replaced synonym must belong to
58 * the same homotypical group
61 * @see TypeDesignationBase
62 * @see NameTypeDesignation
63 * @see SpecimenTypeDesignation
66 * @created 08-Nov-2007
68 @XmlAccessorType(XmlAccessType
.FIELD
)
69 @XmlType(name
= "HomotypicalGroup", propOrder
= {
74 public class HomotypicalGroup
extends AnnotatableEntity
{
75 static Logger logger
= Logger
.getLogger(HomotypicalGroup
.class);
77 @XmlElementWrapper(name
= "TypifiedNames")
78 @XmlElement(name
= "TypifiedName")
80 @XmlSchemaType(name
= "IDREF")
81 @OneToMany(mappedBy
="homotypicalGroup", fetch
=FetchType
.LAZY
)
82 protected Set
<TaxonNameBase
> typifiedNames
= new HashSet
<TaxonNameBase
>();
85 * Class constructor: creates a new homotypical group instance with an
86 * empty set of typified {@link TaxonNameBase taxon names}.
88 public HomotypicalGroup() {
93 * Creates a new homotypical group instance with an empty set of typified
94 * {@link TaxonNameBase taxon names}.
96 * @see #HomotypicalGroup()
98 public static HomotypicalGroup
NewInstance(){
99 return new HomotypicalGroup();
103 * Returns the set of {@link TaxonNameBase taxon names} that belong to <i>this</i> homotypical group.
105 * @see #getSpecimenTypeDesignations()
107 public Set
<TaxonNameBase
> getTypifiedNames() {
108 return typifiedNames
;
112 * Adds a new {@link TaxonNameBase taxon name} to the set of taxon names that belong
113 * to <i>this</i> homotypical group.
115 * @param typifiedName the taxon name to be added to <i>this</i> group
116 * @see #getTypifiedNames()
117 * @see #removeTypifiedName(TaxonNameBase)
119 public void addTypifiedName(TaxonNameBase typifiedName
) {
120 if (typifiedName
!= null){
121 typifiedName
.setHomotypicalGroup(this);
122 typifiedNames
.add(typifiedName
);
126 * Removes one element from the set of {@link TaxonNameBase taxon names}
127 * that belong to <i>this</i> homotypical group.
129 * @param taxonBase the taxon name which should be removed from the corresponding set
130 * @see #addTypifiedName(TaxonNameBase)
132 public void removeTypifiedName(TaxonNameBase typifiedName
) {
133 typifiedName
.setHomotypicalGroup(null);
134 typifiedNames
.remove(typifiedName
);
138 * Merges the typified {@link TaxonNameBase taxon names} from one homotypical group into
139 * the set of typified taxon names of <i>this</i> homotypical group.
141 * @param homotypicalGroupToMerge the homotypical group the typified names of which
142 * are to be transferred to <i>this</i> homotypical group
144 public void merge(HomotypicalGroup homotypicalGroupToMerge
){
145 if (homotypicalGroupToMerge
!= null){
146 Set
<TaxonNameBase
> typifiedNames
= new HashSet
<TaxonNameBase
>();
147 typifiedNames
.addAll(homotypicalGroupToMerge
.getTypifiedNames());
148 for (TaxonNameBase typifiedName
: typifiedNames
){
149 this.addTypifiedName(typifiedName
);
156 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
157 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
158 * including the status of these designations.
160 * @see #getTypifiedNames()
161 * @see #getNameTypeDesignations()
162 * @see #getTypeDesignations()
163 * @see TaxonNameBase#getSpecimenTypeDesignations()
166 public Set
<SpecimenTypeDesignation
> getSpecimenTypeDesignations(){
167 Set
<SpecimenTypeDesignation
> result
= new HashSet
<SpecimenTypeDesignation
>();
168 for (TaxonNameBase taxonName
: typifiedNames
){
169 result
.addAll(taxonName
.getSpecimenTypeDesignations());
175 * Returns the set of {@link NameTypeDesignation name type designations} that
176 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
177 * including the status of these designations.
179 * @see #getTypifiedNames()
180 * @see #getSpecimenTypeDesignations()
181 * @see #getTypeDesignations()
182 * @see TaxonNameBase#getNameTypeDesignations()
185 public Set
<NameTypeDesignation
> getNameTypeDesignations(){
186 Set
<NameTypeDesignation
> result
= new HashSet
<NameTypeDesignation
>();
187 for (TaxonNameBase taxonName
: typifiedNames
){
188 result
.addAll(taxonName
.getNameTypeDesignations());
195 * Returns the set of all {@link TypeDesignationBase type designations} that
196 * typify the {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group
197 * (this includes either {@link NameTypeDesignation name type designations} or
198 * {@link SpecimenTypeDesignation specimen type designations}).
200 * @see #getTypifiedNames()
201 * @see #getNameTypeDesignations()
202 * @see #getSpecimenTypeDesignations()
203 * @see TaxonNameBase#getTypeDesignations()
206 public Set
<TypeDesignationBase
> getTypeDesignations(){
207 Set
<TypeDesignationBase
> result
= new HashSet
<TypeDesignationBase
>();
208 for (TaxonNameBase taxonName
: typifiedNames
){
209 result
.addAll(taxonName
.getTypeDesignations());
215 // * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
216 // * typify <i>this</i> homotypical group including the status of these designations.
218 // * @see #getTypifiedNames()
221 // @Cascade({CascadeType.SAVE_UPDATE})
222 // public Set<SpecimenTypeDesignation> getSpecimenTypeDesignations() {
223 // return specimenTypeDesignations;
226 // * @see #getSpecimenTypeDesignations()
228 // protected void setSpecimenTypeDesignations(Set<SpecimenTypeDesignation> specimenTypeDesignations) {
229 // this.specimenTypeDesignations = specimenTypeDesignations;
232 // * Adds a new {@link SpecimenTypeDesignation specimen type designation} to the set
233 // * of specimen type designations assigned to <i>this</i> homotypical group and eventually
234 // * (with a boolean parameter) also to the corresponding set of each of the
235 // * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
237 // * @param specimenTypeDesignation the specimen type designation to be added
238 // * @param addToAllNames the boolean flag indicating whether the addition will also
239 // * carried out for each taxon name
241 // * @see TaxonNameBase#getSpecimenTypeDesignations()
242 // * @see SpecimenTypeDesignation
244 // public void addSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation, boolean addToAllNames) {
245 // if (specimenTypeDesignation != null){
246 // specimenTypeDesignation.setHomotypicalGroup(this);
247 // specimenTypeDesignations.add(specimenTypeDesignation);
249 // if (addToAllNames){
250 // for (TaxonNameBase taxonNameBase : this.typifiedNames){
251 // taxonNameBase.addSpecimenTypeDesignation(specimenTypeDesignation);
256 // * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
257 // * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
258 // * The same element will be removed from the corresponding set of each of
259 // * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
260 // * homotypical group attribute of the specimen type designation will be
263 // * @param specimenTypeDesignation the specimen type designation which should be deleted
264 // * @see #getSpecimenTypeDesignations()
265 // * @see #addSpecimenTypeDesignation(SpecimenTypeDesignation, boolean)
266 // * @see TaxonNameBase#removeSpecimenTypeDesignation(SpecimenTypeDesignation)
267 // * @see SpecimenTypeDesignation#getHomotypicalGroup()
269 // public void removeSpecimenTypeDesignation(SpecimenTypeDesignation specimenTypeDesignation) {
270 // if (specimenTypeDesignation != null){
271 // specimenTypeDesignation.setHomotypicalGroup(null);
272 // specimenTypeDesignations.remove(specimenTypeDesignation);
274 // for (TaxonNameBase taxonNameBase : this.typifiedNames){
275 // taxonNameBase.removeSpecimenTypeDesignation(specimenTypeDesignation);
281 // * Returns the set of {@link NameTypeDesignation name type designations} that
282 // * typify <i>this</i> homotypical group including the status of these designations.
284 // * @see #getTypifiedNames()
287 // @Cascade({CascadeType.SAVE_UPDATE})
288 // public Set<NameTypeDesignation> getNameTypeDesignations() {
289 // return nameTypeDesignations;
292 // * @see #getNameTypeDesignations()
294 // protected void setNameTypeDesignations(Set<NameTypeDesignation> nameTypeDesignations) {
295 // this.nameTypeDesignations = nameTypeDesignations;
298 // * Adds a new {@link NameTypeDesignation name type designation} to the set
299 // * of name type designations assigned to <i>this</i> homotypical group and eventually
300 // * (with a boolean parameter) also to the corresponding set of each of the
301 // * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
303 // * @param nameTypeDesignation the name type designation to be added
304 // * @param addToAllNames the boolean flag indicating whether the addition will also
305 // * carried out for each taxon name
307 // * @see TaxonNameBase#getNameTypeDesignations()
308 // * @see NameTypeDesignation
310 // public void addNameTypeDesignation(NameTypeDesignation nameTypeDesignation, boolean addToAllNames) {
311 // if (nameTypeDesignation != null){
312 // nameTypeDesignation.setHomotypicalGroup(this);
313 // nameTypeDesignations.add(nameTypeDesignation);
315 // if (addToAllNames){
316 // for (TaxonNameBase taxonNameBase : this.typifiedNames){
317 // taxonNameBase.addNameTypeDesignation(nameTypeDesignation);
322 // * Removes one element from the set of {@link NameTypeDesignation name type designations} assigned to the
323 // * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
324 // * The same element will be removed from the corresponding set of each of
325 // * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
326 // * homotypical group attribute of the name type designation will be
329 // * @param nameTypeDesignation the name type designation which should be deleted
330 // * @see #getNameTypeDesignations()
331 // * @see #addNameTypeDesignation(NameTypeDesignation, boolean)
332 // * @see TaxonNameBase#removeNameTypeDesignation(NameTypeDesignation)
333 // * @see NameTypeDesignation#getHomotypicalGroup()
335 // public void removeNameTypeDesignation(NameTypeDesignation nameTypeDesignation) {
336 // if (nameTypeDesignation != null){
337 // nameTypeDesignation.setHomotypicalGroup(null);
338 // nameTypeDesignations.remove(nameTypeDesignation);
340 // for (TaxonNameBase taxonNameBase : this.typifiedNames){
341 // taxonNameBase.removeNameTypeDesignation(nameTypeDesignation);
347 * Retrieves the ordered list (depending on the date of publication) of
348 * {@link taxon.Synonym synonyms} (according to a given reference)
349 * the {@link TaxonNameBase taxon names} of which belong to <i>this</i> homotypical group.
350 * If other names are part of <i>this</i> group that are not considered synonyms
351 * according to the respective reference, then they will not be included in
354 * @param sec the reference whose treatment is to be considered
355 * @return the ordered list of synonyms
356 * @see TaxonNameBase#getSynonyms()
357 * @see TaxonNameBase#getTaxa()
360 public List
<Synonym
> getSynonymsInGroup(ReferenceBase sec
){
361 List
<Synonym
> result
= new ArrayList();
362 for (TaxonNameBase
<?
, ?
>name
: this.getTypifiedNames()){
363 for (Synonym synonym
: name
.getSynonyms()){
364 if ( (synonym
.getSec() == null && sec
== null) ||
365 synonym
.getSec() != null && synonym
.getSec().equals(sec
)){
370 Collections
.sort(result
, new TaxonComparator());