Project

General

Profile

Download (27.4 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

    
10
package eu.etaxonomy.cdm.model.name;
11

    
12

    
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

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

    
26
import org.apache.logging.log4j.LogManager;
27
import org.apache.logging.log4j.Logger;
28
import org.hibernate.annotations.Type;
29
import org.hibernate.envers.Audited;
30

    
31
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
32
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
33
import eu.etaxonomy.cdm.model.term.TermType;
34
import eu.etaxonomy.cdm.model.term.TermVocabulary;
35

    
36
/**
37
 * The class representing the categories of {@link NameRelationship taxon name relationships} between
38
 * two {@link TaxonName taxon names}. These name relationship types are
39
 * based on the concrete {@link NomenclaturalCode nomenclatural code} governing
40
 * the taxon names involved in the name relationship or on decisions taken by
41
 * the competent authorities; they do not depend on the use made of these
42
 * taxon names in a particular reference or in a particular taxonomic treatment.
43
 * Most relationships are to be understood as 'is .... of': for instance
44
 * <i>Linum radiola</i> L. is a replaced synonym of <i>Radiola linoides</i> Roth or
45
 * <i>Astragalus rhizanthus</i> Boiss. is a later homonym of
46
 * <i>Astragalus rhizanthus</i> Royle.
47
 * <P>
48
 * A standard (ordered) list of name relationship type instances will be
49
 * automatically created as the project starts. But this class allows to extend
50
 * this standard list by creating new instances of additional name relationship
51
 * types if needed.
52
 * <P>
53
 * This class corresponds partially to: <ul>
54
 * <li> TaxonRelationshipTerm and NomenclaturalNoteTypeTerm according to the TDWG ontology
55
 * <li> RelationshipType and NomenclaturalNoteType according to the TCS
56
 * </ul>
57
 *
58
 * @author m.doering
59
 * @since 08-Nov-2007 13:06:38
60
 */
61
@XmlAccessorType(XmlAccessType.FIELD)
62
@XmlType(name = "NameRelationshipType", propOrder = {
63
    "nomenclaturalStanding",
64
    "nomenclaturalStandingInverse"}
65
)
66
@Entity
67
//@Indexed disabled to reduce clutter in indexes, since this type is not used by any search
68
//@Indexed(index = "eu.etaxonomy.cdm.model.term.DefinedTermBase")
69
@Audited
70
public class NameRelationshipType extends RelationshipTermBase<NameRelationshipType>
71
        implements INomenclaturalStanding {
72

    
73
    private static final long serialVersionUID = 8504916205254159334L;
74
	static Logger logger = LogManager.getLogger(NameRelationshipType.class);
75

    
76
	private static final UUID uuidOrthographicVariant = UUID.fromString("eeaea868-c4c1-497f-b9fe-52c9fc4aca53");
77
	private static final UUID uuidMisspelling = UUID.fromString("c6f9afcb-8287-4a2b-a6f6-4da3a073d5de");
78
	private static final UUID uuidEmendation = UUID.fromString("6e23ad45-3f2a-462b-ad87-d2389cd6e26c");
79
	private static final UUID uuidLaterHomonym = UUID.fromString("80f06f65-58e0-4209-b811-cb40ad7220a6");
80
	private static final UUID uuidTreatedAsLaterHomonym = UUID.fromString("2990a884-3302-4c8b-90b2-dfd31aaa2778");
81
	private static final UUID uuidAlternativeName = UUID.fromString("049c6358-1094-4765-9fae-c9972a0e7780");
82
	private static final UUID uuidBasionym = UUID.fromString("25792738-98de-4762-bac1-8c156faded4a");
83
	private static final UUID uuidReplacedSynonym = UUID.fromString("71c67c38-d162-445b-b0c2-7aba56106696");
84
	private static final UUID uuidConservedAgainst = UUID.fromString("e6439f95-bcac-4ebb-a8b5-69fa5ce79e6a");
85
	private static final UUID uuidValidatedByName = UUID.fromString("a176c9ad-b4c2-4c57-addd-90373f8270eb");
86
	private static final UUID uuidLaterValidatedByName = UUID.fromString("a25ee4c1-863a-4dab-9499-290bf9b89639");
87
	private static final UUID uuidBlockingNameFor = UUID.fromString("1dab357f-2e12-4511-97a4-e5153589e6a6");
88
	private static final UUID uuidAvoidsHomonymOf = UUID.fromString("c7d59ab9-a8c6-4645-a990-04c698f2c123");
89
	private static final UUID uuidLaterIsonym = UUID.fromString("29ab238d-598d-45b9-addd-003cf39ccc3e");
90
	private static final UUID uuidNonUnspecific = UUID.fromString("78360e2a-159d-4e2f-893e-8666805840fa");
91

    
92

    
93
	public static NameRelationshipType NewInstance(String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
94
		return new NameRelationshipType(term, label, labelAbbrev, symmetric, transitive);
95
	}
96

    
97
    /**
98
     * The {@link NomenclaturalStanding nomenclatural standing} of a name status type for
99
     * the "from"-name in a name relationship.
100
     * It is usually needed for correct formatting of a name in a synonymy by e.g. using
101
     * a dash instead of equal sign in front.
102
     */
103
    @XmlAttribute(name ="NomenclaturalStanding")
104
    @NotNull
105
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
106
        parameters = {@org.hibernate.annotations.Parameter(name="enumClass", value="eu.etaxonomy.cdm.model.name.NomenclaturalStanding")}
107
    )
108
    @Audited
109
	private NomenclaturalStanding nomenclaturalStanding;
110

    
111
    /**
112
     * The {@link NomenclaturalStanding nomenclatural standing} of a name status type for
113
     * the "to"-name in a name relationship.
114
     * It is usually needed for correct formatting of a name in a synonymy by e.g. using
115
     * a dash instead of equal sign in front.
116
     */
117
    @XmlAttribute(name ="NomenclaturalStanding")
118
    @NotNull
119
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
120
        parameters = {@org.hibernate.annotations.Parameter(name="enumClass", value="eu.etaxonomy.cdm.model.name.NomenclaturalStanding")}
121
    )
