Project

General

Profile

Download (37.9 KB) Statistics
| Branch: | Tag: | Revision:
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
package eu.etaxonomy.cdm.model.name;
10

    
11
import java.util.ArrayList;
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

    
26
import eu.etaxonomy.cdm.model.common.Language;
27
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
28
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
29
import eu.etaxonomy.cdm.model.term.Representation;
30
import eu.etaxonomy.cdm.model.term.TermType;
31
import eu.etaxonomy.cdm.model.term.TermVocabulary;
32
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
33

    
34
/**
35
 * The class representing categories of nomenclatural status (like "invalid",
36
 * "conserved" or "novum") to qualify the use of a particular taxon name string
37
 * depending on its {@link eu.etaxonomy.cdm.model.reference.INomenclaturalReference nomenclatural reference} (original publication),
38
 * on its {@link NomenclaturalCode nomenclatural code} and on possible decisions of the corresponding
39
 * competent authorities. Unfortunately the ICBN and the ICZN use sometimes
40
 * different words for the same meaning or the same word for different meanings
41
 * (for instance "valid" and "legitimate").
42
 * <P>
43
 * A standard (ordered) list of nomenclatural status type instances will be
44
 * automatically created as the project starts. But this class allows to extend
45
 * this standard list by creating new instances of additional nomenclatural
46
 * status types if needed. The present standard list follows the ICBN
47
 * terminology.
48
 * <P>
49
 * This class corresponds more or less to: <ul>
50
 * <li> NomenclaturalNoteTypeTerm according to the TDWG ontology
51
 * <li> NomenclaturalNoteType  according to the TCS
52
 * </ul>
53
 *
54
 * @author a.mueller
55
 * @since 10.07.2008
56
 */
