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