001/* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014package org.gbif.api.model.occurrence; 015 016import lombok.Getter; 017 018import lombok.Setter; 019 020import org.gbif.api.annotation.Experimental; 021import org.gbif.api.model.common.Classification; 022import org.gbif.api.model.common.Identifier; 023import org.gbif.api.model.common.LinneanClassification; 024import org.gbif.api.model.common.LinneanClassificationKeys; 025import org.gbif.api.model.common.MediaObject; 026import org.gbif.api.util.ClassificationUtils; 027import org.gbif.api.util.IsoDateInterval; 028import org.gbif.api.vocabulary.BasisOfRecord; 029import org.gbif.api.vocabulary.Continent; 030import org.gbif.api.vocabulary.Country; 031import org.gbif.api.vocabulary.GbifRegion; 032import org.gbif.api.vocabulary.License; 033import org.gbif.api.vocabulary.OccurrenceIssue; 034import org.gbif.api.vocabulary.OccurrenceStatus; 035import org.gbif.api.vocabulary.Rank; 036import org.gbif.api.vocabulary.Sex; 037import org.gbif.api.vocabulary.TaxonomicStatus; 038import org.gbif.dwc.terms.DwcTerm; 039import org.gbif.dwc.terms.GbifTerm; 040import org.gbif.dwc.terms.Term; 041import org.gbif.dwc.terms.UnknownTerm; 042 043import java.lang.reflect.Field; 044import java.lang.reflect.Modifier; 045import java.net.URI; 046import java.util.ArrayList; 047import java.util.Arrays; 048import java.util.Collections; 049import java.util.Date; 050import java.util.EnumSet; 051import java.util.HashMap; 052import java.util.List; 053import java.util.Map; 054import java.util.Objects; 055import java.util.Optional; 056import java.util.Set; 057import java.util.stream.Collectors; 058import java.util.stream.Stream; 059 060import jakarta.annotation.Nullable; 061import jakarta.validation.constraints.Max; 062import jakarta.validation.constraints.Min; 063import jakarta.validation.constraints.NotNull; 064 065import com.fasterxml.jackson.annotation.JsonAnyGetter; 066import com.fasterxml.jackson.annotation.JsonIgnore; 067import com.fasterxml.jackson.annotation.JsonProperty; 068import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 069import com.fasterxml.jackson.databind.annotation.JsonSerialize; 070 071import io.swagger.v3.oas.annotations.ExternalDocumentation; 072import io.swagger.v3.oas.annotations.media.Schema; 073import lombok.EqualsAndHashCode; 074import lombok.ToString; 075 076/** 077 * Represents an Occurrence as interpreted by GBIF, adding typed properties on top of the verbatim ones. 078 */ 079@EqualsAndHashCode 080@ToString 081@SuppressWarnings("unused") 082public class Occurrence extends VerbatimOccurrence implements LinneanClassification, LinneanClassificationKeys { 083 084 public static final String GEO_DATUM = "WGS84"; 085 // keep names of ALL properties of this class in a set for jackson serialization, see #properties() 086 private static final Set<String> PROPERTIES = Collections.unmodifiableSet( 087 Stream.concat( 088 // we need to these JSON properties manually because we have a fixed getter but no field for it 089 Stream.of(DwcTerm.geodeticDatum.simpleName(), "class", DwcTerm.countryCode.simpleName(), GbifTerm.gbifRegion.simpleName(), GbifTerm.publishedByGbifRegion.simpleName()), 090 Stream.concat(Arrays.stream(Occurrence.class.getDeclaredFields()), 091 Arrays.stream(VerbatimOccurrence.class.getDeclaredFields())) 092 .filter(field -> !Modifier.isStatic(field.getModifiers())) 093 .map(Field::getName)).collect(Collectors.toSet())); 094 095 // occurrence fields 096 097 // OpenAPI documentation comes from the enumeration. 098 private BasisOfRecord basisOfRecord; 099 100 @Schema( 101 description = "The number of individuals present at the time of the Occurrence.", 102 externalDocs = @ExternalDocumentation( 103 description = "Darwin Core definition", 104 url = "https://rs.tdwg.org/dwc/terms/individualCount" 105 ) 106 ) 107 private Integer individualCount; 108 109 // OpenAPI documentation comes from the enumeration. 110 private OccurrenceStatus occurrenceStatus; 111 112 // OpenAPI documentation comes from the enumeration. 113 private String sex; 114 115 @Schema( 116 description = "The age class or life stage of the Organism(s) at the time the Occurrence was recorded.\n\n" + 117 "Values are aligned to the [GBIF LifeStage vocabulary](https://registry.gbif.org/vocabulary/LifeStage/concepts)", 118 externalDocs = @ExternalDocumentation( 119 description = "Darwin Core definition", 120 url = "https://rs.tdwg.org/dwc/terms/lifeStage" 121 ) 122 ) 123 private String lifeStage; 124 125 @Schema( 126 description = "Statement about whether an organism or organisms have been introduced to a given place and time " + 127 "through the direct or indirect activity of modern humans.\n\n" + 128 "Values are aligned to the [GBIF EstablishmentMeans vocabulary](https://registry.gbif.org/vocabulary/EstablishmentMeans/concepts), " + 129 "which is derived from the [Darwin Core EstablishmentMeans vocabulary](https://dwc.tdwg.org/em/).", 130 externalDocs = @ExternalDocumentation( 131 description = "Darwin Core definition", 132 url = "https://rs.tdwg.org/dwc/terms/establishmentMeans" 133 ) 134 ) 135 private String establishmentMeans; 136 137 @Schema( 138 description = "The degree to which an Organism survives, reproduces, and expands its range at the given " + 139 "place and time.\n\n" + 140 "Values are aligned to the [GBIF DegreeOfEstablishment vocabulary](https://registry.gbif.org/vocabulary/DegreeOfEstablishment/concepts), " + 141 "which is derived from the [Darwin Core DegreeOfEstablishment vocabulary](https://dwc.tdwg.org/doe/).", 142 externalDocs = @ExternalDocumentation( 143 description = "Darwin Core definition", 144 url = "https://rs.tdwg.org/dwc/terms/degreeOfEstablishment" 145 ) 146 ) 147 private String degreeOfEstablishment; 148 149 @Schema( 150 description = "The process by which an Organism came to be in a given place at a given time.\n\n" + 151 "Values are aligned to the [GBIF Pathway vocabulary](https://registry.gbif.org/vocabulary/Pathway/concepts), " + 152 "which is derived from the [Darwin Core Pathway vocabulary](https://dwc.tdwg.org/pw/).", 153 externalDocs = @ExternalDocumentation( 154 description = "Darwin Core definition", 155 url = "https://rs.tdwg.org/dwc/terms/pathway" 156 ) 157 ) 158 private String pathway; 159 160 161 @Schema( 162 description = "The map of classifications associated with this occurrence keyed by checklistKey.", 163 externalDocs = @ExternalDocumentation( 164 description = "Darwin Core definition", 165 url = "https://rs.tdwg.org/dwc/terms/" 166 ) 167 ) 168 private Map<String, Classification> classifications; 169 170 @Schema( 171 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the most specific " + 172 "(lowest rank) taxon for this occurrence. This could be a synonym, see `acceptedTaxonKey`.", 173 externalDocs = @ExternalDocumentation( 174 description = "Darwin Core definition", 175 url = "https://rs.tdwg.org/dwc/terms/" 176 ) 177 ) 178 @Deprecated 179 private Integer taxonKey; 180 181 @Schema( 182 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the kingdom of this occurrence.", 183 externalDocs = @ExternalDocumentation( 184 description = "Darwin Core definition", 185 url = "https://rs.tdwg.org/dwc/terms/" 186 ) 187 ) 188 @Deprecated 189 private Integer kingdomKey; 190 191 @Schema( 192 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the phylum of this occurrence.", 193 externalDocs = @ExternalDocumentation( 194 description = "Darwin Core definition", 195 url = "https://rs.tdwg.org/dwc/terms/" 196 ) 197 ) 198 @Deprecated 199 private Integer phylumKey; 200 201 @Schema( 202 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the class of this" + 203 "occurrence.", 204 externalDocs = @ExternalDocumentation( 205 description = "Darwin Core definition", 206 url = "https://rs.tdwg.org/dwc/terms/" 207 ) 208 ) 209 @Deprecated 210 private Integer classKey; 211 212 @Schema( 213 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the order of this" + 214 "occurrence.", 215 externalDocs = @ExternalDocumentation( 216 description = "Darwin Core definition", 217 url = "https://rs.tdwg.org/dwc/terms/" 218 ) 219 ) 220 @Deprecated 221 private Integer orderKey; 222 223 @Schema( 224 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the family of this" + 225 "occurrence.", 226 externalDocs = @ExternalDocumentation( 227 description = "Darwin Core definition", 228 url = "https://rs.tdwg.org/dwc/terms/" 229 ) 230 ) 231 @Deprecated 232 private Integer familyKey; 233 234 @Schema( 235 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the genus of this" + 236 "occurrence.", 237 externalDocs = @ExternalDocumentation( 238 description = "Darwin Core definition", 239 url = "https://rs.tdwg.org/dwc/terms/" 240 ) 241 ) 242 @Deprecated 243 private Integer genusKey; 244 245 @Schema( 246 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the subgenus of this" + 247 "occurrence.", 248 externalDocs = @ExternalDocumentation( 249 description = "Darwin Core definition", 250 url = "https://rs.tdwg.org/dwc/terms/" 251 ) 252 ) 253 @Deprecated 254 private Integer subgenusKey; 255 256 @Schema( 257 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the species of this" + 258 "occurrence.", 259 externalDocs = @ExternalDocumentation( 260 description = "Darwin Core definition", 261 url = "https://rs.tdwg.org/dwc/terms/" 262 ) 263 ) 264 @Deprecated 265 private Integer speciesKey; 266 267 @Schema( 268 description = "A taxon key from the selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) for the accepted taxon of " + 269 "this occurrence.", 270 externalDocs = @ExternalDocumentation( 271 description = "Darwin Core definition", 272 url = "https://rs.tdwg.org/dwc/terms/" 273 ) 274 ) 275 @Deprecated 276 private Integer acceptedTaxonKey; 277 278 // taxonomy as name strings → LinneanClassification 279 280 @Schema( 281 description = "The scientific name (including authorship) for the taxon from the " + 282 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence. This could be a synonym, see " + 283 "also `acceptedScientificName`.", 284 externalDocs = @ExternalDocumentation( 285 description = "Darwin Core definition", 286 url = "https://rs.tdwg.org/dwc/terms/" 287 ) 288 ) 289 private String scientificName; // the interpreted name matching taxonKey 290 291 @Schema( 292 description = "The scientific name authorship for the taxon from the " + 293 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence. This could be a synonym, see " + 294 "also `acceptedScientificName`.", 295 externalDocs = @ExternalDocumentation( 296 description = "Darwin Core definition", 297 url = "https://rs.tdwg.org/dwc/terms/" 298 ) 299 ) 300 private String scientificNameAuthorship; 301 302 @Schema( 303 description = "The accepted scientific name (including authorship) for the taxon from the " + 304 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 305 externalDocs = @ExternalDocumentation( 306 description = "Darwin Core definition", 307 url = "https://rs.tdwg.org/dwc/terms/" 308 ) 309 ) 310 private String acceptedScientificName; 311 312 @Schema( 313 description = "The kingdom name (excluding authorship) for the kingdom from the " + 314 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 315 externalDocs = @ExternalDocumentation( 316 description = "Darwin Core definition", 317 url = "https://rs.tdwg.org/dwc/terms/" 318 ) 319 ) 320 private String kingdom; 321 322 @Schema( 323 description = "The phylum name (excluding authorship) for the phylum from the " + 324 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 325 externalDocs = @ExternalDocumentation( 326 description = "Darwin Core definition", 327 url = "https://rs.tdwg.org/dwc/terms/" 328 ) 329 ) 330 private String phylum; 331 332 @Schema( 333 description = "The class name (excluding authorship) for the class from the " + 334 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 335 externalDocs = @ExternalDocumentation( 336 description = "Darwin Core definition", 337 url = "https://rs.tdwg.org/dwc/terms/" 338 ) 339 ) 340 @JsonProperty("class") 341 private String clazz; 342 343 @Schema( 344 description = "The order name (excluding authorship) for the order from the " + 345 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 346 externalDocs = @ExternalDocumentation( 347 description = "Darwin Core definition", 348 url = "https://rs.tdwg.org/dwc/terms/" 349 ) 350 ) 351 private String order; 352 353 @Schema( 354 description = "The family name (excluding authorship) for the family from the " + 355 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 356 externalDocs = @ExternalDocumentation( 357 description = "Darwin Core definition", 358 url = "https://rs.tdwg.org/dwc/terms/" 359 ) 360 ) 361 private String family; 362 363 @Schema( 364 description = "The genus name (excluding authorship) for the genus from the " + 365 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 366 externalDocs = @ExternalDocumentation( 367 description = "Darwin Core definition", 368 url = "https://rs.tdwg.org/dwc/terms/" 369 ) 370 ) 371 private String genus; 372 373 @Schema( 374 description = "The subgenus name (excluding authorship) for the subgenus from the " + 375 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 376 externalDocs = @ExternalDocumentation( 377 description = "Darwin Core definition", 378 url = "https://rs.tdwg.org/dwc/terms/" 379 ) 380 ) 381 private String subgenus; 382 383 @Schema( 384 description = "The species name (excluding authorship) for the species from the " + 385 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 386 externalDocs = @ExternalDocumentation( 387 description = "Darwin Core definition", 388 url = "https://rs.tdwg.org/dwc/terms/" 389 ) 390 ) 391 private String species; 392 393 // atomised scientific name 394 395 @Schema( 396 description = "The genus name part of the species name from the " + 397 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 398 externalDocs = @ExternalDocumentation( 399 description = "Darwin Core definition", 400 url = "https://rs.tdwg.org/dwc/terms/genericName" 401 ) 402 ) 403 private String genericName; 404 405 @Schema( 406 description = "The specific name part of the species name from the " + 407 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 408 externalDocs = @ExternalDocumentation( 409 description = "Darwin Core definition", 410 url = "https://rs.tdwg.org/dwc/terms/specificEpithet" 411 ) 412 ) 413 private String specificEpithet; 414 415 @Schema( 416 description = "The infraspecific name part of the species name from the " + 417 "selected taxonomy (e.g. Catalogue of Life, GBIF Backbone) matched to this occurrence.", 418 externalDocs = @ExternalDocumentation( 419 description = "Darwin Core definition", 420 url = "https://rs.tdwg.org/dwc/terms/infraspecificEpithet" 421 ) 422 ) 423 private String infraspecificEpithet; 424 425 @Schema( 426 description = "The taxonomic rank of the most specific name in the scientificName.", 427 externalDocs = @ExternalDocumentation( 428 description = "Darwin Core definition", 429 url = "https://rs.tdwg.org/dwc/terms/taxonRank" 430 ) 431 ) 432 private Rank taxonRank; 433 434 @Schema( 435 description = "The status of the use of the scientificName as a label for a taxon.", 436 externalDocs = @ExternalDocumentation( 437 description = "Darwin Core definition", 438 url = "https://rs.tdwg.org/dwc/terms/taxonomicStatus" 439 ) 440 ) 441 private TaxonomicStatus taxonomicStatus; 442 443 @Schema( 444 description = "The IUCN Red List Category of the taxon of this occurrence.\n\n" + 445 "See the [GBIF vocabulary](https://rs.gbif.org/vocabulary/iucn/threat_status/) for the values and their " + 446 "definitions, and the [IUCN Red List of Threatened Species dataset in GBIF](https://doi.org/10.15468/0qnb58) " + 447 "for the version of the Red List GBIF's interpretation procedures are using.", 448 externalDocs = @ExternalDocumentation( 449 description = "GBIF vocabulary", 450 url = "https://rs.gbif.org/vocabulary/iucn/threat_status/" 451 ) 452 ) 453 private String iucnRedListCategory; 454 455 // identification 456 457 @Schema( 458 description = "The date on which the subject was determined as representing the Taxon.", 459 externalDocs = @ExternalDocumentation( 460 description = "Darwin Core definition", 461 url = "https://rs.tdwg.org/dwc/terms/dateIdentified" 462 ) 463 ) 464 private Date dateIdentified; 465 466 // location 467 468 @Schema( 469 description = "The geographic latitude (in decimal degrees, using the WGS84 datum) of the geographic centre " + 470 "of the location of the occurrence.", 471 externalDocs = @ExternalDocumentation( 472 description = "Darwin Core definition", 473 url = "https://rs.tdwg.org/dwc/terms/decimalLatitude" 474 ) 475 ) 476 private Double decimalLatitude; 477 478 @Schema( 479 description = "The geographic longitude (in decimal degrees, using the WGS84 datum) of the geographic centre " + 480 "of the location of the occurrence.", 481 externalDocs = @ExternalDocumentation( 482 description = "Darwin Core definition", 483 url = "https://rs.tdwg.org/dwc/terms/decimalLongitude" 484 ) 485 ) 486 private Double decimalLongitude; 487 488 //coordinatePrecision and coordinateUncertaintyInMeters should be BigDecimal see POR-2795 489 490 @Schema( 491 description = "A decimal representation of the precision of the coordinates given in the decimalLatitude and decimalLongitude.", 492 externalDocs = @ExternalDocumentation( 493 description = "Darwin Core definition", 494 url = "https://rs.tdwg.org/dwc/terms/coordinatePrecision" 495 ) 496 ) 497 private Double coordinatePrecision; 498 499 @Schema( 500 description = "The horizontal distance (in metres) from the given decimalLatitude and decimalLongitude " + 501 "describing the smallest circle containing the whole of the Location.", 502 externalDocs = @ExternalDocumentation( 503 description = "Darwin Core definition", 504 url = "https://rs.tdwg.org/dwc/terms/coordinateUncertaintyInMeters" 505 ) 506 ) 507 private Double coordinateUncertaintyInMeters; 508 509 @Schema( 510 description = "**Deprecated.** This value is always null. It is an obsolete Darwin Core term.", 511 externalDocs = @ExternalDocumentation( 512 description = "Darwin Core definition", 513 url = "https://rs.tdwg.org/dwc/terms/" 514 ) 515 ) 516 @Deprecated //see getter 517 private Double coordinateAccuracy; 518 519 @Schema( 520 description = "Elevation (altitude) in metres above sea level. This is not a current Darwin Core term." 521 ) 522 private Double elevation; 523 524 @Schema( 525 description = "The value of the potential error associated with the elevation. This is not a current Darwin Core term." 526 ) 527 private Double elevationAccuracy; 528 529 @Schema( 530 description = "Depth in metres below sea level. This is not a current Darwin Core term." 531 ) 532 private Double depth; 533 534 @Schema( 535 description = "The value of the potential error associated with the depth. This is not a current Darwin Core term." 536 ) 537 private Double depthAccuracy; 538 539 // OpenAPI documentation from enumeration 540 private Continent continent; 541 542 @JsonSerialize(using = Country.IsoSerializer.class) 543 @JsonDeserialize(using = Country.IsoDeserializer.class) 544 private Country country; 545 546 @Schema( 547 description = "The name of the next-smaller administrative region than country (state, province, canton, " + 548 "department, region, etc.) in which the occurrence occurs.\n\n" + 549 "This value is unaltered by GBIF's processing; see also the GADM fields.", 550 externalDocs = @ExternalDocumentation( 551 description = "Darwin Core definition", 552 url = "https://rs.tdwg.org/dwc/terms/stateProvince" 553 ) 554 ) 555 private String stateProvince; 556 557 @Schema( 558 description = "The administrative divisions according to the [GADM database](https://gadm.org/).\n\n" + 559 "This value is applied by GBIF's processing without consideration of the `stateProvince`, `county` or `locality` fields." 560 ) 561 private Gadm gadm = new Gadm(); 562 563 @Schema( 564 description = "The name of the water body in which the Location occurs.", 565 externalDocs = @ExternalDocumentation( 566 description = "Darwin Core definition", 567 url = "https://rs.tdwg.org/dwc/terms/waterBody" 568 ) 569 ) 570 private String waterBody; 571 572 @Schema( 573 description = "The distance in metres of the occurrence from a centroid known to be applied to occurrences " + 574 "during georeferencing. This can potentially indicate low-precision georeferencing, check the values of " + 575 "`coordinateUncertaintyInMeters` and `georeferenceRemarks`." 576 ) 577 private Double distanceFromCentroidInMeters; 578 579 @Schema( 580 description = "A list (concatenated and separated) of geographic names less specific than the information captured in the dwc:locality term.", 581 externalDocs = @ExternalDocumentation( 582 description = "Darwin Core definition", 583 url = "https://rs.tdwg.org/dwc/terms/higherGeography" 584 ) 585 ) 586 private String higherGeography; 587 588 @Schema( 589 description = "A list (concatenated and separated) of names of people, groups, or organizations who determined the georeference (spatial representation) for the dcterms:Location.", 590 externalDocs = @ExternalDocumentation( 591 description = "Darwin Core definition", 592 url = "https://rs.tdwg.org/dwc/terms/georeferencedBy" 593 ) 594 ) 595 private String georeferencedBy; 596 597 // recording event 598 599 @Schema( 600 description = "The four-digit year in which the event occurred, according to the Common Era calendar.", 601 externalDocs = @ExternalDocumentation( 602 description = "Darwin Core definition", 603 url = "https://rs.tdwg.org/dwc/terms/year" 604 ) 605 ) 606 private Integer year; 607 608 @Schema( 609 description = "The integer month in which the Event occurred.", 610 externalDocs = @ExternalDocumentation( 611 description = "Darwin Core definition", 612 url = "https://rs.tdwg.org/dwc/terms/month" 613 ) 614 ) 615 private Integer month; 616 617 @Schema( 618 description = "The integer day of the month on which the Event occurred.", 619 externalDocs = @ExternalDocumentation( 620 description = "Darwin Core definition", 621 url = "https://rs.tdwg.org/dwc/terms/day" 622 ) 623 ) 624 private Integer day; 625 626 @Schema( 627 description = "The date-time during which an Event occurred. For occurrences, this is the date-time when the " + 628 "event was recorded. Not suitable for a time in a geological context.", 629 externalDocs = @ExternalDocumentation( 630 description = "Darwin Core definition", 631 url = "https://rs.tdwg.org/dwc/terms/eventDate" 632 ) 633 ) 634 private IsoDateInterval eventDate; 635 636 @Schema( 637 description = "The latest integer day of the year on which the Event occurred (1 for 1 January, 365 for " + 638 "31 December, except in a leap year, in which case it is 366).", 639 externalDocs = @ExternalDocumentation( 640 description = "Darwin Core definition", 641 url = "https://rs.tdwg.org/dwc/terms/endDayOfYear" 642 ) 643 ) 644 private Integer startDayOfYear; 645 646 @Schema( 647 description = "The earliest integer day of the year on which the Event occurred (1 for 1 January, 365 for " + 648 "31 December, except in a leap year, in which case it is 366).", 649 externalDocs = @ExternalDocumentation( 650 description = "Darwin Core definition", 651 url = "https://rs.tdwg.org/dwc/terms/startDayOfYear" 652 ) 653 ) 654 private Integer endDayOfYear; 655 656 @Schema( 657 description = "A list (concatenated and separated) of nomenclatural types (type status, typified scientific name, " + 658 "publication) applied to the occurrence.", 659 externalDocs = @ExternalDocumentation( 660 description = "Darwin Core definition", 661 url = "https://rs.tdwg.org/dwc/terms/typeStatus" 662 ) 663 ) 664 private String typeStatus; 665 666 // extracted from type status, but we should propose a new dwc term for this! 667 // for example: "Paratype of Taeniopteryx metequi Ricker & Ross" is status=Paratype, typifiedName=Taeniopteryx metequi Ricker & Ross 668 @Schema( 669 description = "The scientific name that is based on the type specimen.\n\n" + 670 "This is not yet a Darwin Core term, see the [proposal to add it](https://github.com/tdwg/dwc/issues/28)." 671 ) 672 private String typifiedName; // missing from DwC 673 674 @Schema( 675 description = "A specific interpretation issue found during processing and interpretation of the record.\n\n" + 676 "See the https://links.gbif.org/occurrence-issues[list of occurrence issues] and the " + 677 "https://gbif.github.io/gbif-api/apidocs/org/gbif/api/vocabulary/OccurrenceIssue.html[OccurrenceIssue enumeration] " + 678 "for possible values and definitions." 679 ) 680 private Set<OccurrenceIssue> issues = EnumSet.noneOf(OccurrenceIssue.class); 681 682 // record level 683 684 @Schema( 685 description = "The most recent date-time on which the occurrence was changed, according to the publisher.", 686 externalDocs = @ExternalDocumentation( 687 description = "Dublin Core definition", 688 url = "https://purl.org/dc/terms/modified" 689 ) 690 ) 691 private Date modified; // interpreted dc:modified, i.e. date changed in source 692 693 @Schema( 694 description = "The time this occurrence was last processed by GBIF's interpretation system “Pipelines”.\n\n" + 695 "This is the time the record was last changed in GBIF, **not** the time the record was last changed by the " + 696 "publisher. Data is also reprocessed when we changed the taxonomic backbone, geographic data sources or " + 697 "other interpretation procedures.\n\n" + 698 "An earlier interpretation system distinguished between “parsing” and “interpretation”, but in the current " + 699 "system there is only one process — the two dates will always be the same." 700 ) 701 private Date lastInterpreted; 702 703 @Schema( 704 description = "A related resource that is referenced, cited, or otherwise pointed to by the described resource.", 705 externalDocs = @ExternalDocumentation( 706 description = "Dublin Core definition", 707 url = "https://purl.org/dc/terms/references" 708 ) 709 ) 710 private URI references; 711 712 @Schema( 713 description = "A legal document giving official permission to do something with the occurrence.", 714 externalDocs = @ExternalDocumentation( 715 description = "Dublin Core definition", 716 url = "https://purl.org/dc/terms/license" 717 ) 718 ) 719 private License license; 720 721 @Schema( 722 description = "A number or enumeration value for the quantity of organisms.", 723 externalDocs = @ExternalDocumentation( 724 description = "Darwin Core definition", 725 url = "https://rs.tdwg.org/dwc/terms/organismQuantity" 726 ) 727 ) 728 private Double organismQuantity; 729 730 @Schema( 731 description = "The type of quantification system used for the quantity of organisms.", 732 externalDocs = @ExternalDocumentation( 733 description = "Darwin Core definition", 734 url = "https://rs.tdwg.org/dwc/terms/organismQuantityType" 735 ) 736 ) 737 private String organismQuantityType; 738 739 @Schema( 740 description = "The unit of measurement of the size (time duration, length, area, or volume) of a sample in a sampling event.", 741 externalDocs = @ExternalDocumentation( 742 description = "Darwin Core definition", 743 url = "https://rs.tdwg.org/dwc/terms/sampleSizeUnit" 744 ) 745 ) 746 private String sampleSizeUnit; 747 748 @Schema( 749 description = "A numeric value for a measurement of the size (time duration, length, area, or volume) of a sample in a sampling event.", 750 externalDocs = @ExternalDocumentation( 751 description = "Darwin Core definition", 752 url = "https://rs.tdwg.org/dwc/terms/sampleSizeValue" 753 ) 754 ) 755 private Double sampleSizeValue; 756 757 @Schema( 758 description = "The relative measurement of the quantity of the organism (i.e. without absolute units)." 759 ) 760 private Double relativeOrganismQuantity; 761 762 @Schema( 763 description = "Flag occurrence when associatedSequences/extension exists" 764 ) 765 private boolean isSequenced; 766 767 @Schema( 768 description = "A list (concatenated and separated) of identifiers (publication, global unique identifier, URI) " 769 + "of genetic sequence information associated with the material entity.", 770 externalDocs = 771 @ExternalDocumentation( 772 description = "Darwin Core definition", 773 url = "https://rs.tdwg.org/dwc/terms/associatedSequences")) 774 private String associatedSequences; 775 776 // interpreted extension data 777 778 @Schema( 779 description = "Alternative identifiers for the occurrence.", 780 externalDocs = @ExternalDocumentation( 781 description = "GBIF Alternative Identifiers extension", 782 url = "https://rs.gbif.org/terms/1.0/Identifier" 783 ) 784 ) 785 private List<Identifier> identifiers = new ArrayList<>(); 786 787 @Schema( 788 description = "Multimedia related to te occurrence.", 789 externalDocs = @ExternalDocumentation( 790 description = "GBIF Multimedia extension", 791 url = "https://rs.gbif.org/terms/1.0/Multimedia" 792 ) 793 ) 794 private List<MediaObject> media = new ArrayList<>(); 795 796 @Schema( 797 description = "Measurements or facts about the the occurrence.", 798 externalDocs = @ExternalDocumentation( 799 description = "Darwin Core definition", 800 url = "https://rs.tdwg.org/dwc/terms/MeasurementOrFact" 801 ) 802 ) 803 private List<MeasurementOrFact> facts = new ArrayList<>(); 804 805 @Schema( 806 description = "Relationships between occurrences.", 807 externalDocs = @ExternalDocumentation( 808 description = "Darwin Core definition", 809 url = "https://rs.tdwg.org/dwc/terms/ResourceRelationship" 810 ) 811 ) 812 private List<OccurrenceRelation> relations = new ArrayList<>(); 813 814 @Schema( 815 description = "A list of the globally unique identifiers for the person, people, groups, or organizations " + 816 "responsible for recording the original Occurrence.", 817 externalDocs = @ExternalDocumentation( 818 description = "Darwin Core definition", 819 url = "https://rs.tdwg.org/dwc/terms/recordedByID" 820 ) 821 ) 822 @JsonProperty("recordedByIDs") 823 private List<AgentIdentifier> recordedByIds = new ArrayList<>(); 824 825 @Schema( 826 description = "A list of the globally unique identifiers for the person, people, groups, or organizations " + 827 "responsible for assigning the Taxon to the occurrence.", 828 externalDocs = @ExternalDocumentation( 829 description = "Darwin Core definition", 830 url = "https://rs.tdwg.org/dwc/terms/identifiedByID" 831 ) 832 ) 833 @JsonProperty("identifiedByIDs") 834 private List<AgentIdentifier> identifiedByIds = new ArrayList<>(); 835 836 @Schema( 837 description = "**Experimental.** The UUID of the institution holding the specimen occurrence, from GRSciColl." 838 ) 839 @Experimental 840 private String institutionKey; 841 842 @Schema( 843 description = "**Experimental.** The UUID of the collection containing the specimen occurrence, from GRSciColl." 844 ) 845 @Experimental 846 private String collectionKey; 847 848 @Schema( 849 description = "**Experimental.** Whether the occurrence belongs to a machine-calculated cluster of probable " + 850 "duplicate occurrences.", 851 externalDocs = @ExternalDocumentation( 852 description = "GBIF Data Blog", 853 url = "https://data-blog.gbif.org/post/clustering-occurrences/" 854 ) 855 ) 856 @Experimental 857 private boolean isInCluster; 858 859 @Schema( 860 description = "An identifier for the set of data. May be a global unique identifier or an identifier specific to " + 861 "a collection or institution.", 862 externalDocs = @ExternalDocumentation( 863 description = "Darwin Core definition", 864 url = "https://rs.tdwg.org/dwc/terms/datasetID" 865 ) 866 ) 867 private String datasetID; 868 869 @Schema( 870 description = "The name identifying the data set from which the record was derived.", 871 externalDocs = @ExternalDocumentation( 872 description = "Darwin Core definition", 873 url = "https://rs.tdwg.org/dwc/terms/" 874 ) 875 ) 876 private String datasetName; 877 878 @Schema( 879 description = "A list (concatenated and separated) of previous or alternate fully qualified catalogue numbers " + 880 "or other human-used identifiers for the same occurrence, whether in the current or any other data set or collection.", 881 externalDocs = @ExternalDocumentation( 882 description = "Darwin Core definition", 883 url = "https://rs.tdwg.org/dwc/terms/otherCatalogNumbers" 884 ) 885 ) 886 private String otherCatalogNumbers; 887 888 @Schema( 889 description = "The full name of the earliest possible geochronologic eon or lowest chrono-stratigraphic eonothem or the informal name (\"Precambrian\") attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 890 externalDocs = @ExternalDocumentation( 891 description = "Darwin Core definition", 892 url = "https://rs.tdwg.org/dwc/terms/earliestEonOrLowestEonothem" 893 ) 894 ) 895 private String earliestEonOrLowestEonothem; 896 897 @Schema( 898 description = "The full name of the latest possible geochronologic eon or highest chrono-stratigraphic eonothem or the informal name (\"Precambrian\") attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 899 externalDocs = @ExternalDocumentation( 900 description = "Darwin Core definition", 901 url = "https://rs.tdwg.org/dwc/terms/latestEonOrHighestEonothem" 902 ) 903 ) 904 private String latestEonOrHighestEonothem; 905 906 @Schema( 907 description = "The full name of the earliest possible geochronologic era or lowest chronostratigraphic erathem attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 908 externalDocs = @ExternalDocumentation( 909 description = "Darwin Core definition", 910 url = "https://rs.tdwg.org/dwc/terms/earliestEraOrLowestErathem" 911 ) 912 ) 913 private String earliestEraOrLowestErathem; 914 915 @Schema( 916 description = "The full name of the latest possible geochronologic era or highest chronostratigraphic erathem attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 917 externalDocs = @ExternalDocumentation( 918 description = "Darwin Core definition", 919 url = "https://rs.tdwg.org/dwc/terms/latestEraOrHighestErathem" 920 ) 921 ) 922 private String latestEraOrHighestErathem; 923 924 @Schema( 925 description = "The full name of the earliest possible geochronologic period or lowest chronostratigraphic system attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 926 externalDocs = @ExternalDocumentation( 927 description = "Darwin Core definition", 928 url = "https://rs.tdwg.org/dwc/terms/earliestPeriodOrLowestSystem" 929 ) 930 ) 931 private String earliestPeriodOrLowestSystem; 932 933 @Schema( 934 description = "The full name of the latest possible geochronologic period or highest chronostratigraphic system attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 935 externalDocs = @ExternalDocumentation( 936 description = "Darwin Core definition", 937 url = "https://rs.tdwg.org/dwc/terms/latestPeriodOrHighestSystem" 938 ) 939 ) 940 private String latestPeriodOrHighestSystem; 941 942 @Schema( 943 description = "The full name of the earliest possible geochronologic epoch or lowest chronostratigraphic series attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 944 externalDocs = @ExternalDocumentation( 945 description = "Darwin Core definition", 946 url = "https://rs.tdwg.org/dwc/terms/earliestEpochOrLowestSeries" 947 ) 948 ) 949 private String earliestEpochOrLowestSeries; 950 951 @Schema( 952 description = "The full name of the latest possible geochronologic epoch or highest chronostratigraphic series attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 953 externalDocs = @ExternalDocumentation( 954 description = "Darwin Core definition", 955 url = "https://rs.tdwg.org/dwc/terms/latestEpochOrHighestSeries" 956 ) 957 ) 958 private String latestEpochOrHighestSeries; 959 960 @Schema( 961 description = "The full name of the earliest possible geochronologic age or lowest chronostratigraphic stage attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 962 externalDocs = @ExternalDocumentation( 963 description = "Darwin Core definition", 964 url = "https://rs.tdwg.org/dwc/terms/earliestAgeOrLowestStage" 965 ) 966 ) 967 private String earliestAgeOrLowestStage; 968 969 @Schema( 970 description = "The full name of the latest possible geochronologic age or highest chronostratigraphic stage attributable to the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 971 externalDocs = @ExternalDocumentation( 972 description = "Darwin Core definition", 973 url = "https://rs.tdwg.org/dwc/terms/latestAgeOrHighestStage" 974 ) 975 ) 976 private String latestAgeOrHighestStage; 977 978 @Schema( 979 description = "The full name of the lowest possible geological biostratigraphic zone of the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 980 externalDocs = @ExternalDocumentation( 981 description = "Darwin Core definition", 982 url = "https://rs.tdwg.org/dwc/terms/lowestBiostratigraphicZone" 983 ) 984 ) 985 private String lowestBiostratigraphicZone; 986 987 @Schema( 988 description = "The full name of the highest possible geological biostratigraphic zone of the stratigraphic horizon from which the dwc:MaterialEntity was collected.", 989 externalDocs = @ExternalDocumentation( 990 description = "Darwin Core definition", 991 url = "https://rs.tdwg.org/dwc/terms/highestBiostratigraphicZone" 992 ) 993 ) 994 private String highestBiostratigraphicZone; 995 996 @Schema( 997 description = "The full name of the lithostratigraphic group from which the dwc:MaterialEntity was collected.", 998 externalDocs = @ExternalDocumentation( 999 description = "Darwin Core definition", 1000 url = "https://rs.tdwg.org/dwc/terms/group" 1001 ) 1002 ) 1003 private String group; 1004 1005 @Schema( 1006 description = "The full name of the lithostratigraphic formation from which the dwc:MaterialEntity was collected.", 1007 externalDocs = @ExternalDocumentation( 1008 description = "Darwin Core definition", 1009 url = "https://rs.tdwg.org/dwc/terms/formation" 1010 ) 1011 ) 1012 private String formation; 1013 1014 @Schema( 1015 description = "The full name of the lithostratigraphic member from which the dwc:MaterialEntity was collected.", 1016 externalDocs = @ExternalDocumentation( 1017 description = "Darwin Core definition", 1018 url = "https://rs.tdwg.org/dwc/terms/member" 1019 ) 1020 ) 1021 private String member; 1022 1023 @Schema( 1024 description = "The full name of the lithostratigraphic bed from which the dwc:MaterialEntity was collected.", 1025 externalDocs = @ExternalDocumentation( 1026 description = "Darwin Core definition", 1027 url = "https://rs.tdwg.org/dwc/terms/bed" 1028 ) 1029 ) 1030 private String bed; 1031 1032 1033 @Schema( 1034 description = "A person, group, or organization responsible for recording the original occurrence.", 1035 externalDocs = @ExternalDocumentation( 1036 description = "Darwin Core definition", 1037 url = "https://rs.tdwg.org/dwc/terms/recordedBy" 1038 ) 1039 ) 1040 private String recordedBy; 1041 1042 @Schema( 1043 description = "A list (concatenated and separated) of names of people, groups, or organizations who assigned the " + 1044 "Taxon to the occurrence.", 1045 externalDocs = @ExternalDocumentation( 1046 description = "Darwin Core definition", 1047 url = "https://rs.tdwg.org/dwc/terms/identifiedBy" 1048 ) 1049 ) 1050 private String identifiedBy; 1051 1052 @Schema( 1053 description = "A preparation or preservation method for a specimen.", 1054 externalDocs = @ExternalDocumentation( 1055 description = "Darwin Core definition", 1056 url = "https://rs.tdwg.org/dwc/terms/preparations" 1057 ) 1058 ) 1059 private String preparations; 1060 1061 @Schema( 1062 description = "The methods or protocols used during an Event, denoted by an IRI.", 1063 externalDocs = @ExternalDocumentation( 1064 description = "Darwin Core definition", 1065 url = "https://rs.tdwg.org/dwc/terms/samplingProtocol" 1066 ) 1067 ) 1068 private String samplingProtocol; 1069 1070 @Schema( 1071 description = "**Deprecated: use the nucleotideSequence instead.** The DNA sequence ID of an occurrence." 1072 ) 1073 @Deprecated 1074 private List<String> dnaSequenceID = new ArrayList<>(); 1075 1076 @Schema(description = "Nucleotide Sequence objects of an occurrence.") 1077 @Getter 1078 @Setter 1079 private List<NucleotideSequence> nucleotideSequence = new ArrayList<>(); 1080 1081 public Occurrence() { 1082 1083 } 1084 1085 /** 1086 * Create occurrence instance from existing verbatim one, copying over all data. 1087 */ 1088 public Occurrence(@Nullable VerbatimOccurrence verbatim) { 1089 if (verbatim != null) { 1090 setKey(verbatim.getKey()); 1091 setDatasetKey(verbatim.getDatasetKey()); 1092 setPublishingOrgKey(verbatim.getPublishingOrgKey()); 1093 setPublishingCountry(verbatim.getPublishingCountry()); 1094 setProtocol(verbatim.getProtocol()); 1095 setCrawlId(verbatim.getCrawlId()); 1096 if (verbatim.getLastCrawled() != null) { 1097 setLastCrawled(new Date(verbatim.getLastCrawled().getTime())); 1098 } 1099 if (verbatim.getVerbatimFields() != null) { 1100 getVerbatimFields().putAll(verbatim.getVerbatimFields()); 1101 } 1102 if (verbatim.getLastParsed() != null) { 1103 setLastParsed(verbatim.getLastParsed()); 1104 } 1105 setExtensions(verbatim.getExtensions()); 1106 } 1107 } 1108 1109 @Nullable 1110 public BasisOfRecord getBasisOfRecord() { 1111 return basisOfRecord; 1112 } 1113 1114 public void setBasisOfRecord(BasisOfRecord basisOfRecord) { 1115 this.basisOfRecord = basisOfRecord; 1116 } 1117 1118 @Nullable 1119 public Integer getIndividualCount() { 1120 return individualCount; 1121 } 1122 1123 public void setIndividualCount(Integer individualCount) { 1124 this.individualCount = individualCount; 1125 } 1126 1127 @Nullable 1128 public OccurrenceStatus getOccurrenceStatus() { 1129 return occurrenceStatus; 1130 } 1131 1132 public void setOccurrenceStatus(OccurrenceStatus occurrenceStatus) { 1133 this.occurrenceStatus = occurrenceStatus; 1134 } 1135 1136 @Nullable 1137 public String getSex() { 1138 return sex; 1139 } 1140 1141 public void setSex(String sex) { 1142 this.sex = sex; 1143 } 1144 1145 @Nullable 1146 public String getLifeStage() { 1147 return lifeStage; 1148 } 1149 1150 public void setLifeStage(String lifeStage) { 1151 this.lifeStage = lifeStage; 1152 } 1153 1154 @Nullable 1155 public String getEstablishmentMeans() { 1156 return establishmentMeans; 1157 } 1158 1159 public void setEstablishmentMeans(String establishmentMeans) { 1160 this.establishmentMeans = establishmentMeans; 1161 } 1162 1163 /** 1164 * The best matching, accepted name usage representing this occurrence. 1165 * In case the verbatim scientific name and its classification can only be matched to a higher rank this will 1166 * represent the lowest matching rank. In the worst case this could just be for example Animalia. 1167 */ 1168 @Nullable 1169 public Integer getTaxonKey() { 1170 return taxonKey; 1171 } 1172 1173 public void setTaxonKey(Integer taxonKey) { 1174 this.taxonKey = taxonKey; 1175 } 1176 1177 @Nullable 1178 @Override 1179 public Integer getKingdomKey() { 1180 return kingdomKey; 1181 } 1182 1183 @Override 1184 public void setKingdomKey(@Nullable Integer kingdomKey) { 1185 this.kingdomKey = kingdomKey; 1186 } 1187 1188 @Nullable 1189 @Override 1190 public Integer getPhylumKey() { 1191 return phylumKey; 1192 } 1193 1194 @Override 1195 public void setPhylumKey(@Nullable Integer phylumKey) { 1196 this.phylumKey = phylumKey; 1197 } 1198 1199 @Nullable 1200 @Override 1201 public Integer getClassKey() { 1202 return classKey; 1203 } 1204 1205 @Override 1206 public void setClassKey(@Nullable Integer classKey) { 1207 this.classKey = classKey; 1208 } 1209 1210 @Nullable 1211 @Override 1212 public Integer getOrderKey() { 1213 return orderKey; 1214 } 1215 1216 @Override 1217 public void setOrderKey(@Nullable Integer orderKey) { 1218 this.orderKey = orderKey; 1219 } 1220 1221 @Nullable 1222 @Override 1223 public Integer getFamilyKey() { 1224 return familyKey; 1225 } 1226 1227 @Override 1228 public void setFamilyKey(@Nullable Integer familyKey) { 1229 this.familyKey = familyKey; 1230 } 1231 1232 @Nullable 1233 @Override 1234 public Integer getGenusKey() { 1235 return genusKey; 1236 } 1237 1238 @Override 1239 public void setGenusKey(@Nullable Integer genusKey) { 1240 this.genusKey = genusKey; 1241 } 1242 1243 @Nullable 1244 @Override 1245 public Integer getSubgenusKey() { 1246 return subgenusKey; 1247 } 1248 1249 @Override 1250 public void setSubgenusKey(@Nullable Integer subgenusKey) { 1251 this.subgenusKey = subgenusKey; 1252 } 1253 1254 @Nullable 1255 @Override 1256 public Integer getHigherRankKey(Rank rank) { 1257 return ClassificationUtils.getHigherRankKey(this, rank); 1258 } 1259 1260 /** 1261 * An ordered map with entries for all higher Linnean ranks excluding the taxonKey itself. 1262 * The map starts with the highest rank, e.g. the kingdom and maps the name usage key to its canonical name. 1263 * 1264 * @return map of higher ranks 1265 */ 1266 @NotNull 1267 @JsonIgnore 1268 public Map<Integer, String> getHigherClassificationMap() { 1269 return taxonKey == null ? ClassificationUtils.getHigherClassificationMap(this) 1270 : ClassificationUtils.getHigherClassificationMap(this, taxonKey, null, null); 1271 } 1272 1273 /** 1274 * The accepted species for this occurrence. In case the taxonKey is of a higher rank than species (e.g. genus) 1275 * speciesKey is null. In case taxonKey represents an infraspecific taxon the speciesKey points to the species 1276 * the infraspecies is classified as. In case of taxonKey being a species the speciesKey is the same. 1277 */ 1278 @Nullable 1279 @Override 1280 public Integer getSpeciesKey() { 1281 return speciesKey; 1282 } 1283 1284 @Override 1285 public void setSpeciesKey(@Nullable Integer speciesKey) { 1286 this.speciesKey = speciesKey; 1287 } 1288 1289 /** 1290 * The accepted taxon key from the selected taxonomy. 1291 */ 1292 @Nullable 1293 public Integer getAcceptedTaxonKey() { 1294 return acceptedTaxonKey; 1295 } 1296 1297 public void setAcceptedTaxonKey(Integer acceptedTaxonKey) { 1298 this.acceptedTaxonKey = acceptedTaxonKey; 1299 } 1300 1301 @Nullable 1302 public String getSpecificEpithet() { 1303 return specificEpithet; 1304 } 1305 1306 public void setSpecificEpithet(String specificEpithet) { 1307 this.specificEpithet = specificEpithet; 1308 } 1309 1310 @Nullable 1311 public String getInfraspecificEpithet() { 1312 return infraspecificEpithet; 1313 } 1314 1315 public void setInfraspecificEpithet(String infraspecificEpithet) { 1316 this.infraspecificEpithet = infraspecificEpithet; 1317 } 1318 1319 @Nullable 1320 public Rank getTaxonRank() { 1321 return taxonRank; 1322 } 1323 1324 public void setTaxonRank(Rank taxonRank) { 1325 this.taxonRank = taxonRank; 1326 } 1327 1328 /** 1329 * The status of the use of the scientificName as a label for a taxon. 1330 * The GBIF recommended controlled value vocabulary can be found at <a href="http://rs.gbif.org/vocabulary/gbif/taxonomic_status.xml">http://rs.gbif.org/vocabulary/gbif/taxonomic_status.xm</a>. 1331 */ 1332 @Nullable 1333 public TaxonomicStatus getTaxonomicStatus() { 1334 return taxonomicStatus; 1335 } 1336 1337 public void setTaxonomicStatus(TaxonomicStatus taxonomicStatus) { 1338 this.taxonomicStatus = taxonomicStatus; 1339 } 1340 1341 /** 1342 * The IUCN Red List Category. 1343 */ 1344 @Nullable 1345 public String getIucnRedListCategory() { 1346 return iucnRedListCategory; 1347 } 1348 1349 public void setIucnRedListCategory(String iucnRedListCategory) { 1350 this.iucnRedListCategory = iucnRedListCategory; 1351 } 1352 1353 /** 1354 * The scientific name for taxonKey from the selected taxonomy. 1355 */ 1356 @Nullable 1357 public String getScientificName() { 1358 return scientificName; 1359 } 1360 1361 public void setScientificName(@Nullable String scientificName) { 1362 this.scientificName = scientificName; 1363 } 1364 1365 /** 1366 * The scientific name authorship for taxonKey from the selected taxonomy. 1367 */ 1368 @Nullable 1369 public String getScientificNameAuthorship() { 1370 return scientificNameAuthorship; 1371 } 1372 1373 public void setScientificNameAuthorship(String scientificNameAuthorship) { 1374 this.scientificNameAuthorship = scientificNameAuthorship; 1375 } 1376 1377 /** 1378 * The verbatim scientific name as provided by the source. 1379 */ 1380 @Nullable 1381 @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 1382 public String getVerbatimScientificName() { 1383 return getVerbatimField(DwcTerm.scientificName); 1384 } 1385 1386 public void setVerbatimScientificName(String scientificName) { 1387 //DO NOTHING 1388 } 1389 1390 /** 1391 * The accepted scientific name for the acceptedTaxonKey from the selected taxonomy. 1392 */ 1393 @Nullable 1394 public String getAcceptedScientificName() { 1395 return acceptedScientificName; 1396 } 1397 1398 public void setAcceptedScientificName(String acceptedScientificName) { 1399 this.acceptedScientificName = acceptedScientificName; 1400 } 1401 1402 @Nullable 1403 @Override 1404 public String getKingdom() { 1405 return kingdom; 1406 } 1407 1408 @Override 1409 public void setKingdom(@Nullable String kingdom) { 1410 this.kingdom = kingdom; 1411 } 1412 1413 @Nullable 1414 @Override 1415 public String getPhylum() { 1416 return phylum; 1417 } 1418 1419 @Override 1420 public void setPhylum(@Nullable String phylum) { 1421 this.phylum = phylum; 1422 } 1423 1424 @Nullable 1425 @Override 1426 public String getClazz() { 1427 return clazz; 1428 } 1429 1430 @Override 1431 public void setClazz(@Nullable String clazz) { 1432 this.clazz = clazz; 1433 } 1434 1435 @Nullable 1436 @Override 1437 public String getOrder() { 1438 return order; 1439 } 1440 1441 @Override 1442 public void setOrder(@Nullable String order) { 1443 this.order = order; 1444 } 1445 1446 @Nullable 1447 @Override 1448 public String getFamily() { 1449 return family; 1450 } 1451 1452 @Override 1453 public void setFamily(@Nullable String family) { 1454 this.family = family; 1455 } 1456 1457 @Nullable 1458 @Override 1459 public String getGenus() { 1460 return genus; 1461 } 1462 1463 @Override 1464 public void setGenus(@Nullable String genus) { 1465 this.genus = genus; 1466 } 1467 1468 @Nullable 1469 public String getGenericName() { 1470 return genericName; 1471 } 1472 1473 public void setGenericName(String genericName) { 1474 this.genericName = genericName; 1475 } 1476 1477 @Nullable 1478 @Override 1479 public String getSubgenus() { 1480 return subgenus; 1481 } 1482 1483 @Override 1484 public void setSubgenus(@Nullable String subgenus) { 1485 this.subgenus = subgenus; 1486 } 1487 1488 @Nullable 1489 @Override 1490 public String getHigherRank(Rank rank) { 1491 return ClassificationUtils.getHigherRank(this, rank); 1492 } 1493 1494 /** 1495 * The corresponding scientific name of the speciesKey from the selected taxonomy. 1496 */ 1497 @Nullable 1498 @Override 1499 public String getSpecies() { 1500 return species; 1501 } 1502 1503 @Override 1504 public void setSpecies(@Nullable String species) { 1505 this.species = species; 1506 } 1507 1508 @Nullable 1509 public Date getDateIdentified() { 1510 return dateIdentified == null ? null : new Date(dateIdentified.getTime()); 1511 } 1512 1513 public void setDateIdentified(@Nullable Date dateIdentified) { 1514 this.dateIdentified = dateIdentified == null ? null : new Date(dateIdentified.getTime()); 1515 } 1516 1517 /** 1518 * The decimalLongitude in decimal degrees always for the WGS84 datum. If a different geodetic datum was given the verbatim 1519 * coordinates are transformed into WGS84 values. 1520 */ 1521 @Nullable 1522 public Double getDecimalLongitude() { 1523 return decimalLongitude; 1524 } 1525 1526 public void setDecimalLongitude(@Nullable Double decimalLongitude) { 1527 this.decimalLongitude = decimalLongitude; 1528 } 1529 1530 @Nullable 1531 public Double getDecimalLatitude() { 1532 return decimalLatitude; 1533 } 1534 1535 public void setDecimalLatitude(@Nullable Double decimalLatitude) { 1536 this.decimalLatitude = decimalLatitude; 1537 } 1538 1539 /** 1540 * The uncertainty radius for lat/lon in meters. 1541 */ 1542 @Nullable 1543 public Double getCoordinateUncertaintyInMeters() { 1544 return coordinateUncertaintyInMeters; 1545 } 1546 1547 public void setCoordinateUncertaintyInMeters(@Nullable Double coordinateUncertaintyInMeters) { 1548 this.coordinateUncertaintyInMeters = coordinateUncertaintyInMeters; 1549 } 1550 1551 @Nullable 1552 public Double getCoordinatePrecision() { 1553 return coordinatePrecision; 1554 } 1555 1556 public void setCoordinatePrecision(Double coordinatePrecision) { 1557 this.coordinatePrecision = coordinatePrecision; 1558 } 1559 1560 /** 1561 * @deprecated to be removed in the public v2 of the API (see POR-3061) 1562 * The uncertainty for latitude in decimal degrees. 1563 * Note that the longitude degrees have a different accuracy in degrees which changes with latitude and is largest at the poles. 1564 */ 1565 @Nullable 1566 @Deprecated 1567 public Double getCoordinateAccuracy() { 1568 return coordinateAccuracy; 1569 } 1570 1571 public void setCoordinateAccuracy(@Nullable Double coordinateAccuracy) { 1572 this.coordinateAccuracy = coordinateAccuracy; 1573 } 1574 1575 /** 1576 * The geodetic datum for the interpreted decimal coordinates. 1577 * This is always WGS84 if a coordinate exists as we reproject other datums into WGS84. 1578 */ 1579 @Schema( 1580 description = "The geodetic datum for the interpreted decimal coordinates.\n\n" + 1581 "Coordinates are reprojected to WGS84 if they exist, so this field is either null or `WGS84`." 1582 ) 1583 @Nullable 1584 public String getGeodeticDatum() { 1585 if (decimalLatitude != null) { 1586 return GEO_DATUM; 1587 } 1588 return null; 1589 } 1590 1591 /** 1592 * This private method is needed for jackson deserialization only. 1593 */ 1594 private void setGeodeticDatum(String datum) { 1595 // ignore, we have a static WGS84 value 1596 } 1597 1598 /** 1599 * Elevation in meters usually above sea level (altitude). 1600 * </br> 1601 * The elevation is calculated using the equation: (minimumElevationInMeters + maximumElevationInMeters) / 2. 1602 */ 1603 @Nullable 1604 public Double getElevation() { 1605 return elevation; 1606 } 1607 1608 public void setElevation(@Nullable Double elevation) { 1609 this.elevation = elevation; 1610 } 1611 1612 /** 1613 * Elevation accuracy is the uncertainty for the elevation in meters. 1614 * </br> 1615 * The elevation accuracy is calculated using the equation: (maximumElevationInMeters - minimumElevationInMeters) / 2 1616 */ 1617 @Nullable 1618 public Double getElevationAccuracy() { 1619 return elevationAccuracy; 1620 } 1621 1622 public void setElevationAccuracy(@Nullable Double elevationAccuracy) { 1623 this.elevationAccuracy = elevationAccuracy; 1624 } 1625 1626 /** 1627 * Depth in meters below the surface. Complimentary to elevation, the depth can be 10 meters below the surface of a 1628 * lake in 1100m (=elevation). 1629 * </br> 1630 * The depth is calculated using the equation: (minimumDepthInMeters + maximumDepthInMeters) / 2. 1631 */ 1632 @Nullable 1633 public Double getDepth() { 1634 return depth; 1635 } 1636 1637 public void setDepth(@Nullable Double depth) { 1638 this.depth = depth; 1639 } 1640 1641 /** 1642 * Depth accuracy is the uncertainty for the depth in meters. 1643 * </br> 1644 * The depth accuracy is calculated using the equation: (maximumDepthInMeters - minimumDepthInMeters) / 2 1645 */ 1646 @Nullable 1647 public Double getDepthAccuracy() { 1648 return depthAccuracy; 1649 } 1650 1651 public void setDepthAccuracy(@Nullable Double depthAccuracy) { 1652 this.depthAccuracy = depthAccuracy; 1653 } 1654 1655 @Nullable 1656 public Continent getContinent() { 1657 return continent; 1658 } 1659 1660 public void setContinent(@Nullable Continent continent) { 1661 this.continent = continent; 1662 } 1663 1664 @Schema( 1665 description = "The 2-letter country code (as per ISO-3166-1) of the country, territory or area in which the " + 1666 "occurrence was recorded.", 1667 externalDocs = @ExternalDocumentation( 1668 description = "Darwin Core definition", 1669 url = "https://rs.tdwg.org/dwc/terms/countryCode" 1670 ) 1671 ) 1672 @Nullable 1673 @JsonProperty("countryCode") 1674 public Country getCountry() { 1675 return country; 1676 } 1677 1678 public void setCountry(@Nullable Country country) { 1679 this.country = country; 1680 } 1681 1682 @Nullable 1683 @JsonProperty("gbifRegion") 1684 public GbifRegion getGbifRegion() { 1685 return Optional.ofNullable(country).map(Country::getGbifRegion).orElse(null); 1686 } 1687 1688 private void setGbifRegion(String gbifRegion) { 1689 // ignore, setter only to avoid JSON being written into the fields map 1690 } 1691 1692 /** 1693 * Renders the country title as a JSON property country in addition to the ISO 3166 2 letter countryCode being 1694 * serialized by the regular country Java property. 1695 * Made private to use it only for JSON serialization and not within Java code. 1696 */ 1697 @Schema( 1698 description = "The title (as per ISO-3166-1) of the country, territory or area in which the " + 1699 "occurrence was recorded.", 1700 externalDocs = @ExternalDocumentation( 1701 description = "Darwin Core definition", 1702 url = "https://rs.tdwg.org/dwc/terms/country" 1703 ) 1704 ) 1705 @Nullable 1706 @JsonProperty("country") 1707 private String getCountryTitle() { 1708 return country == null ? null : country.getTitle(); 1709 } 1710 1711 private void setCountryTitle(String country) { 1712 // ignore, setter only to avoid JSON being written into the fields map 1713 } 1714 1715 @Nullable 1716 public String getStateProvince() { 1717 return stateProvince; 1718 } 1719 1720 public void setStateProvince(@Nullable String stateProvince) { 1721 this.stateProvince = stateProvince; 1722 } 1723 1724 @Nullable 1725 public String getWaterBody() { 1726 return waterBody; 1727 } 1728 1729 public void setWaterBody(@Nullable String waterBody) { 1730 this.waterBody = waterBody; 1731 } 1732 1733 /** 1734 * The distance in metres from a known centroid, e.g. a country centroid. 1735 */ 1736 public Double getDistanceFromCentroidInMeters() { 1737 return distanceFromCentroidInMeters; 1738 } 1739 1740 public void setDistanceFromCentroidInMeters(Double distanceFromCentroidInMeters) { 1741 this.distanceFromCentroidInMeters = distanceFromCentroidInMeters; 1742 } 1743 1744 @Nullable 1745 public String getHigherGeography() { 1746 return higherGeography; 1747 } 1748 1749 public void setHigherGeography(String higherGeography) { 1750 this.higherGeography = higherGeography; 1751 } 1752 1753 @Nullable 1754 public String getGeoreferencedBy() { 1755 return georeferencedBy; 1756 } 1757 1758 public void setGeoreferencedBy(String georeferencedBy) { 1759 this.georeferencedBy = georeferencedBy; 1760 } 1761 1762 /** 1763 * The full year of the event date. 1764 * 1765 * @return the year of the event date 1766 */ 1767 @Min(1500) 1768 @Max(2030) 1769 @Nullable 1770 public Integer getYear() { 1771 return year; 1772 } 1773 1774 public void setYear(@Nullable Integer year) { 1775 this.year = year; 1776 } 1777 1778 /** 1779 * The month of the year of the event date starting with zero for january following {@link Date}. 1780 * 1781 * @return the month of the event date 1782 */ 1783 @Min(1) 1784 @Max(12) 1785 @Nullable 1786 public Integer getMonth() { 1787 return month; 1788 } 1789 1790 public void setMonth(@Nullable Integer month) { 1791 this.month = month; 1792 } 1793 1794 /** 1795 * The day of the month of the event date. 1796 * 1797 * @return the day of the event date 1798 */ 1799 @Min(1) 1800 @Max(31) 1801 @Nullable 1802 public Integer getDay() { 1803 return day; 1804 } 1805 1806 public void setDay(@Nullable Integer day) { 1807 this.day = day; 1808 } 1809 1810 /** 1811 * The date the occurrence was recorded or collected. 1812 */ 1813 @Nullable 1814 public IsoDateInterval getEventDate() { 1815 return eventDate == null ? null : new IsoDateInterval(eventDate.getFrom(), eventDate.getTo()); 1816 } 1817 1818 public void setEventDate(@Nullable IsoDateInterval eventDate) { 1819 this.eventDate = eventDate == null ? null : new IsoDateInterval(eventDate.getFrom(), eventDate.getTo()); 1820 } 1821 1822 /** 1823 * The earliest integer day of the year of the event. 1824 * 1825 * @return the earliest integer day of the event date 1826 */ 1827 @Min(1) 1828 @Max(366) 1829 @Nullable 1830 public Integer getStartDayOfYear() { 1831 return startDayOfYear; 1832 } 1833 1834 public void setStartDayOfYear(@Nullable Integer startDayOfYear) { 1835 this.startDayOfYear = startDayOfYear; 1836 } 1837 1838 /** 1839 * The latest integer day of the year of the event. 1840 * 1841 * @return the latest integer day of the event date 1842 */ 1843 @Min(1) 1844 @Max(366) 1845 @Nullable 1846 public Integer getEndDayOfYear() { 1847 return endDayOfYear; 1848 } 1849 1850 public void setEndDayOfYear(@Nullable Integer endDayOfYear) { 1851 this.endDayOfYear = endDayOfYear; 1852 } 1853 1854 @Nullable 1855 public String getTypeStatus() { 1856 return typeStatus; 1857 } 1858 1859 public void setTypeStatus(@Nullable String typeStatus) { 1860 this.typeStatus = typeStatus; 1861 } 1862 1863 /** 1864 * The scientific name the type status of this specimen applies to. 1865 */ 1866 @Nullable 1867 public String getTypifiedName() { 1868 return typifiedName; 1869 } 1870 1871 public void setTypifiedName(@Nullable String typifiedName) { 1872 this.typifiedName = typifiedName; 1873 } 1874 1875 /** 1876 * A set of issues found for this occurrence. 1877 */ 1878 @NotNull 1879 public Set<OccurrenceIssue> getIssues() { 1880 return issues; 1881 } 1882 1883 public void setIssues(Set<OccurrenceIssue> issues) { 1884 Objects.requireNonNull(issues, "Issues cannot be null"); 1885 EnumSet<OccurrenceIssue> set = EnumSet.noneOf(OccurrenceIssue.class); 1886 set.addAll(issues); 1887 this.issues = set; 1888 } 1889 1890 public void addIssue(OccurrenceIssue issue) { 1891 Objects.requireNonNull(issue, "Issue needs to be specified"); 1892 issues.add(issue); 1893 } 1894 1895 /** 1896 * The interpreted dc:modified from the verbatim source data. 1897 * Ideally indicating when a record was last modified in the source. 1898 */ 1899 @Nullable 1900 public Date getModified() { 1901 return modified == null ? null : new Date(modified.getTime()); 1902 } 1903 1904 public void setModified(@Nullable Date modified) { 1905 this.modified = modified == null ? null : new Date(modified.getTime()); 1906 } 1907 1908 /** 1909 * The date this occurrence last went through the interpretation phase of the GBIF indexing. 1910 */ 1911 @Nullable 1912 public Date getLastInterpreted() { 1913 return lastInterpreted == null ? null : new Date(lastInterpreted.getTime()); 1914 } 1915 1916 public void setLastInterpreted(@Nullable Date lastInterpreted) { 1917 this.lastInterpreted = lastInterpreted == null ? null : new Date(lastInterpreted.getTime()); 1918 } 1919 1920 /** 1921 * An external link to more details, the records "homepage". 1922 */ 1923 @Nullable 1924 public URI getReferences() { 1925 return references; 1926 } 1927 1928 public void setReferences(URI references) { 1929 this.references = references; 1930 } 1931 1932 /** 1933 * A number or enumeration value for the quantity of organisms. 1934 */ 1935 @Nullable 1936 public Double getOrganismQuantity() { 1937 return organismQuantity; 1938 } 1939 1940 public void setOrganismQuantity(@Nullable Double organismQuantity) { 1941 this.organismQuantity = organismQuantity; 1942 } 1943 1944 /** 1945 * The type of quantification system used for the quantity of organisms. 1946 */ 1947 @Nullable 1948 public String getOrganismQuantityType() { 1949 return organismQuantityType; 1950 } 1951 1952 public void setOrganismQuantityType(@Nullable String organismQuantityType) { 1953 this.organismQuantityType = organismQuantityType; 1954 } 1955 1956 /** 1957 * The unit of measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 1958 */ 1959 @Nullable 1960 public String getSampleSizeUnit() { 1961 return sampleSizeUnit; 1962 } 1963 1964 public void setSampleSizeUnit(@Nullable String sampleSizeUnit) { 1965 this.sampleSizeUnit = sampleSizeUnit; 1966 } 1967 1968 /** 1969 * A numeric value for a measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 1970 */ 1971 @Nullable 1972 public Double getSampleSizeValue() { 1973 return sampleSizeValue; 1974 } 1975 1976 public void setSampleSizeValue(@Nullable Double sampleSizeValue) { 1977 this.sampleSizeValue = sampleSizeValue; 1978 } 1979 1980 /** 1981 * Calculated filed organismQuantity / sampleSizeValue, if the type is identical 1982 */ 1983 @Nullable 1984 public Double getRelativeOrganismQuantity() { 1985 return relativeOrganismQuantity; 1986 } 1987 1988 public void setRelativeOrganismQuantity(@Nullable Double relativeOrganismQuantity) { 1989 this.relativeOrganismQuantity = relativeOrganismQuantity; 1990 } 1991 1992 /** 1993 * Flag occurrence when associatedSequences/extension exists 1994 */ 1995 public boolean getIsSequenced() { 1996 return isSequenced; 1997 } 1998 1999 public void setIsSequenced(boolean isSequenced) { 2000 this.isSequenced = isSequenced; 2001 } 2002 2003 /** 2004 * A list (concatenated and separated) of identifiers (publication, global unique identifier, URI) of genetic 2005 * sequence information associated with the material entity. 2006 */ 2007 @Nullable 2008 public String getAssociatedSequences() { 2009 return associatedSequences; 2010 } 2011 2012 public void setAssociatedSequences(String associatedSequences) { 2013 this.associatedSequences = associatedSequences; 2014 } 2015 2016 /** 2017 * Applied license to the occurrence record or dataset to which this record belongs to. 2018 */ 2019 @NotNull 2020 public License getLicense() { 2021 return license; 2022 } 2023 2024 public void setLicense(License license) { 2025 this.license = license; 2026 } 2027 2028 @NotNull 2029 public List<Identifier> getIdentifiers() { 2030 return identifiers; 2031 } 2032 2033 public void setIdentifiers(List<Identifier> identifiers) { 2034 this.identifiers = identifiers; 2035 } 2036 2037 @NotNull 2038 public List<MediaObject> getMedia() { 2039 return media; 2040 } 2041 2042 public void setMedia(List<MediaObject> media) { 2043 this.media = media; 2044 } 2045 2046 @NotNull 2047 public List<MeasurementOrFact> getFacts() { 2048 return facts; 2049 } 2050 2051 public void setFacts(List<MeasurementOrFact> facts) { 2052 this.facts = facts; 2053 } 2054 2055 @NotNull 2056 public List<OccurrenceRelation> getRelations() { 2057 return relations; 2058 } 2059 2060 public void setRelations(List<OccurrenceRelation> relations) { 2061 this.relations = relations; 2062 } 2063 2064 @NotNull 2065 public List<AgentIdentifier> getRecordedByIds() { 2066 return recordedByIds; 2067 } 2068 2069 public void setRecordedByIds(List<AgentIdentifier> recordedByIds) { 2070 this.recordedByIds = recordedByIds; 2071 } 2072 2073 @NotNull 2074 public List<AgentIdentifier> getIdentifiedByIds() { 2075 return identifiedByIds; 2076 } 2077 2078 public void setIdentifiedByIds(List<AgentIdentifier> identifiedByIds) { 2079 this.identifiedByIds = identifiedByIds; 2080 } 2081 2082 @NotNull 2083 public Gadm getGadm() { 2084 return gadm; 2085 } 2086 2087 public void setGadm(Gadm gadm) { 2088 this.gadm = gadm; 2089 } 2090 2091 @Nullable 2092 @Experimental 2093 public String getInstitutionKey() { 2094 return institutionKey; 2095 } 2096 2097 public void setInstitutionKey(String institutionKey) { 2098 this.institutionKey = institutionKey; 2099 } 2100 2101 @Nullable 2102 @Experimental 2103 public String getCollectionKey() { 2104 return collectionKey; 2105 } 2106 2107 public void setCollectionKey(String collectionKey) { 2108 this.collectionKey = collectionKey; 2109 } 2110 2111 public boolean getIsInCluster() { 2112 return isInCluster; 2113 } 2114 2115 public void setIsInCluster(boolean isInCluster) { 2116 this.isInCluster = isInCluster; 2117 } 2118 2119 @Nullable 2120 public String getDegreeOfEstablishment() { 2121 return degreeOfEstablishment; 2122 } 2123 2124 public void setDegreeOfEstablishment(String degreeOfEstablishment) { 2125 this.degreeOfEstablishment = degreeOfEstablishment; 2126 } 2127 2128 @Nullable 2129 public String getPathway() { 2130 return pathway; 2131 } 2132 2133 public void setPathway(String pathway) { 2134 this.pathway = pathway; 2135 } 2136 2137 public String getDatasetID() { 2138 return datasetID; 2139 } 2140 2141 public void setDatasetID(String datasetID) { 2142 this.datasetID = datasetID; 2143 } 2144 2145 public String getDatasetName() { 2146 return datasetName; 2147 } 2148 2149 public void setDatasetName(String datasetName) { 2150 this.datasetName = datasetName; 2151 } 2152 2153 public String getOtherCatalogNumbers() { 2154 return otherCatalogNumbers; 2155 } 2156 2157 public void setOtherCatalogNumbers(String otherCatalogNumbers) { 2158 this.otherCatalogNumbers = otherCatalogNumbers; 2159 } 2160 2161 @Nullable 2162 public String getEarliestEonOrLowestEonothem() { 2163 return earliestEonOrLowestEonothem; 2164 } 2165 2166 public void setEarliestEonOrLowestEonothem(String earliestEonOrLowestEonothem) { 2167 this.earliestEonOrLowestEonothem = earliestEonOrLowestEonothem; 2168 } 2169 2170 @Nullable 2171 public String getLatestEonOrHighestEonothem() { 2172 return latestEonOrHighestEonothem; 2173 } 2174 2175 public void setLatestEonOrHighestEonothem(String latestEonOrHighestEonothem) { 2176 this.latestEonOrHighestEonothem = latestEonOrHighestEonothem; 2177 } 2178 2179 @Nullable 2180 public String getEarliestEraOrLowestErathem() { 2181 return earliestEraOrLowestErathem; 2182 } 2183 2184 public void setEarliestEraOrLowestErathem(String earliestEraOrLowestErathem) { 2185 this.earliestEraOrLowestErathem = earliestEraOrLowestErathem; 2186 } 2187 2188 @Nullable 2189 public String getLatestEraOrHighestErathem() { 2190 return latestEraOrHighestErathem; 2191 } 2192 2193 public void setLatestEraOrHighestErathem(String latestEraOrHighestErathem) { 2194 this.latestEraOrHighestErathem = latestEraOrHighestErathem; 2195 } 2196 2197 @Nullable 2198 public String getEarliestPeriodOrLowestSystem() { 2199 return earliestPeriodOrLowestSystem; 2200 } 2201 2202 public void setEarliestPeriodOrLowestSystem(String earliestPeriodOrLowestSystem) { 2203 this.earliestPeriodOrLowestSystem = earliestPeriodOrLowestSystem; 2204 } 2205 2206 @Nullable 2207 public String getLatestPeriodOrHighestSystem() { 2208 return latestPeriodOrHighestSystem; 2209 } 2210 2211 public void setLatestPeriodOrHighestSystem(String latestPeriodOrHighestSystem) { 2212 this.latestPeriodOrHighestSystem = latestPeriodOrHighestSystem; 2213 } 2214 2215 @Nullable 2216 public String getEarliestEpochOrLowestSeries() { 2217 return earliestEpochOrLowestSeries; 2218 } 2219 2220 public void setEarliestEpochOrLowestSeries(String earliestEpochOrLowestSeries) { 2221 this.earliestEpochOrLowestSeries = earliestEpochOrLowestSeries; 2222 } 2223 2224 @Nullable 2225 public String getLatestEpochOrHighestSeries() { 2226 return latestEpochOrHighestSeries; 2227 } 2228 2229 public void setLatestEpochOrHighestSeries(String latestEpochOrHighestSeries) { 2230 this.latestEpochOrHighestSeries = latestEpochOrHighestSeries; 2231 } 2232 2233 @Nullable 2234 public String getEarliestAgeOrLowestStage() { 2235 return earliestAgeOrLowestStage; 2236 } 2237 2238 public void setEarliestAgeOrLowestStage(String earliestAgeOrLowestStage) { 2239 this.earliestAgeOrLowestStage = earliestAgeOrLowestStage; 2240 } 2241 2242 @Nullable 2243 public String getLatestAgeOrHighestStage() { 2244 return latestAgeOrHighestStage; 2245 } 2246 2247 public void setLatestAgeOrHighestStage(String latestAgeOrHighestStage) { 2248 this.latestAgeOrHighestStage = latestAgeOrHighestStage; 2249 } 2250 2251 @Nullable 2252 public String getLowestBiostratigraphicZone() { 2253 return lowestBiostratigraphicZone; 2254 } 2255 2256 public void setLowestBiostratigraphicZone(String lowestBiostratigraphicZone) { 2257 this.lowestBiostratigraphicZone = lowestBiostratigraphicZone; 2258 } 2259 2260 @Nullable 2261 public String getHighestBiostratigraphicZone() { 2262 return highestBiostratigraphicZone; 2263 } 2264 2265 public void setHighestBiostratigraphicZone(String highestBiostratigraphicZone) { 2266 this.highestBiostratigraphicZone = highestBiostratigraphicZone; 2267 } 2268 2269 @Nullable 2270 public String getGroup() { 2271 return group; 2272 } 2273 2274 public void setGroup(String group) { 2275 this.group = group; 2276 } 2277 2278 @Nullable 2279 public String getFormation() { 2280 return formation; 2281 } 2282 2283 public void setFormation(String formation) { 2284 this.formation = formation; 2285 } 2286 2287 @Nullable 2288 public String getMember() { 2289 return member; 2290 } 2291 2292 public void setMember(String member) { 2293 this.member = member; 2294 } 2295 2296 @Nullable 2297 public String getBed() { 2298 return bed; 2299 } 2300 2301 public void setBed(String bed) { 2302 this.bed = bed; 2303 } 2304 2305 public String getRecordedBy() { 2306 return recordedBy; 2307 } 2308 2309 public void setRecordedBy(String recordedBy) { 2310 this.recordedBy = recordedBy; 2311 } 2312 2313 public String getIdentifiedBy() { 2314 return identifiedBy; 2315 } 2316 2317 public void setIdentifiedBy(String identifiedBy) { 2318 this.identifiedBy = identifiedBy; 2319 } 2320 2321 public String getPreparations() { 2322 return preparations; 2323 } 2324 2325 public void setPreparations(String preparations) { 2326 this.preparations = preparations; 2327 } 2328 2329 public String getSamplingProtocol() { 2330 return samplingProtocol; 2331 } 2332 2333 public void setSamplingProtocol(String samplingProtocol) { 2334 this.samplingProtocol = samplingProtocol; 2335 } 2336 2337 @Deprecated 2338 public List<String> getDnaSequenceID() { 2339 return dnaSequenceID; 2340 } 2341 2342 @Deprecated 2343 public void setDnaSequenceID(List<String> dnaSequenceID) { 2344 this.dnaSequenceID = dnaSequenceID; 2345 } 2346 2347 public Map<String, Classification> getClassifications() { 2348 return classifications; 2349 } 2350 2351 public void setClassifications(Map<String, Classification> classifications) { 2352 this.classifications = classifications; 2353 } 2354 2355 /** 2356 * Convenience method checking if any spatial validation rule has not passed. 2357 * Primarily used to indicate that the record should not be displayed on a map. 2358 */ 2359 @JsonIgnore 2360 public boolean hasSpatialIssue() { 2361 for (OccurrenceIssue rule : OccurrenceIssue.GEOSPATIAL_RULES) { 2362 if (issues.contains(rule)) { 2363 return true; 2364 } 2365 } 2366 return false; 2367 } 2368 2369 /** 2370 * This private method is only for serialization via jackson and not exposed anywhere else! 2371 * It maps the verbatimField terms into properties with their simple name or qualified names for UnknownTerms. 2372 */ 2373 @JsonAnyGetter 2374 private Map<String, String> jsonVerbatimFields() { 2375 Map<String, String> extendedProps = new HashMap<>(); 2376 for (Map.Entry<Term, String> prop : getVerbatimFields().entrySet()) { 2377 Term t = prop.getKey(); 2378 if (t instanceof UnknownTerm || PROPERTIES.contains(t.simpleName())) { 2379 extendedProps.put(t.qualifiedName(), prop.getValue()); 2380 } else { 2381 // render all terms in controlled enumerations as simple names only - unless we have a property of that name already! 2382 extendedProps.put(t.simpleName(), prop.getValue()); 2383 } 2384 } 2385 return extendedProps; 2386 } 2387}