57
@XmlAccessorType(XmlAccessType.FIELD)
58
@XmlType(name = "NomenclaturalStatusType")
59
@Entity
60
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
61
//@Indexed(index = "eu.etaxonomy.cdm.model.term.DefinedTermBase")
62
@Audited
63
public class NomenclaturalStatusType extends OrderedTermBase<NomenclaturalStatusType> {
64

    
65
	private static final long serialVersionUID = 1337101678484153972L;
66

    
67
	private static Logger logger = Logger.getLogger(NomenclaturalStatusType.class);
68

    
69
	//Botanical uuids
70
	public static final UUID uuidIcnafpNomStatusVocabulary = UUID.fromString("bb28cdca-2f8a-4f11-9c21-517e9ae87f1f");
71

    
72
	private static final UUID uuidAmbiguous = UUID.fromString("90f5012b-705b-4488-b4c6-002d2bc5198e");
73
	private static final UUID uuidDoubtful = UUID.fromString("0ffeb39e-872e-4c0f-85ba-a4150d9f9e7d");
74
	private static final UUID uuidConfusum = UUID.fromString("24955174-aa5c-4e71-a2fd-3efc79e885db");
75
	private static final UUID uuidIllegitimate = UUID.fromString("b7c544cf-a375-4145-9d3e-4b97f3f18108");
76
	private static final UUID uuidSuperfluous = UUID.fromString("6890483a-c6ba-4ae1-9ab1-9fbaa5736ce9");
77
	private static final UUID uuidRejected = UUID.fromString("48107cc8-7a5b-482e-b438-efbba050b851");
78
	private static final UUID uuidUtiqueRejected = UUID.fromString("04338fdd-c12a-402f-a1ca-68b4bf0be042");
79
	private static final UUID uuidConservedProp = UUID.fromString("82bab006-5aed-4301-93ec-980deb30cbb1");
80
	private static final UUID uuidOrthographyConservedProp = UUID.fromString("02f82bc5-1066-454b-a023-11967cba9092");
81
	private static final UUID uuidLegitimate = UUID.fromString("51a3613c-b53b-4561-b0cd-9163d91c15aa");
82
	private static final UUID uuidAlternative = UUID.fromString("3b8a8519-420f-4dfa-b050-b410cc257961");
83
	private static final UUID uuidNovum = UUID.fromString("05fcb68f-af60-4851-b912-892512058897");
84
	private static final UUID uuidUtiqueRejectedProp = UUID.fromString("643ee07f-026c-426c-b838-c778c8613383");
85
	private static final UUID uuidOrthographyConserved = UUID.fromString("34a7d383-988b-4117-b8c0-52b947f8c711");
86
	private static final UUID uuidRejectedProp = UUID.fromString("248e44c2-5436-4526-a352-f7467ecebd56");
87
	private static final UUID uuidConserved = UUID.fromString("6330f719-e2bc-485f-892b-9f882058a966");
88
	private static final UUID uuidSanctioned = UUID.fromString("1afe55c4-76aa-46c0-afce-4dc07f512733");
89
	private static final UUID uuidInvalid = UUID.fromString("b09d4f51-8a77-442a-bbce-e7832aaf46b7");
90
	private static final UUID uuidNudum = UUID.fromString("e0d733a8-7777-4b27-99a3-05ab50e9f312");
91
	private static final UUID uuidCombinationInvalid = UUID.fromString("f858e619-7b7f-4225-913b-880a2143ec83");
92
	private static final UUID uuidCombinationIllegitimate = UUID.fromString("d901d455-4e01-45cb-b653-01a840b97eed");
93
	private static final UUID uuidProvisional = UUID.fromString("a277507e-ad93-4978-9419-077eb889c951");
94
	private static final UUID uuidValid = UUID.fromString("bd036217-5499-4ccd-8f4c-72e06158db93");
95
	private static final UUID uuidOpusUtiqueOppr = UUID.fromString("a5055d80-dbba-4660-b091-a1835d59fe7c");
96
	private static final UUID uuidSubnudum = UUID.fromString("92a76bd0-6ea8-493f-98e0-4be0b98c092f");
97
	private static final UUID uuidOrthographyRejected = UUID.fromString("39a25673-f716-4ec7-ae27-2498fce43166");
98
	private static final UUID uuidConservedDesig = UUID.fromString("4e9c9702-a74d-4033-9d47-792ad123712c");
99
	private static final UUID uuidIned = UUID.fromString("51429574-c6f9-4aa1-bab9-0bbc5b160ba1");
100

    
101
	private static final UUID uuidCombNov = UUID.fromString("ed508710-deef-44b1-96f6-1ce6d2c9c884");
102

    
103
	//zoological uuids
104
	public static final UUID uuidIcznNomStatusVocabulary = UUID.fromString("5e3c08e9-13a9-498e-861e-b9b5656ab6ac");
105

    
106
	private static final UUID uuidZooNotAvailable = UUID.fromString("6d9ed462-b761-4da3-9304-4749e883d4eb");
107
	private static final UUID uuidZooInvalid = UUID.fromString("2bef7039-c129-410b-815e-2a1f7249127b");
108
	private static final UUID uuidZooSuppressed = UUID.fromString("a61602c7-fbd4-4eb4-98a2-44919db8920b");
109
	private static final UUID uuidZooOblitum = UUID.fromString("6a6f7a88-991f-4f76-8ce9-4110839fae8b");
110

    
111

    
112
    public static NomenclaturalStatusType NewLatinInstance(String description, String label, String labelAbbrev) {
113
        return new NomenclaturalStatusType(description, label, labelAbbrev, Language.LATIN());
114
    }
115

    
116
	public static NomenclaturalStatusType NewInstance(String description, String label, String labelAbbrev, Language language) {
117
		return new NomenclaturalStatusType(description, label, labelAbbrev, language);
118
	}
119

    
120
	public static NomenclaturalStatusType NewInstance(String description, String label, String labelAbbrev) {
121
		return new NomenclaturalStatusType(description, label, labelAbbrev);
122
	}
123

    
124
	protected static Map<UUID, NomenclaturalStatusType> termMap = null;
125
	private static Map<String, UUID> abbrevMap = null;
126
	private static Map<String, UUID> labelMap = null;
127

    
128

    
129
	protected static Map<UUID, NomenclaturalStatusType> zooTermMap = null;
130
	private static Map<String, UUID> zooAbbrevMap = null;
131
	private static Map<String, UUID> zooLabelMap = null;
132

    
133
	protected static NomenclaturalStatusType getTermByUuid(UUID uuid){
134
	    if ((termMap == null || termMap.isEmpty()) && (zooTermMap == null || zooTermMap.isEmpty())){
135
	        return getTermByClassAndUUID(NomenclaturalStatusType.class, uuid);
136
	    }
137
		NomenclaturalStatusType result = null;
138
		if (termMap != null){
139
			result = termMap.get(uuid);
140
		}
141
		if (result == null && zooTermMap != null){
142
			result = 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
	@Override
183
	public void resetTerms(){
184
		termMap = null;
185
		zooTermMap = null;
186
	}
187

    
188
	/**
189
	 * Returns the boolean value indicating whether <i>this</i> nomenclatural status
190
	 * type is itself "invalid" or a kind of "invalid" (true) or not (false) -
191
	 * this corresponds to "not available" for {@link IZoologicalName zoological names} -.
192
	 * Returns false if <i>this</i> nomenclatural status type is null. The use
193
	 * of "invalid" {@link TaxonName taxon names} should be avoided.<BR>
194
	 * A taxon name is "invalid" if it is not "valid"; this means that
195
	 * the taxon name:<ul>
196
	 * <li>has not been effectively published or
197
	 * <li>has a form which does not comply with the rules of the
198
	 * 	   {@link NomenclaturalCode nomenclature code} or
199
	 * <li>is not accompanied by a description or diagnosis or by a reference to
200
	 * 	   such a previously published description or diagnosis
201
	 * </ul>
202
	 *
203
	 * @see  #VALID()
204
	 * @see  #isIllegitimateType()
205
	 * @see  eu.etaxonomy.cdm.model.term.DefinedTermBase#getKindOf()
206
	 */
207
	@Transient
208
	public boolean isInvalidType(){
209
		if (this.equals(INVALID())
210
			|| this.equals(NUDUM())
211
			|| 	this.equals(PROVISIONAL())
212
			||  this.equals(INED())
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). Corresponds to "valid" for {@link IZoologicalName zoological names}.<BR>
227
	 * Returns false if <i>this</i> nomenclatural status type is null.<BR>
228
	 * A "valid" (zool.: "available") {@link TaxonName 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.term.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
				this.equals(CONSERVED_DESIG())
247
			){
248
			return true;
249
		}else{
250
			return false;
251
		}
252
	}
253

    
254
	/**
255
	 * Returns the boolean value indicating whether <i>this</i> nomenclatural status
256
	 * type is itself "illegitimate" or a kind of "illegitimate" (true)
257
	 * or not (false) - this corresponds to "invalid" for {@link IZoologicalName zoological names} -.
258
	 * Returns false if <i>this</i> nomenclatural status type is null.<BR>
259
	 * A "valid" ("available") {@link TaxonName taxon name}, unless "conserved" or
260
	 * "sanctioned", is "illegitimate" if it was "superfluous" when published
261
	 * or has been later "rejected".
262
	 *
263
	 * @see  #VALID()
264
	 * @see  #isInvalidType()
265
	 * @see  #ILLEGITIMATE()
266
	 * @see  #CONSERVED()
267
	 * @see  #SANCTIONED()
268
	 * @see  eu.etaxonomy.cdm.model.term.DefinedTermBase#getKindOf()
269
	 */
270
	@Transient
271
	public boolean isIllegitimateType(){
272
		if (this.equals(ILLEGITIMATE()) ||
273
				this.equals(SUPERFLUOUS()) ||
274
				this.equals(REJECTED()) ||
275
				this.equals(UTIQUE_REJECTED()) ||
276
				this.equals(CONSERVED_PROP()) ||
277
				this.equals(ORTHOGRAPHY_CONSERVED_PROP()) ||
278
				this.equals(ZOO_INVALID()) ||
279
				this.equals(ZOO_SUPPRESSED()) ||
280
				this.equals(ORTHOGRAPHY_REJECTED())
281
			){
282
			return true;
283
		}else{
284
			return false;
285
		}
286
	}
287

    
288

    
289
	/**
290
	 * Returns the nomenclatural status type "ambiguous". A "valid"
291
	 * ("available") {@link TaxonName taxon name} is "ambiguous" if it has been used so long
292
	 * by different authors in different senses (other than the originally
293
	 * intended) that it has become a persistent cause of error and confusion.<BR>
294
	 * An "ambiguous" taxon name is treated as if "rejected" and is therefore
295
	 * also "illegitimate" ("invalid" for {@link IZoologicalName zoological names}).
296
	 *
297
	 * @see  #VALID()
298
	 * @see  #REJECTED()
299
	 * @see  #isIllegitimateType()
300
	 */
301
	public static final NomenclaturalStatusType AMBIGUOUS(){
302
		return getTermByUuid(uuidAmbiguous);
303
	}
304

    
305
	/**
306
	 * Returns the nomenclatural status type "doubtful" (dubious). A "valid"
307
	 * ("available") {@link TaxonName taxon name} is "doubtful" if its
308
	 * application is uncertain; the confusion being derived from an incomplete
309
	 * or confusing description.<BR>
310
	 * A "doubtful" taxon name is treated as if "rejected" and is therefore
311
	 * also "illegitimate" (("invalid" for {@link IZoologicalName zoological names}).
312
	 *
313
	 * @see  #VALID()
314
	 * @see  #REJECTED()
315
	 * @see  #isIllegitimateType()
316
	 */
317
	public static final NomenclaturalStatusType DOUBTFUL(){
318
		return getTermByUuid(uuidDoubtful);
319
	}
320

    
321
	/**
322
	 * Returns the nomenclatural status type "confusum". A "valid" ("available")
323
	 * {@link TaxonName taxon name} is "confusum" if it has been widely
324
	 * and persistently used for a taxon or taxa not including its type.<BR>
325
	 * A "confusum" taxon name is treated as if "rejected" and is therefore
326
	 * also "illegitimate" ("invalid" for {@link IZoologicalName zoological names}).
327
	 *
328
	 * @see  #VALID()
329
	 * @see  #REJECTED()
330
	 * @see  #isIllegitimateType()
331
	 */
332
	public static final NomenclaturalStatusType CONFUSUM(){
333
		return getTermByUuid(uuidConfusum);
334
	}
335

    
336
	/**
337
	 * Returns the nomenclatural status type "illegitimate" ("invalid" for
338
	 * {@link IZoologicalName zoological names}). A "valid" ("available")
339
	 * {@link TaxonName taxon name}, unless "conserved" or "sanctioned", is "illegitimate"
340
	 * if it was "superfluous" when published or has been later "rejected".<BR>
341
	 *
342
	 * @see  #VALID()
343
	 * @see  #SUPERFLUOUS()
344
	 * @see  #REJECTED()
345
	 */
346
	public static final NomenclaturalStatusType ILLEGITIMATE(){
347
		return getTermByUuid(uuidIllegitimate);
348
	}
349

    
350
	/**
351
	 * Returns the nomenclatural status type "superfluous". A "valid"
352
	 * ("available") {@link TaxonName taxon name} is "superfluous" if, when published,
353
	 * the taxon to which it was applied, as circumscribed by its {@link NonViralName#getCombinationAuthorship() author},
354
	 * definitely included the type of a name which ought to have been adopted,
355
	 * or of which the epithet ought to have been adopted, under the rules of
356
	 * the {@link NomenclaturalCode nomenclature code}, and if it has not been later declared
357
	 * "conserved" or "sanctioned" by the competent authorities.<BR>
358
	 * A "superfluous" taxon name is therefore also "illegitimate" ("invalid" for
359
	 * {@link IZoologicalName zoological names}).
360
	 *
361
	 * @see  #VALID()
362
	 * @see  #CONSERVED()
363
	 * @see  #SANCTIONED()
364
	 * @see  #isIllegitimateType()
365
	 */
366
	public static final NomenclaturalStatusType SUPERFLUOUS(){
367
		return getTermByUuid(uuidSuperfluous);
368
	}
369

    
370
	/**
371
	 * Returns the nomenclatural status type "rejected". A "valid" ("available")
372
	 * {@link TaxonName taxon name} is "rejected" if, even though by the strict
373
	 * application of the rules of the {@link NomenclaturalCode nomenclature code}, and especially
374
	 * of the principle of priority, it should be "legitimate" ("valid" for
375
	 * {@link IZoologicalName zoological names}), competent authorities decided to handle
376
	 * it as "illegitimate".<BR>
377
	 * A "rejected" taxon name is therefore also "illegitimate" ("invalid" for
378
	 * zoological names). A "rejected" taxon name is always rejected in favour
379
	 * of a "conserved" taxon name.
380
	 *
381
	 * @see  #VALID()
382
	 * @see  #isLegitimateType()
383
	 * @see  #isIllegitimateType()
384
	 * @see  #CONSERVED()
385
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
386
	 */
387
	public static final NomenclaturalStatusType REJECTED(){
388
		return getTermByUuid(uuidRejected);
389
	}
390

    
391
	/**
392
	 * Returns the nomenclatural status type "utique rejected". A "valid"
393
	 * ("available") {@link TaxonName taxon name} is "utique rejected" if it is rejected
394
	 * outright (without being rejected in favour of a "conserved" taxon name).<BR>
395
	 * An "utique rejected" taxon name is therefore also "illegitimate"
396
	 * ("invalid" for zoological names).
397
	 *
398
	 * @see  #REJECTED()
399
	 * @see  #VALID()
400
	 * @see  #isIllegitimateType()
401
	 * @see  #CONSERVED()
402
	 */
403
	public static final NomenclaturalStatusType UTIQUE_REJECTED(){
404
		return getTermByUuid(uuidUtiqueRejected);
405
	}
406

    
407
	/**
408
	 * Returns the nomenclatural status type "proposed to be conserved". A
409
	 * "valid" ("available") {@link TaxonName taxon name} is "proposed to be conserved"
410
	 * if, even though by the strict application of the rules of
411
	 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
412
	 * it is "illegitimate" ("invalid" for {@link IZoologicalName zoological names}),
413
	 * it has been submitted to competent authorities in order to decide whether
414
	 * it should be handled as "legitimate".<BR>
415
	 * A "proposed to be conserved" taxon name is therefore still "illegitimate"
416
	 * ("invalid" for zoological names).
417
	 *
418
	 * {@link https://dev.e-taxonomy.eu/trac/ticket/5662}
419
	 *
420
	 * @see  #VALID()
421
	 * @see  #isIllegitimateType()
422
	 * @see  #isLegitimateType()
423
	 * @see  #CONSERVED()
424
	 * @see  #CONSERVED_DESIG()
425
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
426
	 */
427
	public static final NomenclaturalStatusType CONSERVED_PROP(){
428
		return getTermByUuid(uuidConservedProp);
429
	}
430

    
431
    /**
432
     * Returns the nomenclatural status type "designated to be conserved". A
433
     * "valid" ("available") {@link TaxonName taxon name} is "designated to be conserved".
434
     * The name is considered to be legitimate as it has been decided by the General Committee
435
     * though not yet ratified by the Int. Bot./Zool. Congr.
436
     *
437
     * NOTE: This interpretation needs further clarification.
438
     *
439
     * {@link https://dev.e-taxonomy.eu/trac/ticket/5662}
440
     *
441
     * @see  #VALID()
442
     * @see  #isIllegitimateType()
443
     * @see  #isLegitimateType()
444
     * @see  #CONSERVED()
445
     * @see  #CONSERVED_PROP()()
446
     * @see  NameRelationshipType#CONSERVED_AGAINST()
447
     */
448
    public static final NomenclaturalStatusType CONSERVED_DESIG(){
449
        return getTermByUuid(uuidConservedDesig);
450
    }
451

    
452
	/**
453
	 * Returns the nomenclatural status type "proposed to be conserved
454
	 * (orthography)". A {@link TaxonName taxon name} is "proposed to be conserved
455
	 * (orthography)" if, even though originally published with another
456
	 * spelling, it has been submitted to competent authorities in order to
457
	 * decide whether the proposed alternative spelling should be "conserved".<BR>
458
	 * A "proposed to be conserved (orthography)" taxon name is therefore still
459
	 * "illegitimate" ("invalid" for {@link IZoologicalName zoological names}).
460
	 *
461
	 * @see  #isIllegitimateType()
462
	 * @see  #CONSERVED_PROP()
463
	 * @see  #CONSERVED()
464
	 * @see  NameRelationshipType#ORTHOGRAPHIC_VARIANT()
465
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
466
	 */
467
	public static final NomenclaturalStatusType ORTHOGRAPHY_CONSERVED_PROP(){
468
		return getTermByUuid(uuidOrthographyConservedProp);
469
	}
470

    
471
	/**
472
	 * Returns the nomenclatural status type "legitimate" ("valid" for
473
	 * {@link IZoologicalName zoological names}). A "valid" ("available")
474
	 * {@link TaxonName taxon name}, unless "rejected", is "legitimate" if it was not
475
	 * "superfluous" when published or has been later "conserved".<BR>
476
	 *
477
	 * @see  #VALID()
478
	 * @see  #SUPERFLUOUS()
479
	 * @see  #CONSERVED()
480
	 */
481
	public static final NomenclaturalStatusType LEGITIMATE(){
482
		return getTermByUuid(uuidLegitimate);
483
	}
484

    
485
	/**
486
	 * Returns the nomenclatural status type "alternative". A family
487
	 * {@link BotanicalName botanical name} is "alternative" if it is a classical name
488
	 * long in use, in some cases even before 1753, and is considered as
489
	 * {@link NomenclaturalStatusType#VALID() "valid"} although it does not follow the rules for
490
	 * family names (see Article 18 of the ICBN).<BR>
491
	 * An "alternative" taxon name is treated as if "conserved" and is therefore
492
	 * also "legitimate".
493
	 *
494
	 * @see  #VALID()
495
	 * @see  #CONSERVED()
496
	 * @see  #isLegitimateType()
497
	 * @see  NameRelationshipType#ALTERNATIVE_NAME()
498
	 */
499
	public static final NomenclaturalStatusType ALTERNATIVE(){
500
		return getTermByUuid(uuidAlternative);
501
	}
502

    
503
	/**
504
	 * Returns the nomenclatural status type "novum". A "valid"
505
	 * ("available") {@link TaxonName taxon name} is "novum" if it has been created
506
	 * in order either to replace an earlier name that is "illegitimate" or to
507
	 * avoid the building of a "later homonym".<BR>
508
	 * A "novum" taxon name is therefore also "legitimate" ("valid" for
509
	 * {@link IZoologicalName zoological names}).
510
	 *
511
	 * @see  #VALID()
512
	 * @see  #isIllegitimateType()
513
	 * @see  NameRelationshipType#REPLACED_SYNONYM()
514
	 * @see  NameRelationshipType#BLOCKING_NAME_FOR()
515
	 */
516
	public static final NomenclaturalStatusType NOVUM(){
517
		return getTermByUuid(uuidNovum);
518
	}
519

    
520
	/**
521
	 * Returns the nomenclatural status type "proposed to be utique rejected". A
522
	 * "valid" ("available") {@link TaxonName taxon name} is "proposed to be utique rejected"
523
	 * if, even though by the strict application of the rules of
524
	 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
525
	 * it is "legitimate" ("valid" for {@link IZoologicalName zoological names}),
526
	 * it has been submitted to competent authorities in order to decide whether
527
	 * it should be handled as "illegitimate" (without to be rejected in favour
528
	 * of a "conserved" taxon name).<BR>
529
	 * A "proposed to be utique rejected" taxon name is therefore still "legitimate"
530
	 * ("valid" for zoological names).
531
	 *
532
	 * @see  #VALID()
533
	 * @see  #isLegitimateType()
534
	 * @see  #isIllegitimateType()
535
	 * @see  #REJECTED()
536
	 * @see  #REJECTED_PROP()
537
	 */
538
	public static final NomenclaturalStatusType UTIQUE_REJECTED_PROP(){
539
		return getTermByUuid(uuidUtiqueRejectedProp);
540
	}
541

    
542
	/**
543
	 * Returns the nomenclatural status type "conserved (orthography)". A
544
	 * {@link TaxonName taxon name} is "conserved (orthography)" if competent authorities
545
	 * decided to conserve a different spelling to the one published originally.<BR>
546
	 * A "conserved (orthography)" taxon name is "conserved" and hence
547
	 * "legitimate" ("valid" for {@link IZoologicalName zoological names}).
548
	 *
549
	 * @see  #isLegitimateType()
550
	 * @see  #CONSERVED()
551
	 * @see  #ORTHOGRAPHY_CONSERVED_PROP()
552
	 * @see  NameRelationshipType#ORTHOGRAPHIC_VARIANT()
553
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
554
	 */
555
	public static final NomenclaturalStatusType ORTHOGRAPHY_CONSERVED(){
556
		return getTermByUuid(uuidOrthographyConserved);
557
	}
558

    
559
    /**
560
     * Returns the nomenclatural status type "orthography rejected". <BR>
561
     * TBC.
562
     * See also {@link http://dev.e-taxonomy.eu/trac/ticket/5649}
563
     *
564
     * @see  #ORTHOGRAPHY_CONSERVED()
565
     * @see  #REJECTED()
566
     * @see  #isIllegitimateType()
567
     */
568
    public static final NomenclaturalStatusType ORTHOGRAPHY_REJECTED(){
569
        return getTermByUuid(uuidOrthographyRejected);
570
    }
571

    
572
	/**
573
	 * Returns the nomenclatural status type "proposed to be rejected". A
574
	 * "valid" ("available") {@link TaxonName taxon name} is "proposed to be rejected"
575
	 * if, even though by the strict application of the rules of
576
	 * the {@link NomenclaturalCode nomenclature code}, and especially of the principle of priority,
577
	 * it should be "legitimate" ("valid" for {@link IZoologicalName zoological names}),
578
	 * it has been submitted to competent authorities in order to decide whether
579
	 * it should be handled as "illegitimate".<BR>
580
	 * A "proposed to be rejected" taxon name is therefore still "legitimate"
581
	 * ("valid" for zoological names). A "proposed to be rejected" taxon name is always
582
	 * to be rejected in favour of a "proposed to be conserved" taxon name.
583
	 *
584
	 * @see  #VALID()
585
	 * @see  #isLegitimateType()
586
	 * @see  #isIllegitimateType()
587
	 * @see  #REJECTED()
588
	 * @see  #CONSERVED_PROP()
589
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
590
	 */
591
	public static final NomenclaturalStatusType REJECTED_PROP(){
592
		return getTermByUuid(uuidRejectedProp);
593
	}
594

    
595

    
596
	/**
597
	 * Returns the nomenclatural status type "conserved". A "valid"
598
	 * ("available") {@link TaxonName taxon name} is "conserved" if, even though by the strict
599
	 * application of the rules of the {@link NomenclaturalCode nomenclature code}, and especially of
600
	 * the principle of priority, it should be "illegitimate" ("invalid" for
601
	 * {@link IZoologicalName zoological names}), competent authorities decided to handle
602
	 * it as "legitimate".<BR>
603
	 * A "conserved" taxon name is therefore also "legitimate" ("valid" for
604
	 * zoological names).
605
	 *
606
	 * @see  #VALID()
607
	 * @see  #isIllegitimateType()
608
	 * @see  #isLegitimateType()
609
	 * @see  NameRelationshipType#CONSERVED_AGAINST()
610
	 */
611
	public static final NomenclaturalStatusType CONSERVED(){
612
		return getTermByUuid(uuidConserved);
613
	}
614

    
615
	/**
616
	 * Returns the nomenclatural status type "sanctioned". {@link BotanicalName Botanical names}
617
	 * for fungi are "sanctioned" if they were published in the opera mentioned
618
	 * in Article 13.1d of the {@link NomenclaturalCode#ICBN() ICBN}.<BR>
619
	 * A "sanctioned" taxon name is treated as if "conserved" and is therefore
620
	 * also "legitimate".
621
	 *
622
	 * @see  #VALID()
623
	 * @see  #CONSERVED()
624
	 * @see  #isLegitimateType()
625
	 */
626
	public static final NomenclaturalStatusType SANCTIONED(){
627
		return getTermByUuid(uuidSanctioned);
628
	}
629

    
630
	/**
631
	 * Returns the nomenclatural status type "invalid" (this corresponds to
632
	 * "not available" for {@link IZoologicalName zoological names}). The use of "invalid"
633
	 * {@link TaxonName taxon names} should be avoided.<BR>
634
	 * A taxon name is "invalid" if it is not "valid"; this means that
635
	 * the taxon name:<ul>
636
	 * <li>has not been effectively published or
637
	 * <li>has a form which does not comply with the rules of the
638
	 * 	   {@link NomenclaturalCode nomenclature code} or
639
	 * <li>is not accompanied by a description or diagnosis or by a reference to
640
	 * 	   such a previously published description or diagnosis
641
	 * </ul>
642
	 *
643
	 * @see  #VALID()
644
	 * @see  #isInvalidType()
645
	 * @see  #ILLEGITIMATE()
646
	 */
647
	public static final NomenclaturalStatusType INVALID(){
648
		return getTermByUuid(uuidInvalid);
649
	}
650

    
651
	/**
652
	 * Returns the nomenclatural status type "nudum". A {@link TaxonName taxon name} is "nudum"
653
	 * if its publication is not accompanied by a description or diagnosis or
654
	 * by a reference to such a previously published description or diagnosis.<BR>
655
	 * A "nudum" taxon name is therefore also "invalid" ("not available" for
656
	 * {@link IZoologicalName zoological names}).
657
	 *
658
	 * @see  #isInvalidType()
659
	 */
660
	public static final NomenclaturalStatusType NUDUM(){
661
		return getTermByUuid(uuidNudum);
662
	}
663

    
664
	/**
665
	 * Returns the nomenclatural status type "invalid combination". A
666
	 * {@link TaxonName bi- or trinomial} is an "invalid combination" if its
667
	 * {@link NonViralName#getCombinationAuthorship() author} did not definitely associate the final
668
	 * epithet with the name of the genus or species, or with its abbreviation.<BR>
669
	 * An "invalid combination" taxon name is therefore also "invalid"
670
	 * ("not available" for {@link IZoologicalName zoological names}).
671
	 *
672
	 * @see  #isInvalidType()
673
	 */
674
	public static final NomenclaturalStatusType COMBINATION_INVALID(){
675
		return getTermByUuid(uuidCombinationInvalid);
676
	}
677

    
678
	/**
679
	 * Returns the nomenclatural status type "illegitimate combination".
680
	 * TODO explanation
681
	 *
682
	 * @see  #isInvalidType()
683
	 */
684
	public static final NomenclaturalStatusType COMBINATION_ILLEGITIMATE(){
685
		return getTermByUuid(uuidCombinationIllegitimate);
686
	}
687

    
688
	/**
689
	 * Returns the nomenclatural status type "provisional". A {@link TaxonName taxon name} is
690
	 * "provisional" if it is not validly published, because not finally accepted by the author<BR>
691
	 * Some people use it in the same way as {@link #INED() ined.}
692
	 *
693
	 * @see #INED()
694
	 * @see  #isInvalidType()
695
	 */
696
	public static final NomenclaturalStatusType PROVISIONAL(){
697
		return getTermByUuid(uuidProvisional);
698
	}
699

    
700
    /**
701
     * Returns the nomenclatural status type "ined.". A {@link TaxonName taxon name} is
702
     * "inedited" if it it has not yet been published.<BR>
703
     * An inedited taxon name is therefore also "invalid" (bot.) / "not available (zool.)
704
     *<BR>
705
     * see also http://dev.e-taxonomy.eu/trac/ticket/5896
706
     *
707
     * @see #PROVISIONAL()
708
     * @see  #isInvalidType()
709
     * @return
710
     */
711
    public static final NomenclaturalStatusType INED(){
712
        return getTermByUuid(uuidIned);
713
    }
714

    
715
	/**
716
	 * Returns the nomenclatural status type "valid" (this corresponds to
717
	 * "available" for {@link IZoologicalName zoological names}).<BR>
718
	 * A {@link TaxonName taxon name} is "valid" if it:<ul>
719
	 * <li>has been effectively published and
720
	 * <li>has a form which complies with the rules of the
721
	 * 	   {@link NomenclaturalCode nomenclature code} and
722
	 * <li>is accompanied by a description or diagnosis or by a reference to
723
	 * 	   such a previously published description or diagnosis
724
	 * </ul>
725
	 *
726
	 * @see  #INVALID()
727
	 * @see  #LEGITIMATE()
728
	 */
729
	public static final NomenclaturalStatusType VALID(){
730
		return getTermByUuid(uuidValid);
731
	}
732

    
733
	/**
734
	 * Returns the nomenclatural status type "subnudum". This type is not
735
	 * covered by {@link NomenclaturalCode nomenclature codes}. It appears sometimes in literature and
736
	 * represents the opinion of the author who considers the {@link TaxonName taxon name} to be
737
	 * unusable for an unambiguous taxonomic use.
738
	 *
739
	 * @see  #AMBIGUOUS()
740
	 * @see  #CONFUSUM()
741
	 *
742
	 */
743
	public static final NomenclaturalStatusType SUBNUDUM(){
744
		return getTermByUuid(uuidSubnudum);
745
	}
746

    
747
	/**
748
	 * Returns the nomenclatural status type "comb. nov.". No further information available for now.
749
	 * @return
750
	 */
751
	//TODO javadoc. this term was added for Flore du Gabon
752
	public static final NomenclaturalStatusType COMB_NOV(){
753
		return getTermByUuid(uuidCombNov);
754
	}
755

    
756
	/**
757
	 * Returns the nomenclatural status type "opus utique oppressum". This type
758
	 * relates to article 32.7 (old ICBN) and article 32.9 as well as App. 6
759
	 * (new {@link NomenclaturalCode#ICBN() ICBN}). This is a reference list of botanical opera, in which all
760
	 * {@link BotanicalName taxon names} (or names of a certain rank) are oppressed. Such a name has the
761
	 * status "invalid" but in contrary to "rejected" not a single name
762
	 * is rejected by the commission but an opus with regard to the validity of
763
	 * all taxon names occurring in it.<BR>
764
	 * An "opus utique oppressum" taxon name is therefore also "invalid"
765
	 * ("not available" for {@link IZoologicalName zoological names}).
766
	 *
767
	 * @see  #isInvalidType()
768
	 */
769
	public static final NomenclaturalStatusType OPUS_UTIQUE_OPPR(){
770
		return getTermByUuid(uuidOpusUtiqueOppr);
771
	}
772

    
773
	/**
774
	 * TODO
775
	 * @return
776
	 */
777
	public static final  NomenclaturalStatusType ZOO_NOT_AVAILABLE (){
778
		return getTermByUuid(uuidZooNotAvailable);
779
	}
780

    
781
	/**
782
	 * TODO
783
	 * @return
784
	 */
785
	public static final  NomenclaturalStatusType ZOO_INVALID (){
786
		return getTermByUuid(uuidZooInvalid);
787
	}
788

    
789
	/**
790
	 * TODO
791
	 * @return
792
	 */
793
	public static final  NomenclaturalStatusType ZOO_SUPPRESSED (){
794
		return getTermByUuid(uuidZooSuppressed);
795
	}
796

    
797
	public static final  NomenclaturalStatusType ZOO_OBLITUM (){
798
        return getTermByUuid(uuidZooOblitum);
799
    }
800

    
801

    
802
	//TODO further Zoological status
803

    
804
	//TODO Soraya
805
	//	orth. var.: orthographic variant
806
	//	pro syn.: pro synonymo
807

    
808
	// TODO
809
	// Preliminary implementation for BotanicalNameParser.
810
	// not yet complete
811
	/**
812
	 * Returns the nomenclatural status type identified through its label
813
	 * abbreviation. Preliminary implementation for BotanicalNameParser.
814
	 *
815
	 * @param statusAbbreviation	the label abbreviation
816
	 * @param name                  the taxon name
817
	 * @return  					the nomenclatural status type
818
	 *
819
	 */
820
	public static NomenclaturalStatusType getNomenclaturalStatusTypeByAbbreviation(String statusAbbreviation, ITaxonNameBase name) throws UnknownCdmTypeException{
821
		if (statusAbbreviation == null){
822
			throw new NullPointerException("Abbreviation is NULL in getNomenclaturalStatusTypeByAbbreviation");
823
		}
824
		NomenclaturalStatusType result = null;
825
		statusAbbreviation = normalizeStatusAbbrev(statusAbbreviation);
826

    
827
		//TODO handle undefined names correctly
828
		boolean isZooname = name == null? false : name.getNameType().equals(NomenclaturalCode.ICZN);
829

    
830
		Map<String, UUID> map = isZooname ? zooAbbrevMap : abbrevMap;
831
		if (map == null ){
832
			return null;
833
		}
834
		//non unique abbrev
835
		if (! isZooname && statusAbbreviation.equalsIgnoreCase("nom. alternativ.")){
836
			return NomenclaturalStatusType.ALTERNATIVE();
837
		}
838
		UUID uuid = map.get(statusAbbreviation);
839
		if (uuid != null ){
840
			result = getTermByUuid(uuid);
841
		}
842
		if (result != null){
843
			return result;
844
		}else {
845
			throw new UnknownCdmTypeException("Unknown nom. status abbreviation: " + statusAbbreviation);
846
		}
847
	}
848

    
849
    private static String normalizeStatusAbbrev(String statusAbbreviation) {
850
        //#7109 should not happen anymore
851
        if (statusAbbreviation.equalsIgnoreCase("nom. valid")){
852
            statusAbbreviation = "nom. val.";
853
        }
854
        return statusAbbreviation;
855
    }
856

    
857
    /**
858
	 * Returns the nomenclatural status type identified through its label.
859
	 *
860
	 * @param	statusLabel	the nomenclatural status label
861
	 * @return  the nomenclatural status type
862
	 *
863
	 */
864
	public static NomenclaturalStatusType getNomenclaturalStatusTypeByLabel(String statusLabel) throws UnknownCdmTypeException{
865
		if (statusLabel == null){
866
			throw new NullPointerException("Status label is NULL in getNomenclaturalStatusTypeBylabel");
867
		}
868
		NomenclaturalStatusType result = null;
869
		if (labelMap == null){
870
			return null;
871
		}
872
		statusLabel = statusLabel.toLowerCase();
873
		UUID uuid = labelMap.get(statusLabel);
874
		if (uuid != null ){
875
			result = getTermByUuid(uuid);
876
		}
877
		if (result != null){
878
			return result;
879
		}else {
880
			if (statusLabel == null){
881
				statusLabel = "(null)";
882
			}
883
			throw new UnknownCdmTypeException("Unknown nom. status label: " + statusLabel);
884
		}
885
	}
886

    
887
	/**
888
	 * Fills <i>this</i> nomenclatural status type with contents (uuid, uri,
889
	 * description text, label and label abbreviation) coming from a csv line.
890
	 * The implicit language for the description text is "latin".
891
	 * This method overrides the method of {@link eu.etaxonomy.cdm.model.term.DefinedTermBase DefinedTermBase}.
892
	 *
893
	 * @param	csvLine 	the (ordered) list of substrings from a csv string
894
	 * 						to be used to fill <i>this</i> nomenclatural status type
895
	 * @see					#NomenclaturalStatusType(String, String, String)
896
	 * @see					#readCsvLine(List, Language)
897
	 * @see					eu.etaxonomy.cdm.model.term.DefinedTermBase#readCsvLine(List)
898
	 */
899

    
900
	@Override
901
    public NomenclaturalStatusType readCsvLine(Class<NomenclaturalStatusType> termClass, List<String> csvLine, TermType termType,
902
            Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) {   //TODO should be List<String> but makes error for some strange reason
903
		try {
904
			NomenclaturalStatusType newInstance = termClass.newInstance();
905
			newInstance.setTermType(termType);
906
			DefinedTermBase.readCsvLine(newInstance, csvLine, Language.LATIN(), abbrevAsId);
907
			return newInstance;
908
		} catch (Exception e) {
909
			e.printStackTrace();
910
			throw new RuntimeException(e);
911
		}
912
	}
913

    
914
	@Override
915
	protected void setDefaultTerms(TermVocabulary<NomenclaturalStatusType> termVocabulary) {
916
		if (termVocabulary.getUuid().equals(uuidIcnafpNomStatusVocabulary)){
917
			termMap = new HashMap<>();
918
			abbrevMap = new HashMap<>();
919
			labelMap = new HashMap<>();
920
			for (NomenclaturalStatusType term : termVocabulary.getTerms()){
921
				termMap.put(term.getUuid(), term);
922
				addStatusType(term, abbrevMap, labelMap);
923
			}
924
		}else if (termVocabulary.getUuid().equals(uuidIcznNomStatusVocabulary)){
925
			zooTermMap = new HashMap<>();
926
			zooAbbrevMap = new HashMap<>();
927
			zooLabelMap = new HashMap<>();
928
			for (NomenclaturalStatusType term : termVocabulary.getTerms()){
929
				zooTermMap.put(term.getUuid(), term);
930
				addStatusType(term, zooAbbrevMap, zooLabelMap);
931
			}
932
		}else{
933
			throw new IllegalArgumentException("Unknown Nom.Status Vocabulary");
934
		}
935
	}
936

    
937
	public static void initDefaultTerms() {
938
        TermVocabulary<NomenclaturalStatusType> vocabulary = getTermByUuid(uuidDoubtful).getVocabulary();
939
        (new NomenclaturalStatusType()).setDefaultTerms(vocabulary);
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<>();
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
	 * NomenclaturalStatusType should always be shown in latin, therefore the only existing representation
975
	 * is the latin one. In case we pass in another Language to this method it will return a <code>null</code> representation.
976
	 *
977
	 * In case the representation becomes null, we fall back to the latin representation.
978
	 *
979
	 */
980
	@Override
981
	public Representation getRepresentation(Language lang) {
982
		Representation representation = super.getRepresentation(lang);
983

    
984
		if(representation == null){
985
			representation = super.getRepresentation(Language.LATIN());
986
		}
987

    
988
		return representation;
989
	}
990
}
(25-25/41)