root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/name/NameRelationshipType.java

Revision 13119, 21.4 kB (checked in by a.mueller, 8 months ago)

Symbols for relations (#2634)

  • Property svn:keywords set to Id
Line 
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
10package eu.etaxonomy.cdm.model.name;
11
12
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.UUID;
17
18import javax.persistence.Entity;
19import javax.persistence.Transient;
20import javax.xml.bind.annotation.XmlAccessType;
21import javax.xml.bind.annotation.XmlAccessorType;
22import javax.xml.bind.annotation.XmlType;
23
24import org.apache.log4j.Logger;
25import org.hibernate.envers.Audited;
26import org.hibernate.search.annotations.Indexed;
27
28import eu.etaxonomy.cdm.common.CdmUtils;
29import eu.etaxonomy.cdm.model.common.DefinedTermBase;
30import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
31import eu.etaxonomy.cdm.model.common.TermVocabulary;
32
33/**
34 * The class representing the categories of {@link NameRelationship taxon name relationships} between
35 * two {@link TaxonNameBase taxon names}. These name relationship types are
36 * based on the concrete {@link NomenclaturalCode nomenclatural code} governing
37 * the taxon names involved in the name relationship or on decisions taken by
38 * the competent authorities; they do not depend on the use made of these
39 * taxon names in a particular reference or in a particular taxonomic treatment.
40 * Most relationships are to be understood as 'is .... of': for instance
41 * <i>Linum radiola</i> L. is a replaced synonym of <i>Radiola linoides</i> Roth or
42 * <i>Astragalus rhizanthus</i> Boiss. is a later homonym of
43 * <i>Astragalus rhizanthus</i> Royle. 
44 * <P>
45 * A standard (ordered) list of name relationship type instances will be
46 * automatically created as the project starts. But this class allows to extend
47 * this standard list by creating new instances of additional name relationship
48 * types if needed.
49 * <P>
50 * This class corresponds partially to: <ul>
51 * <li> TaxonRelationshipTerm and NomenclaturalNoteTypeTerm according to the TDWG ontology
52 * <li> RelationshipType and NomenclaturalNoteType according to the TCS
53 * </ul>
54 *
55 * @author m.doering
56 * @version 1.0
57 * @created 08-Nov-2007 13:06:38
58 */
59@XmlAccessorType(XmlAccessType.FIELD)
60@XmlType(name = "NameRelationshipType")
61@Entity
62@Indexed(index = "eu.etaxonomy.cdm.model.common.DefinedTermBase")
63@Audited
64public class NameRelationshipType extends RelationshipTermBase<NameRelationshipType> {
65        static Logger logger = Logger.getLogger(NameRelationshipType.class);
66
67        private static final UUID uuidOrthographicVariant = UUID.fromString("eeaea868-c4c1-497f-b9fe-52c9fc4aca53");
68        private static final UUID uuidMisspelling = UUID.fromString("c6f9afcb-8287-4a2b-a6f6-4da3a073d5de");
69        private static final UUID uuidEmendation = UUID.fromString("6e23ad45-3f2a-462b-ad87-d2389cd6e26c");
70        private static final UUID uuidLaterHomonym = UUID.fromString("80f06f65-58e0-4209-b811-cb40ad7220a6");
71        private static final UUID uuidTreatedAsLaterHomonym = UUID.fromString("2990a884-3302-4c8b-90b2-dfd31aaa2778");
72        private static final UUID uuidAlternativeName = UUID.fromString("049c6358-1094-4765-9fae-c9972a0e7780");
73        private static final UUID uuidBasionym = UUID.fromString("25792738-98de-4762-bac1-8c156faded4a");
74        private static final UUID uuidReplacedSynonym = UUID.fromString("71c67c38-d162-445b-b0c2-7aba56106696");
75        private static final UUID uuidConservedAgainst = UUID.fromString("e6439f95-bcac-4ebb-a8b5-69fa5ce79e6a");
76        private static final UUID uuidValidatedByName = UUID.fromString("a176c9ad-b4c2-4c57-addd-90373f8270eb");
77        private static final UUID uuidLaterValidatedByName = UUID.fromString("a25ee4c1-863a-4dab-9499-290bf9b89639");
78        private static final UUID uuidBlockingNameFor = UUID.fromString("1dab357f-2e12-4511-97a4-e5153589e6a6");
79       
80        protected static Map<UUID, NameRelationshipType> termMap = null;               
81       
82        protected static NameRelationshipType findTermByUuid(UUID uuid){
83                if (termMap == null){
84                        return null;
85                }
86                return (NameRelationshipType)termMap.get(uuid);
87        }
88       
89       
90        // ************* CONSTRUCTORS *************/   
91        /**
92         * Class constructor: creates a new empty name relationship type instance.
93         *
94         * @see         #NameRelationshipType(String, String, String, boolean, boolean)
95         */
96        public NameRelationshipType() {
97        }
98       
99        /**
100         * Class constructor: creates an additional name relationship type
101         * instance with a description, a label, a label abbreviation and the flags
102         * indicating whether <i>this</i> new name relationship type is symmetric and/or
103         * transitive.
104         *
105         * @param       term             the string (in the default language) describing the
106         *                                               new name relationship type to be created
107         * @param       label            the string identifying the new name relationship
108         *                                               type to be created
109         * @param       labelAbbrev  the string identifying (in abbreviated form) the
110         *                                               new name relationship type to be created
111         * @param       symmetric        the boolean indicating whether the new name
112         *                                               relationship type to be created is symmetric
113         * @param       transitive       the boolean indicating whether the new name
114         *                                               relationship type to be created is transitive
115         * @see                                  #NameRelationshipType()
116         */
117        public NameRelationshipType(String term, String label, String labelAbbrev, boolean symmetric, boolean transitive) {
118                super(term, label, labelAbbrev, symmetric, transitive);
119        }
120
121
122       
123//************************** METHODS ********************************
124       
125        /* (non-Javadoc)
126         * @see eu.etaxonomy.cdm.model.common.DefinedTermBase#resetTerms()
127         */
128        @Override
129        public void resetTerms(){
130                termMap = null;
131        }
132       
133        // TODO this method should be moved to consistency proof classes
134        /**
135         * Returns the boolean value indicating whether the nomenclatural status
136         * type of the {@link eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom() first taxon name}
137         * involved in a name relationship with <i>this</i> name relationship type should
138         * be "invalid" (true) or not (false). Returns false if <i>this</i> name
139         * relationship status type is null.
140         *
141         * @see  #isLegitimateType()
142         * @see  #isIllegitimateType()
143         * @see  NomenclaturalStatusType#isInvalidType()
144         * @see  eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
145         */
146        @Transient
147        public boolean isInvalidType(){
148                if (this.equals(VALIDATED_BY_NAME()) || 
149                                this.equals(LATER_VALIDATED_BY_NAME())
150                        ){
151                        return true;   
152                }else{
153                        return false;
154                }
155        }
156
157        // TODO this method should be moved to consistency proof classes
158        /**
159         * Returns the boolean value indicating whether the nomenclatural status
160         * type of the {@link eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom() first taxon name}
161         * involved in a name relationship with <i>this</i> name relationship type should
162         * be "legitimate" (true) or not (false). Returns false if <i>this</i> name
163         * relationship status type is null.
164         *
165         * @see  #isInvalidType()
166         * @see  #isIllegitimateType()
167         * @see  NomenclaturalStatusType#isLegitimateType()
168         * @see  eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
169         */
170        @Transient
171        public boolean isLegitimateType(){
172                if (this.equals(BASIONYM()) || 
173                                this.equals(REPLACED_SYNONYM()) || 
174                                this.equals(ALTERNATIVE_NAME()) ||
175                                this.equals(CONSERVED_AGAINST())
176                        ){
177                        return true;   
178                }else{
179                        return false;
180                }
181        }
182
183        // TODO this method should be moved to consistency proof classes
184        /**
185         * Returns the boolean value indicating whether the nomenclatural status
186         * type of the {@link eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom() first taxon name}
187         * involved in a name relationship with <i>this</i> name relationship type should
188         * be "illegitimate" (true) or not (false). Returns false if <i>this</i> name
189         * relationship status type is null.
190         *
191         * @see  #isInvalidType()
192         * @see  #isLegitimateType()
193         * @see  NomenclaturalStatusType#isIllegitimateType()
194         * @see  eu.etaxonomy.cdm.model.common.RelationshipBase#getRelatedFrom()
195         */
196        @Transient
197        public boolean isIllegitimateType(){
198                //TODO: implement isX method. Maybe as persistent class attribute?
199                //TODO: RejectedInFavour,
200                if (this.equals(LATER_HOMONYM()) || 
201                                this.equals(TREATED_AS_LATER_HOMONYM())
202                        ){
203                        return true;   
204                }else{
205                        return false;
206                }
207        }
208       
209        @Transient
210        public boolean isBasionymRelation(){
211                if (BASIONYM() == null){
212                        throw new IllegalStateException("NameRelationships have not been initialized yet. Please initialize DefinedTerms first");
213                }
214                return this.equals(BASIONYM());
215        }
216       
217        @Transient
218        public boolean isReplacedSynonymRelation(){
219                if (REPLACED_SYNONYM() == null){
220                        throw new IllegalStateException("NameRelationships have not been initialized yet. Please initialize DefinedTerms first");
221                }
222                return this.equals(REPLACED_SYNONYM());
223        }
224
225       
226        /**
227         * Returns the "orthographic variant" name relationship type. The first
228         * {@link TaxonNameBase taxon name} involved in such a relationship is an
229         * orthographic variant of the second taxon name. The two {@link TaxonNameBase taxon names}
230         * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
231         * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
232         * must be almost identical (so one usually does not differentiate them).<BR>
233         * For instance <i>Angelica silvestris</i> L. is an orthographic variant of
234         * <i>Angelica sylvestris</i> L.<BR>
235         * This type is symmetric and transitive but usually orthographic variant relationships should be organized
236         * in a star schema with the correct variant in the middle and other variants pointing to it.
237         */
238        public static final NameRelationshipType ORTHOGRAPHIC_VARIANT(){
239                  return findTermByUuid(uuidOrthographicVariant);
240        }
241        /**
242         * Returns the "misspelling" name relationship type. The first
243         * {@link TaxonNameBase taxon name} involved in such a relationship is a
244         * misspelling of the second taxon name. The two {@link TaxonNameBase taxon names}
245         * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
246         * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
247         * must be almost identical (so one usually does not differentiate them).<BR>
248         * For instance <i>Anhelica silvestris</i> L. is a misspelling of
249         * <i>Angelica silvestris</i> L.<BR>
250         * A misspelling is always accicentally (not on purpose). Therefore misspellings are a
251         * subset of {@link #ORTHOGRAPHIC_VARIANT orthographic variants} and are complementary to
252         * emendations. A misspelling is always an {@link #ORTHOGRAPHIC_VARIANT orthographic variant}, too.
253         * This type is symmetric and transitive but usually the misspelling relationships should be organized
254         * in a star schema with the correct variant in the middle and the misspellings pointing to it.
255         */
256        public static final NameRelationshipType MISSPELLING(){
257                  return findTermByUuid(uuidMisspelling);
258        }
259        /**
260         * Returns the "emendation" name relationship type. The first
261         * {@link TaxonNameBase taxon name} involved in such a relationship is a
262         * misspelling of the second taxon name. The two {@link TaxonNameBase taxon names}
263         * involved in such a relationship must have the same {@link NonViralName#getAuthorshipCache() authorship}
264         * and {@link Rank rank}, belong to the same {@link HomotypicalGroup homotypical group} and their name parts
265         * must be almost identical (so one usually does not differentiate them).<BR>
266         * For instance <i>Angelica silvestris</i> L. is a emendation of
267         * <i>Angelica sylvestris</i> L.<BR>
268         * The name corrected by an emendation has originally been used on purpose (not accidentially)
269         * Therefore emendations are a subset of {@link #ORTHOGRAPHIC_VARIANT orthographic variants} and are
270         * complementary to {@link #MISSPELLING missepllings}. An emendation is always an
271         * {@link #ORTHOGRAPHIC_VARIANT orthographic variant}, too.<BR>
272         * This type is symmetric and transitive but usually the misspelling relationships should be organized
273         * in a star schema with the correct variant in the middle and the misspellings pointing to it.
274         */
275        public static final NameRelationshipType EMENDATION(){
276                  return findTermByUuid(uuidEmendation);
277        }
278        /**
279         * Returns the "later homonym" name relationship type. The first
280         * {@link TaxonNameBase taxon name} involved in such a relationship should
281         * have been published after the second taxon name. The two {@link TaxonNameBase taxon names}
282         * involved in such a relationship must belong to different
283         * {@link HomotypicalGroup homotypical groups}, have in general different
284         * {@link NonViralName#getAuthorshipCache() authorship} and their name parts (excluding infraspecific
285         * {@link Rank ranks}) must be (almost) identical, so one could be mistaken for
286         * the other one. The first taxon name is "illegitimate" and the second one
287         * is "legitimate" (this corresponds to "invalid" and "valid" in case of
288         * {@link ZoologicalName zoological names}).<BR>
289         * For instance <i>Astragalus rhizanthus</i> Boiss. is a later homonym of
290         * <i>Astragalus rhizanthus</i> Royle.<BR>
291         * This type is not symmetric but transitive.
292         *
293         * @see NomenclaturalStatusType#isIllegitimateType()
294         * @see NomenclaturalStatusType#isLegitimateType()
295         */
296        public static final NameRelationshipType LATER_HOMONYM(){
297          return findTermByUuid(uuidLaterHomonym);
298        }
299        /**
300         * Returns the "treated as later homonym" name relationship type. The first
301         * {@link TaxonNameBase taxon name} involved in such a relationship is
302         * treated as an homonym although it has been published before the second
303         * taxon name. The two taxon names involved must belong to different
304         * {@link HomotypicalGroup homotypical groups} and their name parts (excluding
305         * {@link Rank#isInfraSpecific() infraspecific ranks} and {@link NonViralName#getAuthorshipCache() authorship}) must be
306         * almost identical (so one could be mistaken for the other). The first
307         * taxon name is "illegitimate" and the second one is "legitimate" (this
308         * corresponds to "invalid" and "valid" in case of {@link ZoologicalName zoological names}).<BR>
309         * This type is not symmetric but transitive.
310         *
311         * @see #LATER_HOMONYM()
312         * @see NomenclaturalStatusType#isIllegitimateType()
313         * @see NomenclaturalStatusType#isLegitimateType()
314         */
315        public static final NameRelationshipType TREATED_AS_LATER_HOMONYM(){
316          return findTermByUuid(uuidTreatedAsLaterHomonym);
317        }
318        /**
319         * Returns the "alternative name" name relationship type. Both {@link TaxonNameBase taxon names}
320         * involved in such a relationship are family names. The first one is a
321         * classical name long in use, in some cases, even before 1753 and is considered as
322         * {@link NomenclaturalStatusType#VALID() valid} and also {@link NomenclaturalStatusType#isLegitimateType() legitimate}
323         * although it does not follow the rules for family names (see Article 18 of
324         * the ICBN). An alternative name is typified by the type of the name
325         * it is alternative to (so both must belong to the same
326         * {@link HomotypicalGroup homotypical group}).<BR>
327         * For instance <i>Cruciferae</i> Adans is an alternative name to
328         * <i>Brassicaceae</i> Lindl.<BR>
329         * This type is neither symmetric nor transitive.
330         */
331        public static final NameRelationshipType ALTERNATIVE_NAME(){
332          return findTermByUuid(uuidAlternativeName);
333        }
334        /**
335         * Returns the "basionym" name relationship type. The first {@link TaxonNameBase taxon name}
336         * involved in such a relationship is the "basionym" of the second taxon
337         * name. Both taxon names belong to the same {@link HomotypicalGroup homotypical group}).
338         * The basionym is the epithet-bringing taxon name (first taxon name
339         * ever validly published given to the same {@link Rank#isInfraGeneric() infrageneric}
340         * taxon, the epithet of which is the same as in the second taxon name
341         * originated through a reclassification).<BR>
342         * According to the ICBN the author of the basionym must be mentioned in the
343         * later taxon name (by placing it in parentheses before the authority of
344         * the new combination). For instance <i>Pinus abies</i> L. is the basionym of
345         * <i>Picea abies</i> (L.) H. Karst.<BR>
346         * This type is neither symmetric nor transitive.
347         */
348        public static final NameRelationshipType BASIONYM(){
349          return findTermByUuid(uuidBasionym);
350        }
351        /**
352         * Returns the "replaced synonym" name relationship type. The first
353         * {@link TaxonNameBase taxon name} involved in such a relationship is the
354         * "replaced synonym" of the second taxon name. Both taxon names belong to
355         * the same {@link HomotypicalGroup homotypical group}. The replaced synonym is the
356         * first taxon name ever validly published given to the same
357         * {@link Rank#isInfraGeneric() infrageneric} taxon that is either itself a
358         * "later homonym" or the epithet of which could not be used in the new
359         * taxon name originated through a reclassification. A new epithet must be
360         * proposed if the use of the original epithet leads to an already existing
361         * taxon name (for another taxon) or in botany to autonyms (since the ICBN
362         * does not allow such names where epithet and genus name are the same).<BR>
363         * For instance <i>Spartium biflorum</i> Desf. is the replaced synonym of
364         * of <i>Cytisus fontanesii</i> Spach ("novum" taxon name) because at the time
365         * of reclassification a taxon name <i>Cytisus biflorum</i> had been already
366         * published by L'H�r.<BR>
367         * This type is neither symmetric nor transitive.
368         *
369         * @see #BASIONYM()
370         * @see #LATER_HOMONYM()
371         * @see NomenclaturalStatusType#NOVUM()
372         */
373        public static final NameRelationshipType REPLACED_SYNONYM(){
374          return findTermByUuid(uuidReplacedSynonym);
375        }
376        /**
377         * Returns the "conserved against" name relationship type. Both {@link TaxonNameBase taxon names}
378         * involved in such a relationship belong to the same {@link HomotypicalGroup homotypical group}.
379         * Competent authorities decided, regardless of the general
380         * nomenclatural rules, to handle the first one as the "legitimate"
381         * one and the second taxon name as "illegitimate" (this corresponds to
382         * "valid" and "invalid" in case of {@link ZoologicalName zoological names}).<BR>
383         * For instance <i>Cephaloziella</i> (Spruce) Schiffn. is conserved against
384         * <i>Dichiton</i> Mont.<BR>
385         * This type is neither symmetric nor transitive.
386         *
387         * @see NomenclaturalStatusType#CONSERVED()
388         * @see NomenclaturalStatusType#REJECTED()
389         * @see NomenclaturalStatusType#isLegitimateType()
390         * @see NomenclaturalStatusType#isIllegitimateType()
391         */
392        public static final NameRelationshipType CONSERVED_AGAINST(){
393          return findTermByUuid(uuidConservedAgainst);
394        }
395        /**
396         * Returns the "validated by name" name relationship type. The two
397         * {@link TaxonNameBase taxon names} involved in such a relationship were published
398         * in order to define the same taxonomical group but the first
399         * (earlier) taxon name was invalidly published whereas the second (later)
400         * taxon name is the one which was validly published for the first time.<BR>
401         * This type is neither symmetric nor transitive.
402         *
403         * @see         NomenclaturalStatusType#isInvalidType()
404         * @see         NomenclaturalStatusType#VALID()
405         */
406        public static final NameRelationshipType VALIDATED_BY_NAME(){
407          return findTermByUuid(uuidValidatedByName);
408        }
409        /**
410         * Returns the "later validated by name" name relationship type. The two
411         * {@link TaxonNameBase taxon names} involved in such a relationship were published
412         * in order to define the same taxonomical group but the first
413         * (earlier) taxon name was invalidly published whereas the second (later)
414         * taxon name is the one which was validly published for the first time.<BR>
415         * This type is neither symmetric nor transitive.
416         *
417         * @see         NomenclaturalStatusType#isInvalidType()
418         * @see         NomenclaturalStatusType#VALID()
419         */
420        public static final NameRelationshipType LATER_VALIDATED_BY_NAME(){
421          return findTermByUuid(uuidLaterValidatedByName); 
422        }
423        /**
424         * Returns the "blocking name" name relationship type. The first
425         * {@link TaxonNameBase taxon name} involved in such a relationship is the
426         * "blocking name" for the second taxon name. Both taxon names belong to
427         * different {@link HomotypicalGroup homotypical groups}). The blocking taxon name is the
428         * {@link Rank#isInfraGeneric() infrageneric} taxon name, already published at the time of
429         * reclassification, which makes illegitim (because of homonymy) the use of
430         * the epithet in the second taxon name originated through a reclassification.
431         * Therefore a "replaced synonym" name relationship arises.<BR>
432         * For instance  <i>Cytisus biflorum</i> L'H�r. is the blocking name for
433         * <i>Cytisus fontanesii</i> Spach ("novum" taxon name) when reclassifying
434         * <i>Spartium biflorum</i> Desf. from <i>Spartium</i> to <i>Cytisus</i>.<BR>
435         * This type is neither symmetric nor transitive.
436         *
437         * @see #REPLACED_SYNONYM()
438         * @see #LATER_HOMONYM()
439         * @see NomenclaturalStatusType#NOVUM()
440         */
441        public static final NameRelationshipType BLOCKING_NAME_FOR(){
442          return  findTermByUuid(uuidBlockingNameFor);
443        }
444
445        @Override
446        protected void setDefaultTerms(TermVocabulary<NameRelationshipType> termVocabulary) {
447                termMap = new HashMap<UUID, NameRelationshipType>();
448                for (NameRelationshipType term : termVocabulary.getTerms()){
449                        termMap.put(term.getUuid(), term);
450                }
451        }
452
453        @Override
454        public NameRelationshipType readCsvLine(Class<NameRelationshipType> termClass, List<String> csvLine, Map<UUID,DefinedTermBase> terms) {
455                NameRelationshipType result = super.readCsvLine(termClass, csvLine, terms);
456                String kindOfString = csvLine.get(10).trim();
457                if (CdmUtils.isNotEmpty(kindOfString)){
458                        UUID uuidKindOf = UUID.fromString(kindOfString);
459                        DefinedTermBase kindOf = terms.get(uuidKindOf);
460                        result.setKindOf((NameRelationshipType)kindOf);
461                }
462                return result;
463        }
464}
Note: See TracBrowser for help on using the browser.