001package org.gbif.api.vocabulary;
002
003import org.gbif.dwc.terms.DwcTerm;
004import org.gbif.dwc.terms.GbifTerm;
005import org.gbif.dwc.terms.Term;
006import org.gbif.utils.AnnotationUtils;
007
008import java.util.Set;
009
010import com.google.common.collect.ImmutableSet;
011
012import static org.gbif.api.vocabulary.InterpretationRemarkSeverity.ERROR;
013import static org.gbif.api.vocabulary.InterpretationRemarkSeverity.INFO;
014import static org.gbif.api.vocabulary.InterpretationRemarkSeverity.WARNING;
015
016/**
017 * Enumeration of issues for each name usage record encountered during checklist processing.
018 */
019public enum NameUsageIssue implements InterpretationRemark {
020  /**
021   * The value for dwc:parentNameUsageID could not be resolved.
022   */
023  PARENT_NAME_USAGE_ID_INVALID(ERROR, DwcTerm.parentNameUsageID),
024
025  /**
026   * The value for dwc:acceptedNameUsageID could not be resolved.
027   */
028  ACCEPTED_NAME_USAGE_ID_INVALID(ERROR, DwcTerm.acceptedNameUsageID),
029
030  /**
031   * The value for dwc:originalNameUsageID could not be resolved.
032   */
033  ORIGINAL_NAME_USAGE_ID_INVALID(ERROR, DwcTerm.originalNameUsageID),
034
035  /**
036   * Synonym lacking an accepted name.
037   */
038  ACCEPTED_NAME_MISSING(DwcTerm.taxonomicStatus, DwcTerm.acceptedNameUsageID, DwcTerm.acceptedNameUsage),
039
040  /**
041   * dwc:taxonRank could not be interpreted
042   */
043  RANK_INVALID(DwcTerm.taxonRank),
044
045  /**
046   * dwc:nomenclaturalStatus could not be interpreted
047   */
048  NOMENCLATURAL_STATUS_INVALID(DwcTerm.nomenclaturalStatus),
049
050  /**
051   * dwc:taxonomicStatus could not be interpreted
052   */
053  TAXONOMIC_STATUS_INVALID(DwcTerm.taxonomicStatus),
054
055  /**
056   * The scientific name was assembled from the individual name parts and not given as a whole string.
057   */
058  SCIENTIFIC_NAME_ASSEMBLED(INFO, DwcTerm.scientificName, DwcTerm.genus, DwcTerm.specificEpithet, DwcTerm.infraspecificEpithet, DwcTerm.taxonRank, DwcTerm.scientificNameAuthorship, DwcTerm.namePublishedInYear),
059
060  /**
061   * If a synonym points to another synonym as its accepted taxon the chain is resolved.
062   */
063  CHAINED_SYNOYM(DwcTerm.acceptedNameUsageID, DwcTerm.acceptedNameUsage),
064
065  /**
066   * The authorship of the original name does not match the authorship in brackets of the actual name.
067   */
068  BASIONYM_AUTHOR_MISMATCH(DwcTerm.scientificName, DwcTerm.scientificNameAuthorship, DwcTerm.originalNameUsageID, DwcTerm.originalNameUsage),
069
070  TAXONOMIC_STATUS_MISMATCH(DwcTerm.taxonomicStatus, DwcTerm.acceptedNameUsageID, DwcTerm.acceptedNameUsage),
071
072  /**
073   * The child parent classification resulted into a cycle that needed to be resolved/cut.
074   */
075  PARENT_CYCLE(ERROR, DwcTerm.parentNameUsageID, DwcTerm.parentNameUsage),
076
077  /**
078   * The given ranks of the names in the classification hierarchy do not follow the hierarchy of ranks.
079   */
080  CLASSIFICATION_RANK_ORDER_INVALID(ERROR, DwcTerm.parentNameUsageID, DwcTerm.parentNameUsage, DwcTerm.taxonRank),
081
082  /**
083   * The denormalized classification could not be applied to the name usage.
084   * For example if the id based classification has no ranks.
085   */
086  CLASSIFICATION_NOT_APPLIED(DwcTerm.kingdom, DwcTerm.phylum, DwcTerm.class_, DwcTerm.order, DwcTerm.family, DwcTerm.genus),
087
088  /**
089   * At least one vernacular name extension record attached to this name usage is invalid.
090   */
091  VERNACULAR_NAME_INVALID(DwcTerm.vernacularName),
092
093  /**
094   * At least one description extension record attached to this name usage is invalid.
095   */
096  DESCRIPTION_INVALID(GbifTerm.Description),
097
098  /**
099   * At least one distribution extension record attached to this name usage is invalid.
100   */
101  DISTRIBUTION_INVALID(GbifTerm.Distribution),
102
103  /**
104   * At least one species profile extension record attached to this name usage is invalid.
105   */
106  SPECIES_PROFILE_INVALID(GbifTerm.SpeciesProfile),
107
108  /**
109   * At least one multimedia extension record attached to this name usage is invalid.
110   * This covers multimedia coming in through various extensions including
111   * Audubon core, Simple images or multimedia or EOL media.
112   */
113  MULTIMEDIA_INVALID(GbifTerm.Multimedia),
114
115  /**
116   * At least one bibliographic reference extension record attached to this name usage is invalid.
117   */
118  BIB_REFERENCE_INVALID(GbifTerm.Reference),
119
120  /**
121   * At least one alternative identifier extension record attached to this name usage is invalid.
122   */
123  ALT_IDENTIFIER_INVALID(GbifTerm.Identifier),
124
125  /**
126   * Name usage could not be matched to the GBIF backbone.
127   */
128  BACKBONE_MATCH_NONE(INFO, DwcTerm.scientificName, DwcTerm.scientificNameAuthorship, DwcTerm.kingdom, DwcTerm.taxonRank),
129
130  /**
131   * Name usage could only be matched to the GBIF backbone using fuzzy matching.
132   * @deprecated because there should be no fuzzy matching being used anymore for matching checklist names
133   */
134  @Deprecated
135  BACKBONE_MATCH_FUZZY(DwcTerm.scientificName, DwcTerm.scientificNameAuthorship, DwcTerm.kingdom, DwcTerm.taxonRank),
136
137  /**
138   * Synonym has a verbatim accepted name which is not unique and refers to several records.
139   */
140  ACCEPTED_NAME_NOT_UNIQUE(DwcTerm.acceptedNameUsage),
141
142  /**
143   * Record has a verbatim parent name which is not unique and refers to several records.
144   */
145  PARENT_NAME_NOT_UNIQUE(DwcTerm.parentNameUsage),
146
147  /**
148   * Record has a verbatim original name (basionym) which is not unique and refers to several records.
149   */
150  ORIGINAL_NAME_NOT_UNIQUE(DwcTerm.originalNameUsage),
151
152  /**
153   * There were problems representing all name usage relationships,
154   * i.e. the link to the parent, accepted and/or original name.
155   * The interpreted record in ChecklistBank is lacking some of the original source relation.
156   */
157  RELATIONSHIP_MISSING(DwcTerm.parentNameUsageID, DwcTerm.acceptedNameUsageID, DwcTerm.originalNameUsageID, DwcTerm.parentNameUsage, DwcTerm.acceptedNameUsage, DwcTerm.originalNameUsage),
158
159  /**
160   * Record has a original name (basionym) relationship which was derived from name & authorship comparison, but did not exist explicitly in the data.
161   * This should only be flagged in programmatically generated GBIF backbone usages.
162   * GBIF backbone specific issue.
163   */
164  ORIGINAL_NAME_DERIVED(INFO),
165
166  /**
167   * There have been more than one accepted name in a homotypical basionym group of names.
168   * GBIF backbone specific issue.
169   */
170  CONFLICTING_BASIONYM_COMBINATION(),
171
172  /**
173   * The group (currently only genera are tested) are lacking any accepted species
174   * GBIF backbone specific issue.
175   */
176  NO_SPECIES(INFO),
177
178  /**
179   * The (accepted) bi/trinomial name does not match the parent name and should be recombined into the parent genus/species.
180   * For example the species Picea alba with a parent genus Abies is a mismatch and should be replaced by Abies alba.
181   * GBIF backbone specific issue.
182   */
183  NAME_PARENT_MISMATCH(),
184
185  /**
186   * A potential orthographic variant exists in the backbone.
187   * GBIF backbone specific issue.
188   */
189  ORTHOGRAPHIC_VARIANT(INFO),
190
191  /**
192   * A not synonymized homonym exists for this name in some other backbone source which have been ignored at build time.
193   */
194  HOMONYM(INFO, DwcTerm.scientificName),
195
196  /**
197   * A bi/trinomial name published earlier than the parent genus was published.
198   * This might indicate that the name should rather be a recombination.
199   */
200  PUBLISHED_BEFORE_GENUS(DwcTerm.scientificName, DwcTerm.scientificNameAuthorship, DwcTerm.namePublishedInYear, DwcTerm.genus, DwcTerm.parentNameUsageID, DwcTerm.parentNameUsage);
201
202  private final Set<Term> related;
203  private final InterpretationRemarkSeverity severity;
204  private final boolean isDeprecated;
205
206  NameUsageIssue(Term ... related) {
207    this(WARNING, related);
208  }
209
210  NameUsageIssue(InterpretationRemarkSeverity severity, Term ... related) {
211    if (related == null) {
212      this.related = ImmutableSet.of();
213    } else {
214      this.related = ImmutableSet.copyOf(related);
215    }
216    this.severity = severity;
217    this.isDeprecated = AnnotationUtils.isFieldDeprecated(NameUsageIssue.class, this.name());
218  }
219
220  @Override
221  public String getId() {
222    return name();
223  }
224
225  @Override
226  public Set<Term> getRelatedTerms() {
227    return related;
228  }
229
230  @Override
231  public InterpretationRemarkSeverity getSeverity(){
232    return severity;
233  }
234
235  @Override
236  public boolean isDeprecated(){
237    return isDeprecated;
238  }
239
240}