122
    @Audited
123
    private NomenclaturalStanding nomenclaturalStandingInverse;
124

    
125
	protected static Map<UUID, NameRelationshipType> termMap = null;
126

    
127
	protected static NameRelationshipType findTermByUuid(UUID uuid){
128
		if (termMap == null || termMap.isEmpty()){
129
		    return getTermByClassAndUUID(NameRelationshipType.class, uuid);
130
		} else {
131
		    return termMap.get(uuid);
132
		}
133
	}
134

    
135
//********************************** Constructor *********************************/
136

    
137
  	//for hibernate use only
138
  	@Deprecated
139
  	protected  NameRelationshipType() {
140
		super(TermType.NameRelationshipType);
141
	}
142

    
143
	/**
144
	 * Class constructor: creates an additional name relationship type
145
	 * instance with a description, a label, a label abbreviation and the flags
146
	 * indicating whether <i>this</i> new name relationship type is symmetric and/or
147
	 * transitive.
148
	 *
149
	 * @param	term  		 the string (in the default language) describing the
150
	 * 						 new name relationship type to be created
151
	 * @param	label  		 the string identifying the new name relationship
152
	 * 						 type to be created
153
	 * @param	labelAbbrev  the string identifying (in abbreviated form) the
154
	 * 						 new name relationship type to be created
155
	 * @param	symmetric	 the boolean indicating whether the new name
156
	 * 						 relationship type to be created is symmetric
157
	 * @param	transitive	 the boolean indicating whether the new name
158
	 * 						 relationship type to be created is transitive
159
	 * @see 				 #NameRelationshipType()
160
	 */
161
	private NameRelationshipType(String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
162
		super(TermType.NameRelationshipType, term, label, labelAbbrev, symmetric, transitive);
163
	}
164

    
165
// ************************ GETTER / SETTER ******************/
166

    
167
    public NomenclaturalStanding getNomenclaturalStanding() {
168
        return nomenclaturalStanding;
169
    }
170
    public void setNomenclaturalStanding(NomenclaturalStanding nomenclaturalStanding) {
171
        this.nomenclaturalStanding = nomenclaturalStanding;
172
    }
173

    
174
    public NomenclaturalStanding getNomenclaturalStandingInverse() {
175
        return nomenclaturalStandingInverse;
176
    }
177
    public void setNomenclaturalStandingInverse(NomenclaturalStanding nomenclaturalStandingInverse) {
178
        this.nomenclaturalStandingInverse = nomenclaturalStandingInverse;
179
    }
180

    
181
//************************** METHODS ********************************
182

    
183
	@Override
