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.Arrays; 022import java.util.List; 023 024/** 025 * All Darwin Core terms with namespace http://rs.tdwg.org/dwc/terms/ as an 026 * enumeration with alternative term names found sometimes in data. 027 * Old, deprecated terms are kept but marked as such. 028 */ 029public enum DwcTerm implements Term, AlternativeNames, Serializable { 030 031 /** 032 * CLASS TERMS 033 * Listed in the order given on the Darwin Core Quick Reference Guide. 034 * @see <a href="http://rs.tdwg.org/dwc/terms/index.htm#theterms">DwC Quick Reference Guide</a> 035 * Location is not on this list because it is a term in the dcterm namespace. 036 */ 037 Occurrence(DwcTerm.GROUP_OCCURRENCE, "DarwinCore", "SimpleDarwinCore"), 038 Organism(DwcTerm.GROUP_ORGANISM), 039 MaterialSample(DwcTerm.GROUP_MATERIAL_SAMPLE), 040 Event(DwcTerm.GROUP_EVENT), 041 GeologicalContext(DwcTerm.GROUP_GEOLOGICALCONTEXT), 042 Identification(DwcTerm.GROUP_IDENTIFICATION), 043 Taxon(DwcTerm.GROUP_TAXON), 044 MeasurementOrFact(DwcTerm.GROUP_MEASUREMENTORFACT), 045 ResourceRelationship(DwcTerm.GROUP_RESOURCERELATIONSHIP), 046 047 /** 048 * PROPERTY TERMS 049 * Listed in the order given on the Darwin Core Quick Reference Guide. 050 * @see <a href="http://rs.tdwg.org/dwc/terms/index.htm#theterms">DwC Quick Reference Guide</a> 051 */ 052 institutionID(DwcTerm.GROUP_RECORD), 053 collectionID(DwcTerm.GROUP_RECORD), 054 datasetID(DwcTerm.GROUP_RECORD), 055 institutionCode(DwcTerm.GROUP_RECORD), 056 collectionCode(DwcTerm.GROUP_RECORD), 057 datasetName(DwcTerm.GROUP_RECORD), 058 ownerInstitutionCode(DwcTerm.GROUP_RECORD), 059 basisOfRecord(DwcTerm.GROUP_RECORD), 060 informationWithheld(DwcTerm.GROUP_RECORD), 061 dataGeneralizations(DwcTerm.GROUP_RECORD), 062 dynamicProperties(DwcTerm.GROUP_RECORD), 063 064 occurrenceID(DwcTerm.GROUP_OCCURRENCE), 065 catalogNumber(DwcTerm.GROUP_OCCURRENCE, "catalogNumberNumeric"), 066 recordNumber(DwcTerm.GROUP_OCCURRENCE, "collectorNumber"), 067 recordedBy(DwcTerm.GROUP_OCCURRENCE, "collector"), 068 recordedByID(DwcTerm.GROUP_OCCURRENCE, "gbif:recordedByID", "http://rs.gbif.org/terms/1.0/recordedByID"), 069 individualCount(DwcTerm.GROUP_OCCURRENCE), 070 organismQuantity(DwcTerm.GROUP_OCCURRENCE), 071 organismQuantityType(DwcTerm.GROUP_OCCURRENCE), 072 sex(DwcTerm.GROUP_OCCURRENCE), 073 @Vocabulary lifeStage(DwcTerm.GROUP_OCCURRENCE), 074 reproductiveCondition(DwcTerm.GROUP_OCCURRENCE), 075 behavior(DwcTerm.GROUP_OCCURRENCE), 076 @Vocabulary establishmentMeans(DwcTerm.GROUP_OCCURRENCE), 077 @Vocabulary degreeOfEstablishment(DwcTerm.GROUP_OCCURRENCE), 078 @Vocabulary pathway(DwcTerm.GROUP_OCCURRENCE), 079 georeferenceVerificationStatus(DwcTerm.GROUP_OCCURRENCE), 080 occurrenceStatus(DwcTerm.GROUP_OCCURRENCE), 081 preparations(DwcTerm.GROUP_OCCURRENCE), 082 disposition(DwcTerm.GROUP_OCCURRENCE), 083 associatedMedia(DwcTerm.GROUP_OCCURRENCE), 084 associatedOccurrences(DwcTerm.GROUP_OCCURRENCE), 085 associatedReferences(DwcTerm.GROUP_OCCURRENCE), 086 associatedSequences(DwcTerm.GROUP_OCCURRENCE), 087 associatedTaxa(DwcTerm.GROUP_OCCURRENCE), 088 otherCatalogNumbers(DwcTerm.GROUP_OCCURRENCE), 089 occurrenceRemarks(DwcTerm.GROUP_OCCURRENCE), 090 091 organismID(DwcTerm.GROUP_ORGANISM, "individualID"), 092 organismName(DwcTerm.GROUP_ORGANISM), 093 organismScope(DwcTerm.GROUP_ORGANISM), 094 associatedOrganisms(DwcTerm.GROUP_ORGANISM), 095 previousIdentifications(DwcTerm.GROUP_ORGANISM), 096 organismRemarks(DwcTerm.GROUP_ORGANISM), 097 098 materialSampleID(DwcTerm.GROUP_MATERIAL_SAMPLE), 099 100 eventID(DwcTerm.GROUP_EVENT), 101 parentEventID(DwcTerm.GROUP_EVENT), 102 fieldNumber(DwcTerm.GROUP_EVENT), 103 eventDate(DwcTerm.GROUP_EVENT, "earliestDateCollected", "latestDateCollected"), 104 eventTime(DwcTerm.GROUP_EVENT), 105 startDayOfYear(DwcTerm.GROUP_EVENT), 106 endDayOfYear(DwcTerm.GROUP_EVENT), 107 year(DwcTerm.GROUP_EVENT), 108 month(DwcTerm.GROUP_EVENT), 109 day(DwcTerm.GROUP_EVENT), 110 verbatimEventDate(DwcTerm.GROUP_EVENT), 111 habitat(DwcTerm.GROUP_EVENT), 112 samplingProtocol(DwcTerm.GROUP_EVENT), 113 sampleSizeValue(DwcTerm.GROUP_EVENT), 114 sampleSizeUnit(DwcTerm.GROUP_EVENT), 115 samplingEffort(DwcTerm.GROUP_EVENT), 116 fieldNotes(DwcTerm.GROUP_EVENT), 117 eventRemarks(DwcTerm.GROUP_EVENT), 118 119 locationID(DwcTerm.GROUP_LOCATION), 120 higherGeographyID(DwcTerm.GROUP_LOCATION), 121 higherGeography(DwcTerm.GROUP_LOCATION), 122 continent(DwcTerm.GROUP_LOCATION), 123 waterBody(DwcTerm.GROUP_LOCATION), 124 islandGroup(DwcTerm.GROUP_LOCATION), 125 island(DwcTerm.GROUP_LOCATION), 126 country(DwcTerm.GROUP_LOCATION), 127 countryCode(DwcTerm.GROUP_LOCATION), 128 stateProvince(DwcTerm.GROUP_LOCATION, "state", "province"), 129 county(DwcTerm.GROUP_LOCATION), 130 municipality(DwcTerm.GROUP_LOCATION, "city"), 131 locality(DwcTerm.GROUP_LOCATION), 132 verbatimLocality(DwcTerm.GROUP_LOCATION), 133 minimumElevationInMeters(DwcTerm.GROUP_LOCATION), 134 maximumElevationInMeters(DwcTerm.GROUP_LOCATION), 135 verbatimElevation(DwcTerm.GROUP_LOCATION), 136 verticalDatum(DwcTerm.GROUP_LOCATION), 137 minimumDepthInMeters(DwcTerm.GROUP_LOCATION), 138 maximumDepthInMeters(DwcTerm.GROUP_LOCATION), 139 verbatimDepth(DwcTerm.GROUP_LOCATION), 140 minimumDistanceAboveSurfaceInMeters(DwcTerm.GROUP_LOCATION), 141 maximumDistanceAboveSurfaceInMeters(DwcTerm.GROUP_LOCATION), 142 locationAccordingTo(DwcTerm.GROUP_LOCATION), 143 locationRemarks(DwcTerm.GROUP_LOCATION), 144 decimalLatitude(DwcTerm.GROUP_LOCATION, "latitude"), 145 decimalLongitude(DwcTerm.GROUP_LOCATION, "longitude"), 146 geodeticDatum(DwcTerm.GROUP_LOCATION, "datum", "horizontaldatum"), 147 coordinateUncertaintyInMeters(DwcTerm.GROUP_LOCATION), 148 coordinatePrecision(DwcTerm.GROUP_LOCATION), 149 pointRadiusSpatialFit(DwcTerm.GROUP_LOCATION), 150 verbatimCoordinates(DwcTerm.GROUP_LOCATION), 151 verbatimLatitude(DwcTerm.GROUP_LOCATION), 152 verbatimLongitude(DwcTerm.GROUP_LOCATION), 153 verbatimCoordinateSystem(DwcTerm.GROUP_LOCATION), 154 verbatimSRS(DwcTerm.GROUP_LOCATION), 155 footprintWKT(DwcTerm.GROUP_LOCATION), 156 footprintSRS(DwcTerm.GROUP_LOCATION), 157 footprintSpatialFit(DwcTerm.GROUP_LOCATION), 158 georeferencedBy(DwcTerm.GROUP_LOCATION), 159 georeferencedDate(DwcTerm.GROUP_LOCATION), 160 georeferenceProtocol(DwcTerm.GROUP_LOCATION), 161 georeferenceSources(DwcTerm.GROUP_LOCATION), 162 georeferenceRemarks(DwcTerm.GROUP_LOCATION), 163 164 geologicalContextID(DwcTerm.GROUP_GEOLOGICALCONTEXT), 165 earliestEonOrLowestEonothem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 166 latestEonOrHighestEonothem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 167 earliestEraOrLowestErathem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 168 latestEraOrHighestErathem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 169 earliestPeriodOrLowestSystem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 170 latestPeriodOrHighestSystem(DwcTerm.GROUP_GEOLOGICALCONTEXT), 171 earliestEpochOrLowestSeries(DwcTerm.GROUP_GEOLOGICALCONTEXT), 172 latestEpochOrHighestSeries(DwcTerm.GROUP_GEOLOGICALCONTEXT), 173 earliestAgeOrLowestStage(DwcTerm.GROUP_GEOLOGICALCONTEXT), 174 latestAgeOrHighestStage(DwcTerm.GROUP_GEOLOGICALCONTEXT), 175 lowestBiostratigraphicZone(DwcTerm.GROUP_GEOLOGICALCONTEXT), 176 highestBiostratigraphicZone(DwcTerm.GROUP_GEOLOGICALCONTEXT), 177 lithostratigraphicTerms(DwcTerm.GROUP_GEOLOGICALCONTEXT), 178 group(DwcTerm.GROUP_GEOLOGICALCONTEXT), 179 formation(DwcTerm.GROUP_GEOLOGICALCONTEXT), 180 member(DwcTerm.GROUP_GEOLOGICALCONTEXT), 181 bed(DwcTerm.GROUP_GEOLOGICALCONTEXT), 182 183 identificationID(DwcTerm.GROUP_IDENTIFICATION), 184 verbatimIdentification(DwcTerm.GROUP_IDENTIFICATION), 185 identificationQualifier(DwcTerm.GROUP_IDENTIFICATION), 186 typeStatus(DwcTerm.GROUP_IDENTIFICATION), 187 identifiedBy(DwcTerm.GROUP_IDENTIFICATION), 188 identifiedByID(DwcTerm.GROUP_IDENTIFICATION, "gbif:identifiedByID", "http://rs.gbif.org/terms/1.0/identifiedByID"), 189 dateIdentified(DwcTerm.GROUP_IDENTIFICATION), 190 identificationReferences(DwcTerm.GROUP_IDENTIFICATION), 191 identificationVerificationStatus(DwcTerm.GROUP_IDENTIFICATION), 192 identificationRemarks(DwcTerm.GROUP_IDENTIFICATION), 193 194 taxonID(DwcTerm.GROUP_TAXON, "nameUsageID"), 195 scientificNameID(DwcTerm.GROUP_TAXON, "nameID"), 196 acceptedNameUsageID(DwcTerm.GROUP_TAXON, "acceptedTaxonID"), 197 parentNameUsageID(DwcTerm.GROUP_TAXON, "higherNameUsageID", "parentTaxonID"), 198 originalNameUsageID(DwcTerm.GROUP_TAXON, "originalNameID", "basionymID"), 199 nameAccordingToID(DwcTerm.GROUP_TAXON, "taxonAccordingToID"), 200 namePublishedInID(DwcTerm.GROUP_TAXON), 201 taxonConceptID(DwcTerm.GROUP_TAXON), 202 scientificName(DwcTerm.GROUP_TAXON), 203 acceptedNameUsage(DwcTerm.GROUP_TAXON, "acceptedTaxon"), 204 parentNameUsage(DwcTerm.GROUP_TAXON, "parentTaxon", "higherTaxon", "higherNameUsage"), 205 originalNameUsage(DwcTerm.GROUP_TAXON, "originalName", "originalTaxon", "basionym"), 206 nameAccordingTo(DwcTerm.GROUP_TAXON, "taxonAccordingTo"), 207 namePublishedIn(DwcTerm.GROUP_TAXON), 208 namePublishedInYear(DwcTerm.GROUP_TAXON), 209 higherClassification(DwcTerm.GROUP_TAXON), 210 kingdom(DwcTerm.GROUP_TAXON), 211 phylum(DwcTerm.GROUP_TAXON), 212 /** 213 * The taxonomic class. 214 * The real Darwin Core term is class, but as java does not allow this name we use a variation instead. 215 */ 216 class_(DwcTerm.GROUP_TAXON, "class"), 217 order(DwcTerm.GROUP_TAXON), 218 family(DwcTerm.GROUP_TAXON), 219 subfamily(DwcTerm.GROUP_TAXON), 220 genus(DwcTerm.GROUP_TAXON), 221 genericName(DwcTerm.GROUP_TAXON, "gbif:genericName", "http://rs.gbif.org/terms/1.0/genericName"), 222 subgenus(DwcTerm.GROUP_TAXON), 223 infragenericEpithet(DwcTerm.GROUP_TAXON), 224 specificEpithet(DwcTerm.GROUP_TAXON), 225 infraspecificEpithet(DwcTerm.GROUP_TAXON), 226 cultivarEpithet(DwcTerm.GROUP_TAXON), 227 taxonRank(DwcTerm.GROUP_TAXON, "rank"), 228 verbatimTaxonRank(DwcTerm.GROUP_TAXON), 229 scientificNameAuthorship(DwcTerm.GROUP_TAXON), 230 vernacularName(DwcTerm.GROUP_TAXON), 231 nomenclaturalCode(DwcTerm.GROUP_TAXON), 232 taxonomicStatus(DwcTerm.GROUP_TAXON), 233 nomenclaturalStatus(DwcTerm.GROUP_TAXON), 234 taxonRemarks(DwcTerm.GROUP_TAXON, "taxonRemark"), 235 236 measurementID(DwcTerm.GROUP_MEASUREMENTORFACT), 237 measurementType(DwcTerm.GROUP_MEASUREMENTORFACT), 238 measurementValue(DwcTerm.GROUP_MEASUREMENTORFACT), 239 measurementAccuracy(DwcTerm.GROUP_MEASUREMENTORFACT), 240 measurementUnit(DwcTerm.GROUP_MEASUREMENTORFACT), 241 measurementDeterminedBy(DwcTerm.GROUP_MEASUREMENTORFACT), 242 measurementDeterminedDate(DwcTerm.GROUP_MEASUREMENTORFACT), 243 measurementMethod(DwcTerm.GROUP_MEASUREMENTORFACT), 244 measurementRemarks(DwcTerm.GROUP_MEASUREMENTORFACT), 245 246 resourceRelationshipID(DwcTerm.GROUP_RESOURCERELATIONSHIP), 247 resourceID(DwcTerm.GROUP_RESOURCERELATIONSHIP), 248 relationshipOfResourceID(DwcTerm.GROUP_RESOURCERELATIONSHIP), 249 relatedResourceID(DwcTerm.GROUP_RESOURCERELATIONSHIP), 250 relationshipOfResource(DwcTerm.GROUP_RESOURCERELATIONSHIP), 251 relationshipAccordingTo(DwcTerm.GROUP_RESOURCERELATIONSHIP), 252 relationshipEstablishedDate(DwcTerm.GROUP_RESOURCERELATIONSHIP), 253 relationshipRemarks(DwcTerm.GROUP_RESOURCERELATIONSHIP); 254 255 private static final String PREFIX = "dwc"; 256 private static final String NS = "http://rs.tdwg.org/dwc/terms/"; 257 private static final URI NS_URI = URI.create(NS); 258 259 public static final String GROUP_RECORD = "Record"; 260 public static final String GROUP_OCCURRENCE = "Occurrence"; 261 public static final String GROUP_ORGANISM = "Organism"; 262 public static final String GROUP_MATERIAL_SAMPLE = "MaterialSample"; 263 public static final String GROUP_EVENT = "Event"; 264 public static final String GROUP_LOCATION = "Location"; 265 public static final String GROUP_GEOLOGICALCONTEXT = "GeologicalContext"; 266 public static final String GROUP_IDENTIFICATION = "Identification"; 267 public static final String GROUP_TAXON = "Taxon"; 268 public static final String GROUP_MEASUREMENTORFACT = "MeasurementOrFact"; 269 public static final String GROUP_RESOURCERELATIONSHIP = "ResourceRelationship"; 270 271 /** 272 * Lists all term groups in the order given on the Darwin Core Quick Reference Guide. 273 * @see <a href="http://rs.tdwg.org/dwc/terms/index.htm#theterms">DwC Quick Reference Guide</a> 274 */ 275 public static final String[] GROUPS = 276 {GROUP_RECORD, GROUP_OCCURRENCE, GROUP_ORGANISM, GROUP_EVENT, GROUP_LOCATION, 277 GROUP_GEOLOGICALCONTEXT, GROUP_IDENTIFICATION, GROUP_TAXON, 278 GROUP_MEASUREMENTORFACT, GROUP_RESOURCERELATIONSHIP}; 279 280 public static final DwcTerm[] TAXONOMIC_TERMS = Arrays.stream(values()) 281 .filter(t -> !t.isClass() && t.getGroup().equals(GROUP_TAXON)) 282 .toArray(DwcTerm[]::new); 283 284 /** 285 * List of all higher rank terms in dwc, ordered by rank and starting with kingdom. 286 */ 287 public static final DwcTerm[] HIGHER_RANKS = 288 {DwcTerm.kingdom, DwcTerm.phylum, DwcTerm.class_, DwcTerm.order, 289 DwcTerm.family, DwcTerm.subfamily, DwcTerm.genus, DwcTerm.subgenus}; 290 291 /** 292 * List of all class terms in dwc. 293 */ 294 public static final DwcTerm[] CLASS_TERMS = Arrays.stream(values()) 295 .filter(DwcTerm::isClass) 296 .toArray(DwcTerm[]::new); 297 298 private final String groupName; 299 public final String normQName; 300 public final String[] normAlts; 301 302 private DwcTerm(String groupName, String... alternatives) { 303 normQName = TermFactory.normaliseTerm(qualifiedName()); 304 for (int i = 0; i < alternatives.length; i++) { 305 alternatives[i] = TermFactory.normaliseTerm(alternatives[i]); 306 } 307 normAlts = alternatives; 308 this.groupName = groupName; 309 } 310 311 312 /** 313 * The simple term name without a namespace. 314 * For example scientificName. 315 * @return simple term name 316 */ 317 @Override 318 public String simpleName() { 319 if (this == class_) { 320 return "class"; 321 } 322 return name(); 323 } 324 325 /** 326 * Array of alternative simple names in use for the term. 327 * Often based on older dwc versions. 328 * @return simple term name 329 */ 330 @Override 331 public String[] alternativeNames() { 332 return normAlts; 333 } 334 335 /** 336 * The optional group the term is grouped in. 337 * For example Taxon, Identification, etc. 338 */ 339 public String getGroup() { 340 return groupName; 341 } 342 343 /** 344 * @return true if the dwc term is defining a class instead of a property, e.g. Taxon 345 */ 346 @Override 347 public boolean isClass() { 348 return Character.isUpperCase(simpleName().charAt(0)); 349 } 350 351 /** 352 * List all terms that belong to a given group. 353 * 354 * @param group the group to list terms for 355 * 356 * @return the list of dwc terms in the given group 357 */ 358 public static List<DwcTerm> listByGroup(String group) { 359 List<DwcTerm> terms = new ArrayList<DwcTerm>(); 360 for (DwcTerm t : DwcTerm.values()) { 361 if (t.getGroup().equalsIgnoreCase(group)) { 362 terms.add(t); 363 } 364 } 365 return terms; 366 } 367 368 @Override 369 public String prefix() { 370 return PREFIX; 371 } 372 373 @Override 374 public URI namespace() { 375 return NS_URI; 376 } 377 378 @Override 379 public String toString() { 380 return prefixedName(); 381 } 382}