Project

General

Profile

Download (44.8 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.HashMap;
12
import java.util.List;
13
import java.util.Map;
14
import java.util.UUID;
15

    
16
import javax.persistence.Entity;
17
import javax.persistence.Transient;
18
import javax.validation.constraints.NotNull;
19
import javax.xml.bind.annotation.XmlAccessType;
20
import javax.xml.bind.annotation.XmlAccessorType;
21
import javax.xml.bind.annotation.XmlAttribute;
22
import javax.xml.bind.annotation.XmlType;
23

    
24
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
25
import org.hibernate.annotations.Type;
26
import org.hibernate.envers.Audited;
27

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

    
37
/**
38
 * The class representing the taxonomical ranks (like "Family", "Genus" or
39
 * "Species") used for {@link TaxonName taxon names} across all {@link NomenclaturalCode nomenclatural codes}
40
 * for prokaryotes (bacteria) (ICNP, former ICNB), viruses (ICVCN), plants and fungi (ICBN),
41
 * cultivars (ICNCP) and animals (ICZN).
42
 * <P>
43
 * A standard (ordered) list of taxonomical rank instances will be automatically
44
 * created as the project starts. But this class allows to extend this standard
45
 * list by creating new instances of additional taxonomical ranks if needed.
46
 * <P>
47
 * This class corresponds to: <ul>
48
 * <li> TaxonRankTerm according to the TDWG ontology
49
 * <li> TaxonomicRankEnum according to the TCS
50
 * <li> Rank according to the ABCD schema
51
 * </ul>
52
 *
53
 * @author m.doering
54
 * @since 08-Nov-2007 13:06:46
55
 */
56
@XmlAccessorType(XmlAccessType.FIELD)
57
@XmlType(name = "Rank")
58
@Entity
59
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
60
//@Indexed(index = "eu.etaxonomy.cdm.model.term.DefinedTermBase")
61
@Audited
62
public class Rank extends OrderedTermBase<Rank> {
63
    private static final long serialVersionUID = -8648081681348758485L;
64
    private static final Logger logger = LogManager.getLogger(Rank.class);
65

    
66
    private static final UUID uuidEmpire = UUID.fromString("ac470211-1586-4b24-95ca-1038050b618d");
67
    private static final UUID uuidDomain = UUID.fromString("ffca6ec8-8b88-417b-a6a0-f7c992aac19b");
68
    private static final UUID uuidSuperkingdom = UUID.fromString("64223610-7625-4cfd-83ad-b797bf7f0edd");
69
    private static final UUID uuidKingdom = UUID.fromString("fbe7109d-66b3-498c-a697-c6c49c686162");
70
    private static final UUID uuidSubkingdom = UUID.fromString("a71bd9d8-f3ab-4083-afb5-d89315d71655");
71
    private static final UUID uuidInfrakingdom = UUID.fromString("1e37930c-86cf-44f6-90fd-7822928df260");
72
    private static final UUID uuidSuperphylum = UUID.fromString("0d0cecb1-e254-4607-b210-6801e7ecbb04");
73
    private static final UUID uuidPhylum = UUID.fromString("773430d2-76b4-438c-b817-97a543a33287");
74
    private static final UUID uuidSubphylum = UUID.fromString("23a9b6ff-9408-49c9-bd9e-7a2ca5ab4725");
75
    private static final UUID uuidInfraphylum = UUID.fromString("1701de3a-7693-42a5-a2d3-42697f944190");
76
    private static final UUID uuidSuperdivision = UUID.fromString("a735a48f-4fc8-49a7-ae0c-6a984f658131");
77
    private static final UUID uuidDivision = UUID.fromString("7e56f5cc-123a-4fd1-8cbb-6fd80358b581");
78
    private static final UUID uuidSubdivision = UUID.fromString("931c840f-7a6b-4d76-ad38-bfdd77d7b2e8");
79
    private static final UUID uuidInfradivision = UUID.fromString("c0ede273-be52-4dee-b411-66ee08d30c94");
80
    private static final UUID uuidSuperclass = UUID.fromString("e65b4e1a-21ec-428d-9b9f-e87721ab967c");
81
    private static final UUID uuidClass = UUID.fromString("f23d14c4-1d34-4ee6-8b4e-eee2eb9a3daf");
82
    private static final UUID uuidSubclass = UUID.fromString("8cb26733-e2f5-46cb-ab5c-f99254f877aa");
83
    private static final UUID uuidInfraclass = UUID.fromString("ad23cfda-879a-4021-8629-c54d27caf717");
84
    private static final UUID uuidSuperorder = UUID.fromString("c8c67a22-301a-4219-b882-4a49121232ff");
85
    private static final UUID uuidOrder = UUID.fromString("b0785a65-c1c1-4eb4-88c7-dbd3df5aaad1");
86
    private static final UUID uuidSuborder = UUID.fromString("768ad378-fa85-42ab-b668-763225832f57");
87
    private static final UUID uuidInfraorder = UUID.fromString("84099182-a6f5-47d7-8586-33c9e9955a10");
88
    public static final UUID uuidSectionZoology = UUID.fromString("691d371e-10d7-43f0-93db-3d7fa1a62c54");
89
    public static final UUID uuidSubsectionZoology = UUID.fromString("0ed32d28-adc4-4303-a9ca-68e2acd67e33");
90
    private static final UUID uuidSuperfamily = UUID.fromString("2cfa510a-dcea-4a03-b66a-b1528f9b0796");
91
    private static final UUID uuidFamily = UUID.fromString("af5f2481-3192-403f-ae65-7c957a0f02b6");
92
    private static final UUID uuidSubfamily = UUID.fromString("862526ee-7592-4760-a23a-4ff3641541c5");
93
    private static final UUID uuidInfrafamily = UUID.fromString("c3f2e3bb-6eef-4a26-9fb7-b14f4c8c5e4f");
94
    private static final UUID uuidSupertribe = UUID.fromString("11e94828-8c61-499b-87d6-1de35ce2c51c");
95
    private static final UUID uuidTribe = UUID.fromString("4aa6890b-0363-4899-8d7c-ee0cb78e6166");
96
    private static final UUID uuidSubtribe = UUID.fromString("ae41ecc5-5165-4126-9d24-79939ae5d822");
97
    private static final UUID uuidInfratribe = UUID.fromString("1ec02e8f-f2b7-4c65-af9f-b436b34c79a3");
98
    private static final UUID uuidSupragenericTaxon = UUID.fromString("1fdc0b93-c354-441a-8406-091e0303ff5c");
99
    public static final UUID uuidGenus = UUID.fromString("1b11c34c-48a8-4efa-98d5-84f7f66ef43a");
100
    private static final UUID uuidSubgenus = UUID.fromString("78786e16-2a70-48af-a608-494023b91904");
101
    private static final UUID uuidInfragenus = UUID.fromString("a9972969-82cd-4d54-b693-a096422f13fa");
102
    public static final UUID uuidSectionBotany = UUID.fromString("3edff68f-8527-49b5-bf91-7e4398bb975c");
103
    public static final UUID uuidSubsectionBotany = UUID.fromString("d20f5b61-d463-4448-8f8a-c1ff1f262f59");
104
    private static final UUID uuidSeries = UUID.fromString("d7381ecf-48f8-429b-9c54-f461656978cd");
105
    private static final UUID uuidSubseries = UUID.fromString("80c9a263-f4db-4a13-b6c2-b7fec1aa1200");
106
    private static final UUID uuidSpeciesAggregate = UUID.fromString("1ecae058-4217-4f75-9c27-6d8ba099ac7a");
107
    private static final UUID uuidSpeciesGroup = UUID.fromString("d1988a11-292b-46fa-8fb7-bc64ea6d8fc6");
108
    public static final UUID uuidInfragenericTaxon = UUID.fromString("41bcc6ac-37d3-4fd4-bb80-3cc5b04298b9");
109
    public static final UUID uuidSpecies = UUID.fromString("b301f787-f319-4ccc-a10f-b4ed3b99a86d");
110
    private static final UUID uuidSubspecificAggregate = UUID.fromString("72c248b9-027d-4402-b375-dd4f0850c9ad");
111
    private static final UUID uuidGrexInfraspec = UUID.fromString("08dcb4ff-ac58-48a3-93af-efb3d836ac84");
112
    private static final UUID uuidSubgrex = UUID.fromString("fc7cd06f-199c-4128-92b2-312ac42efc34");
113
    private static final UUID uuidSubspecies = UUID.fromString("462a7819-8b00-4190-8313-88b5be81fad5");
114
    private static final UUID uuidInfraspecies = UUID.fromString("f28ebc9e-bd50-4194-9af1-42f5cb971a2c");
115
    private static final UUID uuidNatio = UUID.fromString("965f2f38-7f97-4270-ab5a-1999bf050a22");
116
    private static final UUID uuidVariety = UUID.fromString("d5feb6a5-af5c-45ef-9878-bb4f36aaf490");
117
    private static final UUID uuidBioVariety = UUID.fromString("a3a364cb-1a92-43fc-a717-3c44980a0991");
118
    private static final UUID uuidPathoVariety = UUID.fromString("2f4f4303-a099-47e3-9048-d749d735423b");
119
    private static final UUID uuidSubvariety = UUID.fromString("9a83862a-7aee-480c-a98d-4bceaf8712ca");
120
    private static final UUID uuidSubsubvariety = UUID.fromString("bff22f84-553a-4429-a4e7-c4b3796c3a18");
121

    
122
    public static final UUID uuidProles = UUID.fromString("8810d1ba-6a34-4ae3-a355-919ccd1cd1a5");
123
    public static final UUID uuidSubproles = UUID.fromString("47bd1439-c2ba-4c4e-994f-9c60853258f8");
124
    public static final UUID uuidRace = UUID.fromString("196dee39-cfd8-4460-8bf0-88b83da27f62");
125
    public static final UUID uuidLusus = UUID.fromString("4c8e12f6-2c16-4eda-a7db-fd247dcce789");
126
    public static final UUID uuidSublusus = UUID.fromString("1fafa596-a8e7-4e62-a378-3cc8cb3627ca");
127

    
128
    private static final UUID uuidConvar = UUID.fromString("2cc740c9-cebb-43c8-9b06-1bef79e6a56a");
129
    private static final UUID uuidForm = UUID.fromString("0461281e-458a-47b9-8d41-19a3d39356d5");
130
    private static final UUID uuidSpecialForm = UUID.fromString("bed20aee-2f5a-4635-9c02-eff06246d067");
131
    private static final UUID uuidSubform = UUID.fromString("47cfc5b0-0fb7-4ceb-b61d-e1dd8de8b569");
132
    private static final UUID uuidSubsubform = UUID.fromString("1c8ac389-4349-4ae0-87be-7239f6635068");
133
    public static final UUID uuidInfraspecificTaxon = UUID.fromString("eb75c27d-e154-4570-9d96-227b2df60474");
134
    private static final UUID uuidCandidate = UUID.fromString("ead9a1f5-dfd4-4de2-9121-70a47accb10b");
135
    public static final UUID uuidDenominationClass = UUID.fromString("49bdf74a-2170-40ed-8be2-887a0db517bf");
136
    public static final UUID uuidGrexICNCP = UUID.fromString("1abffd79-1a1e-4a00-bb48-08df756d73d3");
137
    public static final UUID uuidGraftChimaera = UUID.fromString("6b4063bc-f934-4796-9bf3-0ef3aea5c1cb");
138
    public static final UUID uuidCultivarGroup = UUID.fromString("d763e7d3-e7de-4bb1-9d75-225ca6948659");
139
    public static final UUID uuidCultivar = UUID.fromString("5e98415b-dc6e-440b-95d6-ea33dbb39ad0");
140
    private static final UUID uuidUnknownRank = UUID.fromString("5c4d6755-2cf6-44ca-9220-cccf8881700b");
141

    
142
    //additional (not yet in csv files, but used in single databases)
143
    //https://dev.e-taxonomy.eu/redmine/issues/7285
144
    public static final UUID uuidCohort = UUID.fromString("3e4dc2fa-79e8-4ee7-b7d8-4c02a18fe555");  //edaphobase
145
    public static final UUID uuidHyporder = UUID.fromString("2a1bdf1f-80fc-4846-b4d7-edcbf664f270");  //edaphobase
146
    //E+M
147
    public static UUID uuidCollSpecies = UUID.fromString("e14630ee-9446-4bb4-a7b7-4c3881bc5d94");
148

    
149
    private static Map<String, UUID> idInVocMap = null;
150
    private static Map<String, UUID> labelMap = null;
151

    
152
    protected static Map<UUID, Rank> termMap = null;
153

    
154
//*********************** Factory methods ********************************************/
155

    
156
    /**
157
     * Creates an additional rank with a description (in the {@link Language#DEFAULT() default language}),
158
     * a label and a label abbreviation.
159
     *
160
     * @param	term  		 the string (in the default language) describing the
161
     * 						 new rank to be created
162
     * @param	label  		 the string identifying the new rank to be created
163
     * @param	labelAbbrev  the string identifying (in abbreviated form) the
164
     * 						 new rank to be created
165
     * @see 				 #NewInstance()
166
     */
167
    public static Rank NewInstance(RankClass rankClass, String term, String label, String labelAbbrev){
168
        return new Rank(rankClass, term, label, labelAbbrev);
169
    }
170

    
171
    /**
172
     * The {@link RankClass rank class} of a rank. It is usually needed for correct formatting of a
173
     * rank by using e.g. isSupraGeneric(). Prior to v3.3 this was computed by comparison of ranks.
174
     */
175
    @XmlAttribute(name ="RankClass")
176
    @NotNull
177
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
178
        parameters = {@org.hibernate.annotations.Parameter(name="enumClass", value="eu.etaxonomy.cdm.model.name.RankClass")}
179
    )
180
    @Audited
181
    private RankClass rankClass;
182

    
183

    
184
//********************************** Constructor *********************************/
185

    
186
      //for hibernate use only
187
      @Deprecated
188
      protected Rank() {
189
        super(TermType.Rank);
190
    }
191

    
192
    /**
193
     * Class constructor: creates an additional rank instance with a description
194
     * (in the {@link eu.etaxonomy.cdm.model.common.Language#DEFAULT() default language}), a label and a label abbreviation.
195
     *
196
     * @param	term  		 the string (in the default language) describing the
197
     * 						 new rank to be created
198
     * @param	label  		 the string identifying the new rank to be created
199
     * @param	labelAbbrev  the string identifying (in abbreviated form) the
200
     * 						 new rank to be created
201
     * @see 	#Rank()
202
     */
203
    protected Rank(RankClass rankClass, String term, String label, String labelAbbrev) {
204
        super(TermType.Rank, term, label, labelAbbrev);
205
        this.rankClass = rankClass;
206
    }
207

    
208

    
209
//********* METHODS **************************************/
210

    
211
    @Override
212
    public void resetTerms(){
213
        termMap = null;
214
    }
215

    
216
    protected static Rank getTermByUuid(UUID uuid){
217
        if (termMap == null || termMap.isEmpty()){
218
           return getTermByClassAndUUID(Rank.class, uuid);
219
        } else {
220
            return termMap.get(uuid);
221
        }
222
    }
223

    
224
    public static final Rank EMPIRE(){
225
      return getTermByUuid(uuidEmpire);
226
    }
227
    public static final Rank DOMAIN(){
228
          return getTermByUuid(uuidDomain);
229
    }
230
    public static final Rank SUPERKINGDOM(){
231
        return getTermByUuid(uuidSuperkingdom);
232
    }
233
    public static final Rank KINGDOM(){
234
        return getTermByUuid(uuidKingdom);
235
    }
236
    public static final Rank SUBKINGDOM(){
237
        return getTermByUuid(uuidSubkingdom);
238
    }
239
    public static final Rank INFRAKINGDOM(){
240
        return getTermByUuid(uuidInfrakingdom);
241
    }
242
    public static final Rank SUPERPHYLUM(){
243
        return getTermByUuid(uuidSuperphylum);
244
    }
245
    public static final Rank PHYLUM(){
246
        return getTermByUuid(uuidPhylum);
247
    }
248
    public static final Rank SUBPHYLUM(){
249
        return getTermByUuid(uuidSubphylum);
250
    }
251
    public static final Rank INFRAPHYLUM(){
252
        return getTermByUuid(uuidInfraphylum);
253
    }
254
    public static final Rank SUPERDIVISION(){
255
        return getTermByUuid(uuidSuperdivision);
256
    }
257
    public static final Rank DIVISION(){
258
        return getTermByUuid(uuidDivision);
259
    }
260
    public static final Rank SUBDIVISION(){
261
        return getTermByUuid(uuidSubdivision);
262
    }
263
    public static final Rank INFRADIVISION(){
264
        return getTermByUuid(uuidInfradivision);
265
    }
266
    public static final Rank SUPERCLASS(){
267
        return getTermByUuid(uuidSuperclass);
268
    }
269
    public static final Rank CLASS(){
270
        return getTermByUuid(uuidClass);
271
    }
272
    public static final Rank SUBCLASS(){
273
        return getTermByUuid(uuidSubclass);
274
    }
275
    public static final Rank INFRACLASS(){
276
        return getTermByUuid(uuidInfraclass);
277
    }
278
    public static final Rank SUPERORDER(){
279
        return getTermByUuid(uuidSuperorder);
280
    }
281
    public static final Rank ORDER(){
282
        return getTermByUuid(uuidOrder);
283
    }
284
    public static final Rank SUBORDER(){
285
        return getTermByUuid(uuidSuborder);
286
    }
287
    public static final Rank INFRAORDER(){
288
        return getTermByUuid(uuidInfraorder);
289
    }
290
    public static final Rank SUPERFAMILY(){
291
        return getTermByUuid(uuidSuperfamily);
292
    }
293
    public static final Rank FAMILY(){
294
        return getTermByUuid(uuidFamily);
295
    }
296
    public static final Rank SUBFAMILY(){
297
        return getTermByUuid(uuidSubfamily);
298
    }
299
    public static final Rank INFRAFAMILY(){
300
        return getTermByUuid(uuidInfrafamily);
301
    }
302
    public static final Rank SUPERTRIBE(){
303
        return getTermByUuid(uuidSupertribe);
304
    }
305
    public static final Rank TRIBE(){
306
        return getTermByUuid(uuidTribe);
307
    }
308
    public static final Rank SUBTRIBE(){
309
        return getTermByUuid(uuidSubtribe);
310
    }
311
    public static final Rank INFRATRIBE(){
312
        return getTermByUuid(uuidInfratribe);
313
    }
314
    public static final Rank SUPRAGENERICTAXON(){
315
        return getTermByUuid(uuidSupragenericTaxon);
316
    }
317
    public static final Rank GENUS(){
318
        return getTermByUuid(uuidGenus);
319
    }
320
    public static final Rank SUBGENUS(){
321
        return getTermByUuid(uuidSubgenus);
322
    }
323
    public static final Rank INFRAGENUS(){
324
        return getTermByUuid(uuidInfragenus);
325
    }
326
    public static final Rank SECTION_BOTANY(){
327
        return getTermByUuid(uuidSectionBotany);
328
    }
329
    public static final Rank SUBSECTION_BOTANY(){
330
        return getTermByUuid(uuidSubsectionBotany);
331
    }
332
    public static final Rank SECTION_ZOOLOGY(){
333
        return getTermByUuid(uuidSectionZoology);
334
    }
335
    public static final Rank SUBSECTION_ZOOLOGY(){
336
        return getTermByUuid(uuidSubsectionZoology);
337
    }
338
    public static final Rank SERIES(){
339
        return getTermByUuid(uuidSeries);
340
    }
341
    public static final Rank SUBSERIES(){
342
        return getTermByUuid(uuidSubseries);
343
    }
344
    public static final Rank SPECIESAGGREGATE(){
345
        return getTermByUuid(uuidSpeciesAggregate);
346
    }
347
    public static final Rank SPECIESGROUP(){
348
        return getTermByUuid(uuidSpeciesGroup);
349
    }
350
    /**
351
     * 'Unranked infrageneric'. An infrageneric rank which is on purpose not further defined.
352
     * This sometimes holds for names from the 19th century.
353
     */
354
    public static final Rank INFRAGENERICTAXON(){
355
        return getTermByUuid(uuidInfragenericTaxon);
356
    }
357
    public static final Rank SPECIES(){
358
        return getTermByUuid(uuidSpecies);
359
    }
360
    public static final Rank SUBSPECIFICAGGREGATE(){
361
        return getTermByUuid(uuidSubspecificAggregate);
362
    }
363
    public static final Rank GREX_INFRASPEC(){
364
        return getTermByUuid(uuidGrexInfraspec);
365
    }
366
    public static final Rank SUBGREX(){
367
        return getTermByUuid(uuidSubgrex);
368
    }
369
    public static final Rank SUBSPECIES(){
370
        return getTermByUuid(uuidSubspecies);
371
    }
372
    public static final Rank INFRASPECIES(){
373
        return getTermByUuid(uuidInfraspecies);
374
    }
375
    public static final Rank VARIETY(){
376
        return getTermByUuid(uuidVariety);
377
    }
378
    public static final Rank BIOVARIETY(){
379
        return getTermByUuid(uuidBioVariety);
380
    }
381
    public static final Rank PATHOVARIETY(){
382
        return getTermByUuid(uuidPathoVariety);
383
    }
384
    public static final Rank SUBVARIETY(){
385
        return getTermByUuid(uuidSubvariety);
386
    }
387
    public static final Rank SUBSUBVARIETY(){
388
        return getTermByUuid(uuidSubsubvariety );
389
    }
390
    public static final Rank PROLES(){
391
        return getTermByUuid(uuidProles);
392
    }
393
    public static final Rank SUBPROLES(){
394
        return getTermByUuid(uuidSubproles);
395
    }
396
    public static final Rank RACE(){
397
        return getTermByUuid(uuidRace);
398
    }
399
    public static final Rank LUSUS(){
400
        return getTermByUuid(uuidLusus);
401
    }
402
    public static final Rank SUBLUSUS(){
403
        return getTermByUuid(uuidSublusus);
404
    }
405

    
406
    public static final Rank CONVAR(){
407
        return getTermByUuid(uuidConvar);
408
    }
409
    public static final Rank FORM(){
410
        return getTermByUuid(uuidForm);
411
    }
412
    public static final Rank SPECIALFORM(){
413
        return getTermByUuid(uuidSpecialForm);
414
    }
415
    public static final Rank SUBFORM(){
416
        return getTermByUuid(uuidSubform);
417
    }
418
    public static final Rank SUBSUBFORM(){
419
        return getTermByUuid(uuidSubsubform);
420
    }
421
    /**
422
     * 'Unranked infraspecific'. An infraspecific rank which is on purpose not further defined.
423
     * This sometimes holds for names from the 19th century.
424
     */
425
    public static final Rank INFRASPECIFICTAXON(){
426
        return getTermByUuid(uuidInfraspecificTaxon);
427
    }
428
    public static final Rank CANDIDATE(){
429
        return getTermByUuid(uuidCandidate);
430
    }
431
    public static final Rank DENOMINATIONCLASS(){
432
        return getTermByUuid(uuidDenominationClass);
433
    }
434
    public static final Rank GREX_ICNCP(){
435
        return getTermByUuid(uuidGrexICNCP);
436
    }
437
    public static final Rank GRAFTCHIMAERA(){
438
        return getTermByUuid(uuidGraftChimaera);
439
    }
440
    public static final Rank CULTIVARGROUP(){
441
        return getTermByUuid(uuidCultivarGroup);
442
    }
443
    public static final Rank CULTIVAR(){
444
        return getTermByUuid(uuidCultivar);
445
    }
446
    public static final Rank UNKNOWN_RANK(){
447
        return getTermByUuid(uuidUnknownRank);
448
    }
449
    public static final Rank NATIO(){
450
        return getTermByUuid(uuidNatio);
451
    }
452
    /**
453
     * @see #INFRASPECIFICTAXON()
454
     */
455
    public static final Rank UNRANKED_INFRASPECIFIC(){
456
        return getTermByUuid(uuidInfraspecificTaxon);
457
    }
458
    /**
459
     * @see #INFRAGENERICTAXON()
460
     */
461
    public static final Rank UNRANKED_INFRAGENERIC(){
462
        return getTermByUuid(uuidInfragenericTaxon);
463
    }
464

    
465
// ************************ GETTER / SETTER **********************************/
466

    
467
    public RankClass getRankClass() {
468
        return rankClass;
469
    }
470

    
471
    public void setRankClass(RankClass rankClass) {
472
        this.rankClass = rankClass;
473
    }
474

    
475
// ******************************** METHODS ***************************************/
476

    
477
    /**
478
     * Returns the boolean value indicating whether <i>this</i> rank is higher than
479
     * the genus rank (true) or not (false). Returns false if <i>this</i> rank is null.
480
     *
481
     * @see  #isGenus()
482
     * @see  #isInfraGeneric()
483
     * @see  #isSpecies()
484
     * @see  #isInfraSpecific()
485
     */
486
    @Transient
487
    public boolean isSupraGeneric(){
488
        return this.rankClass.equals(RankClass.Suprageneric); // (this.isHigher(Rank.GENUS()));
489
    }
490

    
491
    /**
492
     * Returns the boolean value indicating whether <i>this</i> rank is the genus rank
493
     * (true) or not (false). Returns false if <i>this</i> rank is null.
494
     *
495
     * @see  #isSupraGeneric()
496
     * @see  #isInfraGeneric()
497
     * @see  #isSpecies()
498
     * @see  #isInfraSpecific()
499
     */
500
    @Transient
501
    public boolean isGenus(){
502
        return this.rankClass.equals(RankClass.Genus); // (this.equals(Rank.GENUS()));
503
    }
504

    
505
    /**
506
     * Returns the boolean value indicating whether <i>this</i> rank is higher than the
507
     * species rank and lower than the genus rank (true) or not (false). Species groups or
508
     * aggregates are also handled as infrageneric ranks.
509
     * Returns false if <i>this</i> rank is null.
510
     *
511
     * @see  #isSupraGeneric()
512
     * @see  #isGenus()
513
     * @see  #isInfraGenericButNotSpeciesGroup()
514
     * @see  #isSpeciesAggregate()
515
     * @see  #isSpecies()
516
     * @see  #isInfraSpecific()
517
     */
518
    @Transient
519
    public boolean isInfraGeneric(){
520
        return this.rankClass.equals(RankClass.Infrageneric) || this.rankClass.equals(RankClass.SpeciesGroup) ; //(this.isLower(Rank.GENUS()) && this.isHigher(Rank.SPECIES()));
521
    }
522

    
523
    /**
524
     * Returns the boolean value indicating whether <i>this</i> rank is higher than the
525
     * species aggregate/group rank and lower than the genus rank (true) or not (false).
526
     * Returns false if <i>this</i> rank is null.
527
     *
528
     * @see  #isSupraGeneric()
529
     * @see  #isGenus()
530
     * @see  #isInfraGeneric()
531
     * @see  #isSpeciesAggregate()
532
     * @see  #isSpecies()
533
     * @see  #isInfraSpecific()
534
     */
535
    @Transient
536
    public boolean isInfraGenericButNotSpeciesGroup(){
537
        return this.rankClass.equals(RankClass.Infrageneric) ;
538
    }
539

    
540
    /**
541
     * Returns true if this rank indicates a rank that aggregates species
542
     * like species aggregates or species groups, false otherwise.
543
     * @return
544
     */
545
    @Transient
546
    public boolean isSpeciesAggregate(){
547
        return this.rankClass.equals(RankClass.SpeciesGroup); //(this.equals(Rank.SPECIESAGGREGATE()) || (this.isLower(Rank.SPECIESAGGREGATE()) && this.isHigher(Rank.SPECIES())));
548
    }
549

    
550
    /**
551
     * Returns the boolean value indicating whether <i>this</i> rank is the species
552
     * rank (true) or not (false). Returns false if <i>this</i> rank is null.
553
     *
554
     * @see  #isSupraGeneric()
555
     * @see  #isGenus()
556
     * @see  #isInfraGeneric()
557
     * @see  #isInfraSpecific()
558
     */
559
    @Transient
560
    public boolean isSpecies(){
561
        return this.rankClass.equals(RankClass.Species); //(this.equals(Rank.SPECIES()));
562
    }
563

    
564
    /**
565
     * Returns the boolean value indicating whether <i>this</i> rank is lower than the
566
     * species rank (true) or not (false). Returns false if <i>this</i> rank is null.
567
     *
568
     * @see  #isSupraGeneric()
569
     * @see  #isGenus()
570
     * @see  #isInfraGeneric()
571
     * @see  #isSpecies()
572
     */
573
    @Transient
574
    public boolean isInfraSpecific(){
575
        return this.rankClass.equals(RankClass.Infraspecific); // (this.isLower(Rank.SPECIES()));
576
    }
577

    
578
    @Transient
579
    public boolean isCultivar(){
580
        //TODO handle correctly as rankClass?
581
        return this.uuid.equals(uuidCultivar) || this.uuid.equals(uuidCultivarGroup)
582
                || this.uuid.equals(uuidGraftChimaera) || this.uuid.equals(uuidGrexICNCP)
583
                || this.uuid.equals(uuidDenominationClass);
584
    }
585

    
586

    
587
    /**
588
     * Returns the rank identified through a label or the identifier within the vocabulary
589
     * Preliminary implementation for BotanicalNameParser.
590
     *
591
     * @param	strRank	the string identifying the rank
592
     * @return  		the rank
593
     */
594
    public static Rank getRankByLatinNameOrIdInVoc(String strRank) throws UnknownCdmTypeException{
595
        return getRankByLatinNameOrIdInVoc(strRank, false);
596
    }
597

    
598
    /**
599
     * Returns the rank identified through a label or the identifier within the vocabulary
600
     * for a given nomenclatural code.
601
     * Preliminary implementation for BotanicalNameParser.
602
     *
603
     * @param	strRank	the string identifying the rank
604
     * @param   nc      the nomenclatural code
605
     * @return  		the rank
606
     */
607
    public static Rank getRankByLatinNameOrIdInVoc(String strRank, NomenclaturalCode nc) throws UnknownCdmTypeException{
608
        return getRankByLatinNameOrIdInVoc(strRank, nc, false);
609
    }
610

    
611
    // TODO
612
    // Preliminary implementation for BotanicalNameParser.
613
    // not yet complete
614
    /**
615
     * Returns the rank identified through a label or the identifier within the vocabulary.
616
     * Preliminary implementation for BotanicalNameParser.
617
     *
618
     * @param	strRank	the string identifying the rank
619
     * @param 	useUnknown 	if true the rank UNKNOWN_RANK is returned if the abbrev is
620
     * 			unknown or not yet implemented
621
     * @return  		the rank
622
     */
623
    public static Rank getRankByLatinNameOrIdInVoc(String strRank, boolean useUnknown) throws UnknownCdmTypeException{
624
        try {
625
            strRank = strRank.replace("prol.", "proles");
626
            return getRankByIdInVoc(strRank);
627
        } catch (UnknownCdmTypeException e) {
628
            return getRankByLatinName(strRank, useUnknown);
629
        }
630
    }
631

    
632
    // TODO
633
    // Preliminary implementation for BotanicalNameParser.
634
    // not yet complete
635
    /**
636
     * Returns the rank identified through a label or the identifier within the vocabulary.
637
     * Preliminary implementation for BotanicalNameParser.
638
     *
639
     * @param	strRank	the string identifying the rank
640
     * @param   nc      the nomenclatural code
641
     * @param 	useUnknown 	if true the rank UNKNOWN_RANK is returned if the abbrev is
642
     * 			unknown or not yet implemented
643
     * @return  		the rank
644
     */
645
    public static Rank getRankByLatinNameOrIdInVoc(String strRank, NomenclaturalCode nc, boolean useUnknown)
646
            throws UnknownCdmTypeException{
647
        try {
648
            return getRankByIdInVoc(strRank, nc);
649
        } catch (UnknownCdmTypeException e) {
650
            return getRankByLatinName(strRank, nc, useUnknown);
651
        }
652
    }
653

    
654
    /**
655
     * Returns the rank identified through the vocabulary identifier.
656
     * Preliminary implementation for BotanicalNameParser.<BR>
657
     * Note: For abbrev = "[unranked]" the result is undefined.
658
     * It maybe the infrageneric unranked or the infraspecific unranked.
659
     * You need to define by context which one is correct.
660
     *
661
     * @param	abbrev	the string for the name abbreviation
662
     * @return  		the rank
663
     */
664
    public static Rank getRankByIdInVoc(String abbrev) throws UnknownCdmTypeException{
665
        return getRankByIdInVoc(abbrev, false);
666
    }
667

    
668
    /**
669
     * Returns the rank identified through an abbreviated name for a given nomenclatural code.
670
     * See also {@link #getRankByIdInVoc(String, boolean)}
671
     *
672
     * @param	abbrev	the string for the name abbreviation
673
     * @param	nc	    the nomenclatural code
674
     * @return  		the rank
675
     */
676
    public static Rank getRankByIdInVoc(String abbrev, NomenclaturalCode nc) throws UnknownCdmTypeException{
677
        return getRankByIdInVoc(abbrev, nc, false);
678
    }
679

    
680
    // TODO
681
    // Preliminary implementation for BotanicalNameParser.
682
    // not yet complete
683
    /**
684
     * Returns the rank identified through an abbreviated representation.
685
     * At the moment it uses the English abbreviations (being Latin because
686
     * we do not have Latin representations yet.
687
     * TODO
688
     * If no according abbreviation is available it throws either an UnknownCdmTypeException
689
     * or an #Rank.UNKNOWN() object depending on the useUnknown flag.
690
     *
691
     * @param	idInVoc		the string for the name abbreviation
692
     * @param 	useUnknown 	if true the rank UNKNOWN_RANK is returned if the abbrev is
693
     * 			unknown or not yet existent
694
     * @return  the rank
695
     */
696
    public static Rank getRankByIdInVoc(String idInVoc, boolean useUnknown) throws UnknownCdmTypeException{
697
        Rank result = null;
698
        if (idInVoc == null){
699
            throw new NullPointerException("idInVoc is NULL in getRankByIdInVoc");
700
        }
701
        if (isBlank(idInVoc)){
702
            //handle empty idInVoc as unknown
703
            idInVoc = "oijas34\u0155";
704
        }
705
        if (idInVocMap == null){
706
            return null;
707
        }
708
        idInVoc = normalizeSectionAndSubsection(idInVoc);
709
        idInVoc = normalizeSubgen(idInVoc);
710
        idInVoc = normalizeSpecialForm(idInVoc);
711
        idInVoc = normalizeSsp(idInVoc);
712
        idInVoc = normalizeForma(idInVoc);
713
        UUID uuid = idInVocMap.get(idInVoc);
714
        if (uuid != null ){
715
            result = getTermByUuid(uuid);
716
        }
717
        if (result != null){
718
            return result;
719
        }else {
720
            if (idInVoc == null){
721
                idInVoc = "(null)";
722
            }
723
            if (useUnknown){
724
                logger.info("Unknown rank name: " + idInVoc + ". Rank 'UNKNOWN_RANK' created instead");
725
                return Rank.UNKNOWN_RANK();
726
            }else{
727
                throw new UnknownCdmTypeException("Unknown rank abbreviation: " + idInVoc);
728
            }
729
        }
730
    }
731

    
732
    private static String normalizeSectionAndSubsection(String idInVoc) {
733
        if (idInVoc.equals("sect.")){
734
            return "sect.(bot.)";
735
        }else if (idInVoc.equals("subsect.")){
736
            return "subsect.(bot.)";
737
        }
738
        return idInVoc;
739
    }
740

    
741
    private static String normalizeSubgen(String idInVoc) {
742
        if (idInVoc.equals("subgen.")){
743
            return "subg.";
744
        }
745
        return idInVoc;
746
    }
747

    
748
    private static String normalizeSpecialForm(String idInVoc) {
749
        if (idInVoc.equals("f.sp.") || idInVoc.equals("f. sp.")){
750
            return "f.spec.";
751
        }
752
        return idInVoc;
753
    }
754

    
755
    private static String normalizeForma(String idInVoc) {
756
        if (idInVoc.equals("forma")){
757
            return "f.";
758
        }
759
        return idInVoc;
760
    }
761

    
762
    private static String normalizeSsp(String idInVoc) {
763
        if (idInVoc.equals("ssp.") && !idInVocMap.containsKey("ssp.") && idInVocMap.containsKey("subsp.")){
764
            return "subsp.";
765
        }
766
        return idInVoc;
767
    }
768

    
769
    // TODO
770
    // Preliminary implementation to cover Botany and Zoology.
771
    /**
772
     * Returns the rank identified through an abbreviated name for a given nomenclatural code.
773
     * Preliminary implementation for ICBN and ICZN.
774
     * See also {@link #getRankByIdInVoc(String, boolean)}
775

    
776
     *
777
     * @param	abbrev		the string for the name abbreviation
778
     * @param	nc	        the nomenclatural code
779
     * @param 	useUnknown 	if true the rank UNKNOWN_RANK is returned if the abbrev is
780
     * 			unknown or not yet implemented
781
     * @return  the rank
782
     */
783
    public static Rank getRankByIdInVoc(String abbrev, NomenclaturalCode nc, boolean useUnknown)
784
            throws UnknownCdmTypeException{
785

    
786
        if (nc != null && nc.equals(NomenclaturalCode.ICZN)) {
787
            if (abbrev != null){
788
                if (abbrev.equalsIgnoreCase("sect.")) {
789
                    return Rank.SECTION_ZOOLOGY();
790
                } else if (abbrev.equalsIgnoreCase("subsect.")) {
791
                    return Rank.SUBSECTION_ZOOLOGY();
792
                }
793
            }
794
        }else if (nc != null && nc.equals(NomenclaturalCode.ICNAFP)) {
795
            if (abbrev != null){
796
                if (abbrev.equalsIgnoreCase("sect.")) {
797
                    return Rank.SECTION_BOTANY();
798
                } else if (abbrev.equalsIgnoreCase("subsect.")) {
799
                    return Rank.SUBSECTION_BOTANY();
800
                }
801
            }
802
        }
803
        return getRankByIdInVoc(abbrev, useUnknown);
804
    }
805

    
806
    // TODO
807
    // Preliminary implementation for BotanicalNameParser.
808
    // not yet complete
809
    /**
810
     * Returns the rank identified through a name.
811
     * Preliminary implementation for BotanicalNameParser.
812
     *
813
     * @param	rankName	the string for the name of the rank
814
     * @return  			the rank
815
     */
816
    public static Rank getRankByLatinName(String rankName) throws UnknownCdmTypeException{
817
        return getRankByLatinName(rankName, false);
818
    }
819

    
820

    
821
    // TODO
822
    // Preliminary implementation for ICBN and ICZN.
823
    // not yet complete
824
    /**
825
     * Returns the rank identified through a name for a given nomenclatural code.
826
     * Preliminary implementation for ICBN and ICZN.
827
     *
828
     * @param	rankName	the string for the name of the rank
829
     * @param	nc	        the nomenclatural code
830
     * @return  			the rank
831
     */
832
    public static Rank getRankByLatinName(String rankName, NomenclaturalCode nc) throws UnknownCdmTypeException{
833
        return getRankByLatinName(rankName, nc, false);
834
    }
835

    
836
    /**
837
     * Returns the rank identified through a name.
838
     * Preliminary implementation for BotanicalNameParser.
839
     * TODO At the moment we do not have Latin representations yet.
840
     *
841
     * @param	rankName	the string for the name of the rank
842
     * @param 	useUnknown 	if true the rank UNKNOWN_RANK is returned if the rank name is
843
     * 			unknown or not yet implemented
844
     * @return  			the rank
845
     */
846
    public static Rank getRankByLatinName(String rankName, boolean useUnknown)
847
            throws UnknownCdmTypeException{
848
        if (rankName.equalsIgnoreCase("Regnum")){ return Rank.KINGDOM();
849
        }else if (rankName.equalsIgnoreCase("Subregnum")){ return Rank.SUBKINGDOM();
850
        }else if (rankName.equalsIgnoreCase("Phylum")){ return Rank.PHYLUM();
851
        }else if (rankName.equalsIgnoreCase("Subphylum")){ return Rank.SUBPHYLUM();
852
        }else if (rankName.equalsIgnoreCase("Divisio")){ return Rank.DIVISION();
853
        }else if (rankName.equalsIgnoreCase("Subdivisio")){ return Rank.SUBDIVISION();
854
        }else if (rankName.equalsIgnoreCase("Classis")){ return Rank.CLASS();
855
        }else if (rankName.equalsIgnoreCase("Subclassis")){ return Rank.SUBCLASS();
856
        }else if (rankName.equalsIgnoreCase("Superordo")){ return Rank.SUPERORDER();
857
        }else if (rankName.equalsIgnoreCase("Ordo")){ return Rank.ORDER();
858
        }else if (rankName.equalsIgnoreCase("Subordo")){ return Rank.SUBORDER();
859
        }else if (rankName.equalsIgnoreCase("Familia")){ return Rank.FAMILY();
860
        }else if (rankName.equalsIgnoreCase("Subfamilia")){ return Rank.SUBFAMILY();
861
        }else if (rankName.equalsIgnoreCase("Tribus")){ return Rank.TRIBE();
862
        }else if (rankName.equalsIgnoreCase("Subtribus")){ return Rank.SUBTRIBE();
863
        }else if (rankName.equalsIgnoreCase("Genus")){ return Rank.GENUS();
864
        }else if (rankName.equalsIgnoreCase("Subgenus")){ return Rank.SUBGENUS();
865
        }else if (rankName.equalsIgnoreCase("Sectio")){ return Rank.SECTION_BOTANY();
866
        }else if (rankName.equalsIgnoreCase("Subsectio")){ return Rank.SUBSECTION_BOTANY();
867
        }else if (rankName.equalsIgnoreCase("Series")){ return Rank.SERIES();
868
        }else if (rankName.equalsIgnoreCase("Subseries")){ return Rank.SUBSERIES();
869
        }else if (rankName.equalsIgnoreCase("Aggregate")){ return Rank.SPECIESAGGREGATE();
870
        }else if (rankName.equalsIgnoreCase("Speciesgroup")){ return Rank.SPECIESGROUP();
871
        }else if (rankName.equalsIgnoreCase("Species")){ return Rank.SPECIES();
872
        }else if (rankName.equalsIgnoreCase("Subspecies")){ return Rank.SUBSPECIES();
873
        }else if (rankName.equalsIgnoreCase("Convarietas")){ return Rank.CONVAR();
874
        }else if (rankName.equalsIgnoreCase("Varietas")){ return Rank.VARIETY();
875
        }else if (rankName.equalsIgnoreCase("Subvarietas")){ return Rank.SUBVARIETY();
876
        }else if (rankName.equalsIgnoreCase("Forma")){ return Rank.FORM();
877
        }else if (rankName.equalsIgnoreCase("Subforma")){ return Rank.SUBFORM();
878
        }else if (rankName.equalsIgnoreCase("Forma spec.")){ return Rank.SPECIALFORM();
879
        }else if (rankName.equalsIgnoreCase("tax.infragen.")){ return Rank.INFRAGENERICTAXON();
880
        }else if (rankName.equalsIgnoreCase("tax.infrasp.")){ return Rank.INFRASPECIFICTAXON();
881
        // old ranks
882
        }else if (rankName.equalsIgnoreCase("proles")){ return Rank.PROLES();
883
        }else if (rankName.equalsIgnoreCase("race")){ return Rank.RACE();
884
        }else if (rankName.equalsIgnoreCase("sublusus")){ return Rank.SUBLUSUS();
885

    
886
        }else if (rankName.equalsIgnoreCase("taxon")){ return Rank.INFRASPECIFICTAXON(); //to create the name put 'taxon' and the infraspeciesepi to the field unnamed namephrase
887

    
888
        }else{
889
            if (rankName == null){
890
                rankName = "(null)";  //see NPE above
891
            }
892
            if (useUnknown){
893
                if (logger.isInfoEnabled()){logger.info("Unknown rank name: " + rankName+". Rank 'UNKNOWN_RANK' created instead");}
894
                return Rank.UNKNOWN_RANK();
895
            }else{
896
                throw new UnknownCdmTypeException("Unknown rank name: " + rankName);
897
            }
898
        }
899
    }
900

    
901
    /**
902
     * Defines the rank according to the English name.
903
     * @param rankName English rank name.
904
     * @param nc Defines the handling of the section and subsection ranks. These are in different orders depending on the
905
     * nomenclatural code.
906
     * @param useUnknown if true, the "Unknown" rank is returned as a placeholder.
907
     * @return
908
     * @throws UnknownCdmTypeException never thrown if useUnknown is true
909
     */
910
    public static Rank getRankByEnglishName(String rankName, NomenclaturalCode nc, boolean useUnknown) throws UnknownCdmTypeException{
911
        Rank result = null;
912
        if (rankName == null){
913
            throw new NullPointerException("Abbrev is NULL in getRankByAbbreviation");
914
        }
915
        if (labelMap == null){
916
            return null;
917
        }
918
        //handle section and subsection (not unique representations)
919
        if (rankName.equalsIgnoreCase("Section")){
920
            if (nc != null && nc.equals(NomenclaturalCode.ICZN)){	return Rank.SECTION_ZOOLOGY();
921
            }else if (nc != null && nc.equals(NomenclaturalCode.ICNAFP)){return Rank.SECTION_BOTANY();
922
            }else{
923
                String errorWarning = "Section is only defined for ICZN and ICNAFP at the moment but here needed for " + ((nc == null)? "(null)": nc.toString());
924
                logger.warn(errorWarning);
925
                throw new UnknownCdmTypeException (errorWarning);
926
            }
927
        }else if (rankName.equalsIgnoreCase("Subsection")){
928
            if (nc != null && nc.equals(NomenclaturalCode.ICZN)){ return Rank.SUBSECTION_ZOOLOGY();
929
            }else if (nc != null && nc.equals(NomenclaturalCode.ICNAFP)){ return Rank.SUBSECTION_BOTANY();
930
            }else{
931
                String errorWarning = "Subsection is only defined for ICZN and ICBN at the moment but here needed for " + ((nc == null)? "(null)": nc.toString());
932
                logger.warn(errorWarning);
933
                throw new UnknownCdmTypeException (errorWarning);
934
            }
935
        }
936

    
937
        rankName = rankName.toLowerCase();
938

    
939
        UUID uuid = labelMap.get(rankName);
940
        if (uuid != null ){
941
            result = getTermByUuid(uuid);
942
        }
943
        if (result != null){
944
            return result;
945
        }else {
946
            if (rankName == null){
947
                rankName = "(null)";
948
            }
949
            if (useUnknown){
950
                if (logger.isInfoEnabled()){logger.info("Unknown rank name: " + rankName + ". Rank 'UNKNOWN_RANK' created instead");}
951
                return Rank.UNKNOWN_RANK();
952
            }else{
953
                throw new UnknownCdmTypeException("Unknown rank: " + rankName);
954
            }
955
        }
956
    }
957

    
958
    /**
959
     * Preliminary implementation for name parser.
960
     */
961
    public static Rank getRankByLatinName(String rankName, NomenclaturalCode nc, boolean useUnknown)
962
        throws UnknownCdmTypeException {
963

    
964
        if (nc.equals(NomenclaturalCode.ICZN)) {
965
            if (rankName.equalsIgnoreCase("Sectio")) { return Rank.SECTION_ZOOLOGY();
966
            }else if (rankName.equalsIgnoreCase("Subsectio")) { return Rank.SUBSECTION_ZOOLOGY();
967
            }
968
        }
969
        return getRankByLatinName(rankName, useUnknown);
970
    }
971

    
972
    /**
973
     * Returns the abbreviated rank name for <i>this</i> rank according to the English representation
974
     * abbreviated label.
975
     * TODO Needs to be changed to Latin as soon as Latin representations are available.
976
     *
977
     * @return	the abbreviation string for <i>this</i> rank
978
     */
979
    public String getAbbreviation(){
980
        Language language = Language.getLanguageFromUuid(Language.uuidEnglish);
981
        String result = this.getRepresentation(language).getAbbreviatedLabel();
982
        if (result== null) {
983
            logger.warn("Abbreviation for rank " + this.toString() +  " not yet implemented");
984
            return "no abbreviation available.";
985
        }else{
986
            return result;
987
        }
988
    }
989

    
990
    @Transient
991
    public String getInfraGenericMarker() throws UnknownCdmTypeException{
992
        String result = null;
993
        if (! this.isInfraGeneric()){
994
            throw new IllegalStateException("An infrageneric marker is only available for an infrageneric rank but was asked for rank: " + this.toString());
995
        }else{
996
            result = this.getAbbreviation();
997
        }
998
        if (result == null){
999
            throw new UnknownCdmTypeException("Abbreviation for rank unknown: " + this.toString());
1000
        }
1001
        return result;
1002
    }
1003

    
1004

    
1005

    
1006
    @Override
1007
    public Rank readCsvLine(Class<Rank> termClass, List<String> csvLine, TermType termType, Map<UUID, DefinedTermBase> terms, boolean abbrevAsId) {
1008
        Rank rank = super.readCsvLine(termClass, csvLine, termType, terms, abbrevAsId);
1009
        RankClass rankClass = RankClass.getByKey(csvLine.get(5));
1010
        assert rankClass != null: "XXXXXXXXXXXXXXXXXXXXX  Rank class must not be null: " + csvLine ;
1011
        rank.setRankClass(rankClass);
1012
        return rank;
1013
    }
1014

    
1015
    @Override
1016
    protected void setDefaultTerms(TermVocabulary<Rank> termVocabulary) {
1017
        termMap = new HashMap<UUID, Rank>();
1018
        for (Rank term : termVocabulary.getTerms()){
1019
            termMap.put(term.getUuid(), term);
1020
            addRank(term);
1021
        }
1022
    }
1023

    
1024
    // FIXME:Remoting This is a ugly hack and need to be removed
1025
    // once the static initialisation is refactored
1026
    public static void initDefaultTerms() {
1027
        TermVocabulary<Rank> vocabulary = getTermByUuid(uuidKingdom).getVocabulary();
1028
        if(idInVocMap != null) {
1029
            idInVocMap.clear();
1030
        }
1031
        (new Rank()).setDefaultTerms(vocabulary);
1032
    }
1033

    
1034
    private void addRank(Rank rank) {
1035
        if (rank == null){
1036
            logger.warn("rank is NULL");
1037
            return;
1038
        }
1039
        if (rank.getUuid().equals(uuidSectionZoology) || rank.getUuid().equals(uuidSubsectionZoology )){
1040
            //sect./subsect. is used for botanical sections, see also #getRankByAbbreviation(String, NomenclaturalCode, boolean)
1041
            return;
1042
        }
1043
        Language lang = Language.DEFAULT();  //TODO should be Latin but at the moment we have only English representations
1044
        Representation representation = rank.getRepresentation(lang);
1045
        String abbrevLabel = representation.getAbbreviatedLabel();
1046
        String label = representation.getLabel();
1047

    
1048
        //initialize maps
1049
        if (idInVocMap == null){
1050
            idInVocMap = new HashMap<>();
1051
        }
1052
        if (labelMap == null){
1053
            labelMap = new HashMap<>();
1054
        }
1055
        labelMap.put(label.toLowerCase(), rank.getUuid());
1056
        //add to map
1057
        if (isBlank(abbrevLabel)){
1058
            if (logger.isDebugEnabled()){logger.info("Abbreviated label for rank is NULL or empty.Can't add rank to abbrevLabel map: " + CdmUtils.Nz(rank.getLabel()));}
1059
        }else{
1060
            idInVocMap.put(abbrevLabel, rank.getUuid());
1061
        }
1062
    }
1063

    
1064

    
1065
    /**
1066
     * It is necessary to skip the vocabulary check, otherwise we would have
1067
     * problems in some CacheStrategies, due to uninitialized Vocabularies.
1068
     *
1069
     * @see eu.etaxonomy.cdm.model.term.OrderedTermBase#compareTo(eu.etaxonomy.cdm.model.term.OrderedTermBase)
1070
     */
1071
    @Override
1072
    public int compareTo(Rank orderedTerm) {
1073
        return performCompareTo(orderedTerm, true);
1074
    }
1075

    
1076
}
(26-26/39)