184
	public void resetTerms(){
185
		termMap = null;
186
	}
187

    
188
    @Override
189
    @Transient
190
    public boolean isInvalidExplicit() {
191
        return this.nomenclaturalStanding.isInvalidExplicit();
192
    }
193
    @Transient
194
    public boolean isInvalidExplicitInverse() {
195
        return this.nomenclaturalStandingInverse.isInvalidExplicit();
196
    }
197

    
198
    @Override
199
    @Transient
200
    public boolean isIllegitimate() {
201
        return this.nomenclaturalStanding.isLegitimate();
202
    }
203
    @Transient
204
    public boolean isIllegitimateInverse() {
205
        return this.nomenclaturalStandingInverse.isLegitimate();
206
    }
207

    
208
    @Override
209
    @Transient
210
    public boolean isValidExplicit() {
211
        return this.nomenclaturalStanding.isValidExplicit();
212
    }
213
    @Transient
214
    public boolean isValidExplicitInverse() {
215
        return this.nomenclaturalStandingInverse.isValidExplicit();
216
    }
217

    
218
    @Override
219
    @Transient
220
    public boolean isNoStatus() {
221
        return this.nomenclaturalStanding.isNoStatus();
222
    }
223
    @Transient
224
    public boolean isNoStatusInverse() {
225
        return this.nomenclaturalStandingInverse.isNoStatus();
226
    }
227

    
228
    @Override
229
    @Transient
230
    public boolean isInvalid() {
231
        return this.nomenclaturalStanding.isInvalid();
232
    }
233
    @Transient
234
    public boolean isInvalidInverse() {
235
        return this.nomenclaturalStandingInverse.isInvalid();
236
    }
237

    
238
    @Override
239
    @Transient
240
    public boolean isLegitimate() {
241
        //later homonym, treated as later homonym, ...
242
        return this.nomenclaturalStanding.isLegitimate();
243
    }
244
    @Transient
245
    public boolean isLegitimateInverse() {
246
        return this.nomenclaturalStandingInverse.isLegitimate();
247
    }
248

    
249
    @Override
250
    @Transient
251
    public boolean isValid() {
252
        return this.nomenclaturalStanding.isValid();
253
    }
254
    @Transient
255
    public boolean isValidInverse() {
256
        return this.nomenclaturalStandingInverse.isValid();
257
    }
258

    
259
    @Override
260
    @Transient
261
    public boolean isDesignationOnly(){
262
        return this.nomenclaturalStanding.isDesignationOnly();
263
    }
264
    @Transient
265
    public boolean isDesignationOnlyInverse(){
266
        return this.nomenclaturalStandingInverse.isDesignationOnly();
267
    }
268

    
269
	@Transient
270
	protected boolean isRelationshipType(NameRelationshipType type) {
271
	    if (type == null){
272
	        throw new IllegalStateException("NameRelationships have not been initialized yet. Please initialize DefinedTerms first");
273
	    }
274
	    return this.equals(type);
275
	}
276

    
277
	@Transient
278
	public boolean isBasionymRelation(){
279
        return isRelationshipType(BASIONYM());
280
	}
281

    
282
	@Transient
283
	public boolean isReplacedSynonymRelation(){
284
        return isRelationshipType(REPLACED_SYNONYM());
285
	}
286

    
287

    
288
	/**
289
	 * Returns the "orthographic variant" name relationship type. The first
290
	 * {@link TaxonName taxon name} involved in such a relationship is an
291
	 * orthographic variant of the second taxon name. The two {@link TaxonName taxon names}
292
	 * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
293
	 * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
294
	 * must be almost identical (so one usually does not differentiate them).<BR>
295
	 * For instance <i>Angelica silvestris</i> L. is an orthographic variant of
296
	 * <i>Angelica sylvestris</i> L.
297
	 * <BR>
298
	 * This type is symmetric and transitive but usually orthographic
299
	 * variant relationships should be organized in a star schema with the (only!)
300
	 * correct variant in the middle and other variants pointing to it.
301
	 * <BR>
302
	 * ICNAFP: Art. 61.2. "For the purpose of this Code, orthographical variants are the various spelling,
303
	 * compounding, and inflectional forms of a name or its final epithet (including typographical errors)
304
	 * when only one nomenclatural type is involved."<BR>
305
	 * Art. 61.1. "Only one orthographical variant of any one name is treated as validly published:
306
	 * the form that appears in the original publication (but see Art. 6.10), except
307
	 *
308
	 * @see #MISSPELLING()
309
	 */
