Revision 82ca4447
Added by Andreas Müller over 7 years ago
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/HomotypicGroupTaxonComparator.java | ||
---|---|---|
31 | 31 |
* basionyms (according to the following ordering)</li> |
32 | 32 |
* <li>If a name is illegitimate or not does play a role for ordering</li> |
33 | 33 |
* <li>Names with publication year should always come first</li> |
34 |
* <li>Names with no publication year are sorted alphabetically</li> |
|
34 |
* <li>Names with no publication year are sorted by rank</li> |
|
35 |
* <li>Names with no publication year and equal rank are sorted alphabetically</li> |
|
35 | 36 |
* <li>If 2 names have a replaced synonym relationship the replaced synonym comes first, |
36 | 37 |
* the replacement name comes later as this reflects the order of publication</li> |
37 | 38 |
* </ul> |
... | ... | |
54 | 55 |
* @param firstNameInGroup |
55 | 56 |
*/ |
56 | 57 |
public HomotypicGroupTaxonComparator(@SuppressWarnings("rawtypes") TaxonBase firstTaxonInGroup) { |
58 |
super(true); |
|
59 |
this.firstTaxonInGroup = firstTaxonInGroup; |
|
60 |
this.firstNameInGroup = firstTaxonInGroup == null ? null: firstTaxonInGroup.getName(); |
|
61 |
} |
|
62 |
|
|
63 |
/** |
|
64 |
* @param firstNameInGroup |
|
65 |
*/ |
|
66 |
public HomotypicGroupTaxonComparator(@SuppressWarnings("rawtypes") TaxonBase firstTaxonInGroup, boolean includeRanks) { |
|
67 |
super(includeRanks); |
|
57 | 68 |
this.firstTaxonInGroup = firstTaxonInGroup; |
58 | 69 |
this.firstNameInGroup = firstTaxonInGroup == null ? null: firstTaxonInGroup.getName(); |
59 | 70 |
} |
... | ... | |
81 | 92 |
|
82 | 93 |
//not same homotypical group - |
83 | 94 |
//NOTE: this comparator should usually not be used |
84 |
// for comparing names of different homotypcial groups.
|
|
95 |
// for comparing names of different homotypical groups.
|
|
85 | 96 |
// The following is only to have a defined compare behavior |
86 | 97 |
// which follows the contract of Comparator#compare. |
87 | 98 |
if (name1 == null || |
88 | 99 |
name2 == null || |
89 | 100 |
! name1.getHomotypicalGroup().equals(name2.getHomotypicalGroup())){ |
90 | 101 |
|
91 |
// |
|
92 |
// HomotypicalGroup hg1 = name1.getHomotypicalGroup(); |
|
93 |
// HomotypicalGroup hg2 = name2.getHomotypicalGroup(); |
|
94 |
|
|
95 |
|
|
96 | 102 |
String compareString1 = name1 != null ? |
97 |
// getFirstNameInHomotypicalGroup(name1) |
|
98 | 103 |
name1.getHomotypicalGroup().getUuid().toString() : |
99 | 104 |
taxonBase1.getUuid().toString(); |
100 | 105 |
String compareString2 = name2 != null ? |
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/taxon/TaxonComparator.java | ||
---|---|---|
18 | 18 |
|
19 | 19 |
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus; |
20 | 20 |
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType; |
21 |
import eu.etaxonomy.cdm.model.name.Rank; |
|
21 | 22 |
import eu.etaxonomy.cdm.model.name.TaxonNameBase; |
22 | 23 |
import eu.etaxonomy.cdm.model.name.ZoologicalName; |
23 | 24 |
import eu.etaxonomy.cdm.model.reference.Reference; |
... | ... | |
35 | 36 |
@SuppressWarnings("unused") |
36 | 37 |
private static final Logger logger = Logger.getLogger(TaxonComparator.class); |
37 | 38 |
|
39 |
private boolean includeRanks = false; |
|
40 |
|
|
41 |
/** |
|
42 |
* @param includeRanks |
|
43 |
*/ |
|
44 |
public TaxonComparator() { |
|
45 |
super(); |
|
46 |
} |
|
47 |
|
|
48 |
/** |
|
49 |
* @param includeRanks |
|
50 |
*/ |
|
51 |
public TaxonComparator(boolean includeRanks) { |
|
52 |
super(); |
|
53 |
this.includeRanks = includeRanks; |
|
54 |
} |
|
55 |
|
|
56 |
|
|
38 | 57 |
/** |
39 | 58 |
* Returns an integer generated by comparing first the nomenclatural status and then the |
40 | 59 |
* {@link eu.etaxonomy.cdm.model.name.INomenclaturalReference#getYear() publication years} |
... | ... | |
198 | 217 |
result = intDate1.compareTo(intDate2); |
199 | 218 |
} |
200 | 219 |
|
201 |
if (result == 0){ |
|
220 |
if (result == 0 && includeRanks){ |
|
221 |
Rank rank1 = name1 == null? null : name1.getRank(); |
|
222 |
Rank rank2 = name2 == null? null : name2.getRank(); |
|
223 |
|
|
224 |
if (rank1 == null && rank2 == null){ |
|
225 |
result = 0; |
|
226 |
}else if (rank1 == null){ |
|
227 |
return 1; |
|
228 |
}else if (rank2 == null){ |
|
229 |
return -1; |
|
230 |
}else{ |
|
231 |
//for some strange reason compareTo for ranks returns 1 if rank2 is lower. So we add minus (-) |
|
232 |
result = - rank1.compareTo(rank2); |
|
233 |
} |
|
234 |
} |
|
235 |
|
|
236 |
if (result == 0 && name1 != null && name2 != null){ |
|
202 | 237 |
result = name1.compareTo(name2); |
203 | 238 |
if (result != 0){ |
204 | 239 |
return result; |
cdmlib-model/src/test/java/eu/etaxonomy/cdm/model/taxon/HomotypicGroupTaxonComparatorTest.java | ||
---|---|---|
55 | 55 |
private List<TaxonBase<?>> list; |
56 | 56 |
|
57 | 57 |
private Taxon taxon1; |
58 |
private Synonym synonym1; |
|
59 | 58 |
private Synonym synonym2; |
60 | 59 |
private Synonym synonym3; |
61 | 60 |
|
... | ... | |
211 | 210 |
public void testCompare_BasionymGroupsSomeWithYears() { |
212 | 211 |
|
213 | 212 |
//2 basionym groups, 1 new combination with year (botName2) and 1 basionym with year (botName5) |
214 |
//The later should come first according to the rules, though alphabetically behing
|
|
213 |
//The later should come first according to the rules, though alphabetically being |
|
215 | 214 |
//basionym botName4 |
216 | 215 |
|
217 | 216 |
botName2.setNomenclaturalReference(ref2); |
... | ... | |
246 | 245 |
Assert.assertEquals(botName3, list.get(3).getName()); |
247 | 246 |
} |
248 | 247 |
|
248 |
@Test |
|
249 |
public void testCompare_BasionymGroupsWithRanks1() { |
|
250 |
|
|
251 |
botName2.setRank(Rank.VARIETY()); |
|
252 |
botName2.setInfraSpecificEpithet("varbbbb"); |
|
253 |
|
|
254 |
botName3.setRank(Rank.VARIETY()); |
|
255 |
botName3.setInfraSpecificEpithet("subspccc"); |
|
256 |
|
|
257 |
botName4.setRank(Rank.SUBSPECIES()); |
|
258 |
botName4.setInfraSpecificEpithet("subspddd"); |
|
259 |
|
|
260 |
|
|
261 |
HomotypicalGroup homotypicalGroup = botName2.getHomotypicalGroup(); |
|
262 |
taxon1.addHeterotypicSynonymName(botName3); |
|
263 |
taxon1.addHeterotypicSynonymName(botName5, homotypicalGroup, null, null); |
|
264 |
botName3.addBasionym(botName5); |
|
265 |
|
|
266 |
synonym2 = taxon1.addHeterotypicSynonymName(botName2).getSynonym(); |
|
267 |
taxon1.addHeterotypicSynonymName(botName4, homotypicalGroup, null, null); |
|
268 |
botName2.addBasionym(botName4); |
|
269 |
|
|
270 |
|
|
271 |
list.addAll(taxon1.getSynonyms()); |
|
272 |
Collections.sort(list, new HomotypicGroupTaxonComparator(null)); |
|
273 |
|
|
274 |
Assert.assertEquals("basionym with rank species should comes first", botName5, list.get(0).getName()); |
|
275 |
Assert.assertEquals(botName3, list.get(1).getName()); |
|
276 |
Assert.assertEquals(botName4, list.get(2).getName()); |
|
277 |
Assert.assertEquals(botName2, list.get(3).getName()); |
|
278 |
|
|
279 |
//add replaced synonym relation between basionyms |
|
280 |
botName5.addReplacedSynonym(botName4, null, null, null); |
|
281 |
Collections.sort(list, new HomotypicGroupTaxonComparator(null)); |
|
282 |
Assert.assertEquals("basionym of second group should come first now as it is the replaced synonym", |
|
283 |
botName4, list.get(0).getName()); |
|
284 |
Assert.assertEquals(botName2, list.get(1).getName()); |
|
285 |
Assert.assertEquals("replacement name should come after replaced synonym but first in basionym group", |
|
286 |
botName5, list.get(2).getName()); |
|
287 |
Assert.assertEquals(botName3, list.get(3).getName()); |
|
288 |
} |
|
289 |
|
|
290 |
@Test |
|
291 |
public void testCompare_BasionymGroupsWithRanks2() { |
|
292 |
|
|
293 |
|
|
294 |
botName2.setRank(Rank.VARIETY()); |
|
295 |
botName2.setInfraSpecificEpithet("varbbbb"); |
|
296 |
|
|
297 |
botName3.setRank(Rank.VARIETY()); |
|
298 |
botName3.setInfraSpecificEpithet("subspccc"); |
|
299 |
|
|
300 |
botName4.setRank(Rank.SUBSPECIES()); |
|
301 |
botName4.setInfraSpecificEpithet("subspddd"); |
|
302 |
|
|
303 |
botName5.setRank(Rank.VARIETY()); |
|
304 |
botName5.setInfraSpecificEpithet("vareee"); |
|
305 |
|
|
306 |
|
|
307 |
HomotypicalGroup homotypicalGroup = botName2.getHomotypicalGroup(); |
|
308 |
taxon1.addHeterotypicSynonymName(botName3); |
|
309 |
taxon1.addHeterotypicSynonymName(botName5, homotypicalGroup, null, null); |
|
310 |
botName3.addBasionym(botName5); |
|
311 |
|
|
312 |
synonym2 = taxon1.addHeterotypicSynonymName(botName2).getSynonym(); |
|
313 |
taxon1.addHeterotypicSynonymName(botName4, homotypicalGroup, null, null); |
|
314 |
botName2.addBasionym(botName5); |
|
315 |
botName4.addBasionym(botName5); |
|
316 |
|
|
317 |
|
|
318 |
list.addAll(taxon1.getSynonyms()); |
|
319 |
Collections.sort(list, new HomotypicGroupTaxonComparator(null)); |
|
320 |
|
|
321 |
Assert.assertEquals("basionym should comes first", botName5, list.get(0).getName()); |
|
322 |
Assert.assertEquals("subspecies should come next", botName4, list.get(1).getName()); |
|
323 |
Assert.assertEquals("variety with b should come next", botName2, list.get(2).getName()); |
|
324 |
Assert.assertEquals("variety with c should come last", botName3, list.get(3).getName()); |
|
325 |
|
|
326 |
} |
|
327 |
|
|
249 | 328 |
@Test |
250 | 329 |
public void testCompare_NoCircularProblems() { |
251 | 330 |
|
Also available in: Unified diff
Include rank comparison in HomotypicGroupTaxonComparator #3338