Moving editor sources back into trunk
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / store / model / SynonymUtil.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.store.model;
12
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import org.apache.log4j.Logger;
17
18 import eu.etaxonomy.cdm.model.description.TaxonDescription;
19 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
20 import eu.etaxonomy.cdm.model.name.NameRelationship;
21 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
22 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
23 import eu.etaxonomy.cdm.model.taxon.Synonym;
24 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
25 import eu.etaxonomy.cdm.model.taxon.Taxon;
26 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
27 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
28
29 /**
30 * @author n.hoffmann
31 * @created 22.04.2009
32 * @version 1.0
33 */
34 public class SynonymUtil {
35 private static final Logger logger = Logger.getLogger(SynonymUtil.class);
36
37
38 /**
39 * Creates a basionym relationship between basionymName and
40 * each name in its homotypic group.
41 *
42 * @param basionymName
43 * @deprecated TODO move this to cmdlib
44 */
45 public static void setGroupBasionym(TaxonNameBase basionymName) {
46
47
48 HomotypicalGroup homotypicalGroup = basionymName.getHomotypicalGroup();
49
50 if (homotypicalGroup == null) {
51 return;
52 }
53
54 Set<NameRelationship> relations = new HashSet<NameRelationship>();
55 Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
56
57 for(TaxonNameBase typifiedName : homotypicalGroup.getTypifiedNames()){
58
59 Set<NameRelationship> nameRelations = typifiedName.getRelationsFromThisName();
60
61 for(NameRelationship nameRelation : nameRelations){
62 relations.add(nameRelation);
63 }
64 }
65
66 for (NameRelationship relation : relations) {
67
68 // If this is a basionym relation, and toName is in the homotypical group,
69 // remove the relationship.
70 if (relation.getType().equals(NameRelationshipType.BASIONYM()) &&
71 relation.getToName().getHomotypicalGroup().equals(homotypicalGroup)) {
72 removeRelations.add(relation);
73 }
74 }
75
76 // Removing relations from a set through which we are iterating causes a
77 // ConcurrentModificationException. Therefore, we delete the targeted
78 // relations in a second step.
79 for (NameRelationship relation : removeRelations) {
80 basionymName.removeNameRelationship(relation);
81 }
82
83
84 for (TaxonNameBase name : homotypicalGroup.getTypifiedNames()) {
85 if (!name.equals(basionymName)) {
86
87 // First check whether the relationship already exists
88 if (!isNameBasionymOf(basionymName, name)) {
89
90 // Then create it
91 name.addRelationshipFromName(basionymName,
92 NameRelationshipType.BASIONYM(), null);
93 }
94 }
95 }
96 }
97
98 /**
99 * Creates a basionym relationship between basionymName and
100 * each name in its homotypic group.
101 *
102 * @param basionymName
103 * @deprecated TODO move this to cmdlib
104 */
105 public static void removeGroupBasionym(TaxonNameBase basionymName) {
106
107 HomotypicalGroup homotypicalGroup = basionymName.getHomotypicalGroup();
108
109 if (homotypicalGroup == null) {
110 return;
111 }
112
113 Set<NameRelationship> relations = new HashSet<NameRelationship>();
114 Set<NameRelationship> removeRelations = new HashSet<NameRelationship>();
115
116 for(TaxonNameBase typifiedName : homotypicalGroup.getTypifiedNames()){
117
118 Set<NameRelationship> nameRelations = typifiedName.getRelationsFromThisName();
119
120 for(NameRelationship nameRelation : nameRelations){
121 relations.add(nameRelation);
122 }
123 }
124
125 for (NameRelationship relation : relations) {
126
127 // If this is a basionym relation, and toName is in the homotypical group,
128 // and fromName is basionymName, remove the relationship.
129 if (relation.getType().equals(NameRelationshipType.BASIONYM()) &&
130 relation.getFromName().equals(basionymName) &&
131 relation.getToName().getHomotypicalGroup().equals(homotypicalGroup)) {
132 removeRelations.add(relation);
133 }
134 }
135
136 // Removing relations from a set through which we are iterating causes a
137 // ConcurrentModificationException. Therefore, we delete the targeted
138 // relations in a second step.
139 for (NameRelationship relation : removeRelations) {
140 basionymName.removeNameRelationship(relation);
141 }
142 }
143
144 /**
145 * Checks whether synonym's name is the basionym for ALL names
146 * in its group.
147 *
148 * @param synonym
149 *
150 * @return
151 * @deprecated TODO move this to cmdlib
152 */
153 public static boolean isSynonymGroupBasionym(Synonym synonym) {
154
155 TaxonNameBase synonymName = synonym.getName();
156 return isNameGroupBasionym(synonymName);
157 }
158
159 /**
160 * Checks whether name is the basionym for ALL names
161 * in its group.
162 * @param name
163 *
164 * @return
165 * @deprecated TODO move this to cmdlib
166 */
167 public static boolean isNameGroupBasionym(TaxonNameBase name) {
168 if (name == null) {
169 return false;
170 }
171
172 HomotypicalGroup homotypicalGroup = name.getHomotypicalGroup();
173 if (homotypicalGroup == null) {
174 return false;
175 }
176
177 Set<TaxonNameBase> typifiedNames = homotypicalGroup.getTypifiedNames();
178
179 // Check whether there are any other names in the group
180 if (typifiedNames.size() == 1) {
181 return false;
182 }
183
184 boolean isBasionymToAll = true;
185
186 for (TaxonNameBase taxonName : typifiedNames) {
187 if (!taxonName.equals(name)) {
188 if (!isNameBasionymOf(name, taxonName)) {
189 return false;
190 }
191 }
192 }
193 return true;
194 }
195
196 /**
197 * Checks whether a basionym relationship exists between fromName and toName.
198 *
199 * @param fromName
200 * @param toName
201 * @return
202 * @deprecated TODO move this to cmdlib
203 */
204 public static boolean isNameBasionymOf(TaxonNameBase fromName, TaxonNameBase toName) {
205 Set<NameRelationship> relations = toName.getRelationsToThisName();
206 for (NameRelationship relation : relations) {
207 if (relation.getType().equals(NameRelationshipType.BASIONYM()) &&
208 relation.getFromName().equals(fromName)) {
209 return true;
210 }
211 }
212 return false;
213 }
214
215 /**
216 * TODO move this to cdmlib
217 *
218 * Basically we just want to swap the names. Unfortunately this is all super complicated.
219 *
220 * @param oldSynonym
221 * @param oldTaxon
222 * @return
223 *
224 * @deprecated
225 */
226 public static Taxon swapSynonymAndAccepted(Synonym oldSynonym, Taxon oldTaxon) {
227
228 // Create a new taxon from synonym
229 Taxon newTaxon = Taxon.NewInstance(oldSynonym.getName(), oldSynonym.getSec());
230
231 // Create a new synonym from the taxon and add it to the newly created taxon
232 Synonym newSynonym = Synonym.NewInstance(oldTaxon.getName(), oldTaxon.getSec());
233
234 // Remove synonym from taxon
235 oldTaxon.removeSynonym(oldSynonym);
236
237 // Swap parent
238 Taxon parentTaxon = oldTaxon.getTaxonomicParent();
239 newTaxon.setTaxonomicParent(parentTaxon, null, null);
240 oldTaxon.setTaxonomicParent(null, null, null);
241
242 // Swap children
243 Set<Taxon> childTaxa = oldTaxon.getTaxonomicChildren();
244 for (Taxon childTaxon : childTaxa) {
245 childTaxon.setTaxonomicParent(newTaxon, null, null);
246 }
247
248 // Swap taxon and synonym
249 if (NameUtil.isNameHomotypic(newSynonym.getName(), newTaxon)) {
250 newTaxon.addSynonym(newSynonym, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF());
251 } else {
252 newTaxon.addSynonym(newSynonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
253 }
254
255 // Move the other synonyms from old accepted taxon to new accepted taxon
256 for (Synonym synonym : oldTaxon.getSynonyms()) {
257 SynonymRelationshipType synRelType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
258 if (NameUtil.isNameHomotypic(synonym.getName(), newTaxon) != true) {
259 synRelType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
260 }
261 newTaxon.addSynonym(synonym, synRelType);
262 oldTaxon.removeSynonym(synonym);
263 }
264
265 // Move misapplied names
266 for (Taxon misappliedNameTaxon : oldTaxon.getMisappliedNames()) {
267 newTaxon.addMisappliedName(misappliedNameTaxon,
268 misappliedNameTaxon.getName().getCitation(),
269 ""); //TODO: Set the microcitation
270 oldTaxon.removeTaxon(misappliedNameTaxon, TaxonRelationshipType.MISAPPLIED_NAME_FOR());
271 }
272
273 // Move concept relations
274 for (TaxonRelationship relation : oldTaxon.getTaxonRelations()) {
275 if (relation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) ||
276 relation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {
277 continue;
278 }
279 if (oldTaxon.equals(relation.getFromTaxon())) {
280 newTaxon.addTaxonRelation(relation.getToTaxon(), relation.getType(),
281 relation.getCitation(), relation.getCitationMicroReference());
282 } else {
283 if (relation.getToTaxon() != null) {
284 relation.getToTaxon().addTaxonRelation(newTaxon, relation.getType(),
285 relation.getCitation(), relation.getCitationMicroReference());
286 }
287 }
288 oldTaxon.removeTaxonRelation(relation);
289 }
290
291 // Move descriptions
292 Set<TaxonDescription> taxonDescriptions = new HashSet<TaxonDescription>();
293 for(TaxonDescription taxonDescription : oldTaxon.getDescriptions()){
294 taxonDescriptions.add(taxonDescription);
295 }
296 for(TaxonDescription taxonDescription : taxonDescriptions){
297 newTaxon.addDescription(taxonDescription);
298 oldTaxon.removeDescription(taxonDescription);
299 }
300
301 return newTaxon;
302 }
303 }