310
	public static final NameRelationshipType ORTHOGRAPHIC_VARIANT(){
311
		  return findTermByUuid(uuidOrthographicVariant);
312
	}
313

    
314
	/**
315
	 * Returns the "misspelling" name relationship type. The first
316
	 * {@link TaxonName taxon name} involved in such a relationship is a
317
	 * misspelling of the second taxon name. The two {@link TaxonName taxon names}
318
	 * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
319
	 * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
320
	 * must be almost identical (so one usually does not differentiate them).<BR>
321
	 * For instance <i>Anhelica silvestris</i> L. is a misspelling of
322
	 * <i>Angelica silvestris</i> L.<BR>
323
	 * A misspelling is always accicentally (not on purpose). Therefore misspellings are overlapping with
324
	 * {@link #ORTHOGRAPHIC_VARIANT orthographic variants} (in an old version of this documentation they
325
	 * were called a subset but it seems doubtful that certain typos are orth. vars. according to Art. 61.2 (ICNAFP).
326
     * and are complementary to {@link #EMENDATION() emendations}.
327
	 * This type is symmetric and transitive but usually the misspelling relationships should be organized
328
	 * in a star schema with the correct variant in the middle and the misspellings pointing to it.<BR>
329
	 * Misspellings are not handled in the ICNAFP.
330
	 *
331
	 * @see https://dev.e-taxonomy.eu/redmine/issues/9386 for discussion on symmetry of this relation
332
	 *
333
	 * @see #ORTHOGRAPHIC_VARIANT()
334
	 */
335
	public static final NameRelationshipType MISSPELLING(){
336
		  return findTermByUuid(uuidMisspelling);
337
	}
338
	/**
339
	 * Returns the "emendation" name relationship type. The first
340
	 * {@link TaxonName taxon name} involved in such a relationship is a
341
	 * misspelling of the second taxon name. The two {@link TaxonName taxon names}
342
	 * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
343
	 * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
344
	 * must be almost identical (so one usually does not differentiate them).<BR>
345
	 * For instance <i>Angelica silvestris</i> L. is a emendation of
346
	 * <i>Angelica sylvestris</i> L.<BR>
347
	 * The name corrected by an emendation has originally been used on purpose (not accidentially)
348
	 * Therefore emendations are a subset of {@link #ORTHOGRAPHIC_VARIANT orthographic variants} and are
349
	 * complementary to {@link #MISSPELLING missepllings}. An emendation is always an
350
	 * {@link #ORTHOGRAPHIC_VARIANT orthographic variant}, too.<BR>
351
	 * This type is symmetric and transitive but usually the misspelling relationships should be organized
352
	 * in a star schema with the correct variant in the middle and the misspellings pointing to it.
353
	 *
354
	 * TODO IN ICNAFP Art. 47.1 emendations are used for alterations of the diagnostic characters, this
355
	 * is something completely different. We need to check where the above definition comes from (zoology?)
356
	 */
357
	public static final NameRelationshipType EMENDATION(){
358
		  return findTermByUuid(uuidEmendation);
359
	}
360
	/**
361
	 * Returns the "later homonym" name relationship type. The first
362
	 * {@link TaxonName taxon name} involved in such a relationship should
363
	 * have been published after the second taxon name. The two {@link TaxonName taxon names}
364
	 * involved in such a relationship must belong to different
365
	 * {@link HomotypicalGroup homotypical groups}, have in general different
366
	 * {@link NonViralName#getAuthorshipCache() authorship} and their name parts (excluding infraspecific
367
	 * {@link Rank ranks}) must be (almost) identical, so one could be mistaken for
368
	 * the other one. The first taxon name is "illegitimate" and the second one
369
	 * is "legitimate" (this corresponds to "invalid" and "valid" in case of
370
	 * {@link IZoologicalName zoological names}).<BR>
371
	 * For instance <i>Astragalus rhizanthus</i> Boiss. is a later homonym of
372
	 * <i>Astragalus rhizanthus</i> Royle.<BR>
373
	 * This type is not symmetric but transitive.
374
	 *
375
	 * @see	NomenclaturalStatusType#isIllegitimate()
376
	 * @see	NomenclaturalStatusType#isLegitimate()
377
	 */
378
	public static final NameRelationshipType LATER_HOMONYM(){
379
	  return findTermByUuid(uuidLaterHomonym);
380
	}
