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 * The media type given as Dublin Core type values, in particular StillImage, MovingImage or Sound. 184 */ 185 mediaType(DwcTerm.GROUP_OCCURRENCE), 186 187 // experimental Occurrence properties 188 infraspecificMarker(DwcTerm.GROUP_OCCURRENCE), 189 190 // Types and Specimen checklist extension 191 typeDesignatedBy(DwcTerm.GROUP_OCCURRENCE), 192 typeDesignationType(DwcTerm.GROUP_OCCURRENCE), 193 194 /** 195 * Boolean indicating that a valid latitude and longitude exists. 196 * Even if existing it might still have issues, see hasGeospatialIssues and issue. 197 */ 198 hasCoordinate(DwcTerm.GROUP_OCCURRENCE), 199 200 /** 201 * Boolean indicating that some spatial validation rule has not passed. 202 * Primarily used to indicate that the record should not be displayed on a map. 203 */ 204 hasGeospatialIssues(DwcTerm.GROUP_OCCURRENCE), 205 206 /** 207 * The GBIF backbone key. 208 * <p> 209 * The best matching, accepted GBIF backbone name usage representing this occurrence. 210 * In case the verbatim scientific name and its classification can only be matched to a higher rank this will 211 * represent the lowest matching rank. In the worst case this could just be for example Animalia. 212 * </p> 213 * <p> 214 * In contrast dwc:taxonID is only used for the source ids similar to occurrenceID 215 * </p> 216 */ 217 taxonKey(DwcTerm.GROUP_TAXON), 218 219 220 /** 221 * The GBIF backbone key of the accepted taxon key. 222 */ 223 acceptedTaxonKey(DwcTerm.GROUP_TAXON), 224 225 /** 226 * The key to the accepted kingdom in the GBIF backbone. 227 */ 228 kingdomKey(DwcTerm.GROUP_TAXON), 229 230 /** 231 * The key to the accepted phylum in the GBIF backbone. 232 */ 233 phylumKey(DwcTerm.GROUP_TAXON), 234 235 /** 236 * The key to the accepted class in the GBIF backbone. 237 */ 238 classKey(DwcTerm.GROUP_TAXON), 239 240 /** 241 * The key to the accepted order in the GBIF backbone. 242 */ 243 orderKey(DwcTerm.GROUP_TAXON), 244 245 /** 246 * The key to the accepted family in the GBIF backbone. 247 */ 248 familyKey(DwcTerm.GROUP_TAXON), 249 250 /** 251 * The key to the accepted genus in the GBIF backbone. 252 */ 253 genusKey(DwcTerm.GROUP_TAXON), 254 255 /** 256 * The key to the accepted subgenus in the GBIF backbone. 257 */ 258 subgenusKey(DwcTerm.GROUP_TAXON), 259 260 /** 261 * The backbone key to the accepted species. 262 * In case the taxonKey is of a higher rank than species (e.g. genus) speciesKey is null. 263 * In case taxonKey represents an infraspecific taxon the speciesKey points to the species 264 * the infraspecies is classified as. In case of taxonKey being a species the speciesKey is the same. 265 */ 266 speciesKey(DwcTerm.GROUP_TAXON), 267 268 /** 269 * The canonical name without authorship of the accepted species. 270 */ 271 species(DwcTerm.GROUP_TAXON), 272 273 // experimental Taxon properties 274 canonicalName(DwcTerm.GROUP_TAXON), 275 nameType(DwcTerm.GROUP_TAXON), 276 277 /** 278 * The scientific name the type associated acceptedNubKey. 279 */ 280 acceptedScientificName(DwcTerm.GROUP_TAXON), 281 282 /** 283 * Scientific name as provided by the source. 284 */ 285 verbatimScientificName(DwcTerm.GROUP_TAXON), 286 287 /** 288 * The scientific name the type status of this specimen applies to. 289 * Term proposed in Darwin Core, but not yet ratified. 290 */ 291 typifiedName(DwcTerm.GROUP_IDENTIFICATION), 292 293 /** 294 * The kind of protocol used when the record was last crawled by GBIF. 295 * See <a href="http://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/EndpointType.html">EndpointType enumeration</a> for possible values. 296 */ 297 protocol(GbifTerm.GROUP_CRAWLING), 298 299 /** 300 * The date this record was last parsed from raw xml/json into a verbatim GBIF record. 301 */ 302 lastParsed(GbifTerm.GROUP_CRAWLING), 303 304 /** 305 * The date this record was last crawled/harvested by GBIF from the endpoint. 306 */ 307 lastCrawled(GbifTerm.GROUP_CRAWLING), 308 309 // Species Profile checklist extension 310 isMarine(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 311 isTerrestrial(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 312 isFreshwater(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 313 isHybrid(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 314 isExtinct(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 315 livingPeriod(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "timePeriod"), 316 lifeForm(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 317 ageInDays(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 318 sizeInMillimeter(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION), 319 massInGram(GbifTerm.GROUP_SPECIES_PROFILE_EXTENSION, "weightInGram"), 320 321 // Vernacular Name checklist extension 322 organismPart(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 323 isPlural(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 324 isPreferredName(GbifTerm.GROUP_VERNACULAR_NAME_EXTENSION), 325 326 // Distribution checklist extension 327 appendixCITES(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 328 numberOfOccurrences(GbifTerm.GROUP_SPECIES_DISTRIBUTION_EXTENSION), 329 330 /** Boolean indicating if the publishing country is different to the location country. */ 331 repatriated(DwcTerm.GROUP_OCCURRENCE), 332 333 /** Calculated relative organism quantity, based on organism and sample measure types */ 334 relativeOrganismQuantity(DwcTerm.GROUP_MATERIAL_SAMPLE), 335 336 projectId(DwcTerm.GROUP_OCCURRENCE), 337 338 /** Flag occurrence when associatedSequences/extension exists */ 339 isSequenced(DwcTerm.GROUP_OCCURRENCE), 340 341 /** GBIF region based on country code */ 342 gbifRegion(DwcTerm.GROUP_LOCATION), 343 344 /** GBIF region based on publishing country code */ 345 publishedByGbifRegion(DwcTerm.GROUP_LOCATION); 346 347 private static final String PREFIX = "gbif"; 348 private static final String NS = "http://rs.gbif.org/terms/1.0/"; 349 private static final URI NS_URI = URI.create(NS); 350 351 public static final String GROUP_CRAWLING = "Crawling"; 352 public static final String GROUP_DATASET = "Dataset"; 353 public static final String GROUP_ROW_TYPE = "RowType"; 354 public static final String GROUP_SPECIES_DISTRIBUTION_EXTENSION = "SpeciesDistribution"; 355 public static final String GROUP_SPECIES_PROFILE_EXTENSION = "SpeciesProfile"; 356 public static final String GROUP_VERNACULAR_NAME_EXTENSION = "VernacularName"; 357 358 /** 359 * Lists all GBIF term groups. 360 */ 361 public static final String[] GROUPS = {GROUP_CRAWLING, GROUP_DATASET, DwcTerm.GROUP_OCCURRENCE, GROUP_ROW_TYPE, 362 GROUP_SPECIES_DISTRIBUTION_EXTENSION, GROUP_SPECIES_PROFILE_EXTENSION, DwcTerm.GROUP_TAXON, 363 GROUP_VERNACULAR_NAME_EXTENSION, DwcTerm.GROUP_LOCATION}; 364 365 /** 366 * Lists all GBIF terms in taxon group. 367 */ 368 public static final GbifTerm[] TAXONOMIC_TERMS = 369 {GbifTerm.taxonKey, GbifTerm.acceptedTaxonKey, GbifTerm.kingdomKey, GbifTerm.phylumKey, GbifTerm.classKey, 370 GbifTerm.orderKey, GbifTerm.familyKey, GbifTerm.genusKey, GbifTerm.subgenusKey, GbifTerm.speciesKey, 371 GbifTerm.species, GbifTerm.canonicalName, GbifTerm.nameType, GbifTerm.acceptedScientificName, 372 GbifTerm.verbatimScientificName}; 373 374 private final String groupName; 375 private final boolean isDeprecated; 376 public final String[] normAlts; 377 378 GbifTerm(String groupName, String... alternatives) { 379 this.groupName = groupName; 380 this.normAlts = alternatives; 381 boolean deprecatedAnnotationPresent = false; 382 try { 383 deprecatedAnnotationPresent = GbifTerm.class.getField(this.name()).isAnnotationPresent(Deprecated.class); 384 } catch (NoSuchFieldException ignore) { } 385 this.isDeprecated = deprecatedAnnotationPresent; 386 } 387 388 /** 389 * The simple term name without a namespace. 390 * For example taxonKey. 391 * 392 * @return simple term name 393 */ 394 @Override 395 public String simpleName() { 396 return name(); 397 } 398 399 /** 400 * Array of alternative simple names in use for the term. 401 * 402 * @return simple term name 403 */ 404 @Override 405 public String[] alternativeNames() { 406 return normAlts; 407 } 408 409 /** 410 * The optional group the term is grouped in. 411 * For example Occurrence, Taxon, etc. 412 */ 413 public String getGroup() { 414 return groupName; 415 } 416 417 418 /** 419 * List all terms that belong to a given group. 420 * 421 * @param group the group to list terms for 422 * @return the list of GBIF terms in the given group 423 */ 424 public static List<GbifTerm> listByGroup(String group) { 425 List<GbifTerm> terms = new ArrayList<GbifTerm>(); 426 for (GbifTerm t : GbifTerm.values()) { 427 if (t.getGroup().equalsIgnoreCase(group)) { 428 terms.add(t); 429 } 430 } 431 return terms; 432 } 433 434 @Override 435 public String toString() { 436 return prefixedName(); 437 } 438 439 @Override 440 public boolean isClass() { 441 return Character.isUpperCase(simpleName().charAt(0)); 442 } 443 444 @Override 445 public String prefix() { 446 return PREFIX; 447 } 448 449 @Override 450 public URI namespace() { 451 return NS_URI; 452 } 453 454 /** 455 * 456 * @return true if the Term is annotated with @Deprecated. 457 */ 458 public boolean isDeprecated(){ 459 return isDeprecated; 460 } 461 462}