001/* 002 * Copyright 2021 Global Biodiversity Information Facility (GBIF) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.gbif.dwc.terms; 017 018import java.io.Serializable; 019import java.net.URI; 020import java.util.ArrayList; 021import java.util.List; 022 023public enum GbifTerm implements Term, AlternativeNames, Serializable { 024 // row types 025 026 /** 027 * The <a href="http://rs.gbif.org/terms/1.0/Description">GBIF Taxon Description</a> 028 * extension row type. 029 */ 030 Description(GbifTerm.GROUP_ROW_TYPE), 031 032 /** 033 * The <a href="http://rs.gbif.org/terms/1.0/Distribution">GBIF Species Distribution</a> 034 * extension row type. 035 */ 036 Distribution(GbifTerm.GROUP_ROW_TYPE), 037 038 /** 039 * The <a href="http://rs.gbif.org/terms/1.0/Identifier">GBIF Alternative Identifiers</a> 040 * extension row type. 041 */ 042 Identifier(GbifTerm.GROUP_ROW_TYPE), 043 044 /** 045 * The deprecated <a href="http://rs.gbif.org/terms/1.0/Image">GBIF Simple Images</a> 046 * extension row type. 047 */ 048 Image(GbifTerm.GROUP_ROW_TYPE, "Images"), 049 050 /** 051 * The <a href="http://rs.gbif.org/terms/1.0/References">GBIF Literature References</a> 052 * extension row type. 053 */ 054 Reference(GbifTerm.GROUP_ROW_TYPE, "References"), 055 056 /** 057 * The <a href="http://rs.gbif.org/terms/1.0/SpeciesProfile">GBIF Species Profile</a> 058 * extension row type. 059 */ 060 SpeciesProfile(GbifTerm.GROUP_ROW_TYPE, "SpeciesMiniProfile", "SpeciesInfo", "SpeciesData", "SpeciesFactsheet"), 061 062 /** 063 * The <a href="http://rs.gbif.org/terms/1.0/TypesAndSpecimen">GBIF Types and Specimen</a> 064 * extension row type. 065 */ 066 TypesAndSpecimen(GbifTerm.GROUP_ROW_TYPE, "Specimen", "Types", "TypeDesignation"), 067 068 /** 069 * The <a href="http://rs.gbif.org/terms/1.0/VernacularNames">GBIF Vernacular Names</a> 070 * extension row type. 071 */ 072 VernacularName(GbifTerm.GROUP_ROW_TYPE, "VernacularNames", "Vernacular", "Vernaculars"), 073 074 /** 075 * The <a href="http://rs.gbif.org/terms/1.0/Multimedia">GBIF Simple Multimedia</a> 076 * extension row type. 077 */ 078 Multimedia(GbifTerm.GROUP_ROW_TYPE), 079 080 /** 081 * The UUID key for the dataset registered in GBIF. 082 */ 083 datasetKey(GbifTerm.GROUP_DATASET), 084 085 /** 086 * The ISO 3166 2-letter code of the country of the organization that publishes the dataset to which the occurrence belongs. 087 */ 088 publishingCountry(GbifTerm.GROUP_DATASET), 089 090 /** 091 * Numerical, stable identifier assigned by GBIF to an Occurrence record. 092 */ 093 gbifID(DwcTerm.GROUP_OCCURRENCE), 094 095 /** 096 * Timestamp of the last time the record was (re)interpreted by GBIF. 097 */ 098 lastInterpreted(DwcTerm.GROUP_OCCURRENCE), 099 100 /** 101 * The uncertainty radius for the latitude and longitude in decimal degrees. 102 */ 103 @Deprecated 104 coordinateAccuracy(DwcTerm.GROUP_OCCURRENCE), 105 106 /** 107 * Elevation in metres above sea level (altitude). 108 * <p> 109 * The elevation is the absolute vertical position of the observed location (z-coordinate). 110 * If depth is given or not will not impact the 3-dimensional position. 111 * For example a location 100m below the surface of a lake in 2000m altitude has a depth of 100 and 112 * an elevation of 1900. 113 * </p> 114 * <p> 115 * If minimum and maximum values are given the elevation is calculated using the equation: 116 * <code>(minimumElevationInMeters + maximumElevationInMeters) / 2</code>. 117 * For consistency and ease of use GBIF decided to always use a value in metres plus its accuracy instead of 118 * min/max values which are sometimes used in Darwin Core. See also depth & distanceAboveSurface. 119 * </p> 120 */ 121 elevation(DwcTerm.GROUP_LOCATION), 122 123 /** 124 * Elevation accuracy is the uncertainty for the elevation in metres. 125 * <p> 126 * The elevation accuracy is calculated using the equation: <code>(maximumElevationInMeters - minimumElevationInMeters) / 2</code> 127 * in case a minimum and maximum verbatim value is given. 128 * </p> 129 */ 130 elevationAccuracy(DwcTerm.GROUP_LOCATION), 131 132 /** 133 * Depth in metres below the surface. 134 * <p> 135 * Complimentary and relative to elevation, depth indicates the distance to the earth surface, whether that is water 136 * or ground. 137 * For example a location 100m below the surface of a lake in 2000m altitude has a depth of 100 and 138 * an elevation of 1900. 139 * </p> 140 * <p> 141 * The depth is calculated using the equation: <code>(minimumDepthInMeters + maximumDepthInMeters) / 2</code>. 142 * For consistency and ease of use GBIF decided to always use a value in meters plus it's accuracy instead of 143 * min/max values which are sometimes used in Darwin Core. See also elevation & distanceAboveSurface. 144 * </p> 145 */ 146 depth(DwcTerm.GROUP_LOCATION), 147 148 /** 149 * Depth accuracy is the uncertainty for the depth in metres. 150 * <p> 151 * The depth accuracy is calculated using the equation: <code>(maximumDepthInMeters - minimumDepthInMeters) / 2</code> 152 * in case a minimum and maximum verbatim value is given. 153 * </p> 154 */ 155 depthAccuracy(DwcTerm.GROUP_LOCATION), 156 157 /** 158 * Replaced by Darwin Core terms <a href="http://rs.tdwg.org/dwc/terms/minimumDistanceAboveSurfaceInMeters">dwc:minimumDistanceAboveSurfaceInMeters</a> 159 * and <a href="http://rs.tdwg.org/dwc/terms/maximumDistanceAboveSurfaceInMeters">dwc:maximumDistanceAboveSurfaceInMeters</a>. 160 */ 161 @Deprecated 162 distanceAboveSurface(DwcTerm.GROUP_LOCATION), 163 164 /** 165 * Replaced by Darwin Core terms <a href="http://rs.tdwg.org/dwc/terms/minimumDistanceAboveSurfaceInMeters">dwc:minimumDistanceAboveSurfaceInMeters</a> 166 * and <a href="http://rs.tdwg.org/dwc/terms/maximumDistanceAboveSurfaceInMeters">dwc:maximumDistanceAboveSurfaceInMeters</a>. 167 */ 168 @Deprecated 169 distanceAboveSurfaceAccuracy(DwcTerm.GROUP_LOCATION), 170 171 /** 172 * The distance in metres from a known centroid, e.g. a country centroid. 173 */ 174 distanceFromCentroidInMeters(DwcTerm.GROUP_LOCATION), 175 176 /** 177 * Any issue found during processing and interpretation or the record. 178 * See <a href="https://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/OccurrenceIssue.html">OccurrenceIssue enumeration</a> for possible values. 179 */ 180 issue(DwcTerm.GROUP_OCCURRENCE), 181 182 /** 183 * Issue found during processing and interpretation or the record related to a specific checklist. 184 * See <a href="https://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/OccurrenceIssue.html">OccurrenceIssue enumeration</a> for possible values. 185 */ 186 taxonomicIssue(DwcTerm.GROUP_OCCURRENCE), 187 188 /** 189 * Issue found during processing and interpretation or the record that are non-taxonomic. 190 */ 191 nonTaxonomicIssue(DwcTerm.GROUP_OCCURRENCE), 192 193 /** 194 * The media type given as Dublin Core type values, in particular StillImage, MovingImage or Sound. 195 */ 196 mediaType(DwcTerm.GROUP_OCCURRENCE), 197 198 // experimental Occurrence properties 199 infraspecificMarker(DwcTerm.GROUP_OCCURRENCE), 200 201 // Types and Specimen checklist extension 202 typeDesignatedBy(DwcTerm.GROUP_OCCURRENCE), 203 typeDesignationType(DwcTerm.GROUP_OCCURRENCE), 204 205 /** 206 * Boolean indicating that a valid latitude and longitude exists. 207 * Even if existing it might still have issues, see hasGeospatialIssues and issue. 208 */ 209 hasCoordinate(DwcTerm.GROUP_OCCURRENCE), 210 211 /** 212 * Boolean indicating that some spatial validation rule has not passed. 213 * Primarily used to indicate that the record should not be displayed on a map. 214 */ 215 hasGeospatialIssues(DwcTerm.GROUP_OCCURRENCE), 216 217 218 /** 219 * The checklist key. 220 * <p> 221 * The taxonomic checklist to use when search using a taxonKey, a higher taxonKey e.g. phylumKey 222 * or when searching with a scientific name 223 * </p> 224 */ 225 checklistKey(DwcTerm.GROUP_TAXON), 226 227 /** 228 * The GBIF backbone key. 229 * <p> 230 * The best matching, accepted GBIF backbone name usage representing this occurrence. 231 * In case the verbatim scientific name and its classification can only be matched to a higher rank this will 232 * represent the lowest matching rank. In the worst case this could just be for example Animalia. 233 * </p> 234 * <p> 235 * In contrast dwc:taxonID is only used for the source ids similar to occurrenceID 236 * </p> 237 */ 238 taxonKey(DwcTerm.GROUP_TAXON), 239 240 241 /** 242 * The GBIF backbone key of the accepted taxon key. 243 */ 244 acceptedTaxonKey(DwcTerm.GROUP_TAXON), 245 246 /** 247 * The key to the accepted kingdom in the GBIF backbone. 248 */ 249 kingdomKey(DwcTerm.GROUP_TAXON), 250 251 /** 252 * The key to the accepted phylum in the GBIF backbone. 253 */ 254 phylumKey(DwcTerm.GROUP_TAXON), 255 256 /** 257 * The key to the accepted class in the GBIF backbone. 258 */ 259 classKey(DwcTerm.GROUP_TAXON), 260 261 /** 262 * The key to the accepted order in the GBIF backbone. 263 */ 264 orderKey(DwcTerm.GROUP_TAXON), 265 266 /** 267 * The key to the accepted family in the GBIF backbone. 268 */ 269 familyKey(DwcTerm.GROUP_TAXON), 270 271 /** 272 * The key to the accepted genus in the GBIF backbone. 273 */ 274 genusKey(DwcTerm.GROUP_TAXON), 275 276 /** 277 * The key to the accepted subgenus in the GBIF backbone. 278 */ 279 subgenusKey(DwcTerm.GROUP_TAXON), 280 281 /** 282 * The backbone key to the accepted species. 283 * In case the taxonKey is of a higher rank than species (e.g. genus) speciesKey is null. 284 * In case taxonKey represents an infraspecific taxon the speciesKey points to the species 285 * the infraspecies is classified as. In case of taxonKey being a species the speciesKey is the same. 286 */ 287 speciesKey(DwcTerm.GROUP_TAXON), 288 289 /** 290 * The canonical name without authorship of the accepted species. 291 */ 292 species(DwcTerm.GROUP_TAXON), 293 294 // experimental Taxon properties 295 canonicalName(DwcTerm.GROUP_TAXON), 296 nameType(DwcTerm.GROUP_TAXON), 297 298 /** 299 * The scientific name the type associated acceptedNubKey. 300 */ 301 acceptedScientificName(DwcTerm.GROUP_TAXON), 302 303 /** 304 * Scientific name as provided by the source. 305 */ 306 verbatimScientificName(DwcTerm.GROUP_TAXON), 307 308 /** 309 * The scientific name the type status of this specimen applies to. 310 * Term proposed in Darwin Core, but not yet ratified. 311 */ 312 typifiedName(DwcTerm.GROUP_IDENTIFICATION), 313 314 /** 315 * The kind of protocol used when the record was last crawled by GBIF. 316 * See <a href="http://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/EndpointType.html">EndpointType enumeration</a> for possible values. 317 */ 318 protocol(GbifTerm.GROUP_CRAWLING), 319 320 /** 321 * The date this record was last parsed from raw xml/json into a verbatim GBIF record. 322 */ 323 lastParsed(GbifTerm.GROUP_CRAWLING), 324 325 /** 326 * The date this record was last crawled/harvested by GBIF from the endpoint. 327 */ 328 lastCrawled(GbifTerm.GROUP_CRAWLING), 329 330 // Species Profile checklist extension 331 isMarine(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 332 isFreshwater(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 333 isTerrestrial(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 334 isInvasive(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 335 isHybrid(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 336 isExtinct(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 337 livingPeriod(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "timePeriod"), 338 ageInDays(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 339 sizeInMillimeters(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "sizeInMillimeter"), 340 massInGrams(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "massInGram", "weightInGram"), 341 lifeForm(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 342 343 // Vernacular Name checklist extension 344 organismPart(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 345 isPlural(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 346 isPreferredName(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 347 348 // Distribution checklist extension 349 appendixCITES(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 350 numberOfOccurrences(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 351 352 /** Boolean indicating if the publishing country is different to the location country. */ 353 repatriated(DwcTerm.GROUP_OCCURRENCE), 354 355 /** Calculated relative organism quantity, based on organism and sample measure types */ 356 relativeOrganismQuantity(DwcTerm.GROUP_MATERIAL_SAMPLE), 357 358 /** An identifier for a project to which a record belongs. */ 359 projectId(DwcTerm.GROUP_OCCURRENCE), 360 361 /** Flag occurrence when associatedSequences/extension exists */ 362 isSequenced(DwcTerm.GROUP_OCCURRENCE), 363 364 /** GBIF region based on country code */ 365 gbifRegion(DwcTerm.GROUP_LOCATION), 366 367 /** GBIF region based on publishing country code */ 368 publishedByGbifRegion(DwcTerm.GROUP_LOCATION), 369 geologicalTime(DwcTerm.GROUP_OCCURRENCE), 370 lithostratigraphy(DwcTerm.GROUP_OCCURRENCE), 371 biostratigraphy(DwcTerm.GROUP_OCCURRENCE), 372 dnaSequenceID(GbifTerm.GROUP_DNA_DERIVED_DATA); 373 374 private static final String PREFIX = "gbif"; 375 private static final String NS = "http://rs.gbif.org/terms/1.0/"; 376 private static final URI NS_URI = URI.create(NS); 377 378 public static final String GROUP_CRAWLING = "Crawling"; 379 public static final String GROUP_DATASET = "Dataset"; 380 public static final String GROUP_ROW_TYPE = "RowType"; 381 public static final String GROUP_SPECIES_DISTRIBUTION_EXTENSION = "SpeciesDistribution"; 382 public static final String GROUP_SPECIES_PROFILE_EXTENSION = "SpeciesProfile"; 383 public static final String GROUP_VERNACULAR_NAME_EXTENSION = "VernacularName"; 384 public static final String GROUP_DNA_DERIVED_DATA = "DnaDerivedData"; 385 386 /** 387 * Lists all GBIF term groups. 388 */ 389 public static final String[] GROUPS = {GROUP_CRAWLING, GROUP_DATASET, DwcTerm.GROUP_OCCURRENCE, GROUP_ROW_TYPE, 390 GROUP_SPECIES_DISTRIBUTION_EXTENSION, GROUP_SPECIES_PROFILE_EXTENSION, DwcTerm.GROUP_TAXON, 391 GROUP_VERNACULAR_NAME_EXTENSION, DwcTerm.GROUP_LOCATION}; 392 393 /** 394 * Lists all GBIF terms in taxon group. 395 */ 396 public static final GbifTerm[] TAXONOMIC_TERMS = 397 {GbifTerm.checklistKey, GbifTerm.taxonKey, GbifTerm.acceptedTaxonKey, GbifTerm.kingdomKey, GbifTerm.phylumKey, GbifTerm.classKey, 398 GbifTerm.orderKey, GbifTerm.familyKey, GbifTerm.genusKey, GbifTerm.subgenusKey, GbifTerm.speciesKey, 399 GbifTerm.species, GbifTerm.canonicalName, GbifTerm.nameType, GbifTerm.acceptedScientificName, 400 GbifTerm.verbatimScientificName}; 401 402 private final String groupName; 403 private final boolean isDeprecated; 404 public final String[] normAlts; 405 406 GbifTerm(String groupName, String... alternatives) { 407 this.groupName = groupName; 408 this.normAlts = alternatives; 409 boolean deprecatedAnnotationPresent = false; 410 try { 411 deprecatedAnnotationPresent = GbifTerm.class.getField(this.name()).isAnnotationPresent(Deprecated.class); 412 } catch (NoSuchFieldException ignore) { } 413 this.isDeprecated = deprecatedAnnotationPresent; 414 } 415 416 /** 417 * The simple term name without a namespace. 418 * For example taxonKey. 419 * 420 * @return simple term name 421 */ 422 @Override 423 public String simpleName() { 424 return name(); 425 } 426 427 /** 428 * Array of alternative simple names in use for the term. 429 * 430 * @return simple term name 431 */ 432 @Override 433 public String[] alternativeNames() { 434 return normAlts; 435 } 436 437 /** 438 * The optional group the term is grouped in. 439 * For example Occurrence, Taxon, etc. 440 */ 441 public String getGroup() { 442 return groupName; 443 } 444 445 446 /** 447 * List all terms that belong to a given group. 448 * 449 * @param group the group to list terms for 450 * @return the list of GBIF terms in the given group 451 */ 452 public static List<GbifTerm> listByGroup(String group) { 453 List<GbifTerm> terms = new ArrayList<GbifTerm>(); 454 for (GbifTerm t : GbifTerm.values()) { 455 if (t.getGroup().equalsIgnoreCase(group)) { 456 terms.add(t); 457 } 458 } 459 return terms; 460 } 461 462 @Override 463 public String toString() { 464 return prefixedName(); 465 } 466 467 @Override 468 public boolean isClass() { 469 return Character.isUpperCase(simpleName().charAt(0)); 470 } 471 472 @Override 473 public String prefix() { 474 return PREFIX; 475 } 476 477 @Override 478 public URI namespace() { 479 return NS_URI; 480 } 481 482 /** 483 * 484 * @return true if the Term is annotated with @Deprecated. 485 */ 486 public boolean isDeprecated(){ 487 return isDeprecated; 488 } 489 490}