381

    
382

    
383
	/**
384
	 * Returns the "treated as later homonym" name relationship type. The first
385
	 * {@link TaxonName taxon name} involved in such a relationship is
386
	 * treated as an homonym although it has been published before the second
387
	 * taxon name. The two taxon names involved must belong to different
388
	 * {@link HomotypicalGroup homotypical groups} and their name parts (excluding
389
	 * {@link Rank#isInfraSpecific() infraspecific ranks} and {@link NonViralName#getAuthorshipCache() authorship}) must be
390
	 * almost identical (so one could be mistaken for the other). The first
391
	 * taxon name is "illegitimate" and the second one is "legitimate" (this
392
	 * corresponds to "invalid" and "valid" in case of {@link IZoologicalName zoological names}).<BR>
393
	 * This type is not symmetric but transitive.
394
	 *
395
	 * @see	#LATER_HOMONYM()
396
	 * @see	NomenclaturalStatusType#isIllegitimate()
397
	 * @see	NomenclaturalStatusType#isLegitimate()
398
	 */
399
	public static final NameRelationshipType TREATED_AS_LATER_HOMONYM(){
400
	  return findTermByUuid(uuidTreatedAsLaterHomonym);
401
	}
402

    
403
	/**
404
	 * Returns the "later isonym" name relationship type where the first
405
	 * {@link TaxonName taxon name} involved has been published after the second taxon name.<BR>
406
	 * In contrast to the {@link #LATER_HOMONYM() later homonym} relationship the two
407
	 * {@link TaxonName taxon names} involved have the type(s) so they belong to the
408
	 * same {@link HomotypicalGroup homotypical groups}. As later homonyms they have in general
409
	 * different {@link NonViralName#getAuthorshipCache() authorship} and their name parts
410
	 * must be (almost) identical, so one could be mistaken for the other one.<BR>
411
	 * Later isonyms are validly published names but with a wrong citation. So there are rather errors
412
	 * then independent names.<BR>
413
	 * Isonyms are handled in Article 6, Note 2 of the ICNAFP (Melbourne Code):
414
	 * <code>When the same name, based on the same type, has been published independently at different
415
	 *  times perhaps by different authors, then only the earliest of these �isonyms� has
416
	 *  nomenclatural status. The name is always to be cited from its original
417
	 *  place of valid publication, and later isonyms may be disregarded (but see Art. 14.15).</code>
418
	 * <BR><BR>
419
	 * See discussion at: <a href=https://dev.e-taxonomy.eu/redmine/issues/2901>#2901</a>
420
	 *
421
	 */
422
	public static final NameRelationshipType LATER_ISONYM(){
423
		return findTermByUuid(uuidLaterIsonym);
424
	}
425

    
426
	/**
427
	 * Returns the "alternative name" name relationship type. Both {@link TaxonName taxon names}
428
	 * involved in such a relationship are family names. The first one is a
429
	 * classical name long in use, in some cases, even before 1753 and is considered as
430
	 * {@link NomenclaturalStatusType#VALID() valid} and also {@link NomenclaturalStatusType#isLegitimate() legitimate}
431
	 * although it does not follow the rules for family names (see Article 18 of
432
	 * the ICBN). An alternative name is typified by the type of the name
433
	 * it is alternative to (so both must belong to the same
434
	 * {@link HomotypicalGroup homotypical group}).<BR>
435
	 * For instance <i>Cruciferae</i> Adans is an alternative name to
436
	 * <i>Brassicaceae</i> Lindl.<BR>
437
	 * This type is neither symmetric nor transitive.
438
	 */
439
	public static final NameRelationshipType ALTERNATIVE_NAME(){
440
	  return findTermByUuid(uuidAlternativeName);
441
	}
442
	/**
443
	 * Returns the "basionym" name relationship type. The first {@link TaxonName taxon name}
444
	 * involved in such a relationship is the "basionym" of the second taxon
445
	 * name. Both taxon names belong to the same {@link HomotypicalGroup homotypical group}).
446
	 * The basionym is the epithet-bringing taxon name (first taxon name
447
	 * ever validly published given to the same {@link Rank#isInfraGeneric() infrageneric}
448
	 * taxon, the epithet of which is the same as in the second taxon name
449
	 * originated through a reclassification).<BR>
450
	 * According to the ICBN the author of the basionym must be mentioned in the
451
	 * later taxon name (by placing it in parentheses before the authority of
452
	 * the new combination). For instance <i>Pinus abies</i> L. is the basionym of
453
	 * <i>Picea abies</i> (L.) H. Karst.<BR>
454
	 * This type is neither symmetric nor transitive.
455
	 */
