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 taxonomy. 248 */ 249 kingdomKey(DwcTerm.GROUP_TAXON), 250 251 /** 252 * The key to the accepted phylum in the taxonomy. 253 */ 254 phylumKey(DwcTerm.GROUP_TAXON), 255 256 /** 257 * The key to the accepted class in the taxonomy. 258 */ 259 classKey(DwcTerm.GROUP_TAXON), 260 261 /** 262 * The key to the accepted order in the taxonomy. 263 */ 264 orderKey(DwcTerm.GROUP_TAXON), 265 266 /** 267 * The key to the accepted superfamily in the taxonomy. 268 */ 269 superfamilyKey(DwcTerm.GROUP_TAXON), 270 271 /** 272 * The key to the accepted family in the taxonomy. 273 */ 274 familyKey(DwcTerm.GROUP_TAXON), 275 276 /** 277 * The key to the accepted subfamily in the taxonomy. 278 */ 279 subfamilyKey(DwcTerm.GROUP_TAXON), 280 281 /** 282 * The key to the accepted tribe in the taxonomy. 283 */ 284 tribeKey(DwcTerm.GROUP_TAXON), 285 286 /** 287 * The key to the accepted subtribe in the taxonomy. 288 */ 289 subtribeKey(DwcTerm.GROUP_TAXON), 290 291 /** 292 * The key to the accepted genus in the taxonomy. 293 */ 294 genusKey(DwcTerm.GROUP_TAXON), 295 296 /** 297 * The key to the accepted subgenus in the taxonomy. 298 */ 299 subgenusKey(DwcTerm.GROUP_TAXON), 300 301 /** 302 * The backbone key to the accepted species. 303 * In case the taxonKey is of a higher rank than species (e.g. genus) speciesKey is null. 304 * In case taxonKey represents an infraspecific taxon the speciesKey points to the species 305 * the infraspecies is classified as. In case of taxonKey being a species the speciesKey is the same. 306 */ 307 speciesKey(DwcTerm.GROUP_TAXON), 308 309 /** 310 * The canonical name without authorship of the accepted species. 311 */ 312 species(DwcTerm.GROUP_TAXON), 313 314 // experimental Taxon properties 315 canonicalName(DwcTerm.GROUP_TAXON), 316 nameType(DwcTerm.GROUP_TAXON), 317 318 /** 319 * The scientific name the type associated acceptedNubKey. 320 */ 321 acceptedScientificName(DwcTerm.GROUP_TAXON), 322 323 /** 324 * Scientific name as provided by the source. 325 */ 326 verbatimScientificName(DwcTerm.GROUP_TAXON), 327 328 /** 329 * The scientific name the type status of this specimen applies to. 330 * Term proposed in Darwin Core, but not yet ratified. 331 */ 332 typifiedName(DwcTerm.GROUP_IDENTIFICATION), 333 334 /** 335 * The kind of protocol used when the record was last crawled by GBIF. 336 * See <a href="http://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/EndpointType.html">EndpointType enumeration</a> for possible values. 337 */ 338 protocol(GbifTerm.GROUP_CRAWLING), 339 340 /** 341 * The date this record was last parsed from raw xml/json into a verbatim GBIF record. 342 */ 343 lastParsed(GbifTerm.GROUP_CRAWLING), 344 345 /** 346 * The date this record was last crawled/harvested by GBIF from the endpoint. 347 */ 348 lastCrawled(GbifTerm.GROUP_CRAWLING), 349 350 // Species Profile checklist extension 351 isMarine(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 352 isFreshwater(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 353 isTerrestrial(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 354 isInvasive(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 355 isHybrid(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 356 isExtinct(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 357 livingPeriod(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "timePeriod"), 358 ageInDays(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 359 sizeInMillimeters(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "sizeInMillimeter"), 360 massInGrams(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "massInGram", "weightInGram"), 361 lifeForm(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 362 363 // Vernacular Name checklist extension 364 organismPart(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 365 isPlural(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 366 isPreferredName(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 367 368 // Distribution checklist extension 369 appendixCITES(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 370 numberOfOccurrences(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 371 372 /** Boolean indicating if the publishing country is different to the location country. */ 373 repatriated(DwcTerm.GROUP_OCCURRENCE), 374 375 /** Calculated relative organism quantity, based on organism and sample measure types */ 376 relativeOrganismQuantity(DwcTerm.GROUP_MATERIAL_SAMPLE), 377 378 /** An identifier for a project to which a record belongs. */ 379 projectId(DwcTerm.GROUP_OCCURRENCE), 380 381 /** Flag occurrence when associatedSequences/extension exists */ 382 isSequenced(DwcTerm.GROUP_OCCURRENCE), 383 384 /** GBIF region based on country code */ 385 gbifRegion(DwcTerm.GROUP_LOCATION), 386 387 /** GBIF region based on publishing country code */ 388 publishedByGbifRegion(DwcTerm.GROUP_LOCATION), 389 geologicalTime(DwcTerm.GROUP_OCCURRENCE), 390 lithostratigraphy(DwcTerm.GROUP_OCCURRENCE), 391 biostratigraphy(DwcTerm.GROUP_OCCURRENCE), 392 dnaSequenceID(GbifTerm.GROUP_DNA_DERIVED_DATA), 393 394 /** 395 * The <a href="http://rs.tdwg.org/eco/terms/Event">Humboldt</a> extension row type. 396 */ 397 Humboldt(GbifTerm.GROUP_ROW_TYPE); 398 399 private static final String PREFIX = "gbif"; 400 private static final String NS = "http://rs.gbif.org/terms/1.0/"; 401 private static final URI NS_URI = URI.create(NS); 402 403 public static final String GROUP_CRAWLING = "Crawling"; 404 public static final String GROUP_DATASET = "Dataset"; 405 public static final String GROUP_ROW_TYPE = "RowType"; 406 public static final String GROUP_SPECIES_DISTRIBUTION_EXTENSION = "SpeciesDistribution"; 407 public static final String GROUP_SPECIES_PROFILE_EXTENSION = "SpeciesProfile"; 408 public static final String GROUP_VERNACULAR_NAME_EXTENSION = "VernacularName"; 409 public static final String GROUP_DNA_DERIVED_DATA = "DnaDerivedData"; 410 public static final String GROUP_HUMBOLDT = "Humboldt"; 411 412 /** 413 * Lists all GBIF term groups. 414 */ 415 public static final String[] GROUPS = {GROUP_CRAWLING, GROUP_DATASET, DwcTerm.GROUP_OCCURRENCE, GROUP_ROW_TYPE, 416 GROUP_SPECIES_DISTRIBUTION_EXTENSION, GROUP_SPECIES_PROFILE_EXTENSION, DwcTerm.GROUP_TAXON, 417 GROUP_VERNACULAR_NAME_EXTENSION, DwcTerm.GROUP_LOCATION}; 418 419 /** 420 * Lists all GBIF terms in taxon group. 421 */ 422 public static final GbifTerm[] TAXONOMIC_TERMS = 423 {GbifTerm.checklistKey, GbifTerm.taxonKey, GbifTerm.acceptedTaxonKey, GbifTerm.kingdomKey, GbifTerm.phylumKey, 424 GbifTerm.classKey, GbifTerm.orderKey, GbifTerm.superfamilyKey, GbifTerm.familyKey, GbifTerm.subfamilyKey, 425 GbifTerm.tribeKey, GbifTerm.subtribeKey, GbifTerm.genusKey, GbifTerm.subgenusKey, GbifTerm.speciesKey, 426 GbifTerm.species, GbifTerm.canonicalName, GbifTerm.nameType, GbifTerm.acceptedScientificName, 427 GbifTerm.verbatimScientificName}; 428 429 private final String groupName; 430 private final boolean isDeprecated; 431 public final String[] normAlts; 432 433 GbifTerm(String groupName, String... alternatives) { 434 this.groupName = groupName; 435 this.normAlts = alternatives; 436 boolean deprecatedAnnotationPresent = false; 437 try { 438 deprecatedAnnotationPresent = GbifTerm.class.getField(this.name()).isAnnotationPresent(Deprecated.class); 439 } catch (NoSuchFieldException ignore) { } 440 this.isDeprecated = deprecatedAnnotationPresent; 441 } 442 443 /** 444 * The simple term name without a namespace. 445 * For example taxonKey. 446 * 447 * @return simple term name 448 */ 449 @Override 450 public String simpleName() { 451 return name(); 452 } 453 454 /** 455 * Array of alternative simple names in use for the term. 456 * 457 * @return simple term name 458 */ 459 @Override 460 public String[] alternativeNames() { 461 return normAlts; 462 } 463 464 /** 465 * The optional group the term is grouped in. 466 * For example Occurrence, Taxon, etc. 467 */ 468 public String getGroup() { 469 return groupName; 470 } 471 472 473 /** 474 * List all terms that belong to a given group. 475 * 476 * @param group the group to list terms for 477 * @return the list of GBIF terms in the given group 478 */ 479 public static List<GbifTerm> listByGroup(String group) { 480 List<GbifTerm> terms = new ArrayList<GbifTerm>(); 481 for (GbifTerm t : GbifTerm.values()) { 482 if (t.getGroup().equalsIgnoreCase(group)) { 483 terms.add(t); 484 } 485 } 486 return terms; 487 } 488 489 @Override 490 public String toString() { 491 return prefixedName(); 492 } 493 494 @Override 495 public boolean isClass() { 496 return Character.isUpperCase(simpleName().charAt(0)); 497 } 498 499 @Override 500 public String prefix() { 501 return PREFIX; 502 } 503 504 @Override 505 public URI namespace() { 506 return NS_URI; 507 } 508 509 /** 510 * 511 * @return true if the Term is annotated with @Deprecated. 512 */ 513 public boolean isDeprecated(){ 514 return isDeprecated; 515 } 516 517}