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 isTerrestrial(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 333 isFreshwater(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 334 isHybrid(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 335 isExtinct(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 336 livingPeriod(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "timePeriod"), 337 lifeForm(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 338 ageInDays(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 339 sizeInMillimeter(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 340 massInGram(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "weightInGram"), 341 342 // Vernacular Name checklist extension 343 organismPart(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 344 isPlural(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 345 isPreferredName(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 346 347 // Distribution checklist extension 348 appendixCITES(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 349 numberOfOccurrences(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 350 351 /** Boolean indicating if the publishing country is different to the location country. */ 352 repatriated(DwcTerm.GROUP_OCCURRENCE), 353 354 /** Calculated relative organism quantity, based on organism and sample measure types */ 355 relativeOrganismQuantity(DwcTerm.GROUP_MATERIAL_SAMPLE), 356 357 /** An identifier for a project to which a record belongs. */ 358 projectId(DwcTerm.GROUP_OCCURRENCE), 359 360 /** Flag occurrence when associatedSequences/extension exists */ 361 isSequenced(DwcTerm.GROUP_OCCURRENCE), 362 363 /** GBIF region based on country code */ 364 gbifRegion(DwcTerm.GROUP_LOCATION), 365 366 /** GBIF region based on publishing country code */ 367 publishedByGbifRegion(DwcTerm.GROUP_LOCATION), 368 geologicalTime(DwcTerm.GROUP_OCCURRENCE), 369 lithostratigraphy(DwcTerm.GROUP_OCCURRENCE), 370 biostratigraphy(DwcTerm.GROUP_OCCURRENCE), 371 dnaSequenceID(GbifTerm.GROUP_DNA_DERIVED_DATA); 372 373 private static final String PREFIX = "gbif"; 374 private static final String NS = "http://rs.gbif.org/terms/1.0/"; 375 private static final URI NS_URI = URI.create(NS); 376 377 public static final String GROUP_CRAWLING = "Crawling"; 378 public static final String GROUP_DATASET = "Dataset"; 379 public static final String GROUP_ROW_TYPE = "RowType"; 380 public static final String GROUP_SPECIES_DISTRIBUTION_EXTENSION = "SpeciesDistribution"; 381 public static final String GROUP_SPECIES_PROFILE_EXTENSION = "SpeciesProfile"; 382 public static final String GROUP_VERNACULAR_NAME_EXTENSION = "VernacularName"; 383 public static final String GROUP_DNA_DERIVED_DATA = "DnaDerivedData"; 384 385 /** 386 * Lists all GBIF term groups. 387 */ 388 public static final String[] GROUPS = {GROUP_CRAWLING, GROUP_DATASET, DwcTerm.GROUP_OCCURRENCE, GROUP_ROW_TYPE, 389 GROUP_SPECIES_DISTRIBUTION_EXTENSION, GROUP_SPECIES_PROFILE_EXTENSION, DwcTerm.GROUP_TAXON, 390 GROUP_VERNACULAR_NAME_EXTENSION, DwcTerm.GROUP_LOCATION}; 391 392 /** 393 * Lists all GBIF terms in taxon group. 394 */ 395 public static final GbifTerm[] TAXONOMIC_TERMS = 396 {GbifTerm.checklistKey, GbifTerm.taxonKey, GbifTerm.acceptedTaxonKey, GbifTerm.kingdomKey, GbifTerm.phylumKey, GbifTerm.classKey, 397 GbifTerm.orderKey, GbifTerm.familyKey, GbifTerm.genusKey, GbifTerm.subgenusKey, GbifTerm.speciesKey, 398 GbifTerm.species, GbifTerm.canonicalName, GbifTerm.nameType, GbifTerm.acceptedScientificName, 399 GbifTerm.verbatimScientificName}; 400 401 private final String groupName; 402 private final boolean isDeprecated; 403 public final String[] normAlts; 404 405 GbifTerm(String groupName, String... alternatives) { 406 this.groupName = groupName; 407 this.normAlts = alternatives; 408 boolean deprecatedAnnotationPresent = false; 409 try { 410 deprecatedAnnotationPresent = GbifTerm.class.getField(this.name()).isAnnotationPresent(Deprecated.class); 411 } catch (NoSuchFieldException ignore) { } 412 this.isDeprecated = deprecatedAnnotationPresent; 413 } 414 415 /** 416 * The simple term name without a namespace. 417 * For example taxonKey. 418 * 419 * @return simple term name 420 */ 421 @Override 422 public String simpleName() { 423 return name(); 424 } 425 426 /** 427 * Array of alternative simple names in use for the term. 428 * 429 * @return simple term name 430 */ 431 @Override 432 public String[] alternativeNames() { 433 return normAlts; 434 } 435 436 /** 437 * The optional group the term is grouped in. 438 * For example Occurrence, Taxon, etc. 439 */ 440 public String getGroup() { 441 return groupName; 442 } 443 444 445 /** 446 * List all terms that belong to a given group. 447 * 448 * @param group the group to list terms for 449 * @return the list of GBIF terms in the given group 450 */ 451 public static List<GbifTerm> listByGroup(String group) { 452 List<GbifTerm> terms = new ArrayList<GbifTerm>(); 453 for (GbifTerm t : GbifTerm.values()) { 454 if (t.getGroup().equalsIgnoreCase(group)) { 455 terms.add(t); 456 } 457 } 458 return terms; 459 } 460 461 @Override 462 public String toString() { 463 return prefixedName(); 464 } 465 466 @Override 467 public boolean isClass() { 468 return Character.isUpperCase(simpleName().charAt(0)); 469 } 470 471 @Override 472 public String prefix() { 473 return PREFIX; 474 } 475 476 @Override 477 public URI namespace() { 478 return NS_URI; 479 } 480 481 /** 482 * 483 * @return true if the Term is annotated with @Deprecated. 484 */ 485 public boolean isDeprecated(){ 486 return isDeprecated; 487 } 488 489}