456
	public static final NameRelationshipType BASIONYM(){
457
	  return findTermByUuid(uuidBasionym);
458
	}
459
	/**
460
	 * Returns the "replaced synonym" name relationship type. The first
461
	 * {@link TaxonName taxon name} involved in such a relationship is the
462
	 * "replaced synonym" of the second taxon name. Both taxon names belong to
463
	 * the same {@link HomotypicalGroup homotypical group}. The replaced synonym is the
464
	 * first taxon name ever validly published given to the same
465
	 * {@link Rank#isInfraGeneric() infrageneric} taxon that is either itself a
466
	 * "later homonym" or the epithet of which could not be used in the new
467
	 * taxon name originated through a reclassification. A new epithet must be
468
	 * proposed if the use of the original epithet leads to an already existing
469
	 * taxon name (for another taxon) or in botany to autonyms (since the ICBN
470
	 * does not allow such names where epithet and genus name are the same).<BR>
471
	 * For instance <i>Spartium biflorum</i> Desf. is the replaced synonym of
472
	 * of <i>Cytisus fontanesii</i> Spach ("novum" taxon name) because at the time
473
	 * of reclassification a taxon name <i>Cytisus biflorum</i> had been already
474
	 * published by L'H�r.<BR>
475
	 * This type is neither symmetric nor transitive.
476
	 *
477
	 * @see #BASIONYM()
478
	 * @see #LATER_HOMONYM()
479
	 * @see NomenclaturalStatusType#NOVUM()
480
	 */
481
	public static final NameRelationshipType REPLACED_SYNONYM(){
482
	  return findTermByUuid(uuidReplacedSynonym);
483
	}
484
	/**
485
	 * Returns the "conserved against" name relationship type. Both {@link TaxonName taxon names}
486
	 * involved in such a relationship belong to the same {@link HomotypicalGroup homotypical group}.
487
	 * Competent authorities decided, regardless of the general
488
	 * nomenclatural rules, to handle the first one as the "legitimate"
489
	 * one and the second taxon name as "illegitimate" (this corresponds to
490
	 * "valid" and "invalid" in case of {@link IZoologicalName zoological names}).<BR>
491
	 * For instance <i>Cephaloziella</i> (Spruce) Schiffn. is conserved against
492
	 * <i>Dichiton</i> Mont.<BR>
493
	 * This type is neither symmetric nor transitive.
494
	 *
495
	 * @see NomenclaturalStatusType#CONSERVED()
496
	 * @see NomenclaturalStatusType#REJECTED()
497
	 * @see NomenclaturalStatusType#isLegitimate()
498
	 * @see NomenclaturalStatusType#isIllegitimate()
499
	 */
500
	public static final NameRelationshipType CONSERVED_AGAINST(){
501
	  return findTermByUuid(uuidConservedAgainst);
502
	}
503
	/**
504
	 * Returns the "validated by name" name relationship type. The two
505
	 * {@link TaxonName taxon names} involved in such a relationship were published
506
	 * in order to define the same taxonomical group but the first
507
	 * (earlier) taxon name was invalidly published whereas the second (later)
508
	 * taxon name is the one which was validly published for the first time.<BR>
509
	 * This type is neither symmetric nor transitive.
510
	 *
511
	 * @see		NomenclaturalStatusType#isInvalid()
512
	 * @see		NomenclaturalStatusType#VALID()
513
	 */
514
	public static final NameRelationshipType VALIDATED_BY_NAME(){
515
	  return findTermByUuid(uuidValidatedByName);
516
	}
517
	/**
518
	 * Returns the "later validated by name" name relationship type. The two
519
	 * {@link TaxonName taxon names} involved in such a relationship were published
520
	 * in order to define the same taxonomical group but the first
521
	 * (earlier) taxon name was invalidly published whereas the second (later)
522
	 * taxon name is the one which was validly published for the first time.<BR>
523
	 * This type is neither symmetric nor transitive.
524
	 *
525
	 * @see		NomenclaturalStatusType#isInvalid()
526
	 * @see		NomenclaturalStatusType#VALID()
527
	 */
