001package org.gbif.api.vocabulary;
002
003import static org.gbif.api.vocabulary.InterpretationRemarkSeverity.INFO;
004
005import java.util.Arrays;
006import java.util.Collections;
007import java.util.HashSet;
008import java.util.Set;
009import org.gbif.api.util.AnnotationUtils;
010import org.gbif.dwc.terms.EcoTerm;
011import org.gbif.dwc.terms.Term;
012
013public enum EventIssue implements InterpretationRemark {
014  /** See {@link OccurrenceIssue#ZERO_COORDINATE}. */
015  ZERO_COORDINATE(OccurrenceIssue.ZERO_COORDINATE),
016  /** See {@link OccurrenceIssue#COORDINATE_OUT_OF_RANGE}. */
017  COORDINATE_OUT_OF_RANGE(OccurrenceIssue.COORDINATE_OUT_OF_RANGE),
018  /** See {@link OccurrenceIssue#COORDINATE_INVALID}. */
019  COORDINATE_INVALID(OccurrenceIssue.COORDINATE_INVALID),
020  /** See {@link OccurrenceIssue#COORDINATE_ROUNDED}. */
021  COORDINATE_ROUNDED(OccurrenceIssue.COORDINATE_ROUNDED),
022  /** See {@link OccurrenceIssue#GEODETIC_DATUM_INVALID}. */
023  GEODETIC_DATUM_INVALID(OccurrenceIssue.GEODETIC_DATUM_INVALID),
024  /** See {@link OccurrenceIssue#GEODETIC_DATUM_ASSUMED_WGS84}. */
025  GEODETIC_DATUM_ASSUMED_WGS84(OccurrenceIssue.GEODETIC_DATUM_ASSUMED_WGS84),
026  /** See {@link OccurrenceIssue#COORDINATE_REPROJECTED}. */
027  COORDINATE_REPROJECTED(OccurrenceIssue.COORDINATE_REPROJECTED),
028  /** See {@link OccurrenceIssue#COORDINATE_REPROJECTION_FAILED}. */
029  COORDINATE_REPROJECTION_FAILED(OccurrenceIssue.COORDINATE_REPROJECTION_FAILED),
030  /** See {@link OccurrenceIssue#COORDINATE_REPROJECTION_SUSPICIOUS}. */
031  COORDINATE_REPROJECTION_SUSPICIOUS(OccurrenceIssue.COORDINATE_REPROJECTION_SUSPICIOUS),
032  /** See {@link OccurrenceIssue#COORDINATE_ACCURACY_INVALID}. */
033  @Deprecated // see POR-3061
034  COORDINATE_ACCURACY_INVALID(OccurrenceIssue.COORDINATE_ACCURACY_INVALID),
035  /** See {@link OccurrenceIssue#COORDINATE_PRECISION_INVALID}. */
036  COORDINATE_PRECISION_INVALID(OccurrenceIssue.COORDINATE_PRECISION_INVALID),
037  /** See {@link OccurrenceIssue#COORDINATE_UNCERTAINTY_METERS_INVALID}. */
038  COORDINATE_UNCERTAINTY_METERS_INVALID(OccurrenceIssue.COORDINATE_UNCERTAINTY_METERS_INVALID),
039  /** See {@link OccurrenceIssue#COORDINATE_PRECISION_UNCERTAINTY_MISMATCH}. */
040  @Deprecated // see POR-1804
041  COORDINATE_PRECISION_UNCERTAINTY_MISMATCH(
042      OccurrenceIssue.COORDINATE_PRECISION_UNCERTAINTY_MISMATCH),
043  /** See {@link OccurrenceIssue#FOOTPRINT_SRS_INVALID}. */
044  FOOTPRINT_SRS_INVALID(OccurrenceIssue.FOOTPRINT_SRS_INVALID),
045  /** See {@link OccurrenceIssue#FOOTPRINT_WKT_MISMATCH}. */
046  FOOTPRINT_WKT_MISMATCH(OccurrenceIssue.FOOTPRINT_WKT_MISMATCH),
047  /** See {@link OccurrenceIssue#FOOTPRINT_WKT_INVALID}. */
048  FOOTPRINT_WKT_INVALID(OccurrenceIssue.FOOTPRINT_WKT_INVALID),
049  /** See {@link OccurrenceIssue#COUNTRY_COORDINATE_MISMATCH}. */
050  COUNTRY_COORDINATE_MISMATCH(OccurrenceIssue.COUNTRY_COORDINATE_MISMATCH),
051  /** See {@link OccurrenceIssue#COUNTRY_MISMATCH}. */
052  COUNTRY_MISMATCH(OccurrenceIssue.COUNTRY_MISMATCH),
053  /** See {@link OccurrenceIssue#COUNTRY_INVALID}. */
054  COUNTRY_INVALID(OccurrenceIssue.COUNTRY_INVALID),
055  /** See {@link OccurrenceIssue#COUNTRY_DERIVED_FROM_COORDINATES}. */
056  COUNTRY_DERIVED_FROM_COORDINATES(OccurrenceIssue.COUNTRY_DERIVED_FROM_COORDINATES),
057  /** See {@link OccurrenceIssue#CONTINENT_COORDINATE_MISMATCH}. */
058  CONTINENT_COORDINATE_MISMATCH(OccurrenceIssue.CONTINENT_COORDINATE_MISMATCH),
059  /** See {@link OccurrenceIssue#CONTINENT_COUNTRY_MISMATCH}. */
060  CONTINENT_COUNTRY_MISMATCH(OccurrenceIssue.CONTINENT_COUNTRY_MISMATCH),
061  /** See {@link OccurrenceIssue#CONTINENT_INVALID}. */
062  CONTINENT_INVALID(OccurrenceIssue.CONTINENT_INVALID),
063  /** See {@link OccurrenceIssue#CONTINENT_DERIVED_FROM_COUNTRY}. */
064  CONTINENT_DERIVED_FROM_COUNTRY(OccurrenceIssue.CONTINENT_DERIVED_FROM_COUNTRY),
065  /** See {@link OccurrenceIssue#CONTINENT_DERIVED_FROM_COORDINATES}. */
066  CONTINENT_DERIVED_FROM_COORDINATES(OccurrenceIssue.CONTINENT_DERIVED_FROM_COORDINATES),
067  /** See {@link OccurrenceIssue#PRESUMED_SWAPPED_COORDINATE}. */
068  PRESUMED_SWAPPED_COORDINATE(OccurrenceIssue.PRESUMED_SWAPPED_COORDINATE),
069  /** See {@link OccurrenceIssue#PRESUMED_NEGATED_LONGITUDE}. */
070  PRESUMED_NEGATED_LONGITUDE(OccurrenceIssue.PRESUMED_NEGATED_LONGITUDE),
071  /** See {@link OccurrenceIssue#PRESUMED_NEGATED_LATITUDE}. */
072  PRESUMED_NEGATED_LATITUDE(OccurrenceIssue.PRESUMED_NEGATED_LATITUDE),
073  /** See {@link OccurrenceIssue#RECORDED_DATE_MISMATCH}. */
074  RECORDED_DATE_MISMATCH(OccurrenceIssue.RECORDED_DATE_MISMATCH),
075  /** See {@link OccurrenceIssue#RECORDED_DATE_INVALID}. */
076  RECORDED_DATE_INVALID(OccurrenceIssue.RECORDED_DATE_INVALID),
077  /** See {@link OccurrenceIssue#RECORDED_DATE_UNLIKELY}. */
078  RECORDED_DATE_UNLIKELY(OccurrenceIssue.RECORDED_DATE_UNLIKELY),
079  /** See {@link OccurrenceIssue#TAXON_MATCH_FUZZY}. */
080  TAXON_MATCH_FUZZY(OccurrenceIssue.TAXON_MATCH_FUZZY),
081  /** See {@link OccurrenceIssue#TAXON_MATCH_HIGHERRANK}. */
082  TAXON_MATCH_HIGHERRANK(OccurrenceIssue.TAXON_MATCH_HIGHERRANK),
083  /** See {@link OccurrenceIssue#TAXON_MATCH_AGGREGATE}. */
084  TAXON_MATCH_AGGREGATE(OccurrenceIssue.TAXON_MATCH_AGGREGATE),
085  /** See {@link OccurrenceIssue#TAXON_MATCH_SCIENTIFIC_NAME_ID_IGNORED}. */
086  TAXON_MATCH_SCIENTIFIC_NAME_ID_IGNORED(OccurrenceIssue.TAXON_MATCH_SCIENTIFIC_NAME_ID_IGNORED),
087  /** See {@link OccurrenceIssue#TAXON_MATCH_TAXON_CONCEPT_ID_IGNORED}. */
088  TAXON_MATCH_TAXON_CONCEPT_ID_IGNORED(OccurrenceIssue.TAXON_MATCH_TAXON_CONCEPT_ID_IGNORED),
089  /** See {@link OccurrenceIssue#TAXON_MATCH_TAXON_ID_IGNORED}. */
090  TAXON_MATCH_TAXON_ID_IGNORED(OccurrenceIssue.TAXON_MATCH_TAXON_ID_IGNORED),
091  /** See {@link OccurrenceIssue#SCIENTIFIC_NAME_ID_NOT_FOUND}. */
092  SCIENTIFIC_NAME_ID_NOT_FOUND(OccurrenceIssue.SCIENTIFIC_NAME_ID_NOT_FOUND),
093  /** See {@link OccurrenceIssue#TAXON_CONCEPT_ID_NOT_FOUND}. */
094  TAXON_CONCEPT_ID_NOT_FOUND(OccurrenceIssue.TAXON_CONCEPT_ID_NOT_FOUND),
095  /** See {@link OccurrenceIssue#TAXON_ID_NOT_FOUND}. */
096  TAXON_ID_NOT_FOUND(OccurrenceIssue.TAXON_ID_NOT_FOUND),
097  /** See {@link OccurrenceIssue#SCIENTIFIC_NAME_AND_ID_INCONSISTENT}. */
098  SCIENTIFIC_NAME_AND_ID_INCONSISTENT(OccurrenceIssue.SCIENTIFIC_NAME_AND_ID_INCONSISTENT),
099  /** See {@link OccurrenceIssue#TAXON_MATCH_NONE}. */
100  TAXON_MATCH_NONE(OccurrenceIssue.TAXON_MATCH_NONE),
101  /** See {@link OccurrenceIssue#TAXON_MATCH_NAME_AND_ID_AMBIGUOUS}. */
102  TAXON_MATCH_NAME_AND_ID_AMBIGUOUS(OccurrenceIssue.TAXON_MATCH_NAME_AND_ID_AMBIGUOUS),
103  /** See {@link OccurrenceIssue#DEPTH_NOT_METRIC}. */
104  DEPTH_NOT_METRIC(OccurrenceIssue.DEPTH_NOT_METRIC),
105  /** See {@link OccurrenceIssue#DEPTH_UNLIKELY}. */
106  DEPTH_UNLIKELY(OccurrenceIssue.DEPTH_UNLIKELY),
107  /** See {@link OccurrenceIssue#DEPTH_MIN_MAX_SWAPPED}. */
108  DEPTH_MIN_MAX_SWAPPED(OccurrenceIssue.DEPTH_MIN_MAX_SWAPPED),
109  /** See {@link OccurrenceIssue#DEPTH_NON_NUMERIC}. */
110  DEPTH_NON_NUMERIC(OccurrenceIssue.DEPTH_NON_NUMERIC),
111  /** See {@link OccurrenceIssue#ELEVATION_UNLIKELY}. */
112  ELEVATION_UNLIKELY(OccurrenceIssue.ELEVATION_UNLIKELY),
113  /** See {@link OccurrenceIssue#ELEVATION_MIN_MAX_SWAPPED}. */
114  ELEVATION_MIN_MAX_SWAPPED(OccurrenceIssue.ELEVATION_MIN_MAX_SWAPPED),
115  /** See {@link OccurrenceIssue#ELEVATION_NOT_METRIC}. */
116  ELEVATION_NOT_METRIC(OccurrenceIssue.ELEVATION_NOT_METRIC),
117  /** See {@link OccurrenceIssue#ELEVATION_NON_NUMERIC}. */
118  ELEVATION_NON_NUMERIC(OccurrenceIssue.ELEVATION_NON_NUMERIC),
119  /** See {@link OccurrenceIssue#MODIFIED_DATE_INVALID}. */
120  MODIFIED_DATE_INVALID(OccurrenceIssue.MODIFIED_DATE_INVALID),
121  /** See {@link OccurrenceIssue#MODIFIED_DATE_UNLIKELY}. */
122  MODIFIED_DATE_UNLIKELY(OccurrenceIssue.MODIFIED_DATE_UNLIKELY),
123  /** See {@link OccurrenceIssue#IDENTIFIED_DATE_UNLIKELY}. */
124  IDENTIFIED_DATE_UNLIKELY(OccurrenceIssue.IDENTIFIED_DATE_UNLIKELY),
125  /** See {@link OccurrenceIssue#IDENTIFIED_DATE_INVALID}. */
126  IDENTIFIED_DATE_INVALID(OccurrenceIssue.IDENTIFIED_DATE_INVALID),
127
128  /** See {@link OccurrenceIssue#TYPE_STATUS_INVALID}. */
129  TYPE_STATUS_INVALID(OccurrenceIssue.TYPE_STATUS_INVALID),
130  /** See {@link OccurrenceIssue#SUSPECTED_TYPE}. */
131  SUSPECTED_TYPE(OccurrenceIssue.SUSPECTED_TYPE),
132  /** See {@link OccurrenceIssue#MULTIMEDIA_DATE_INVALID}. */
133  MULTIMEDIA_DATE_INVALID(OccurrenceIssue.MULTIMEDIA_DATE_INVALID),
134  /** See {@link OccurrenceIssue#MULTIMEDIA_URI_INVALID}. */
135  MULTIMEDIA_URI_INVALID(OccurrenceIssue.MULTIMEDIA_URI_INVALID),
136  /** See {@link OccurrenceIssue#REFERENCES_URI_INVALID}. */
137  REFERENCES_URI_INVALID(OccurrenceIssue.REFERENCES_URI_INVALID),
138  /** See {@link OccurrenceIssue#INTERPRETATION_ERROR}. */
139  INTERPRETATION_ERROR(OccurrenceIssue.INTERPRETATION_ERROR),
140  /** See {@link OccurrenceIssue#GEOREFERENCED_DATE_UNLIKELY}. */
141  GEOREFERENCED_DATE_UNLIKELY(OccurrenceIssue.GEOREFERENCED_DATE_UNLIKELY),
142  /** See {@link OccurrenceIssue#GEOREFERENCED_DATE_INVALID}. */
143  GEOREFERENCED_DATE_INVALID(OccurrenceIssue.GEOREFERENCED_DATE_INVALID),
144
145  /**
146   * The geospatial scope area is always greater than or equal to the total area sampled as stated
147   * in the (<a href="https://eco.tdwg.org/list/#eco_geospatialScopeAreaValue">term definition</a>).
148   */
149  GEOSPATIAL_SCOPE_AREA_LOWER_THAN_TOTAL_AREA_SAMPLED(
150      INFO, EcoTerm.geospatialScopeAreaValue, EcoTerm.totalAreaSampledValue),
151
152  /** An eco:eventDurationValue must have a corresponding eco:eventDurationUnit. */
153  EVENT_DURATION_UNIT_MISSING(INFO, EcoTerm.eventDurationUnit),
154
155  /** An eco:geospatialScopeAreaValue must have a corresponding eco:geospatialScopeAreaUnit. */
156  GEOSPATIAL_SCOPE_AREA_UNIT_MISSING(INFO, EcoTerm.geospatialScopeAreaUnit),
157
158  /** An eco:samplingEffortValue must have a corresponding eco:samplingEffortUnit. */
159  SAMPLING_EFFORT_UNIT_MISSING(INFO, EcoTerm.samplingEffortUnit),
160
161  /** An eco:totalAreaSampledValue must have a corresponding eco:totalAreaSampledUnit. */
162  TOTAL_AREA_SAMPLED_UNIT_MISSING(INFO, EcoTerm.samplingEffortUnit),
163
164  /** Non target taxa has been provided but the eco:hasNonTargetTaxa is set to false. */
165  HAS_NON_TARGET_TAXA_MISMATCH(INFO, EcoTerm.hasNonTargetTaxa),
166
167  /** Material sample types have been provided but the eco:hasMaterialSamples is set to false. */
168  HAS_MATERIAL_SAMPLES_MISMATCH(INFO, EcoTerm.hasMaterialSamples),
169
170  /** Some target taxonomic scope has been excluded. */
171  TARGET_TAXONOMIC_SCOPE_EXCLUDED(
172      INFO, EcoTerm.targetTaxonomicScope, EcoTerm.excludedTaxonomicScope),
173
174  /** Some target habitat scope has been excluded. */
175  TARGET_HABITAT_SCOPE_EXCLUDED(INFO, EcoTerm.targetHabitatScope, EcoTerm.excludedHabitatScope),
176
177  /** Some target life stage scope has been excluded. */
178  TARGET_LIFE_STAGE_SCOPE_EXCLUDED(
179      INFO, EcoTerm.targetLifeStageScope, EcoTerm.excludedLifeStageScope),
180
181  /** Some target degree of establishment scope has been excluded. */
182  TARGET_DEGREE_OF_ESTABLISHMENT_EXCLUDED(
183      INFO, EcoTerm.targetDegreeOfEstablishmentScope, EcoTerm.excludedDegreeOfEstablishmentScope),
184
185  /** Some target growth form scope has been excluded. */
186  TARGET_GROWTH_FORM_EXCLUDED(INFO, EcoTerm.targetGrowthFormScope, EcoTerm.excludedGrowthFormScope),
187
188  /** Invalid value for numeric fields in Humboldt extension. */
189  SITE_COUNT_INVALID(INFO, EcoTerm.siteCount),
190  GEOSPATIAL_SCOPE_AREA_VALUE_INVALID(INFO, EcoTerm.geospatialScopeAreaValue),
191  TOTAL_AREA_SAMPLED_VALUE_INVALID(INFO, EcoTerm.totalAreaSampledValue),
192  EVENT_DURATION_VALUE_INVALID(INFO, EcoTerm.eventDurationValue),
193  SAMPLING_EFFORT_VALUE_INVALID(INFO, EcoTerm.samplingEffortValue),
194  ABUNDANCE_CAP_INVALID(INFO, EcoTerm.abundanceCap),
195
196  /** Invalid value for boolean fields in Humboldt extension. */
197  IS_TAXONOMIC_SCOPE_FULLY_REPORTED_INVALID(INFO, EcoTerm.isTaxonomicScopeFullyReported),
198  IS_ABSENCE_REPORTED_INVALID(INFO, EcoTerm.isAbsenceReported),
199  HAS_NON_TARGET_TAXA_INVALID(INFO, EcoTerm.hasNonTargetTaxa),
200  ARE_NON_TARGET_TAXA_FULLY_REPORTED_INVALID(INFO, EcoTerm.areNonTargetTaxaFullyReported),
201  IS_LIFE_STAGE_SCOPE_FULLY_REPORTED_INVALID(INFO, EcoTerm.isLifeStageScopeFullyReported),
202  IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED_INVALID(
203      INFO, EcoTerm.isDegreeOfEstablishmentScopeFullyReported),
204  IS_GROWTH_FORM_SCOPE_FULLY_REPORTED_INVALID(INFO, EcoTerm.isGrowthFormScopeFullyReported),
205  HAS_NON_TARGET_ORGANISMS_INVALID(INFO, EcoTerm.hasNonTargetOrganisms),
206  IS_ABUNDANCE_REPORTED_INVALID(INFO, EcoTerm.isAbundanceReported),
207  IS_ABUNDANCE_CAP_REPORTED_INVALID(INFO, EcoTerm.isAbundanceCapReported),
208  IS_VEGETATION_COVER_REPORTED_INVALID(INFO, EcoTerm.isVegetationCoverReported),
209  IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE_INVALID(
210      INFO, EcoTerm.isLeastSpecificTargetCategoryQuantityInclusive),
211  HAS_VOUCHERS_INVALID(INFO, EcoTerm.hasVouchers),
212  HAS_MATERIAL_SAMPLES_INVALID(INFO, EcoTerm.hasMaterialSamples),
213  IS_SAMPLING_EFFORT_REPORTED_INVALID(INFO, EcoTerm.isSamplingEffortReported);
214
215  private final Set<Term> relatedTerms;
216  private final InterpretationRemarkSeverity severity;
217  private final boolean isDeprecated;
218
219  EventIssue(OccurrenceIssue occurrenceIssue) {
220    this.severity = occurrenceIssue.getSeverity();
221    this.relatedTerms = occurrenceIssue.getRelatedTerms();
222    this.isDeprecated = occurrenceIssue.isDeprecated();
223  }
224
225  /** {@link EventIssue} not linked to any specific {@link Term}. */
226  EventIssue(InterpretationRemarkSeverity severity) {
227    this.severity = severity;
228    this.relatedTerms = Collections.emptySet();
229    this.isDeprecated = AnnotationUtils.isFieldDeprecated(EventIssue.class, this.name());
230  }
231
232  /** {@link EventIssue} linked to the provided {@link Term}. */
233  EventIssue(InterpretationRemarkSeverity severity, Term... relatedTerms) {
234    this.severity = severity;
235    this.relatedTerms = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(relatedTerms)));
236    this.isDeprecated = AnnotationUtils.isFieldDeprecated(EventIssue.class, this.name());
237  }
238
239  @Override
240  public String getId() {
241    return name();
242  }
243
244  @Override
245  public Set<Term> getRelatedTerms() {
246    return relatedTerms;
247  }
248
249  @Override
250  public InterpretationRemarkSeverity getSeverity() {
251    return severity;
252  }
253
254  @Override
255  public boolean isDeprecated() {
256    return isDeprecated;
257  }
258}