reset for defined terms
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / Rank.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.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.UUID;
16
17 import javax.persistence.Entity;
18 import javax.persistence.Transient;
19 import javax.xml.bind.annotation.XmlAccessType;
20 import javax.xml.bind.annotation.XmlAccessorType;
21 import javax.xml.bind.annotation.XmlType;
22
23 import org.apache.log4j.Logger;
24 import org.hibernate.envers.Audited;
25 import org.hibernate.search.annotations.Indexed;
26
27 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
28 import eu.etaxonomy.cdm.model.common.Language;
29 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
30 import eu.etaxonomy.cdm.model.common.Representation;
31 import eu.etaxonomy.cdm.model.common.TermVocabulary;
32 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
33
34 /**
35 * The class representing the taxonomical ranks (like "Family", "Genus" or
36 * "Species") used for {@link TaxonNameBase taxon names} across all {@link NomenclaturalCode nomenclatural codes}
37 * for bacteria (ICNB), viruses (ICVCN), plants and fungi (ICBN),
38 * cultivars (ICNCP) and animals (ICZN).
39 * <P>
40 * A standard (ordered) list of taxonomical rank instances will be automatically
41 * created as the project starts. But this class allows to extend this standard
42 * list by creating new instances of additional taxonomical ranks if needed.
43 * <P>
44 * This class corresponds to: <ul>
45 * <li> TaxonRankTerm according to the TDWG ontology
46 * <li> TaxonomicRankEnum according to the TCS
47 * <li> Rank according to the ABCD schema
48 * </ul>
49 *
50 * @author m.doering
51 * @version 1.0
52 * @created 08-Nov-2007 13:06:46
53 */
54 @XmlAccessorType(XmlAccessType.FIELD)
55 @XmlType(name = "Rank")
56 @Entity
57 @Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
58 @Audited
59 public class Rank extends OrderedTermBase<Rank> {
60 private static final long serialVersionUID = -8648081681348758485L;
61 private static final Logger logger = Logger.getLogger(Rank.class);
62
63 private static final UUID uuidEmpire = UUID.fromString("ac470211-1586-4b24-95ca-1038050b618d");
64 private static final UUID uuidDomain = UUID.fromString("ffca6ec8-8b88-417b-a6a0-f7c992aac19b");
65 private static final UUID uuidSuperkingdom = UUID.fromString("64223610-7625-4cfd-83ad-b797bf7f0edd");
66 private static final UUID uuidKingdom = UUID.fromString("fbe7109d-66b3-498c-a697-c6c49c686162");
67 private static final UUID uuidSubkingdom = UUID.fromString("a71bd9d8-f3ab-4083-afb5-d89315d71655");
68 private static final UUID uuidInfrakingdom = UUID.fromString("1e37930c-86cf-44f6-90fd-7822928df260");
69 private static final UUID uuidSuperphylum = UUID.fromString("0d0cecb1-e254-4607-b210-6801e7ecbb04");
70 private static final UUID uuidPhylum = UUID.fromString("773430d2-76b4-438c-b817-97a543a33287");
71 private static final UUID uuidSubphylum = UUID.fromString("23a9b6ff-9408-49c9-bd9e-7a2ca5ab4725");
72 private static final UUID uuidInfraphylum = UUID.fromString("1701de3a-7693-42a5-a2d3-42697f944190");
73 private static final UUID uuidSuperdivision = UUID.fromString("a735a48f-4fc8-49a7-ae0c-6a984f658131");
74 private static final UUID uuidDivision = UUID.fromString("7e56f5cc-123a-4fd1-8cbb-6fd80358b581");
75 private static final UUID uuidSubdivision = UUID.fromString("931c840f-7a6b-4d76-ad38-bfdd77d7b2e8");
76 private static final UUID uuidInfradivision = UUID.fromString("c0ede273-be52-4dee-b411-66ee08d30c94");
77 private static final UUID uuidSuperclass = UUID.fromString("e65b4e1a-21ec-428d-9b9f-e87721ab967c");
78 private static final UUID uuidClass = UUID.fromString("f23d14c4-1d34-4ee6-8b4e-eee2eb9a3daf");
79 private static final UUID uuidSubclass = UUID.fromString("8cb26733-e2f5-46cb-ab5c-f99254f877aa");
80 private static final UUID uuidInfraclass = UUID.fromString("ad23cfda-879a-4021-8629-c54d27caf717");
81 private static final UUID uuidSuperorder = UUID.fromString("c8c67a22-301a-4219-b882-4a49121232ff");
82 private static final UUID uuidOrder = UUID.fromString("b0785a65-c1c1-4eb4-88c7-dbd3df5aaad1");
83 private static final UUID uuidSuborder = UUID.fromString("768ad378-fa85-42ab-b668-763225832f57");
84 private static final UUID uuidInfraorder = UUID.fromString("84099182-a6f5-47d7-8586-33c9e9955a10");
85 private static final UUID uuidSectionZoology = UUID.fromString("691d371e-10d7-43f0-93db-3d7fa1a62c54");
86 private static final UUID uuidSubsectionZoology = UUID.fromString("0ed32d28-adc4-4303-a9ca-68e2acd67e33");
87 private static final UUID uuidSuperfamily = UUID.fromString("2cfa510a-dcea-4a03-b66a-b1528f9b0796");
88 private static final UUID uuidFamily = UUID.fromString("af5f2481-3192-403f-ae65-7c957a0f02b6");
89 private static final UUID uuidSubfamily = UUID.fromString("862526ee-7592-4760-a23a-4ff3641541c5");
90 private static final UUID uuidInfrafamily = UUID.fromString("c3f2e3bb-6eef-4a26-9fb7-b14f4c8c5e4f");
91 private static final UUID uuidSupertribe = UUID.fromString("11e94828-8c61-499b-87d6-1de35ce2c51c");
92 private static final UUID uuidTribe = UUID.fromString("4aa6890b-0363-4899-8d7c-ee0cb78e6166");
93 private static final UUID uuidSubtribe = UUID.fromString("ae41ecc5-5165-4126-9d24-79939ae5d822");
94 private static final UUID uuidInfratribe = UUID.fromString("1ec02e8f-f2b7-4c65-af9f-b436b34c79a3");
95 private static final UUID uuidSupragenericTaxon = UUID.fromString("1fdc0b93-c354-441a-8406-091e0303ff5c");
96 private static final UUID uuidGenus = UUID.fromString("1b11c34c-48a8-4efa-98d5-84f7f66ef43a");
97 private static final UUID uuidSubgenus = UUID.fromString("78786e16-2a70-48af-a608-494023b91904");
98 private static final UUID uuidInfragenus = UUID.fromString("a9972969-82cd-4d54-b693-a096422f13fa");
99 private static final UUID uuidSectionBotany = UUID.fromString("3edff68f-8527-49b5-bf91-7e4398bb975c");
100 private static final UUID uuidSubsectionBotany = UUID.fromString("d20f5b61-d463-4448-8f8a-c1ff1f262f59");
101 private static final UUID uuidSeries = UUID.fromString("d7381ecf-48f8-429b-9c54-f461656978cd");
102 private static final UUID uuidSubseries = UUID.fromString("80c9a263-f4db-4a13-b6c2-b7fec1aa1200");
103 private static final UUID uuidSpeciesAggregate = UUID.fromString("1ecae058-4217-4f75-9c27-6d8ba099ac7a");
104 private static final UUID uuidSpeciesGroup = UUID.fromString("d1988a11-292b-46fa-8fb7-bc64ea6d8fc6");
105 private static final UUID uuidInfragenericTaxon = UUID.fromString("41bcc6ac-37d3-4fd4-bb80-3cc5b04298b9");
106 private static final UUID uuidSpecies = UUID.fromString("b301f787-f319-4ccc-a10f-b4ed3b99a86d");
107 private static final UUID uuidSubspecificAggregate = UUID.fromString("72c248b9-027d-4402-b375-dd4f0850c9ad");
108 private static final UUID uuidSubspecies = UUID.fromString("462a7819-8b00-4190-8313-88b5be81fad5");
109 private static final UUID uuidInfraspecies = UUID.fromString("f28ebc9e-bd50-4194-9af1-42f5cb971a2c");
110 private static final UUID uuidNatio = UUID.fromString("965f2f38-7f97-4270-ab5a-1999bf050a22");
111 private static final UUID uuidVariety = UUID.fromString("d5feb6a5-af5c-45ef-9878-bb4f36aaf490");
112 private static final UUID uuidBioVariety = UUID.fromString("a3a364cb-1a92-43fc-a717-3c44980a0991");
113 private static final UUID uuidPathoVariety = UUID.fromString("2f4f4303-a099-47e3-9048-d749d735423b");
114 private static final UUID uuidSubvariety = UUID.fromString("9a83862a-7aee-480c-a98d-4bceaf8712ca");
115 private static final UUID uuidSubsubvariety = UUID.fromString("bff22f84-553a-4429-a4e7-c4b3796c3a18");
116 private static final UUID uuidConvar = UUID.fromString("2cc740c9-cebb-43c8-9b06-1bef79e6a56a");
117 private static final UUID uuidForm = UUID.fromString("0461281e-458a-47b9-8d41-19a3d39356d5");
118 private static final UUID uuidSpecialForm = UUID.fromString("bed20aee-2f5a-4635-9c02-eff06246d067");
119 private static final UUID uuidSubform = UUID.fromString("47cfc5b0-0fb7-4ceb-b61d-e1dd8de8b569");
120 private static final UUID uuidSubsubform = UUID.fromString("1c8ac389-4349-4ae0-87be-7239f6635068");
121 private static final UUID uuidInfraspecificTaxon = UUID.fromString("eb75c27d-e154-4570-9d96-227b2df60474");
122 private static final UUID uuidCandidate = UUID.fromString("ead9a1f5-dfd4-4de2-9121-70a47accb10b");
123 private static final UUID uuidDenominationClass = UUID.fromString("49bdf74a-2170-40ed-8be2-887a0db517bf");
124 private static final UUID uuidGrex = UUID.fromString("08dcb4ff-ac58-48a3-93af-efb3d836ac84");
125 private static final UUID uuidGraftChimaera = UUID.fromString("6b4063bc-f934-4796-9bf3-0ef3aea5c1cb");
126 private static final UUID uuidCultivarGroup = UUID.fromString("d763e7d3-e7de-4bb1-9d75-225ca6948659");
127 private static final UUID uuidCultivar = UUID.fromString("5e98415b-dc6e-440b-95d6-ea33dbb39ad0");
128 private static final UUID uuidUnknownRank = UUID.fromString("5c4d6755-2cf6-44ca-9220-cccf8881700b");
129
130
131 private static Map<String, UUID> abbrevMap = null;
132 private static Map<String, UUID> labelMap = null;
133
134 protected static Map<UUID, Rank> termMap = null;
135
136
137 // ********************* CONSTRUCTORS ************************************+/
138 /**
139 * Class constructor: creates a new empty rank instance.
140 *
141 * @see #Rank(String, String, String)
142 */
143 public Rank() {
144 }
145
146 /**
147 * Class constructor: creates an additional rank instance with a description
148 * (in the {@link eu.etaxonomy.cdm.model.common.Language#DEFAULT() default language}), a label and a label abbreviation.
149 *
150 * @param term the string (in the default language) describing the
151 * new rank to be created
152 * @param label the string identifying the new rank to be created
153 * @param labelAbbrev the string identifying (in abbreviated form) the
154 * new rank to be created
155 * @see #Rank()
156 */
157 public Rank(String term, String label, String labelAbbrev) {
158 super(term, label, labelAbbrev);
159 }
160
161 /**
162 * Creates a new empty rank.
163 *
164 * @see #NewInstance(String, String, String)
165 */
166 private static Rank NewInstance(){
167 return new Rank();
168 }
169
170 /**
171 * Creates an additional rank with a description (in the {@link Language#DEFAULT() default language}),
172 * a label and a label abbreviation.
173 *
174 * @param term the string (in the default language) describing the
175 * new rank to be created
176 * @param label the string identifying the new rank to be created
177 * @param labelAbbrev the string identifying (in abbreviated form) the
178 * new rank to be created
179 * @see #NewInstance()
180 */
181 private static Rank NewInstance(String term, String label, String labelAbbrev){
182 return new Rank(term, label, labelAbbrev);
183 }
184
185 //********* METHODS **************************************/
186
187 /* (non-Javadoc)
188 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#resetTerms()
189 */
190 @Override
191 public void resetTerms(){
192 termMap = null;
193 }
194
195
196
197 protected static Rank getTermByUuid(UUID uuid){
198 if (termMap == null){
199 return null; //better return null then initialize the termMap in an unwanted way
200 }
201 return (Rank)termMap.get(uuid);
202 }
203
204 public static final Rank EMPIRE(){
205 return getTermByUuid(uuidEmpire);
206 }
207 public static final Rank DOMAIN(){
208 return getTermByUuid(uuidDomain);
209 }
210 public static final Rank SUPERKINGDOM(){
211 return getTermByUuid(uuidSuperkingdom);
212 }
213 public static final Rank KINGDOM(){
214 return getTermByUuid(uuidKingdom);
215 }
216 public static final Rank SUBKINGDOM(){
217 return getTermByUuid(uuidSubkingdom);
218 }
219 public static final Rank INFRAKINGDOM(){
220 return getTermByUuid(uuidInfrakingdom);
221 }
222 public static final Rank SUPERPHYLUM(){
223 return getTermByUuid(uuidSuperphylum);
224 }
225 public static final Rank PHYLUM(){
226 return getTermByUuid(uuidPhylum);
227 }
228 public static final Rank SUBPHYLUM(){
229 return getTermByUuid(uuidSubphylum);
230 }
231 public static final Rank INFRAPHYLUM(){
232 return getTermByUuid(uuidInfraphylum);
233 }
234 public static final Rank SUPERDIVISION(){
235 return getTermByUuid(uuidSuperdivision);
236 }
237 public static final Rank DIVISION(){
238 return getTermByUuid(uuidDivision);
239 }
240 public static final Rank SUBDIVISION(){
241 return getTermByUuid(uuidSubdivision);
242 }
243 public static final Rank INFRADIVISION(){
244 return getTermByUuid(uuidInfradivision);
245 }
246 public static final Rank SUPERCLASS(){
247 return getTermByUuid(uuidSuperclass);
248 }
249 public static final Rank CLASS(){
250 return getTermByUuid(uuidClass);
251 }
252 public static final Rank SUBCLASS(){
253 return getTermByUuid(uuidSubclass);
254 }
255 public static final Rank INFRACLASS(){
256 return getTermByUuid(uuidInfraclass);
257 }
258 public static final Rank SUPERORDER(){
259 return getTermByUuid(uuidSuperorder);
260 }
261 public static final Rank ORDER(){
262 return getTermByUuid(uuidOrder);
263 }
264 public static final Rank SUBORDER(){
265 return getTermByUuid(uuidSuborder);
266 }
267 public static final Rank INFRAORDER(){
268 return getTermByUuid(uuidInfraorder);
269 }
270 public static final Rank SUPERFAMILY(){
271 return getTermByUuid(uuidSuperfamily);
272 }
273 public static final Rank FAMILY(){
274 return getTermByUuid(uuidFamily);
275 }
276 public static final Rank SUBFAMILY(){
277 return getTermByUuid(uuidSubfamily);
278 }
279 public static final Rank INFRAFAMILY(){
280 return getTermByUuid(uuidInfrafamily);
281 }
282 public static final Rank SUPERTRIBE(){
283 return getTermByUuid(uuidSupertribe);
284 }
285 public static final Rank TRIBE(){
286 return getTermByUuid(uuidTribe);
287 }
288 public static final Rank SUBTRIBE(){
289 return getTermByUuid(uuidSubtribe);
290 }
291 public static final Rank INFRATRIBE(){
292 return getTermByUuid(uuidInfratribe);
293 }
294 public static final Rank SUPRAGENERICTAXON(){
295 return getTermByUuid(uuidSupragenericTaxon);
296 }
297 public static final Rank GENUS(){
298 return getTermByUuid(uuidGenus);
299 }
300 public static final Rank SUBGENUS(){
301 return getTermByUuid(uuidSubgenus);
302 }
303 public static final Rank INFRAGENUS(){
304 return getTermByUuid(uuidInfragenus);
305 }
306 public static final Rank SECTION_BOTANY(){
307 return getTermByUuid(uuidSectionBotany);
308 }
309 public static final Rank SUBSECTION_BOTANY(){
310 return getTermByUuid(uuidSubsectionBotany);
311 }
312 public static final Rank SECTION_ZOOLOGY(){
313 return getTermByUuid(uuidSectionZoology);
314 }
315 public static final Rank SUBSECTION_ZOOLOGY(){
316 return getTermByUuid(uuidSubsectionZoology);
317 }
318 public static final Rank SERIES(){
319 return getTermByUuid(uuidSeries);
320 }
321 public static final Rank SUBSERIES(){
322 return getTermByUuid(uuidSubseries);
323 }
324 public static final Rank SPECIESAGGREGATE(){
325 return getTermByUuid(uuidSpeciesAggregate);
326 }
327 public static final Rank SPECIESGROUP(){
328 return getTermByUuid(uuidSpeciesGroup);
329 }
330 public static final Rank INFRAGENERICTAXON(){
331 return getTermByUuid(uuidInfragenericTaxon);
332 }
333 public static final Rank SPECIES(){
334 return getTermByUuid(uuidSpecies);
335 }
336 public static final Rank SUBSPECIFICAGGREGATE(){
337 return getTermByUuid(uuidSubspecificAggregate);
338 }
339 public static final Rank SUBSPECIES(){
340 return getTermByUuid(uuidSubspecies);
341 }
342 public static final Rank INFRASPECIES(){
343 return getTermByUuid(uuidInfraspecies);
344 }
345 public static final Rank VARIETY(){
346 return getTermByUuid(uuidVariety);
347 }
348 public static final Rank BIOVARIETY(){
349 return getTermByUuid(uuidBioVariety);
350 }
351 public static final Rank PATHOVARIETY(){
352 return getTermByUuid(uuidPathoVariety);
353 }
354 public static final Rank SUBVARIETY(){
355 return getTermByUuid(uuidSubvariety);
356 }
357 public static final Rank SUBSUBVARIETY(){
358 return getTermByUuid(uuidSubsubvariety );
359 }
360 public static final Rank CONVAR(){
361 return getTermByUuid(uuidConvar);
362 }
363 public static final Rank FORM(){
364 return getTermByUuid(uuidForm);
365 }
366 public static final Rank SPECIALFORM(){
367 return getTermByUuid(uuidSpecialForm);
368 }
369 public static final Rank SUBFORM(){
370 return getTermByUuid(uuidSubform);
371 }
372 public static final Rank SUBSUBFORM(){
373 return getTermByUuid(uuidSubsubform);
374 }
375 public static final Rank INFRASPECIFICTAXON(){
376 return getTermByUuid(uuidInfraspecificTaxon);
377 }
378 public static final Rank CANDIDATE(){
379 return getTermByUuid(uuidCandidate);
380 }
381 public static final Rank DENOMINATIONCLASS(){
382 return getTermByUuid(uuidDenominationClass);
383 }
384 public static final Rank GREX(){
385 return getTermByUuid(uuidGrex);
386 }
387 public static final Rank GRAFTCHIMAERA(){
388 return getTermByUuid(uuidGraftChimaera);
389 }
390 public static final Rank CULTIVARGROUP(){
391 return getTermByUuid(uuidCultivarGroup);
392 }
393 public static final Rank CULTIVAR(){
394 return getTermByUuid(uuidCultivar);
395 }
396 public static final Rank UNKNOWN_RANK(){
397 return getTermByUuid(uuidUnknownRank);
398 }
399 public static final Rank NATIO(){
400 return getTermByUuid(uuidNatio);
401 }
402
403
404 /**
405 * Returns the boolean value indicating whether <i>this</i> rank is higher than
406 * the genus rank (true) or not (false). Returns false if <i>this</i> rank is null.
407 *
408 * @see #isGenus()
409 * @see #isInfraGeneric()
410 * @see #isSpecies()
411 * @see #isInfraSpecific()
412 */
413 @Transient
414 public boolean isSupraGeneric(){
415 return (this.isHigher(Rank.GENUS()));
416 }
417
418 /**
419 * Returns the boolean value indicating whether <i>this</i> rank is the genus rank
420 * (true) or not (false). Returns false if <i>this</i> rank is null.
421 *
422 * @see #isSupraGeneric()
423 * @see #isInfraGeneric()
424 * @see #isSpecies()
425 * @see #isInfraSpecific()
426 */
427 @Transient
428 public boolean isGenus(){
429 return (this.equals(Rank.GENUS()));
430 }
431
432 /**
433 * Returns the boolean value indicating whether <i>this</i> rank is higher than the
434 * species rank and lower than the genus rank (true) or not (false). Species groups or
435 * aggregates are also handled as infrageneric ranks.
436 * Returns false if <i>this</i> rank is null.
437 *
438 * @see #isSupraGeneric()
439 * @see #isGenus()
440 * @see #isSpeciesAggregate()
441 * @see #isSpecies()
442 * @see #isInfraSpecific()
443 */
444 @Transient
445 public boolean isInfraGeneric(){
446 return (this.isLower(Rank.GENUS()) && this.isHigher(Rank.SPECIES()));
447 }
448
449 /**
450 * Returns true if this rank indicates a rank that aggregates species
451 * like species aggregates or species groups, false otherwise. This methods
452 * currently returns false for all user defined ranks.
453 * @return
454 */
455 @Transient
456 public boolean isSpeciesAggregate(){
457 return (this.equals(Rank.SPECIESAGGREGATE()) || (this.isLower(Rank.SPECIESAGGREGATE()) && this.isHigher(Rank.SPECIES())));
458 }
459
460 /**
461 * Returns the boolean value indicating whether <i>this</i> rank is the species
462 * rank (true) or not (false). Returns false if <i>this</i> rank is null.
463 *
464 * @see #isSupraGeneric()
465 * @see #isGenus()
466 * @see #isInfraGeneric()
467 * @see #isInfraSpecific()
468 */
469 @Transient
470 public boolean isSpecies(){
471 return (this.equals(Rank.SPECIES()));
472 }
473
474 /**
475 * Returns the boolean value indicating whether <i>this</i> rank is lower than the
476 * species rank (true) or not (false). Returns false if <i>this</i> rank is null.
477 *
478 * @see #isSupraGeneric()
479 * @see #isGenus()
480 * @see #isInfraGeneric()
481 * @see #isSpecies()
482 */
483 @Transient
484 public boolean isInfraSpecific(){
485 return (this.isLower(Rank.SPECIES()));
486 }
487
488
489 /**
490 * Returns the rank identified through a name (abbreviated or not).
491 * Preliminary implementation for BotanicalNameParser.
492 *
493 * @param strRank the string identifying the rank
494 * @return the rank
495 */
496 public static Rank getRankByNameOrAbbreviation(String strRank)
497 throws UnknownCdmTypeException{
498 return getRankByNameOrAbbreviation(strRank, false);
499 }
500
501 /**
502 * Returns the rank identified through a name (abbreviated or not) for a given nomenclatural code.
503 * Preliminary implementation for BotanicalNameParser.
504 *
505 * @param strRank the string identifying the rank
506 * @param nc the nomenclatural code
507 * @return the rank
508 */
509 public static Rank getRankByNameOrAbbreviation(String strRank, NomenclaturalCode nc)
510 throws UnknownCdmTypeException{
511 return getRankByNameOrAbbreviation(strRank, nc, false);
512 }
513
514 // TODO
515 // Preliminary implementation for BotanicalNameParser.
516 // not yet complete
517 /**
518 * Returns the rank identified through a name (abbreviated or not).
519 * Preliminary implementation for BotanicalNameParser.
520 *
521 * @param strRank the string identifying the rank
522 * @param useUnknown if true the rank UNKNOWN_RANK is returned if the abbrev is
523 * unknown or not yet implemented
524 * @return the rank
525 */
526 public static Rank getRankByNameOrAbbreviation(String strRank, boolean useUnknown)
527 throws UnknownCdmTypeException{
528 try {
529 return getRankByAbbreviation(strRank);
530 } catch (UnknownCdmTypeException e) {
531 return getRankByName(strRank, useUnknown);
532 }
533 }
534
535 // TODO
536 // Preliminary implementation for BotanicalNameParser.
537 // not yet complete
538 /**
539 * Returns the rank identified through a name (abbreviated or not).
540 * Preliminary implementation for BotanicalNameParser.
541 *
542 * @param strRank the string identifying the rank
543 * @param nc the nomenclatural code
544 * @param useUnknown if true the rank UNKNOWN_RANK is returned if the abbrev is
545 * unknown or not yet implemented
546 * @return the rank
547 */
548 public static Rank getRankByNameOrAbbreviation(String strRank, NomenclaturalCode nc, boolean useUnknown)
549 throws UnknownCdmTypeException{
550 try {
551 return getRankByAbbreviation(strRank, nc);
552 } catch (UnknownCdmTypeException e) {
553 return getRankByName(strRank, nc, useUnknown);
554 }
555 }
556
557 /**
558 * Returns the rank identified through an abbreviated name.
559 * Preliminary implementation for BotanicalNameParser.
560 *
561 * @param abbrev the string for the name abbreviation
562 * @return the rank
563 */
564 public static Rank getRankByAbbreviation(String abbrev)
565 throws UnknownCdmTypeException{
566 return getRankByAbbreviation(abbrev, false);
567 }
568
569 /**
570 * Returns the rank identified through an abbreviated name for a given nomenclatural code.
571 * See also {@link #getRankByAbbreviation(String, boolean)}
572 *
573 * @param abbrev the string for the name abbreviation
574 * @param nc the nomenclatural code
575 * @return the rank
576 */
577 public static Rank getRankByAbbreviation(String abbrev, NomenclaturalCode nc) throws UnknownCdmTypeException{
578 return getRankByAbbreviation(abbrev, nc, false);
579 }
580
581 // TODO
582 // Preliminary implementation for BotanicalNameParser.
583 // not yet complete
584 /**
585 * Returns the rank identified through an abbreviated representation.
586 * At the moment it uses the English abbreviations (being Latin because
587 * we do not have Latin representations yet.
588 * TODO
589 * If no according abbreviation is available it throws either an UnknownCdmTypeException
590 * or an #Rank.UNKNOWN() object depending on the useUnknown flag.
591 *
592 * @param abbrev the string for the name abbreviation
593 * @param useUnknown if true the rank UNKNOWN_RANK is returned if the abbrev is
594 * unknown or not yet existent
595 * @return the rank
596 */
597 public static Rank getRankByAbbreviation(String abbrev, boolean useUnknown) throws UnknownCdmTypeException{
598 Rank result = null;
599 if (abbrev == null){
600 throw new NullPointerException("Abbrev is NULL in getRankByAbbreviation");
601 }
602 if (abbrev.trim().equals("")){
603 //handle empty abbrev as unknown
604 abbrev = "oijaämöö";
605 }
606 if (abbrevMap == null){
607 return null;
608 }
609 UUID uuid = abbrevMap.get(abbrev);
610 if (uuid != null ){
611 result = getTermByUuid(uuid);
612 }
613 if (result != null){
614 return result;
615 }else {
616 if (abbrev == null){
617 abbrev = "(null)";
618 }
619 if (useUnknown){
620 logger.info("Unknown rank name: " + abbrev + ". Rank 'UNKNOWN_RANK' created instead");
621 return Rank.UNKNOWN_RANK();
622 }else{
623 throw new UnknownCdmTypeException("Unknown rank abbreviation: " + abbrev);
624 }
625 }
626 }
627
628 // TODO
629 // Preliminary implementation to cover Botany and Zoology.
630 /**
631 * Returns the rank identified through an abbreviated name for a given nomenclatural code.
632 * Preliminary implementation for ICBN and ICZN.
633 * See also {@link #getRankByAbbreviation(String, boolean)}
634
635 *
636 * @param abbrev the string for the name abbreviation
637 * @param nc the nomenclatural code
638 * @param useUnknown if true the rank UNKNOWN_RANK is returned if the abbrev is
639 * unknown or not yet implemented
640 * @return the rank
641 */
642 public static Rank getRankByAbbreviation(String abbrev, NomenclaturalCode nc, boolean useUnknown)
643 throws UnknownCdmTypeException{
644
645 if (nc.equals(NomenclaturalCode.ICZN)) {
646 if (abbrev.equalsIgnoreCase("sect.")) { return Rank.SECTION_ZOOLOGY();
647 } else if (abbrev.equalsIgnoreCase("subsect.")) { return Rank.SUBSECTION_ZOOLOGY();
648 }
649 }
650 return getRankByAbbreviation(abbrev, useUnknown);
651 }
652
653 // TODO
654 // Preliminary implementation for BotanicalNameParser.
655 // not yet complete
656 /**
657 * Returns the rank identified through a name.
658 * Preliminary implementation for BotanicalNameParser.
659 *
660 * @param rankName the string for the name of the rank
661 * @return the rank
662 */
663 public static Rank getRankByName(String rankName) throws UnknownCdmTypeException{
664 return getRankByName(rankName, false);
665 }
666
667
668 // TODO
669 // Preliminary implementation for ICBN and ICZN.
670 // not yet complete
671 /**
672 * Returns the rank identified through a name for a given nomenclatural code.
673 * Preliminary implementation for ICBN and ICZN.
674 *
675 * @param rankName the string for the name of the rank
676 * @param nc the nomenclatural code
677 * @return the rank
678 */
679 public static Rank getRankByName(String rankName, NomenclaturalCode nc) throws UnknownCdmTypeException{
680 return getRankByName(rankName, nc, false);
681 }
682
683 /**
684 * Returns the rank identified through a name.
685 * Preliminary implementation for BotanicalNameParser.
686 * TODO At the moment we do not have Latin representations yet.
687 *
688 * @param rankName the string for the name of the rank
689 * @param useUnknown if true the rank UNKNOWN_RANK is returned if the rank name is
690 * unknown or not yet implemented
691 * @return the rank
692 */
693 public static Rank getRankByName(String rankName, boolean useUnknown)
694 throws UnknownCdmTypeException{
695 if (rankName.equalsIgnoreCase("Regnum")){ return Rank.KINGDOM();
696 }else if (rankName.equalsIgnoreCase("Subregnum")){ return Rank.SUBKINGDOM();
697 }else if (rankName.equalsIgnoreCase("Phylum")){ return Rank.PHYLUM();
698 }else if (rankName.equalsIgnoreCase("Subphylum")){ return Rank.SUBPHYLUM();
699 }else if (rankName.equalsIgnoreCase("Divisio")){ return Rank.DIVISION();
700 }else if (rankName.equalsIgnoreCase("Subdivisio")){ return Rank.SUBDIVISION();
701 }else if (rankName.equalsIgnoreCase("Classis")){ return Rank.CLASS();
702 }else if (rankName.equalsIgnoreCase("Subclassis")){ return Rank.SUBCLASS();
703 }else if (rankName.equalsIgnoreCase("Superordo")){ return Rank.SUPERORDER();
704 }else if (rankName.equalsIgnoreCase("Ordo")){ return Rank.ORDER();
705 }else if (rankName.equalsIgnoreCase("Subordo")){ return Rank.SUBORDER();
706 }else if (rankName.equalsIgnoreCase("Familia")){ return Rank.FAMILY();
707 }else if (rankName.equalsIgnoreCase("Subfamilia")){ return Rank.SUBFAMILY();
708 }else if (rankName.equalsIgnoreCase("Tribus")){ return Rank.TRIBE();
709 }else if (rankName.equalsIgnoreCase("Subtribus")){ return Rank.SUBTRIBE();
710 }else if (rankName.equalsIgnoreCase("Genus")){ return Rank.GENUS();
711 }else if (rankName.equalsIgnoreCase("Subgenus")){ return Rank.SUBGENUS();
712 }else if (rankName.equalsIgnoreCase("Sectio")){ return Rank.SECTION_BOTANY();
713 }else if (rankName.equalsIgnoreCase("Subsectio")){ return Rank.SUBSECTION_BOTANY();
714 }else if (rankName.equalsIgnoreCase("Series")){ return Rank.SERIES();
715 }else if (rankName.equalsIgnoreCase("Subseries")){ return Rank.SUBSERIES();
716 }else if (rankName.equalsIgnoreCase("Aggregate")){ return Rank.SPECIESAGGREGATE();
717 }else if (rankName.equalsIgnoreCase("Speciesgroup")){ return Rank.SPECIESGROUP();
718 }else if (rankName.equalsIgnoreCase("Species")){ return Rank.SPECIES();
719 }else if (rankName.equalsIgnoreCase("Subspecies")){ return Rank.SUBSPECIES();
720 }else if (rankName.equalsIgnoreCase("Convarietas")){ return Rank.CONVAR();
721 }else if (rankName.equalsIgnoreCase("Varietas")){ return Rank.VARIETY();
722 }else if (rankName.equalsIgnoreCase("Subvarietas")){ return Rank.SUBVARIETY();
723 }else if (rankName.equalsIgnoreCase("Forma")){ return Rank.FORM();
724 }else if (rankName.equalsIgnoreCase("Subforma")){ return Rank.SUBFORM();
725 }else if (rankName.equalsIgnoreCase("Forma spec.")){ return Rank.SPECIALFORM();
726 }else if (rankName.equalsIgnoreCase("tax.infragen.")){ return Rank.INFRAGENERICTAXON();
727 }else if (rankName.equalsIgnoreCase("tax.infrasp.")){ return Rank.INFRASPECIFICTAXON();
728 // old ranks
729 }else if (rankName.equalsIgnoreCase("proles")){ return Rank.INFRASPECIFICTAXON(); //to create the name put prol. and the infraspeciesepi to the field unnamed namephrase
730 }else if (rankName.equalsIgnoreCase("race")){ return Rank.INFRASPECIFICTAXON(); //to create the name put prol. and the infraspeciesepi to the field unnamed namephrase
731 }else if (rankName.equalsIgnoreCase("taxon")){ return Rank.INFRASPECIFICTAXON(); //to create the name put prol. and the infraspeciesepi to the field unnamed namephrase
732 }else if (rankName.equalsIgnoreCase("sublusus")){ return Rank.INFRASPECIFICTAXON(); //to create the name put prol. and the infraspeciesepi to the field unnamed namephrase
733
734 }else{
735 if (rankName == null){
736 rankName = "(null)";
737 }
738 if (useUnknown){
739 logger.info("Unknown rank name: " + rankName+". Rank 'UNKNOWN_RANK' created instead");
740 return Rank.UNKNOWN_RANK();
741 }else{
742 if (rankName == null){
743 rankName = "(null)";
744 }
745 throw new UnknownCdmTypeException("Unknown rank name: " + rankName);
746 }
747 }
748 }
749
750 public static Rank getRankByEnglishName(String rankName, NomenclaturalCode nc, boolean useUnknown) throws UnknownCdmTypeException{
751 Rank result = null;
752 if (rankName == null){
753 throw new NullPointerException("Abbrev is NULL in getRankByAbbreviation");
754 }
755 if (labelMap == null){
756 return null;
757 }
758 //handle section and subsection (not unique representations)
759 if (rankName.equalsIgnoreCase("Section")){
760 if (nc != null && nc.equals(NomenclaturalCode.ICZN)){ return Rank.SECTION_ZOOLOGY();
761 }else if (nc != null && nc.equals(NomenclaturalCode.ICBN)){return Rank.SECTION_BOTANY();
762 }else{
763 String errorWarning = "Section is only defined for ICZN and ICBN at the moment but here needed for " + ((nc == null)? "(null)": nc.toString());
764 logger.warn(errorWarning);
765 throw new UnknownCdmTypeException (errorWarning);
766 }
767 }else if (rankName.equalsIgnoreCase("Subsection")){
768 if (nc != null && nc.equals(NomenclaturalCode.ICZN)){ return Rank.SECTION_ZOOLOGY();
769 }else if (nc != null && nc.equals(NomenclaturalCode.ICBN)){ return Rank.SECTION_BOTANY();
770 }else{
771 String errorWarning = "Subsection is only defined for ICZN and ICBN at the moment but here needed for " + ((nc == null)? "(null)": nc.toString());
772 logger.warn(errorWarning);
773 throw new UnknownCdmTypeException (errorWarning);
774 }
775 }
776
777 rankName = rankName.toLowerCase();
778
779 UUID uuid = labelMap.get(rankName);
780 if (uuid != null ){
781 result = getTermByUuid(uuid);
782 }
783 if (result != null){
784 return result;
785 }else {
786 if (rankName == null){
787 rankName = "(null)";
788 }
789 if (useUnknown){
790 logger.info("Unknown rank name: " + rankName + ". Rank 'UNKNOWN_RANK' created instead");
791 return Rank.UNKNOWN_RANK();
792 }else{
793 throw new UnknownCdmTypeException("Unknown rank: " + rankName);
794 }
795 }
796 }
797
798
799 public static Rank getRankByName(String rankName, NomenclaturalCode nc, boolean useUnknown)
800 throws UnknownCdmTypeException {
801
802 if (nc.equals(NomenclaturalCode.ICZN)) {
803 if (rankName.equalsIgnoreCase("Sectio")) { return Rank.SECTION_ZOOLOGY();
804 }else if (rankName.equalsIgnoreCase("Subsectio")) { return Rank.SUBSECTION_ZOOLOGY();
805 }
806 }
807 return getRankByName(rankName, useUnknown);
808 }
809
810 /**
811 * Returns the abbreviated rank name for <i>this</i> rank according to the English representation
812 * abbreviated label.
813 * TODO Needs to be changed to Latin as soon as Latin representations are available.
814 *
815 * @return the abbreviation string for <i>this</i> rank
816 */
817 public String getAbbreviation(){
818 Language language = Language.ENGLISH();
819 String result = this.getRepresentation(language).getAbbreviatedLabel();
820 if (result== null) {
821 logger.warn("Abbreviation for this Rank " + this.toString() + " not yet implemented");
822 return "no abbreviation available.";
823 }else{
824 return result;
825 }
826 }
827 @Transient
828 public String getInfraGenericMarker() throws UnknownCdmTypeException{
829 String result = null;
830 if (! this.isInfraGeneric()){
831 throw new IllegalStateException("An infrageneric marker is only available for a infrageneric rank but was asked for rank: " + this.toString());
832 }else{
833 result = this.getAbbreviation();
834 }
835 if (result == null){
836 throw new UnknownCdmTypeException("Abbreviation for rank unknown: " + this.toString());
837 }
838 return result;
839 }
840
841
842
843 @Override
844 public Rank readCsvLine(Class<Rank> termClass, List<String> csvLine, Map<UUID, DefinedTermBase> terms) {
845 return super.readCsvLine(termClass, csvLine, terms);
846 }
847
848 @Override
849 protected void setDefaultTerms(TermVocabulary<Rank> termVocabulary) {
850 termMap = new HashMap<UUID, Rank>();
851 for (Rank term : termVocabulary.getTerms()){
852 termMap.put(term.getUuid(), (Rank)term);
853 addRank(term);
854 }
855 }
856
857 /**
858 * @param term
859 */
860 private void addRank(Rank rank) {
861 if (rank == null){
862 logger.warn("rank is NULL");
863 return;
864 }
865 if (rank.getUuid().equals(uuidSectionZoology) || rank.getUuid().equals(uuidSubsectionZoology )){
866 //sect./subsect. is used for botanical sections, see also #getRankByAbbreviation(String, NomenclaturalCode, boolean)
867 return;
868 }
869 Language lang = Language.DEFAULT(); //TODO should be Latin but at the moment we have only English representations
870 Representation representation = rank.getRepresentation(lang);
871 String abbrevLabel = representation.getAbbreviatedLabel();
872 String label = representation.getLabel();
873 if (abbrevLabel == null){
874 logger.warn("label is NULL");
875 return;
876 }
877 //initialize maps
878 if (abbrevMap == null){
879 abbrevMap = new HashMap<String, UUID>();
880 }
881 if (labelMap == null){
882 labelMap = new HashMap<String, UUID>();
883 }
884 //add to map
885 abbrevMap.put(abbrevLabel, rank.getUuid());
886 labelMap.put(label.toLowerCase(), rank.getUuid());
887 }
888
889 }