528
	public static final NameRelationshipType LATER_VALIDATED_BY_NAME(){
529
	  return findTermByUuid(uuidLaterValidatedByName);
530
	}
531
	/**
532
	 * Returns the "blocking name" name relationship type. The first
533
	 * {@link TaxonName taxon name} involved in such a relationship is the
534
	 * "blocking name" for the second taxon name. Both taxon names belong to
535
	 * different {@link HomotypicalGroup homotypical groups}). The blocking taxon name is the
536
	 * {@link Rank#isInfraGeneric() infrageneric} taxon name, already published at the time of
537
	 * reclassification, which makes illegitim (because of homonymy) the use of
538
	 * the epithet in the second taxon name originated through a reclassification.
539
	 * Therefore a "replaced synonym" name relationship arises.<BR>
540
	 * For instance  <i>Cytisus biflorum</i> L'H�r. is the blocking name for
541
	 * <i>Cytisus fontanesii</i> Spach ("novum" taxon name) when reclassifying
542
	 * <i>Spartium biflorum</i> Desf. from <i>Spartium</i> to <i>Cytisus</i>.<BR>
543
	 * This type is neither symmetric nor transitive.
544
	 *
545
	 * @see #REPLACED_SYNONYM()
546
	 * @see #LATER_HOMONYM()
547
	 * @see NomenclaturalStatusType#NOVUM()
548
	 */
549
	public static final NameRelationshipType BLOCKING_NAME_FOR(){
550
	  return findTermByUuid(uuidBlockingNameFor);
551
	}
552

    
553
	/**
554
	 * This relationship relates the replacement name to the blocking name
555
	 * in a situation where a new combination for a name (replaced synonym)
556
	 * is blocked by a name (blocking name) and therefore a new name (replacement name) is created.
557
	 * @return
558
	 */
559
	public static final NameRelationshipType AVOIDS_HOMONYM_OF() {
560
	   return findTermByUuid(uuidAvoidsHomonymOf);
561
	}
562

    
563
	/**
564
     * Returns the unspecific 'non' name relationship type. Name A in this
565
     * relationship is unspecificly marked as not being name B.
566
     * This relationship should only be used if in the given
567
     * context no further information exists to more specifically
568
     * define what kind of non-relationship is meant.
569
     * <BR>
570
     * When cleaning data this relationship type should be replaced
571
     * by one of the below mentioned more specific relationship types.
572
     *
573
     * This type is neither symmetric nor transitive.
574
     *
575
     * @see     #LATER_HOMONYM()
576
     * @see     #TREATED_AS_LATER_HOMONYM()
577
     * @see     #BLOCKING_NAME_FOR()
578
     */
579
	//#5655, #5640
580
    public static final NameRelationshipType UNSPECIFIC_NON(){
581
      return findTermByUuid(uuidNonUnspecific);
582
    }
583

    
584
	@Override
585
	protected void setDefaultTerms(TermVocabulary<NameRelationshipType> termVocabulary) {
586
		termMap = new HashMap<UUID, NameRelationshipType>();
587
		for (NameRelationshipType term : termVocabulary.getTerms()){
588
			termMap.put(term.getUuid(), term);
589
		}
590
	}
591

    
592
	@Override
593
	public NameRelationshipType readCsvLine(Class<NameRelationshipType> termClass, List<String> csvLine, TermType termType,
594
	        Map<UUID,DefinedTermBase> terms, boolean abbrevAsId) {
595
		NameRelationshipType result = super.readCsvLine(termClass, csvLine, termType, terms, abbrevAsId);
596
		String nomenclaturalStanding = csvLine.get(10).trim();  //not in use yet?
597
        result.setNomenclaturalStanding(NomenclaturalStanding.getByKey(nomenclaturalStanding));
598
        String nomenclaturalStandingInverse = csvLine.get(11).trim();  //not in use yet?
599
        result.setNomenclaturalStandingInverse(NomenclaturalStanding.getByKey(nomenclaturalStandingInverse));
600
        String kindOfString = csvLine.get(12).trim();  //not in use yet?
601
		if (isNotBlank(kindOfString)){
602
			UUID uuidKindOf = UUID.fromString(kindOfString);
603
			DefinedTermBase<?> kindOf = terms.get(uuidKindOf);
604
			result.setKindOf((NameRelationshipType)kindOf);
605
		}
606
		return result;
607
	}
608

    
609
}
(17-17/39)