improve to better fulfill the Comparator contract
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / name / NomenclaturalStatusType.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
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.UUID;
19
20 import javax.persistence.Entity;
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.XmlType;
25
26 import org.apache.log4j.Logger;
27 import org.hibernate.envers.Audited;
28 import org.hibernate.search.annotations.Indexed;
29
30 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
31 import eu.etaxonomy.cdm.model.common.Language;
32 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
33 import eu.etaxonomy.cdm.model.common.Representation;
34 import eu.etaxonomy.cdm.model.common.TermType;
35 import eu.etaxonomy.cdm.model.common.TermVocabulary;
36 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
37
38 /**
39 * The class representing categories of nomenclatural status (like "invalid",
40 * "conserved" or "novum") to qualify the use of a particular taxon name string
41 * depending on its {@link eu.etaxonomy.cdm.model.reference.INomenclaturalReference nomenclatural reference} (original publication),
42 * on its {@link NomenclaturalCode nomenclatural code} and on possible decisions of the corresponding
43 * competent authorities. Unfortunately the ICBN and the ICZN use sometimes
44 * different words for the same meaning or the same word for different meanings
45 * (for instance "valid" and "legitimate").
46 * <P>
47 * A standard (ordered) list of nomenclatural status type instances will be
48 * automatically created as the project starts. But this class allows to extend
49 * this standard list by creating new instances of additional nomenclatural
50 * status types if needed. The present standard list follows the ICBN
51 * terminology.
52 * <P>
53 * This class corresponds more or less to: <ul>
54 * <li> NomenclaturalNoteTypeTerm according to the TDWG ontology
55 * <li> NomenclaturalNoteType according to the TCS
56 * </ul>
57 *
58 * @author a.mueller
59 * @created 10.07.2008
60 */
61 @XmlAccessorType(XmlAccessType.FIELD)
62 @XmlType(name = "NomenclaturalStatusType")
63 @Entity
64 @Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
65 @Audited
66 public class NomenclaturalStatusType extends OrderedTermBase<NomenclaturalStatusType> {
67
68 private static final long serialVersionUID = 1337101678484153972L;
69
70 private static Logger logger = Logger.getLogger(NomenclaturalStatusType.class);
71
72 //Botanical uuids
73 public static final UUID uuidIcnafpNomStatusVocabulary = UUID.fromString("bb28cdca-2f8a-4f11-9c21-517e9ae87f1f");
74
75 private static final UUID uuidAmbiguous = UUID.fromString("90f5012b-705b-4488-b4c6-002d2bc5198e");
76 private static final UUID uuidDoubtful = UUID.fromString("0ffeb39e-872e-4c0f-85ba-a4150d9f9e7d");
77 private static final UUID uuidConfusum = UUID.fromString("24955174-aa5c-4e71-a2fd-3efc79e885db");
78 private static final UUID uuidIllegitimate = UUID.fromString("b7c544cf-a375-4145-9d3e-4b97f3f18108");
79 private static final UUID uuidSuperfluous = UUID.fromString("6890483a-c6ba-4ae1-9ab1-9fbaa5736ce9");
80 private static final UUID uuidRejected = UUID.fromString("48107cc8-7a5b-482e-b438-efbba050b851");
81 private static final UUID uuidUtiqueRejected = UUID.fromString("04338fdd-c12a-402f-a1ca-68b4bf0be042");
82 private static final UUID uuidConservedProp = UUID.fromString("82bab006-5aed-4301-93ec-980deb30cbb1");
83 private static final UUID uuidOrthographyConservedProp = UUID.fromString("02f82bc5-1066-454b-a023-11967cba9092");
84 private static final UUID uuidLegitimate = UUID.fromString("51a3613c-b53b-4561-b0cd-9163d91c15aa");
85 private static final UUID uuidAlternative = UUID.fromString("3b8a8519-420f-4dfa-b050-b410cc257961");
86 private static final UUID uuidNovum = UUID.fromString("05fcb68f-af60-4851-b912-892512058897");
87 private static final UUID uuidUtiqueRejectedProp = UUID.fromString("643ee07f-026c-426c-b838-c778c8613383");
88 private static final UUID uuidOrthographyConserved = UUID.fromString("34a7d383-988b-4117-b8c0-52b947f8c711");
89 private static final UUID uuidRejectedProp = UUID.fromString("248e44c2-5436-4526-a352-f7467ecebd56");
90 private static final UUID uuidConserved = UUID.fromString("6330f719-e2bc-485f-892b-9f882058a966");
91 private static final UUID uuidSanctioned = UUID.fromString("1afe55c4-76aa-46c0-afce-4dc07f512733");
92 private static final UUID uuidInvalid = UUID.fromString("b09d4f51-8a77-442a-bbce-e7832aaf46b7");
93 private static final UUID uuidNudum = UUID.fromString("e0d733a8-7777-4b27-99a3-05ab50e9f312");
94 private static final UUID uuidCombinationInvalid = UUID.fromString("f858e619-7b7f-4225-913b-880a2143ec83");
95 private static final UUID uuidCombinationIllegitimate = UUID.fromString("d901d455-4e01-45cb-b653-01a840b97eed");
96 private static final UUID uuidProvisional = UUID.fromString("a277507e-ad93-4978-9419-077eb889c951");
97 private static final UUID uuidValid = UUID.fromString("bd036217-5499-4ccd-8f4c-72e06158db93");
98 private static final UUID uuidOpusUtiqueOppr = UUID.fromString("a5055d80-dbba-4660-b091-a1835d59fe7c");
99 private static final UUID uuidSubnudum = UUID.fromString("92a76bd0-6ea8-493f-98e0-4be0b98c092f");
100 private static final UUID uuidCombNov = UUID.fromString("ed508710-deef-44b1-96f6-1ce6d2c9c884");
101
102 //zoological uuids
103 public static final UUID uuidIcznNomStatusVocabulary = UUID.fromString("5e3c08e9-13a9-498e-861e-b9b5656ab6ac");
104
105 private static final UUID uuidZooNotAvailable = UUID.fromString("6d9ed462-b761-4da3-9304-4749e883d4eb");
106 private static final UUID uuidZooInvalid = UUID.fromString("2bef7039-c129-410b-815e-2a1f7249127b");
107 private static final UUID uuidZooSuppressed = UUID.fromString("a61602c7-fbd4-4eb4-98a2-44919db8920b");
108
109
110
111 public static NomenclaturalStatusType NewInstance(String description, String label, String labelAbbrev, Language language) {
112 return new NomenclaturalStatusType(description, label, labelAbbrev, language);
113 }
114
115 public static NomenclaturalStatusType NewInstance(String description, String label, String labelAbbrev) {
116 return new NomenclaturalStatusType(description, label, labelAbbrev);
117 }
118
119
120 protected static Map<UUID, NomenclaturalStatusType> termMap = null;
121 private static Map<String, UUID> abbrevMap = null;
122 private static Map<String, UUID> labelMap = null;
123
124
125 protected static Map<UUID, NomenclaturalStatusType> zooTermMap = null;
126 private static Map<String, UUID> zooAbbrevMap = null;
127 private static Map<String, UUID> zooLabelMap = null;
128
129
130
131 protected static NomenclaturalStatusType getTermByUuid(UUID uuid){
132 if (termMap == null && zooTermMap == null){
133 // DefaultTermInitializer vocabularyStore = new DefaultTermInitializer();
134 // vocabularyStore.initialize();
135 return null;
136 }
137 NomenclaturalStatusType result = null;
138 if (termMap != null){
139 result = (NomenclaturalStatusType)termMap.get(uuid);
140 }
141 if (result == null && zooTermMap != null){
142 result = (NomenclaturalStatusType)zooTermMap.get(uuid);
143 }
144 return result;
145 }
146
147
148 //********************************** Constructor *********************************/
149
150 //for hibernate use only
151 @Deprecated
152 protected NomenclaturalStatusType() {
153 super(TermType.NomenclaturalStatusType);
154 }
155
156 /**
157 * Class constructor: creates an additional nomenclatural status type
158 * instance with a description (in the {@link eu.etaxonomy.cdm.model.common.Language#DEFAULT() default language}), a label
159 * and a label abbreviation.
160 *
161 * @param term the string (in the default language) describing the
162 * new nomenclatural status type to be created
163 * @param label the string identifying the new nomenclatural status
164 * type to be created
165 * @param labelAbbrev the string identifying (in abbreviated form) the
166 * new nomenclatural status type to be created
167 * @see #NomenclaturalStatusType()
168 * @see #readCsvLine(List, Language)
169 * @see #readCsvLine(List)
170 */
171 private NomenclaturalStatusType(String term, String label, String labelAbbrev) {
172 super(TermType.NomenclaturalStatusType, term, label, labelAbbrev);
173 }
174
175 private NomenclaturalStatusType(String term, String label, String labelAbbrev, Language language) {
176 super(TermType.NomenclaturalStatusType);
177 this.addRepresentation(new Representation(term, label, labelAbbrev, language));
178 }
179
180 //********* METHODS **************************************
181
182
183 @Override
184 public void resetTerms(){
185 termMap = null;
186 zooTermMap = null;
187 }
188
189 /**
190 * Returns the boolean value indicating whether <i>this</i> nomenclatural status
191 * type is itself "invalid" or a kind of "invalid" (true) or not (false) -
192 * this corresponds to "not available" for {@link ZoologicalName zoological names} -.
193 * Returns false if <i>this</i> nomenclatural status type is null. The use
194 * of "invalid" {@link TaxonNameBase taxon names} should be avoided.<BR>
195 * A taxon name is "invalid" if it is not "valid"; this means that
196 * the taxon name:<ul>
197 * <li>has not been effectively published or
198 * <li>has a form which does not comply with the rules of the
199 * {@link NomenclaturalCode nomenclature code} or
200 * <li>is not accompanied by a description or diagnosis or by a reference to
201 * such a previously published description or diagnosis
202 * </ul>
203 *
204 * @see #VALID()
205 * @see #isIllegitimateType()
206 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#getKindOf()
207 */
208 @Transient
209 public boolean isInvalidType(){
210 if (this.equals(INVALID())
211 || this.equals(NUDUM())
212 || this.equals(PROVISIONAL())
213 || this.equals(COMBINATION_INVALID())
214 || this.equals(OPUS_UTIQUE_OPPR())
215 || this.equals(ZOO_NOT_AVAILABLE())
216 ){
217 return true;
218 }else{
219 return false;
220 }
221 }
222
223 /**
224 * Returns the boolean value indicating whether <i>this</i> nomenclatural status
225 * type is itself "legitimate" or a kind of "legitimate" (true)
226 * or not (false). - this corresponds to "valid" for {@link ZoologicalName zoological names} -.
227 * Returns false if <i>this</i> nomenclatural status type is null.<BR>
228 * A "valid" ("available") {@link TaxonNameBase taxon name}, unless "rejected",
229 * is "legitimate" if it was not "superfluous" when published
230 * or has been later "conserved".<BR>
231 *
232 * @see #isInvalidType()
233 * @see #isIllegitimateType()
234 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#getKindOf()
235 */
236 @Transient
237 public boolean isLegitimateType(){
238 if (this.equals(LEGITIMATE()) ||
239 this.equals(NOVUM()) ||
240 this.equals(ALTERNATIVE()) ||
241 this.equals(CONSERVED()) ||
242 this.equals(ORTHOGRAPHY_CONSERVED()) ||
243 this.equals(REJECTED_PROP()) ||
244 this.equals(UTIQUE_REJECTED_PROP()) ||
245 this.equals(COMB_NOV())
246 ){
247 return true;
248 }else{
249 return false;
250 }
251 }
252
253 /**
254 * Returns the boolean value indicating whether <i>this</i> nomenclatural status
255 * type is itself "illegitimate" or a kind of "illegitimate" (true)
256 * or not (false) - this corresponds to "invalid" for {@link ZoologicalName zoological names} -.
257 * Returns false if <i>this</i> nomenclatural status type is null.<BR>
258 * A "valid" ("available") {@link TaxonNameBase taxon name}, unless "conserved" or
259 * "sanctioned", is "illegitimate" if it was "superfluous" when published
260 * or has been later "rejected".
261 *
262 * @see #VALID()
263 * @see #isInvalidType()
264 * @see #ILLEGITIMATE()
265 * @see #CONSERVED()
266 * @see #SANCTIONED()
267 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#getKindOf()
268 */
269 @Transient
270 public boolean isIllegitimateType(){
271 if (this.equals(ILLEGITIMATE()) ||
272 this.equals(SUPERFLUOUS()) ||
273 this.equals(REJECTED()) ||
274 this.equals(UTIQUE_REJECTED()) ||
275 this.equals(CONSERVED_PROP()) ||
276 this.equals(ORTHOGRAPHY_CONSERVED_PROP()) ||
277 this.equals(ZOO_INVALID()) ||
278 this.equals(ZOO_SUPPRESSED())
279 ){
280 return true;
281 }else{
282 return false;
283 }
284 }
285
286 /**
287 * Returns the nomenclatural status type "ambiguous". A "valid"
288 * ("available") {@link TaxonNameBase taxon name} is "ambiguous" if it has been used so long
289 * by different authors in different senses (other than the originally
290 * intended) that it has become a persistent cause of error and confusion.<BR>
291 * An "ambiguous" taxon name is treated as if "rejected" and is therefore
292 * also "illegitimate" ("invalid" for {@link ZoologicalName zoological names}).
293 *
294 * @see #VALID()
295 * @see #REJECTED()
296 * @see #isIllegitimateType()
297 */
298 public static final NomenclaturalStatusType AMBIGUOUS(){
299 return getTermByUuid(uuidAmbiguous);
300 }
301
302 /**
303 * Returns the nomenclatural status type "doubtful" (dubious). A "valid"
304 * ("available") {@link TaxonNameBase taxon name} is "doubtful" if its
305 * application is uncertain; the confusion being derived from an incomplete
306 * or confusing description.<BR>
307 * A "doubtful" taxon name is treated as if "rejected" and is therefore
308 * also "illegitimate" (("invalid" for {@link ZoologicalName zoological names}).
309 *
310 * @see #VALID()
311 * @see #REJECTED()
312 * @see #isIllegitimateType()
313 */
314 public static final NomenclaturalStatusType DOUBTFUL(){
315 return getTermByUuid(uuidDoubtful);
316 }
317
318 /**
319 * Returns the nomenclatural status type "confusum". A "valid" ("available")
320 * {@link TaxonNameBase taxon name} is "confusum" if it has been widely
321 * and persistently used for a taxon or taxa not including its type.<BR>
322 * A "confusum" taxon name is treated as if "rejected" and is therefore
323 * also "illegitimate" ("invalid" for {@link ZoologicalName zoological names}).
324 *
325 * @see #VALID()
326 * @see #REJECTED()
327 * @see #isIllegitimateType()
328 */
329 public static final NomenclaturalStatusType CONFUSUM(){
330 return getTermByUuid(uuidConfusum);
331 }
332
333 /**
334 * Returns the nomenclatural status type "illegitimate" ("invalid" for
335 * {@link ZoologicalName zoological names}). A "valid" ("available")
336 * {@link TaxonNameBase taxon name}, unless "conserved" or "sanctioned", is "illegitimate"
337 * if it was "superfluous" when published or has been later "rejected".<BR>
338 *
339 * @see #VALID()
340 * @see #SUPERFLUOUS()
341 * @see #REJECTED()
342 */
343 public static final NomenclaturalStatusType ILLEGITIMATE(){
344 return getTermByUuid(uuidIllegitimate);
345 }
346
347 /**
348 * Returns the nomenclatural status type "superfluous". A "valid"
349 * ("available") {@link TaxonNameBase taxon name} is "superfluous" if, when published,
350 * the taxon to which it was applied, as circumscribed by its {@link NonViralName#getCombinationAuthorTeam() author},
351 * definitely included the type of a name which ought to have been adopted,
352 * or of which the epithet ought to have been adopted, under the rules of
353 * the {@link NomenclaturalCode nomenclature code}, and if it has not been later declared
354 * "conserved" or "sanctioned" by the competent authorities.<BR>
355 * A "superfluous" taxon name is therefore also "illegitimate" ("invalid" for
356 * {@link ZoologicalName zoological names}).
357 *
358 * @see #VALID()
359 * @see #CONSERVED()
360 * @see #SANCTIONED()
361 * @see #isIllegitimateType()
362 */
363 public static final NomenclaturalStatusType SUPERFLUOUS(){
364 return getTermByUuid(uuidSuperfluous);
365 }
366
367 /**
368 * Returns the nomenclatural status type "rejected". A "valid" ("available")
369 * {@link TaxonNameBase taxon name} is "rejected" if, even though by the strict
370 * application of the rules of the {@link NomenclaturalCode nomenclature code}, and especially
371 * of the principle of priority, it should be "legitimate" ("valid" for
372 * {@link ZoologicalName zoological names}), competent authorities decided to handle
373 * it as "illegitimate".<BR>
374 * A "rejected" taxon name is therefore also "illegitimate" ("invalid" for
375 * zoological names). A "rejected" taxon name is always rejected in favour
376 * of a "conserved" taxon name.
377 *
378 * @see #VALID()
379 * @see #isLegitimateType()
380 * @see #isIllegitimateType()
381 * @see #CONSERVED()
382 * @see NameRelationshipType#CONSERVED_AGAINST()
383 */
384 public static final NomenclaturalStatusType REJECTED(){
385 return getTermByUuid(uuidRejected);
386 }
387
388 /**
389 * Returns the nomenclatural status type "utique rejected". A "valid"
390 * ("available") {@link TaxonNameBase taxon name} is "utique rejected" if it is rejected
391 * outright (without being rejected in favour of a "conserved" taxon name).<BR>
392 * An "utique rejected" taxon name is therefore also "illegitimate"
393 * ("invalid" for zoological names).
394 *
395 * @see #REJECTED()
396 * @see #VALID()
397 * @see #isIllegitimateType()
398 * @see #CONSERVED()
399 */
400 public static final NomenclaturalStatusType UTIQUE_REJECTED(){
401 return getTermByUuid(uuidUtiqueRejected);
402 }
403
404 /**
405 * Returns the nomenclatural status type "proposed to be conserved". A
406 * "valid" ("available") {@link TaxonNameBase taxon name} is "proposed to be conserved"
407 * if, even though by the strict application of the rules of
408 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
409 * it is "illegitimate" ("invalid" for {@link ZoologicalName zoological names}),
410 * it has been submitted to competent authorities in order to decide whether
411 * it should be handled as "legitimate".<BR>
412 * A "proposed to be conserved" taxon name is therefore still "illegitimate"
413 * ("invalid" for zoological names).
414 *
415 * @see #VALID()
416 * @see #isIllegitimateType()
417 * @see #isLegitimateType()
418 * @see #CONSERVED()
419 * @see NameRelationshipType#CONSERVED_AGAINST()
420 */
421 public static final NomenclaturalStatusType CONSERVED_PROP(){
422 return getTermByUuid(uuidConservedProp);
423 }
424
425 /**
426 * Returns the nomenclatural status type "proposed to be conserved
427 * (orthography)". A {@link TaxonNameBase taxon name} is "proposed to be conserved
428 * (orthography)" if, even though originally published with another
429 * spelling, it has been submitted to competent authorities in order to
430 * decide whether the proposed alternative spelling should be "conserved".<BR>
431 * A "proposed to be conserved (orthography)" taxon name is therefore still
432 * "illegitimate" ("invalid" for {@link ZoologicalName zoological names}).
433 *
434 * @see #isIllegitimateType()
435 * @see #CONSERVED_PROP()
436 * @see #CONSERVED()
437 * @see NameRelationshipType#ORTHOGRAPHIC_VARIANT()
438 * @see NameRelationshipType#CONSERVED_AGAINST()
439 */
440 public static final NomenclaturalStatusType ORTHOGRAPHY_CONSERVED_PROP(){
441 return getTermByUuid(uuidOrthographyConservedProp);
442 }
443
444 /**
445 * Returns the nomenclatural status type "legitimate" ("valid" for
446 * {@link ZoologicalName zoological names}). A "valid" ("available")
447 * {@link TaxonNameBase taxon name}, unless "rejected", is "legitimate" if it was not
448 * "superfluous" when published or has been later "conserved".<BR>
449 *
450 * @see #VALID()
451 * @see #SUPERFLUOUS()
452 * @see #CONSERVED()
453 */
454 public static final NomenclaturalStatusType LEGITIMATE(){
455 return getTermByUuid(uuidLegitimate);
456 }
457
458 /**
459 * Returns the nomenclatural status type "alternative". A family
460 * {@link BotanicalName botanical name} is "alternative" if it is a classical name
461 * long in use, in some cases even before 1753, and is considered as
462 * {@link NomenclaturalStatusType#VALID() "valid"} although it does not follow the rules for
463 * family names (see Article 18 of the ICBN).<BR>
464 * An "alternative" taxon name is treated as if "conserved" and is therefore
465 * also "legitimate".
466 *
467 * @see #VALID()
468 * @see #CONSERVED()
469 * @see #isLegitimateType()
470 * @see NameRelationshipType#ALTERNATIVE_NAME()
471 */
472 public static final NomenclaturalStatusType ALTERNATIVE(){
473 return getTermByUuid(uuidAlternative);
474 }
475
476 /**
477 * Returns the nomenclatural status type "novum". A "valid"
478 * ("available") {@link TaxonNameBase taxon name} is "novum" if it has been created
479 * in order either to replace an earlier name that is "illegitimate" or to
480 * avoid the building of a "later homonym".<BR>
481 * A "novum" taxon name is therefore also "legitimate" ("valid" for
482 * {@link ZoologicalName zoological names}).
483 *
484 * @see #VALID()
485 * @see #isIllegitimateType()
486 * @see NameRelationshipType#REPLACED_SYNONYM()
487 * @see NameRelationshipType#BLOCKING_NAME_FOR()
488 */
489 public static final NomenclaturalStatusType NOVUM(){
490 return getTermByUuid(uuidNovum);
491 }
492
493 /**
494 * Returns the nomenclatural status type "proposed to be utique rejected". A
495 * "valid" ("available") {@link TaxonNameBase taxon name} is "proposed to be utique rejected"
496 * if, even though by the strict application of the rules of
497 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
498 * it is "legitimate" ("valid" for {@link ZoologicalName zoological names}),
499 * it has been submitted to competent authorities in order to decide whether
500 * it should be handled as "illegitimate" (without to be rejected in favour
501 * of a "conserved" taxon name).<BR>
502 * A "proposed to be utique rejected" taxon name is therefore still "legitimate"
503 * ("valid" for zoological names).
504 *
505 * @see #VALID()
506 * @see #isLegitimateType()
507 * @see #isIllegitimateType()
508 * @see #REJECTED()
509 * @see #REJECTED_PROP()
510 */
511 public static final NomenclaturalStatusType UTIQUE_REJECTED_PROP(){
512 return getTermByUuid(uuidUtiqueRejectedProp);
513 }
514
515 /**
516 * Returns the nomenclatural status type "conserved (orthography)". A
517 * {@link TaxonNameBase taxon name} is "conserved (orthography)" if competent authorities
518 * decided to conserve a different spelling to the one published originally.<BR>
519 * A "conserved (orthography)" taxon name is "conserved" and hence
520 * "legitimate" ("valid" for {@link ZoologicalName zoological names}).
521 *
522 * @see #isLegitimateType()
523 * @see #CONSERVED()
524 * @see #ORTHOGRAPHY_CONSERVED_PROP()
525 * @see NameRelationshipType#ORTHOGRAPHIC_VARIANT()
526 * @see NameRelationshipType#CONSERVED_AGAINST()
527 */
528 public static final NomenclaturalStatusType ORTHOGRAPHY_CONSERVED(){
529 return getTermByUuid(uuidOrthographyConserved);
530 }
531
532 /**
533 * Returns the nomenclatural status type "proposed to be rejected". A
534 * "valid" ("available") {@link TaxonNameBase taxon name} is "proposed to be rejected"
535 * if, even though by the strict application of the rules of
536 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
537 * it should be "legitimate" ("valid" for {@link ZoologicalName zoological names}),
538 * it has been submitted to competent authorities in order to decide whether
539 * it should be handled as "illegitimate".<BR>
540 * A "proposed to be rejected" taxon name is therefore still "legitimate"
541 * ("valid" for zoological names). A "proposed to be rejected" taxon name is always
542 * to be rejected in favour of a "proposed to be conserved" taxon name.
543 *
544 * @see #VALID()
545 * @see #isLegitimateType()
546 * @see #isIllegitimateType()
547 * @see #REJECTED()
548 * @see #CONSERVED_PROP()
549 * @see NameRelationshipType#CONSERVED_AGAINST()
550 */
551 public static final NomenclaturalStatusType REJECTED_PROP(){
552 return getTermByUuid(uuidRejectedProp);
553 }
554
555 /**
556 * Returns the nomenclatural status type "conserved". A "valid"
557 * ("available") {@link TaxonNameBase taxon name} is "conserved" if, even though by the strict
558 * application of the rules of the {@link NomenclaturalCode nomenclature code}, and especially of
559 * the principle of priority, it should be "illegitimate" ("invalid" for
560 * {@link ZoologicalName zoological names}), competent authorities decided to handle
561 * it as "legitimate".<BR>
562 * A "conserved" taxon name is therefore also "legitimate" ("valid" for
563 * zoological names).
564 *
565 * @see #VALID()
566 * @see #isIllegitimateType()
567 * @see #isLegitimateType()
568 * @see NameRelationshipType#CONSERVED_AGAINST()
569 */
570 public static final NomenclaturalStatusType CONSERVED(){
571 return getTermByUuid(uuidConserved);
572 }
573
574 /**
575 * Returns the nomenclatural status type "sanctioned". {@link BotanicalName Botanical names}
576 * for fungi are "sanctioned" if they were published in the opera mentioned
577 * in Article 13.1d of the {@link NomenclaturalCode#ICBN() ICBN}.<BR>
578 * A "sanctioned" taxon name is treated as if "conserved" and is therefore
579 * also "legitimate".
580 *
581 * @see #VALID()
582 * @see #CONSERVED()
583 * @see #isLegitimateType()
584 */
585 public static final NomenclaturalStatusType SANCTIONED(){
586 return getTermByUuid(uuidSanctioned);
587 }
588
589 /**
590 * Returns the nomenclatural status type "invalid" (this corresponds to
591 * "not available" for {@link ZoologicalName zoological names}). The use of "invalid"
592 * {@link TaxonNameBase taxon names} should be avoided.<BR>
593 * A taxon name is "invalid" if it is not "valid"; this means that
594 * the taxon name:<ul>
595 * <li>has not been effectively published or
596 * <li>has a form which does not comply with the rules of the
597 * {@link NomenclaturalCode nomenclature code} or
598 * <li>is not accompanied by a description or diagnosis or by a reference to
599 * such a previously published description or diagnosis
600 * </ul>
601 *
602 * @see #VALID()
603 * @see #isInvalidType()
604 * @see #ILLEGITIMATE()
605 */
606 public static final NomenclaturalStatusType INVALID(){
607 return getTermByUuid(uuidInvalid);
608 }
609
610 /**
611 * Returns the nomenclatural status type "nudum". A {@link TaxonNameBase taxon name} is "nudum"
612 * if its publication is not accompanied by a description or diagnosis or
613 * by a reference to such a previously published description or diagnosis.<BR>
614 * A "nudum" taxon name is therefore also "invalid" ("not available" for
615 * {@link ZoologicalName zoological names}).
616 *
617 * @see #isInvalidType()
618 */
619 public static final NomenclaturalStatusType NUDUM(){
620 return getTermByUuid(uuidNudum);
621 }
622
623 /**
624 * Returns the nomenclatural status type "invalid combination". A
625 * {@link TaxonNameBase bi- or trinomial} is an "invalid combination" if its
626 * {@link NonViralName#getCombinationAuthorTeam() author} did not definitely associate the final
627 * epithet with the name of the genus or species, or with its abbreviation.<BR>
628 * An "invalid combination" taxon name is therefore also "invalid"
629 * ("not available" for {@link ZoologicalName zoological names}).
630 *
631 * @see #isInvalidType()
632 */
633 public static final NomenclaturalStatusType COMBINATION_INVALID(){
634 return getTermByUuid(uuidCombinationInvalid);
635 }
636
637 /**
638 * Returns the nomenclatural status type "illegitimate combination".
639 * TODO explanation
640 *
641 * @see #isInvalidType()
642 */
643 public static final NomenclaturalStatusType COMBINATION_ILLEGITIMATE(){
644 return getTermByUuid(uuidCombinationIllegitimate);
645 }
646
647 /**
648 * Returns the nomenclatural status type "provisional". A {@link TaxonNameBase taxon name} is
649 * "provisional" if it has not been yet effectively published.<BR>
650 * A "provisional" taxon name is therefore also "invalid"
651 * ("not available" for {@link ZoologicalName zoological names}).
652 *
653 * @see #isInvalidType()
654 */
655 public static final NomenclaturalStatusType PROVISIONAL(){
656 return getTermByUuid(uuidProvisional);
657 }
658
659 /**
660 * Returns the nomenclatural status type "valid" (this corresponds to
661 * "available" for {@link ZoologicalName zoological names}).<BR>
662 * A {@link TaxonNameBase taxon name} is "valid" if it:<ul>
663 * <li>has been effectively published and
664 * <li>has a form which complies with the rules of the
665 * {@link NomenclaturalCode nomenclature code} and
666 * <li>is accompanied by a description or diagnosis or by a reference to
667 * such a previously published description or diagnosis
668 * </ul>
669 *
670 * @see #INVALID()
671 * @see #LEGITIMATE()
672 */
673 public static final NomenclaturalStatusType VALID(){
674 return getTermByUuid(uuidValid);
675 }
676
677 /**
678 * Returns the nomenclatural status type "subnudum". This type is not
679 * covered by {@link NomenclaturalCode nomenclature codes}. It appears sometimes in literature and
680 * represents the opinion of the author who considers the {@link TaxonNameBase taxon name} to be
681 * unusable for an unambiguous taxonomic use.
682 *
683 * @see #AMBIGUOUS()
684 * @see #CONFUSUM()
685 *
686 */
687 public static final NomenclaturalStatusType SUBNUDUM(){
688 return getTermByUuid(uuidSubnudum);
689 }
690
691 /**
692 * Returns the nomenclatural status type "comb. nov.". No further information available for now.
693 * @return
694 */
695 //TODO javadoc. this term was added for Flore du Gabon
696 public static final NomenclaturalStatusType COMB_NOV(){
697 return getTermByUuid(uuidCombNov);
698 }
699
700 /**
701 * Returns the nomenclatural status type "opus utique oppressum". This type
702 * relates to article 32.7 (old ICBN) and article 32.9 as well as App. 6
703 * (new {@link NomenclaturalCode#ICBN() ICBN}). This is a reference list of botanical opera, in which all
704 * {@link BotanicalName taxon names} (or names of a certain rank) are oppressed. Such a name has the
705 * status "invalid" but in contrary to "rejected" not a single name
706 * is rejected by the commission but an opus with regard to the validity of
707 * all taxon names occurring in it.<BR>
708 * An "opus utique oppressum" taxon name is therefore also "invalid"
709 * ("not available" for {@link ZoologicalName zoological names}).
710 *
711 * @see #isInvalidType()
712 */
713 public static final NomenclaturalStatusType OPUS_UTIQUE_OPPR(){
714 return getTermByUuid(uuidOpusUtiqueOppr);
715 }
716
717 /**
718 * TODO
719 * @return
720 */
721 public static final NomenclaturalStatusType ZOO_NOT_AVAILABLE (){
722 return getTermByUuid(uuidZooNotAvailable);
723 }
724
725 /**
726 * TODO
727 * @return
728 */
729 public static final NomenclaturalStatusType ZOO_INVALID (){
730 return getTermByUuid(uuidZooInvalid);
731 }
732
733 /**
734 * TODO
735 * @return
736 */
737 public static final NomenclaturalStatusType ZOO_SUPPRESSED (){
738 return getTermByUuid(uuidZooSuppressed);
739 }
740
741 //TODO further Zoological status
742
743
744 //TODO Soraya
745 // orth. var.: orthographic variant
746 // pro syn.: pro synonymo
747
748 // TODO
749 // Preliminary implementation for BotanicalNameParser.
750 // not yet complete
751 /**
752 * Returns the nomenclatural status type identified through its label
753 * abbreviation. Preliminary implementation for BotanicalNameParser.
754 *
755 * @param statusAbbreviation the label abbreviation
756 * @param name
757 * @return the nomenclatural status type
758 *
759 */
760 public static NomenclaturalStatusType getNomenclaturalStatusTypeByAbbreviation(String statusAbbreviation, NonViralName<?> name) throws UnknownCdmTypeException{
761 if (statusAbbreviation == null){
762 throw new NullPointerException("statusAbbreviation is NULL in getNomenclaturalStatusTypeByAbbreviation");
763 }
764 if (statusAbbreviation == null){
765 throw new NullPointerException("Abbreviation is NULL in getNomenclaturalStatusTypeByAbbreviation");
766 }
767 NomenclaturalStatusType result = null;
768
769 //TODO handle undefined names correctly
770 boolean isZooname = name.getNomenclaturalCode().equals(NomenclaturalCode.ICZN);
771
772 Map<String, UUID> map = isZooname ? zooAbbrevMap : abbrevMap;
773 if (map == null ){
774 return null;
775 }
776 //non unique abbrev
777 if (! isZooname && statusAbbreviation.equalsIgnoreCase("nom. alternativ.")){
778 return NomenclaturalStatusType.ALTERNATIVE();
779 }
780 UUID uuid = map.get(statusAbbreviation);
781 if (uuid != null ){
782 result = getTermByUuid(uuid);
783 }
784 if (result != null){
785 return result;
786 }else {
787 if (statusAbbreviation == null){
788 statusAbbreviation = "(null)";
789 }
790 throw new UnknownCdmTypeException("Unknown nom. status abbreviation: " + statusAbbreviation);
791 }
792
793 // }else if (statusAbbreviation.equalsIgnoreCase("nom. ambig.")) { return NomenclaturalStatusType.AMBIGUOUS();
794 // }else if (statusAbbreviation.equalsIgnoreCase("nom. dub.")) { return NomenclaturalStatusType.DOUBTFUL();
795 // }else if (statusAbbreviation.equalsIgnoreCase("nom. confus.")) { return NomenclaturalStatusType.CONFUSUM();
796 // }else if (statusAbbreviation.equalsIgnoreCase("nom. illeg.")){return NomenclaturalStatusType.ILLEGITIMATE();
797 // }else if (statusAbbreviation.equalsIgnoreCase("nom. superfl.")){ return NomenclaturalStatusType.SUPERFLUOUS();
798 // }else if (statusAbbreviation.equalsIgnoreCase("nom. rej.")) { return NomenclaturalStatusType.REJECTED();
799 // }else if (statusAbbreviation.equalsIgnoreCase("nom. utique rej.")) { return NomenclaturalStatusType.UTIQUE_REJECTED();
800 // }else if (statusAbbreviation.equalsIgnoreCase("nom. cons. prop.")) { return NomenclaturalStatusType.CONSERVED_PROP();
801 // }else if (statusAbbreviation.equalsIgnoreCase("nom. orth. cons. prop.")) { return NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED_PROP();
802 // }else if (statusAbbreviation.equalsIgnoreCase("nom. legit.")) { return NomenclaturalStatusType.LEGITIMATE();
803 // }else if (statusAbbreviation.equalsIgnoreCase("nom. altern.")) { return NomenclaturalStatusType.ALTERNATIVE();
804
805 // }else if (statusAbbreviation.equalsIgnoreCase("nom. alternativ.")) { return NomenclaturalStatusType.ALTERNATIVE();
806
807 // }else if (statusAbbreviation.equalsIgnoreCase("nom. nov.")) { return NomenclaturalStatusType.NOVUM();
808 // }else if (statusAbbreviation.equalsIgnoreCase("nom. utique rej. prop.")) { return NomenclaturalStatusType.UTIQUE_REJECTED_PROP();
809 // }else if (statusAbbreviation.equalsIgnoreCase("nom. orth. cons.")) { return NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED();
810 // }else if (statusAbbreviation.equalsIgnoreCase("nom. rej. prop.")) { return NomenclaturalStatusType.REJECTED_PROP();
811 // }else if (statusAbbreviation.equalsIgnoreCase("nom. cons.")) { return NomenclaturalStatusType.CONSERVED();
812 // }else if (statusAbbreviation.equalsIgnoreCase("nom. sanct.")) { return NomenclaturalStatusType.SANCTIONED();
813 // }else if (statusAbbreviation.equalsIgnoreCase("nom. inval.")) { return NomenclaturalStatusType.INVALID();
814 // }else if (statusAbbreviation.equalsIgnoreCase("nom. nud.")){ return NomenclaturalStatusType.NUDUM();
815 // }else if (statusAbbreviation.equalsIgnoreCase("comb. inval.")){ return NomenclaturalStatusType.COMBINATION_INVALID();
816 // }else if (statusAbbreviation.equalsIgnoreCase("nom. provis.")) { return NomenclaturalStatusType.PROVISIONAL();
817 // }else if (statusAbbreviation.equalsIgnoreCase("nom. valid")) { return NomenclaturalStatusType.VALID();
818 // }else if (statusAbbreviation.equalsIgnoreCase("opus. utique oppr.")) { return NomenclaturalStatusType.OPUS_UTIQUE_OPPR();
819 // }else if (statusAbbreviation.equalsIgnoreCase("nom. subnud.")) { return NomenclaturalStatusType.SUBNUDUM();
820 // //TODO make generic, use labels for map
821 // }else {
822 // if (statusAbbreviation == null){
823 // statusAbbreviation = "(null)";
824 // }
825 // throw new eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException("Unknown NomenclaturalStatusType abbreviation: " + statusAbbreviation);
826 // }
827 }
828
829 /**
830 * Returns the nomenclatural status type identified through its label.
831 *
832 * @param statusLabel the nomenclatural status label
833 * @return the nomenclatural status type
834 *
835 */
836 public static NomenclaturalStatusType getNomenclaturalStatusTypeByLabel(String statusLabel) throws UnknownCdmTypeException{
837 if (statusLabel == null){
838 throw new NullPointerException("Status label is NULL in getNomenclaturalStatusTypeBylabel");
839 }
840 NomenclaturalStatusType result = null;
841 if (statusLabel == null){
842 throw new NullPointerException("Status label is NULL in getNomenclaturalStatusTypeByLabel");
843 }
844 if (labelMap == null){
845 return null;
846 }
847 statusLabel = statusLabel.toLowerCase();
848 UUID uuid = labelMap.get(statusLabel);
849 if (uuid != null ){
850 result = getTermByUuid(uuid);
851 }
852 if (result != null){
853 return result;
854 }else {
855 if (statusLabel == null){
856 statusLabel = "(null)";
857 }
858 throw new UnknownCdmTypeException("Unknown nom. status label: " + statusLabel);
859 }
860
861 // if (statusLabel == null){ throw new NullPointerException("statusLabel is 'null' in getNomenclaturalStatusTypeByLabel");
862 // }else if (statusLabel.equalsIgnoreCase("Ambiguous")) { return NomenclaturalStatusType.AMBIGUOUS();
863 // }else if (statusLabel.equalsIgnoreCase("Doubtful")) { return NomenclaturalStatusType.DOUBTFUL();
864 // }else if (statusLabel.equalsIgnoreCase("Confusum")) { return NomenclaturalStatusType.CONFUSUM();
865 // }else if (statusLabel.equalsIgnoreCase("Illegitimate")){return NomenclaturalStatusType.ILLEGITIMATE();
866 // }else if (statusLabel.equalsIgnoreCase("Superfluous")){ return NomenclaturalStatusType.SUPERFLUOUS();
867 // }else if (statusLabel.equalsIgnoreCase("Rejected")) { return NomenclaturalStatusType.REJECTED();
868 // }else if (statusLabel.equalsIgnoreCase("Utique Rejected")) { return NomenclaturalStatusType.UTIQUE_REJECTED();
869 // }else if (statusLabel.equalsIgnoreCase("Conserved Prop")) { return NomenclaturalStatusType.CONSERVED_PROP();
870 // }else if (statusLabel.equalsIgnoreCase("Orthography Conserved Prop")) { return NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED_PROP();
871 // }else if (statusLabel.equalsIgnoreCase("Legitimate")) { return NomenclaturalStatusType.LEGITIMATE();
872 // }else if (statusLabel.equalsIgnoreCase("Alternative")) { return NomenclaturalStatusType.ALTERNATIVE();
873 // }else if (statusLabel.equalsIgnoreCase("Novum")) { return NomenclaturalStatusType.NOVUM();
874 // }else if (statusLabel.equalsIgnoreCase("Utique Rejected Prop")) { return NomenclaturalStatusType.UTIQUE_REJECTED_PROP();
875 // }else if (statusLabel.equalsIgnoreCase("Orthography Conserved")) { return NomenclaturalStatusType.ORTHOGRAPHY_CONSERVED();
876 // }else if (statusLabel.equalsIgnoreCase("Rejected Prop")) { return NomenclaturalStatusType.REJECTED_PROP();
877 // }else if (statusLabel.equalsIgnoreCase("Conserved")) { return NomenclaturalStatusType.CONSERVED();
878 // }else if (statusLabel.equalsIgnoreCase("Sanctioned")) { return NomenclaturalStatusType.SANCTIONED();
879 // }else if (statusLabel.equalsIgnoreCase("Invalid")) { return NomenclaturalStatusType.INVALID();
880 // }else if (statusLabel.equalsIgnoreCase("Nudum")){ return NomenclaturalStatusType.NUDUM();
881 // }else if (statusLabel.equalsIgnoreCase("Combination Invalid")){ return NomenclaturalStatusType.COMBINATION_INVALID();
882 // }else if (statusLabel.equalsIgnoreCase("Provisional")) { return NomenclaturalStatusType.PROVISIONAL();
883 // }else if (statusLabel.equalsIgnoreCase("Valid")) { return NomenclaturalStatusType.VALID();
884 // }else if (statusLabel.equalsIgnoreCase("Opus Utique Oppr")) { return NomenclaturalStatusType.OPUS_UTIQUE_OPPR();
885 // }else if (statusLabel.equalsIgnoreCase("Subnudum")) { return NomenclaturalStatusType.SUBNUDUM();
886 // }else {
887 // if (statusLabel == null){
888 // statusLabel = "(null)";
889 // }
890 // throw new eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException("Unknown NomenclaturalStatusType abbreviation: " + statusLabel);
891 // }
892 }
893
894
895 /**
896 * Fills <i>this</i> nomenclatural status type with contents (uuid, uri,
897 * description text, label and label abbreviation) coming from a csv line.
898 * The implicit language for the description text is "latin".
899 * This method overrides the method of {@link eu.etaxonomy.cdm.model.common.DefinedTermBase DefinedTermBase}.
900 *
901 * @param csvLine the (ordered) list of substrings from a csv string
902 * to be used to fill <i>this</i> nomenclatural status type
903 * @see #NomenclaturalStatusType(String, String, String)
904 * @see #readCsvLine(List, Language)
905 * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#readCsvLine(List)
906 */
907
908 public NomenclaturalStatusType readCsvLine(Class<NomenclaturalStatusType> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) { //TODO should be List<String> but makes error for some strange reason
909 try {
910 NomenclaturalStatusType newInstance = termClass.newInstance();
911 DefinedTermBase.readCsvLine(newInstance, csvLine, Language.LATIN(), abbrevAsId);
912 return newInstance;
913 } catch (Exception e) {
914 e.printStackTrace();
915 throw new RuntimeException(e);
916 }
917 }
918
919 @Override
920 protected void setDefaultTerms(TermVocabulary<NomenclaturalStatusType> termVocabulary) {
921 if (termVocabulary.getUuid().equals(uuidIcnafpNomStatusVocabulary)){
922 termMap = new HashMap<UUID, NomenclaturalStatusType>();
923 abbrevMap = new HashMap<String, UUID>();
924 labelMap = new HashMap<String, UUID>();
925 for (NomenclaturalStatusType term : termVocabulary.getTerms()){
926 termMap.put(term.getUuid(), term);
927 addStatusType(term, abbrevMap, labelMap);
928 }
929 }else if (termVocabulary.getUuid().equals(uuidIcznNomStatusVocabulary)){
930 zooTermMap = new HashMap<UUID, NomenclaturalStatusType>();
931 zooAbbrevMap = new HashMap<String, UUID>();
932 zooLabelMap = new HashMap<String, UUID>();
933 for (NomenclaturalStatusType term : termVocabulary.getTerms()){
934 zooTermMap.put(term.getUuid(), term);
935 addStatusType(term, zooAbbrevMap, zooLabelMap);
936 }
937 }else{
938 throw new IllegalArgumentException("Unknown Nom.Status Vocabulary");
939 }
940 }
941
942 /**
943 * Adds the status type to the (abbreviated) label maps
944 * @param term
945 */
946 private void addStatusType(NomenclaturalStatusType statusType, Map<String, UUID> abbrevMap, Map<String, UUID> labelMap ) {
947 if (statusType == null){
948 logger.warn("statusType is NULL");
949 return;
950 }
951 List<Language> list = new ArrayList<Language>();
952 list.add(Language.LATIN());
953 list.add(Language.ENGLISH());
954 list.add(Language.DEFAULT());
955
956 Representation representation = statusType.getPreferredRepresentation(list);
957 if (representation != null){
958
959 String abbrevLabel = representation.getAbbreviatedLabel();
960 String label = representation.getLabel();
961 if (abbrevLabel == null){
962 logger.warn("label is NULL");
963 return;
964 }
965
966 //add to map
967 abbrevMap.put(abbrevLabel, statusType.getUuid());
968 labelMap.put(label.toLowerCase(), statusType.getUuid());
969 }
970
971 }
972
973
974
975 /**
976 * NomenclaturalStatusType should always be shown in latin, therefore the only existing representation
977 * is the latin one. In case we pass in another Language to this method it will return a <code>null</code> representation.
978 *
979 * In case the representation becomes null, we fall back to the latin representation.
980 *
981 */
982 @Override
983 public Representation getRepresentation(Language lang) {
984 Representation representation = super.getRepresentation(lang);
985
986 if(representation == null){
987 representation = super.getRepresentation(Language.LATIN());
988 }
989
990 return representation;
991 }
992
993
994 }