Performed project cleanup.
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / HomotypicalGroup.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9
10 package eu.etaxonomy.cdm.model.name;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17
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.XmlType;
27
28 import org.apache.log4j.Logger;
29 import org.hibernate.annotations.Cascade;
30 import org.hibernate.annotations.CascadeType;
31
32 import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
33 import eu.etaxonomy.cdm.model.reference.ReferenceBase;
34 import eu.etaxonomy.cdm.model.taxon.Synonym;
35 import eu.etaxonomy.cdm.model.taxon.TaxonComparator;
36 import eu.etaxonomy.cdm.strategy.cache.name.INameCacheStrategy;
37
38
39 /**
40 * The homotypical group class represents a set of {@link TaxonNameBase taxon names} all sharing
41 * the same type specimens. It can also include names with a {@link common.Rank rank} higher
42 * than "species aggregate" like genera or families which usually are typified by
43 * a taxon name that finally (a name type designation can also point to another
44 * taxon name) points to a species name, which in turn is typified by a (set of)
45 * physical type specimen(s). This class allows to define a
46 * {@link SpecimenTypeDesignation specimen type designation} only once
47 * for the homotypical group instead of defining a type designation for each one
48 * of the taxon names subsumed under one homotypical group.
49 *
50 * @author m.doering
51 * @version 1.0
52 * @created 08-Nov-2007
53 */
54 @XmlAccessorType(XmlAccessType.FIELD)
55 @XmlType(name = "HomotypicalGroup", propOrder = {
56 "typifiedNames",
57 "typeDesignations"
58 })
59 @Entity
60 public class HomotypicalGroup extends AnnotatableEntity {
61 static Logger logger = Logger.getLogger(HomotypicalGroup.class);
62
63 @XmlElementWrapper(name = "TypifiedNames")
64 @XmlElement(name = "TypifiedName")
65 protected Set<TaxonNameBase> typifiedNames = new HashSet();
66
67 @XmlElementWrapper(name = "TypeDesignations")
68 @XmlElement(name = "TypeDesignation")
69 protected Set<SpecimenTypeDesignation> typeDesignations = new HashSet();
70
71 /**
72 * Class constructor: creates a new homotypical group instance with an
73 * empty set of typified {@link TaxonNameBase taxon names} and an empty set of
74 * {@link SpecimenTypeDesignation specimen type designations}.
75 */
76 public HomotypicalGroup() {
77 super();
78 }
79
80 /**
81 * Creates a new homotypical group instance with an empty set of typified
82 * {@link TaxonNameBase taxon names} and an empty set of
83 * {@link SpecimenTypeDesignation specimen type designations}.
84 *
85 * @see #HomotypicalGroup()
86 */
87 public static HomotypicalGroup NewInstance(){
88 return new HomotypicalGroup();
89 }
90
91
92
93 /**
94 * Returns the set of {@link TaxonNameBase taxon names} that belong to <i>this</i> homotypical group.
95 *
96 * @see #getTypeDesignations()
97 */
98 @OneToMany(mappedBy="homotypicalGroup", fetch=FetchType.LAZY)
99 public Set<TaxonNameBase> getTypifiedNames() {
100 return typifiedNames;
101 }
102 /**
103 * @see #getTypifiedNames()
104 */
105 protected void setTypifiedNames(Set<TaxonNameBase> typifiedNames) {
106 this.typifiedNames = typifiedNames;
107 }
108 /**
109 * Adds a new {@link TaxonNameBase taxon name} to the set of taxon names that belong
110 * to <i>this</i> homotypical group and to the corresponding set of each
111 * {@link SpecimenTypeDesignation#getTypifiedNames() type designation}
112 * associated with <i>this</i> homotypical group.
113 *
114 * @param typifiedName the taxon name to be added to <i>this</i> group
115 * @see #getTypifiedNames()
116 * @see #removeTypifiedName(TaxonNameBase)
117 */
118 public void addTypifiedName(TaxonNameBase typifiedName) {
119 if (typifiedName != null){
120 typifiedName.setHomotypicalGroup(this);
121 typifiedNames.add(typifiedName);
122 }
123 }
124 /**
125 * Removes one element from the set of {@link TaxonNameBase taxon names}
126 * that belong to <i>this</i> homotypical group.
127 *
128 * @param taxonBase the taxon name which should be removed from the corresponding set
129 * @see #addTypifiedName(TaxonNameBase)
130 */
131 public void removeTypifiedName(TaxonNameBase typifiedName) {
132 typifiedName.setHomotypicalGroup(null);
133 typifiedNames.remove(typifiedName);
134 }
135
136 /**
137 * Merges the typified {@link TaxonNameBase taxon names} from one homotypical group into
138 * the set of typified taxon names of <i>this</i> homotypical group.
139 *
140 * @param homotypicalGroupToMerge the homotypical group the typified names of which
141 * are to be transferred to <i>this</i> homotypical group
142 */
143 public void merge(HomotypicalGroup homotypicalGroupToMerge){
144 if (homotypicalGroupToMerge != null){
145 Set<TaxonNameBase> typifiedNames = new HashSet<TaxonNameBase>();
146 typifiedNames.addAll(homotypicalGroupToMerge.getTypifiedNames());
147 for (TaxonNameBase typifiedName: typifiedNames){
148 this.addTypifiedName(typifiedName);
149 }
150 }
151 }
152
153
154 /**
155 * Returns the set of {@link SpecimenTypeDesignation specimen type designations} that
156 * typify <i>this</i> homotypical group including the status of these designations.
157 *
158 * @see #getTypifiedNames()
159 */
160 @OneToMany
161 @Cascade({CascadeType.SAVE_UPDATE})
162 public Set<SpecimenTypeDesignation> getTypeDesignations() {
163 return typeDesignations;
164 }
165 /**
166 * @see #getTypeDesignations()
167 */
168 protected void setTypeDesignations(Set<SpecimenTypeDesignation> typeDesignations) {
169 this.typeDesignations = typeDesignations;
170 }
171 /**
172 * Adds a new {@link SpecimenTypeDesignation specimen type designation} to the set
173 * of specimen type designations assigned to <i>this</i> homotypical group and eventually
174 * (with a boolean parameter) also to the corresponding set of each of the
175 * {@link TaxonNameBase taxon names} belonging to <i>this</i> homotypical group.
176 *
177 * @param typeDesignation the specimen type designation to be added
178 * @param addToAllNames the boolean flag indicating whether the addition will also
179 * carried out for each taxon name
180 *
181 * @see TaxonNameBase#getSpecimenTypeDesignations()
182 * @see SpecimenTypeDesignation
183 */
184 public void addTypeDesignation(SpecimenTypeDesignation typeDesignation, boolean addToAllNames) {
185 if (typeDesignation != null){
186 typeDesignation.setHomotypicalGroup(this);
187 typeDesignations.add(typeDesignation);
188 }
189 if (addToAllNames){
190 for (TaxonNameBase taxonNameBase : this.typifiedNames){
191 taxonNameBase.addSpecimenTypeDesignation(typeDesignation);
192 }
193 }
194 }
195 /**
196 * Removes one element from the set of {@link SpecimenTypeDesignation specimen type designations} assigned to the
197 * {@link HomotypicalGroup homotypical group} to which this {@link TaxonNameBase taxon name} belongs.
198 * The same element will be removed from the corresponding set of each of
199 * the taxon names belonging to <i>this</i> homotypical group. Furthermore the
200 * homotypical group attribute of the specimen type designation will be
201 * nullified.
202 *
203 * @param typeDesignation the specimen type designation which should be deleted
204 * @see #getTypeDesignations()
205 * @see #addTypeDesignation(SpecimenTypeDesignation, boolean)
206 * @see TaxonNameBase#removeSpecimenTypeDesignation(SpecimenTypeDesignation)
207 * @see SpecimenTypeDesignation#getHomotypicalGroup()
208 */
209 public void removeTypeDesignation(SpecimenTypeDesignation typeDesignation) {
210 if (typeDesignation != null){
211 typeDesignation.setHomotypicalGroup(null);
212 typeDesignations.remove(typeDesignation);
213 }
214 for (TaxonNameBase taxonNameBase : this.typifiedNames){
215 taxonNameBase.removeSpecimenTypeDesignation(typeDesignation);
216 }
217 }
218
219
220 /**
221 * Retrieves the ordered list (depending on the date of publication) of
222 * {@link taxon.Synonym synonyms} (according to a given reference)
223 * the {@link TaxonNameBase taxon names} of which belong to <i>this>/i> homotypical group.
224 * If other names are part of <i>this</i> group that are not considered synonyms
225 * according to the respective reference, then they will not be included in
226 * the result set.
227 *
228 * @param sec the reference whose treatment is to be considered
229 * @return the ordered list of synonyms
230 * @see TaxonNameBase#getSynonyms()
231 * @see TaxonNameBase#getTaxa()
232 * @see taxon.Synonym
233 */
234 @Transient
235 public List<Synonym> getSynonymsInGroup(ReferenceBase sec){
236 List<Synonym> result = new ArrayList();
237 for (TaxonNameBase<TaxonNameBase, INameCacheStrategy> n:this.getTypifiedNames()){
238 for (Synonym s:n.getSynonyms()){
239 if ( (s.getSec() == null && sec == null) ||
240 s.getSec().equals(sec)){
241 result.add(s);
242 }
243 }
244 }
245 //TODO test
246 Collections.sort(result, new TaxonComparator());
247 return result;
248 }
249 }