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.search; 015import com.fasterxml.jackson.annotation.*; 016 017import com.fasterxml.jackson.core.JacksonException; 018 019import com.fasterxml.jackson.databind.DeserializationContext; 020import com.fasterxml.jackson.databind.JsonDeserializer; 021 022import com.fasterxml.jackson.databind.KeyDeserializer; 023import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 024import com.fasterxml.jackson.databind.node.ObjectNode; 025import org.gbif.api.model.common.search.SearchParameter; 026import org.gbif.api.util.IsoDateInterval; 027import org.gbif.api.vocabulary.BasisOfRecord; 028import org.gbif.api.vocabulary.Continent; 029import org.gbif.api.vocabulary.Country; 030import org.gbif.api.vocabulary.EndpointType; 031import org.gbif.api.vocabulary.GbifRegion; 032import org.gbif.api.vocabulary.License; 033import org.gbif.api.vocabulary.MediaType; 034import org.gbif.api.vocabulary.OccurrenceIssue; 035import org.gbif.api.vocabulary.OccurrenceStatus; 036import org.gbif.api.vocabulary.TaxonomicStatus; 037 038import java.io.IOException; 039import java.io.Serializable; 040import java.lang.reflect.Field; 041import java.util.ArrayList; 042import java.util.Date; 043import java.util.List; 044import java.util.Objects; 045import java.util.Optional; 046import java.util.UUID; 047 048/** 049 * Supported query parameters by the occurrence search and download service. 050 * For download predicates only the numerical types support comparisons other than equals. 051 */ 052@JsonDeserialize(as = OccurrenceSearchParameter.class, using = OccurrenceSearchParameter.OccurrenceSearchParameterDeserializer.class) 053public class OccurrenceSearchParameter implements SearchParameter, Serializable { 054 055 /** 056 * The dataset key as a UUID. 057 */ 058 public final static OccurrenceSearchParameter DATASET_KEY = new OccurrenceSearchParameter("DATASET_KEY", UUID.class); 059 060 /** 061 * The checklist key to use for taxonomy matching. 062 */ 063 public final static OccurrenceSearchParameter CHECKLIST_KEY = new OccurrenceSearchParameter("CHECKLIST_KEY", String.class); 064 065 /** 066 * The 4 digit year. A year of 98 will be 98 common era, not 1998. 067 * This parameter accepts comma separated range values, e.g.: 068 * <dl> 069 * <dt>*,1810</dt> 070 * <dd>Found before or equal to 1810</dd> 071 * <dt>1848,1933</dt> 072 * <dd>Year between 1848 and 1933</dd> 073 * </dl> 074 */ 075 public final static OccurrenceSearchParameter YEAR = new OccurrenceSearchParameter("YEAR", Integer.class); 076 077 /** 078 * The month of the year, starting with 1 for January. 079 * A month query can be used to retrieve seasonal records when used without a year or a year range. 080 * This parameter accepts comma separated range values, e.g.: 081 * <dl> 082 * <dt>4,8</dt> 083 * <dd>Month between April and August</dd> 084 * </dl> 085 */ 086 public final static OccurrenceSearchParameter MONTH = new OccurrenceSearchParameter("MONTH", Integer.class); 087 088 /** 089 * The day of the month. 090 * This parameter accepts comma separated range values, e.g.: 091 * <dl> 092 * <dt>24,28</dt> 093 * <dd>Day of the month between 24 and 28</dd> 094 * </dl> 095 */ 096 public final static OccurrenceSearchParameter DAY = new OccurrenceSearchParameter("DAY", Integer.class); 097 098 /** 099 * The earliest integer day of the year on which the event occurred (1 for January 1, 365 for December 31, except in a 100 * leap year, in which case it is 366). 101 */ 102 public final static OccurrenceSearchParameter START_DAY_OF_YEAR = new OccurrenceSearchParameter("START_DAY_OF_YEAR", Integer.class); 103 104 /** 105 * The latest integer day of the year on which the event occurred (1 for January 1, 365 for December 31, except in a 106 * leap year, in which case it is 366). 107 */ 108 public final static OccurrenceSearchParameter END_DAY_OF_YEAR = new OccurrenceSearchParameter("END_DAY_OF_YEAR", Integer.class); 109 110 /** 111 * Event date (date the occurrence was recorded) in ISO 8601 formats:yyyy, yyyy-MM, yyyy-MM-dd and MM-dd. 112 * This parameter accepts comma separated range values, examples of valid ranges are: 113 * <dl> 114 * <dt>2001-02-11,2010-01-10</dt> 115 * <dd>Dates between 2001-02-11 and 2010-01-10</dd> 116 * <dt>2001-02,2010-01</dt> 117 * <dd>Dates between first day of 2001-02 and last day of 2010-01</dd> 118 * <dt>2001,2010</dt> 119 * <dd>Dates between first day of 2001 and last day of 2010</dd> 120 * <dt>2001,2010-01</dt> 121 * <dd>Dates between first day of 2001 and last day of 2010-01</dd> 122 * <dt>2001-01-10,2010</dt> 123 * <dd>Dates between 2001-01-10 and last day of 2010</dd> 124 * <dt>2001-01-10,*</dt> 125 * <dd>Dates after 2001-01-10</dd> 126 * <dt>*,2001-01-10</dt> 127 * <dd>Dates before 2001-01-10</dd> 128 * <dt>*</dt> 129 * <dd>all dates</dd> 130 * </dl> 131 */ 132 public final static OccurrenceSearchParameter EVENT_DATE = new OccurrenceSearchParameter("EVENT_DATE", IsoDateInterval.class); 133 134 /** 135 * Lower limit for the range of the event date (date the occurrence was recorded). 136 * 137 * Included for backward compatibility as it mimicks the previous search behaviour: 138 * https://github.com/gbif/occurrence/issues/346 139 */ 140 @Deprecated 141 public final static OccurrenceSearchParameter EVENT_DATE_GTE = new OccurrenceSearchParameter("EVENT_DATE_GTE", Date.class); 142 143 /** 144 * An identifier for the set of information associated with an Event (something that occurs at a place and time). 145 * Maybe a global unique identifier or an identifier specific to the data set. 146 */ 147 public final static OccurrenceSearchParameter EVENT_ID = new OccurrenceSearchParameter("EVENT_ID", String.class); 148 149 /** 150 * An identifier for the broader Event that groups this and potentially other Events. 151 */ 152 public final static OccurrenceSearchParameter PARENT_EVENT_ID = new OccurrenceSearchParameter("PARENT_EVENT_ID", String.class); 153 154 /** 155 * An identifier for an Event and its children events. 156 */ 157 public final static OccurrenceSearchParameter EVENT_ID_HIERARCHY = new OccurrenceSearchParameter("EVENT_ID_HIERARCHY", String.class); 158 159 /** 160 * The name of, reference to, or description of the method or protocol used during an Event. 161 */ 162 public final static OccurrenceSearchParameter SAMPLING_PROTOCOL = new OccurrenceSearchParameter("SAMPLING_PROTOCOL", String.class); 163 164 /** 165 * A list (concatenated and separated) of previous assignments of names to the organism. 166 */ 167 public final static OccurrenceSearchParameter PREVIOUS_IDENTIFICATIONS = new OccurrenceSearchParameter("PREVIOUS_IDENTIFICATIONS", String.class); 168 169 /** 170 * Last interpreted date in ISO 8601 formats:yyyy, yyyy-MM, yyyy-MM-dd and MM-dd. 171 * This parameter accepts comma separated range values, examples of valid ranges are: 172 * <dl> 173 * <dt>2001-02-11,2010-01-10</dt> 174 * <dd>Dates between 2001-02-11 and 2010-01-10</dd> 175 * <dt>2001-02,2010-01</dt> 176 * <dd>Dates between first day of 2001-02 and last day of 2010-01</dd> 177 * <dt>2001,2010</dt> 178 * <dd>Dates between first day of 2001 and last day of 2010</dd> 179 * <dt>2001,2010-01</dt> 180 * <dd>Dates between first day of 2001 and last day of 2010-01</dd> 181 * <dt>2001-01-10,2010</dt> 182 * <dd>Dates between 2001-01-10 and last day of 2010</dd> 183 * <dt>2001-01-10,*</dt> 184 * <dd>Dates after 2001-01-10</dd> 185 * <dt>*,2001-01-10</dt> 186 * <dd>Dates before 2001-01-10</dd> 187 * <dt>*</dt> 188 * <dd>all dates</dd> 189 * </dl> 190 */ 191 public final static OccurrenceSearchParameter LAST_INTERPRETED = new OccurrenceSearchParameter("LAST_INTERPRETED", Date.class); 192 193 194 /** 195 * Modified date in ISO 8601 formats:yyyy, yyyy-MM, yyyy-MM-dd and MM-dd. 196 * This parameter accepts comma separated range values, examples of valid ranges are: 197 * <dl> 198 * <dt>2001-02-11,2010-01-10</dt> 199 * <dd>Dates between 2001-02-11 and 2010-01-10</dd> 200 * <dt>2001-02,2010-01</dt> 201 * <dd>Dates between first day of 2001-02 and last day of 2010-01</dd> 202 * <dt>2001,2010</dt> 203 * <dd>Dates between first day of 2001 and last day of 2010</dd> 204 * <dt>2001,2010-01</dt> 205 * <dd>Dates between first day of 2001 and last day of 2010-01</dd> 206 * <dt>2001-01-10,2010</dt> 207 * <dd>Dates between 2001-01-10 and last day of 2010</dd> 208 * <dt>2001-01-10,*</dt> 209 * <dd>Dates after 2001-01-10</dd> 210 * <dt>*,2001-01-10</dt> 211 * <dd>Dates before 2001-01-10</dd> 212 * <dt>*</dt> 213 * <dd>all dates</dd> 214 * </dl> 215 */ 216 public final static OccurrenceSearchParameter MODIFIED = new OccurrenceSearchParameter("MODIFIED", Date.class); 217 218 /** 219 * Latitude in decimals between -90 and 90 based on WGS 84. 220 */ 221 public final static OccurrenceSearchParameter DECIMAL_LATITUDE = new OccurrenceSearchParameter("DECIMAL_LATITUDE", Double.class); 222 223 /** 224 * Longitude in decimals between -180 and 180 based on WGS 84. 225 */ 226 public final static OccurrenceSearchParameter DECIMAL_LONGITUDE = new OccurrenceSearchParameter("DECIMAL_LONGITUDE", Double.class); 227 228 /** 229 * The uncertainty of the coordinate in meters. 230 * This parameter accepts comma separated range values, e.g.: 231 * <dl> 232 * <dt>*,100</dt> 233 * <dd>Uncertainty below or equals 100m</dd> 234 * <dt>10000,*</dt> 235 * <dd>Uncertainty above or equals 10,000m</dd> 236 * <dt>1000,5000</dt> 237 * <dd>Uncertainty between or equals 1000m and 5000m 238 * </dd> 239 * </dl> 240 */ 241 public final static OccurrenceSearchParameter COORDINATE_UNCERTAINTY_IN_METERS = new OccurrenceSearchParameter("COORDINATE_UNCERTAINTY_IN_METERS", Double.class); 242 243 /** 244 * Country the occurrence was recorded in. 245 */ 246 public final static OccurrenceSearchParameter COUNTRY = new OccurrenceSearchParameter("COUNTRY", Country.class); 247 248 /** 249 * GBIF region based on country 250 */ 251 public final static OccurrenceSearchParameter GBIF_REGION = new OccurrenceSearchParameter("GBIF_REGION", GbifRegion.class); 252 253 /** 254 * Continent the occurrence was recorded in. 255 */ 256 public final static OccurrenceSearchParameter CONTINENT = new OccurrenceSearchParameter("CONTINENT", Continent.class); 257 258 /** 259 * The country of the organization that publishes the dataset the occurrence belongs to. 260 */ 261 public final static OccurrenceSearchParameter PUBLISHING_COUNTRY = new OccurrenceSearchParameter("PUBLISHING_COUNTRY", Country.class); 262 263 /** 264 * GBIF region based on publishibg country 265 */ 266 public final static OccurrenceSearchParameter PUBLISHED_BY_GBIF_REGION = new OccurrenceSearchParameter("PUBLISHED_BY_GBIF_REGION", GbifRegion.class); 267 268 /** 269 * Altitude/elevation in meters above sea level. 270 * This parameter accepts comma separated range values, e.g.: 271 * <dl> 272 * <dt>*,100</dt> 273 * <dd>Altitude below or equals 100m</dd> 274 * <dt>100,*</dt> 275 * <dd>Altitude above or equals 100m</dd> 276 * <dt>-2,8.8</dt> 277 * <dd>Altitude between or equals -2m and 8.8m</dd> 278 * </dl> 279 */ 280 public final static OccurrenceSearchParameter ELEVATION = new OccurrenceSearchParameter("ELEVATION", Double.class); 281 282 /** 283 * Depth in meters relative to altitude. For example 10 meters below a lake surface with given altitude. 284 * This parameter accepts comma separated range values, e.g.: 285 * <dl> 286 * <dt>*,10</dt> 287 * <dd>Depth below or equals 10m</dd> 288 * <dt>100,*</dt> 289 * <dd>Depth above or equals 100m</dd> 290 * <dt>12.1,28.8</dt> 291 * <dd>Depth between or equals 12.1m and 28.8m</dd> 292 * </dl> 293 */ 294 public final static OccurrenceSearchParameter DEPTH = new OccurrenceSearchParameter("DEPTH", Double.class); 295 296 /** 297 * An identifier of any form assigned by the source to identify the institution 298 * the record belongs to. Not guaranteed to be unique. 299 */ 300 public final static OccurrenceSearchParameter INSTITUTION_CODE = new OccurrenceSearchParameter("INSTITUTION_CODE", String.class); 301 302 /** 303 * An identifier of any form assigned by the source to identify the physical collection or digital dataset 304 * uniquely within the context of an institution. 305 */ 306 public final static OccurrenceSearchParameter COLLECTION_CODE = new OccurrenceSearchParameter("COLLECTION_CODE", String.class); 307 308 /** 309 * An identifier of any form assigned by the source within a physical collection or digital dataset for the record 310 * which may not be unique, but should be fairly unique in combination with the institution and collection code. 311 */ 312 public final static OccurrenceSearchParameter CATALOG_NUMBER = new OccurrenceSearchParameter("CATALOG_NUMBER", String.class); 313 314 /** 315 * The person who recorded the occurrence. 316 */ 317 public final static OccurrenceSearchParameter RECORDED_BY = new OccurrenceSearchParameter("RECORDED_BY", String.class); 318 319 /** 320 * The person who identified the occurrence. 321 */ 322 public final static OccurrenceSearchParameter IDENTIFIED_BY = new OccurrenceSearchParameter("IDENTIFIED_BY", String.class); 323 324 /** 325 * An identifier given to the Occurrence at the time it was recorded. 326 */ 327 public final static OccurrenceSearchParameter RECORD_NUMBER = new OccurrenceSearchParameter("RECORD_NUMBER", String.class); 328 329 /** 330 * A basis of record enumeration value. 331 */ 332 public final static OccurrenceSearchParameter BASIS_OF_RECORD = new OccurrenceSearchParameter("BASIS_OF_RECORD", BasisOfRecord.class); 333 334 /** 335 * The sex of the biological individual(s) represented in the occurrence. 336 */ 337 public final static OccurrenceSearchParameter SEX = new OccurrenceSearchParameter("SEX", String.class); 338 339 /** 340 * Presents of associated sequences or an extension 341 */ 342 public final static OccurrenceSearchParameter IS_SEQUENCED = new OccurrenceSearchParameter("IS_SEQUENCED", Boolean.class); 343 344 /** 345 * A taxon key from the GBIF backbone. All included and synonym taxa are included in the search, so a search for 346 * aves with taxonKey=212 will match all birds, no matter which species. 347 */ 348 public final static OccurrenceSearchParameter TAXON_KEY = new OccurrenceSearchParameter("TAXON_KEY", String.class); 349 350 /** 351 * A taxon key from the GBIF backbone for the name usage of the currently valid or accepted taxon. 352 */ 353 public final static OccurrenceSearchParameter ACCEPTED_TAXON_KEY = new OccurrenceSearchParameter("ACCEPTED_TAXON_KEY", String.class); 354 355 /** 356 * A kingdom key from the GBIF backbone. 357 */ 358 public final static OccurrenceSearchParameter KINGDOM_KEY = new OccurrenceSearchParameter("KINGDOM_KEY", String.class); 359 360 /** 361 * A phylum key from the GBIF backbone. 362 */ 363 public final static OccurrenceSearchParameter PHYLUM_KEY = new OccurrenceSearchParameter("PHYLUM_KEY", String.class); 364 365 /** 366 * A class key from the GBIF backbone. 367 */ 368 public final static OccurrenceSearchParameter CLASS_KEY = new OccurrenceSearchParameter("CLASS_KEY", String.class); 369 370 /** 371 * A order key from the GBIF backbone. 372 */ 373 public final static OccurrenceSearchParameter ORDER_KEY = new OccurrenceSearchParameter("ORDER_KEY", String.class); 374 375 /** 376 * A family key from the GBIF backbone. 377 */ 378 public final static OccurrenceSearchParameter FAMILY_KEY = new OccurrenceSearchParameter("FAMILY_KEY", String.class); 379 380 /** 381 * A genus key from the GBIF backbone. 382 */ 383 public final static OccurrenceSearchParameter GENUS_KEY = new OccurrenceSearchParameter("GENUS_KEY", String.class); 384 385 /** 386 * A subgenus key from the GBIF backbone. 387 */ 388 public final static OccurrenceSearchParameter SUBGENUS_KEY = new OccurrenceSearchParameter("SUBGENUS_KEY", String.class); 389 390 /** 391 * A species key from the GBIF backbone. 392 */ 393 public final static OccurrenceSearchParameter SPECIES_KEY = new OccurrenceSearchParameter("SPECIES_KEY", String.class); 394 395 /** 396 * Searches the interpreted, full scientific name of the occurrence. 397 */ 398 public final static OccurrenceSearchParameter SCIENTIFIC_NAME = new OccurrenceSearchParameter("SCIENTIFIC_NAME", String.class); 399 400 /** 401 * Scientific name as provided byt the source. 402 */ 403 public final static OccurrenceSearchParameter VERBATIM_SCIENTIFIC_NAME = new OccurrenceSearchParameter("VERBATIM_SCIENTIFIC_NAME", String.class); 404 405 /** 406 * Verbatim identifier for the set of taxon information. Maybe a global unique identifier or an identifier specific to 407 * the data set. 408 */ 409 public final static OccurrenceSearchParameter TAXON_ID = new OccurrenceSearchParameter("TAXON_ID", String.class); 410 411 /** 412 * An identifier for the taxonomic concept to which the record refers - not for the nomenclatural details of a taxon. 413 */ 414 public final static OccurrenceSearchParameter TAXON_CONCEPT_ID = new OccurrenceSearchParameter("TAXON_CONCEPT_ID", String.class); 415 416 /** 417 * The status of the use of the GBIF Backbone taxonKey. 418 */ 419 public final static OccurrenceSearchParameter TAXONOMIC_STATUS = new OccurrenceSearchParameter("TAXONOMIC_STATUS", TaxonomicStatus.class); 420 421 /** 422 * Searches for occurrence records which contain a value on its coordinate fields (latitude and longitude). 423 * HAS_COORDINATE=true searches for occurrence records with a coordinate value. 424 * HAS_COORDINATE=false searches for occurrence records without a coordinate value. 425 */ 426 public final static OccurrenceSearchParameter HAS_COORDINATE = new OccurrenceSearchParameter("HAS_COORDINATE", Boolean.class); 427 428 /** 429 * Geometry in <a href="https://en.wikipedia.org/wiki/Well-known_text">Well Known Text</a> (WKT) format. 430 * E.g.: POLYGON ((30.0 10.0, 10.12 20.23, 20 40, 40 40, 30 10)). 431 * Multi geometries like MULTIPOLYGON are not supported and multiple parameters should be used instead. 432 * Valid geometries are: 433 * <ul> 434 * <li>POINT</li> 435 * <li>LINESTRING</li> 436 * <li>POLYGON</li> 437 * <li>LINEARRING</li> 438 * </ul> 439 */ 440 public final static OccurrenceSearchParameter GEOMETRY = new OccurrenceSearchParameter("GEOMETRY", String.class); 441 442 /** 443 * Use in combination of LATITUDE and LONGITUDE parameters matches within a given distance. 444 * E.g.: geo_distance=100m,40,90 geo_distance=100km,40,90 geo_distance=100mi,40,90. 445 * See supported units in {@link org.gbif.api.model.occurrence.geo.DistanceUnit}. 446 */ 447 public final static OccurrenceSearchParameter GEO_DISTANCE = new OccurrenceSearchParameter("GEO_DISTANCE", String.class); 448 449 /** 450 * The distance from a known centroid, e.g. a country centroid. 451 */ 452 public final static OccurrenceSearchParameter DISTANCE_FROM_CENTROID_IN_METERS = new OccurrenceSearchParameter("DISTANCE_FROM_CENTROID_IN_METERS", Double.class); 453 454 /** 455 * Includes/excludes occurrence records which contain geospatial issues for their coordinate. 456 * See {@link org.gbif.api.vocabulary.OccurrenceIssue#GEOSPATIAL_RULES} 457 * HAS_GEOSPATIAL_ISSUE=true include records with spatial issues. 458 * HAS_GEOSPATIAL_ISSUE=false exclude records with spatial issues. 459 * The absence of this parameter returns any record with or without spatial issues. 460 */ 461 public final static OccurrenceSearchParameter HAS_GEOSPATIAL_ISSUE = new OccurrenceSearchParameter("HAS_GEOSPATIAL_ISSUE", Boolean.class); 462 463 /** 464 * Searches occurrence for those that have a specific issue. 465 */ 466 public final static OccurrenceSearchParameter ISSUE = new OccurrenceSearchParameter("ISSUE", OccurrenceIssue.class); 467 468 /** 469 * Searches occurrence for those that have a specific taxonomic issue. This is separated out from the general issue 470 * field as taxonomic issues will be tied to a specific checklist. 471 */ 472 public final static OccurrenceSearchParameter TAXONOMIC_ISSUE = new OccurrenceSearchParameter("TAXONOMIC_ISSUE", String.class); 473 474 /** 475 * Nomenclatural type (type status, typified scientific name, publication) applied to the subject. 476 */ 477 public final static OccurrenceSearchParameter TYPE_STATUS = new OccurrenceSearchParameter("TYPE_STATUS", String.class); 478 479 /** 480 * The kind of media object. 481 * Recommended terms from the DCMI Type Vocabulary are StillImage, Sound or MovingImage for GBIF to index and show the 482 * media files. 483 */ 484 public final static OccurrenceSearchParameter MEDIA_TYPE = new OccurrenceSearchParameter("MEDIA_TYPE", MediaType.class); 485 486 /** 487 * An identifier for the Occurrence (as opposed to a particular digital record of the occurrence). 488 * In the absence of a persistent global unique identifier, construct one from a combination of identifiers in the 489 * record that will most closely make the occurrenceID globally unique. 490 */ 491 public final static OccurrenceSearchParameter OCCURRENCE_ID = new OccurrenceSearchParameter("OCCURRENCE_ID", String.class); 492 493 /** 494 * The process by which the biological individual(s) represented in the Occurrence became established at the location. 495 */ 496 public final static OccurrenceSearchParameter ESTABLISHMENT_MEANS = new OccurrenceSearchParameter("ESTABLISHMENT_MEANS", String.class); 497 498 /** 499 * Provides the controlled vocabulary for information about degree to which an Organism survives, reproduces, and expands its range at the given place and time. 500 */ 501 public final static OccurrenceSearchParameter DEGREE_OF_ESTABLISHMENT = new OccurrenceSearchParameter("DEGREE_OF_ESTABLISHMENT", String.class); 502 503 /** 504 * Provides the controlled vocabulary for information about the process by which an Organism came to be in a given place at a given time. 505 * The pathway of an organism or organisms have been introduced to a given place and time. 506 */ 507 public final static OccurrenceSearchParameter PATHWAY = new OccurrenceSearchParameter("PATHWAY", String.class); 508 509 /** 510 * Searches for records whose publishing country is different to the country where the record was recorded in. 511 */ 512 public final static OccurrenceSearchParameter REPATRIATED = new OccurrenceSearchParameter("REPATRIATED", Boolean.class); 513 514 /** 515 * An identifier for the Organism instance (as opposed to a particular digital record of the Organism). 516 * May be a globally unique identifier or an identifier specific to the data set. 517 */ 518 public final static OccurrenceSearchParameter ORGANISM_ID = new OccurrenceSearchParameter("ORGANISM_ID", String.class); 519 520 /** 521 * The name of the next smaller administrative region than country in which the Location occurs. 522 */ 523 public final static OccurrenceSearchParameter STATE_PROVINCE = new OccurrenceSearchParameter("STATE_PROVINCE", String.class); 524 525 /** 526 * The name of the water body in which the Location occurs. 527 */ 528 public final static OccurrenceSearchParameter WATER_BODY = new OccurrenceSearchParameter("WATER_BODY", String.class); 529 530 /** 531 * The specific description of the place. 532 * It may contain information modified from the original to correct perceived errors or standardize the description. 533 */ 534 public final static OccurrenceSearchParameter LOCALITY = new OccurrenceSearchParameter("LOCALITY", String.class); 535 536 /** 537 * Protocol used to provide the occurrence record. 538 */ 539 public final static OccurrenceSearchParameter PROTOCOL = new OccurrenceSearchParameter("PROTOCOL", EndpointType.class); 540 541 /** 542 * The license applied to the dataset. 543 */ 544 public final static OccurrenceSearchParameter LICENSE = new OccurrenceSearchParameter("LICENSE", License.class); 545 546 /** 547 * The owning organizations uuid key. 548 */ 549 public final static OccurrenceSearchParameter PUBLISHING_ORG = new OccurrenceSearchParameter("PUBLISHING_ORG", UUID.class); 550 551 /** 552 * The GBIF network that the publishing organisation belongs to. 553 */ 554 public final static OccurrenceSearchParameter NETWORK_KEY = new OccurrenceSearchParameter("NETWORK_KEY", UUID.class); 555 556 /** 557 * The technical installation key that hosts/publishes this record. 558 */ 559 public final static OccurrenceSearchParameter INSTALLATION_KEY = new OccurrenceSearchParameter("INSTALLATION_KEY", UUID.class); 560 561 /** 562 * The organization key of the installation that hosts this record. 563 */ 564 public final static OccurrenceSearchParameter HOSTING_ORGANIZATION_KEY = new OccurrenceSearchParameter("HOSTING_ORGANIZATION_KEY", UUID.class); 565 566 /** 567 * Crawl attempt that harvested this record. 568 */ 569 public final static OccurrenceSearchParameter CRAWL_ID = new OccurrenceSearchParameter("CRAWL_ID", Integer.class); 570 571 /** 572 * GBIF ProjectId. 573 */ 574 public final static OccurrenceSearchParameter PROJECT_ID = new OccurrenceSearchParameter("PROJECT_ID", String.class); 575 576 /** 577 * GBIF Programme Acronym. 578 */ 579 public final static OccurrenceSearchParameter PROGRAMME = new OccurrenceSearchParameter("PROGRAMME", String.class); 580 581 /** 582 * A number or enumeration value for the quantity of organisms. 583 */ 584 public final static OccurrenceSearchParameter ORGANISM_QUANTITY = new OccurrenceSearchParameter("ORGANISM_QUANTITY", Double.class); 585 586 /** 587 * The type of quantification system used for the quantity of organisms. 588 */ 589 public final static OccurrenceSearchParameter ORGANISM_QUANTITY_TYPE = new OccurrenceSearchParameter("ORGANISM_QUANTITY_TYPE", String.class); 590 591 /** 592 * The unit of measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 593 */ 594 public final static OccurrenceSearchParameter SAMPLE_SIZE_UNIT = new OccurrenceSearchParameter("SAMPLE_SIZE_UNIT", String.class); 595 596 /** 597 * A numeric value for a measurement of the size (time duration, length, area, or volume) of a sample in a sampling event. 598 */ 599 public final static OccurrenceSearchParameter SAMPLE_SIZE_VALUE = new OccurrenceSearchParameter("SAMPLE_SIZE_VALUE", Double.class); 600 601 /** 602 * Calculated organismQuantity relative to the sampleSizeValue i.e. -> organismQuantity / sampleSizeValue. 603 */ 604 public final static OccurrenceSearchParameter RELATIVE_ORGANISM_QUANTITY = new OccurrenceSearchParameter("RELATIVE_ORGANISM_QUANTITY", Double.class); 605 606 /** 607 * Collection key. It links to the collection to which this record belongs. 608 */ 609 public final static OccurrenceSearchParameter COLLECTION_KEY = new OccurrenceSearchParameter("COLLECTION_KEY", String.class); 610 611 /** 612 * Institution key. It links to the institution that maintains, recorded or digitized this record. 613 */ 614 public final static OccurrenceSearchParameter INSTITUTION_KEY = new OccurrenceSearchParameter("INSTITUTION_KEY", String.class); 615 616 /** 617 * Agent identifiers from GbifTerm.recordedByID 618 */ 619 public final static OccurrenceSearchParameter RECORDED_BY_ID = new OccurrenceSearchParameter("RECORDED_BY_ID", String.class); 620 621 /** 622 * Agent identifiers from GbifTerm.identifiedByID 623 */ 624 public final static OccurrenceSearchParameter IDENTIFIED_BY_ID = new OccurrenceSearchParameter("IDENTIFIED_BY_ID", String.class); 625 626 /** 627 * An occurrence status enumeration value. 628 */ 629 public final static OccurrenceSearchParameter OCCURRENCE_STATUS = new OccurrenceSearchParameter("OCCURRENCE_STATUS", OccurrenceStatus.class); 630 631 /** 632 * A <a href="https://gadm.org">GADM</a> identifier at any level. 633 */ 634 public final static OccurrenceSearchParameter GADM_GID = new OccurrenceSearchParameter("GADM_GID", String.class); 635 636 /** 637 * A <a href="https://gadm.org">GADM</a> country, island or territory (level zero) identifier. 638 */ 639 public final static OccurrenceSearchParameter GADM_LEVEL_0_GID = new OccurrenceSearchParameter("GADM_LEVEL_0_GID", String.class); 640 641 /** 642 * A <a href="https://gadm.org">GADM</a> first-level identifier. 643 */ 644 public final static OccurrenceSearchParameter GADM_LEVEL_1_GID = new OccurrenceSearchParameter("GADM_LEVEL_1_GID", String.class); 645 646 /** 647 * A <a href="https://gadm.org">GADM</a> second-level identifier. 648 */ 649 public final static OccurrenceSearchParameter GADM_LEVEL_2_GID = new OccurrenceSearchParameter("GADM_LEVEL_2_GID", String.class); 650 651 /** 652 * A <a href="https://gadm.org">GADM</a> third-level identifier. 653 */ 654 public final static OccurrenceSearchParameter GADM_LEVEL_3_GID = new OccurrenceSearchParameter("GADM_LEVEL_3_GID", String.class); 655 656 /** 657 * The life stage of an occurrence. 658 */ 659 public final static OccurrenceSearchParameter LIFE_STAGE = new OccurrenceSearchParameter("LIFE_STAGE", String.class); 660 661 /** 662 * Searches for occurrences that are clustered. 663 */ 664 public final static OccurrenceSearchParameter IS_IN_CLUSTER = new OccurrenceSearchParameter("IS_IN_CLUSTER", Boolean.class); 665 666 /** 667 * Searches for occurrences that have a particular DwC-A extension. 668 */ 669 public final static OccurrenceSearchParameter DWCA_EXTENSION = new OccurrenceSearchParameter("DWCA_EXTENSION", String.class); 670 671 /** 672 * Searches for occurrences that have a IUCN Red List Category. 673 */ 674 public final static OccurrenceSearchParameter IUCN_RED_LIST_CATEGORY = new OccurrenceSearchParameter("IUCN_RED_LIST_CATEGORY", String.class); 675 676 /** 677 * The dwc dataset id. 678 */ 679 public final static OccurrenceSearchParameter DATASET_ID = new OccurrenceSearchParameter("DATASET_ID", String.class); 680 681 /** 682 * The dwc dataset name. 683 */ 684 public final static OccurrenceSearchParameter DATASET_NAME = new OccurrenceSearchParameter("DATASET_NAME", String.class); 685 686 /** 687 * Other catalog numbers associated to an occurrence. 688 */ 689 public final static OccurrenceSearchParameter OTHER_CATALOG_NUMBERS = new OccurrenceSearchParameter("OTHER_CATALOG_NUMBERS", String.class); 690 691 /** 692 * Preparations methods of an occurrence. 693 */ 694 public final static OccurrenceSearchParameter PREPARATIONS = new OccurrenceSearchParameter("PREPARATIONS", String.class); 695 696 /** 697 * The name of the island on or near which the location occurs. 698 */ 699 public final static OccurrenceSearchParameter ISLAND = new OccurrenceSearchParameter("ISLAND", String.class); 700 701 /** 702 * The name of the island group in which the location occurs. 703 */ 704 public final static OccurrenceSearchParameter ISLAND_GROUP = new OccurrenceSearchParameter("ISLAND_GROUP", String.class); 705 706 /** 707 * A list (concatenated and separated) of names of people, groups, or organizations who determined the georeference 708 * (spatial representation) for the location. 709 */ 710 public final static OccurrenceSearchParameter GEOREFERENCED_BY = new OccurrenceSearchParameter("GEOREFERENCED_BY", String.class); 711 712 /** 713 * A list (concatenated and separated) of geographic names less specific than the information captured in the locality 714 * term. 715 */ 716 public final static OccurrenceSearchParameter HIGHER_GEOGRAPHY = new OccurrenceSearchParameter("HIGHER_GEOGRAPHY", String.class); 717 718 /** 719 * An identifier given to the event in the field. Often serves as a link between field notes and the event. 720 */ 721 public final static OccurrenceSearchParameter FIELD_NUMBER = new OccurrenceSearchParameter("FIELD_NUMBER", String.class); 722 723 /** 724 * The full name of the earliest possible geochronologic eon or lowest chrono-stratigraphic eonothem or the informal 725 * name ("Precambrian") attributable to the stratigraphic horizon from which the MaterialEntity was collected. 726 */ 727 public final static OccurrenceSearchParameter EARLIEST_EON_OR_LOWEST_EONOTHEM = new OccurrenceSearchParameter("EARLIEST_EON_OR_LOWEST_EONOTHEM", String.class); 728 729 /** 730 * The full name of the latest possible geochronologic eon or highest chrono-stratigraphic eonothem or the informal 731 * name ("Precambrian") attributable to the stratigraphic horizon from which the MaterialEntity was collected. 732 */ 733 public final static OccurrenceSearchParameter LATEST_EON_OR_HIGHEST_EONOTHEM = new OccurrenceSearchParameter("LATEST_EON_OR_HIGHEST_EONOTHEM", String.class); 734 735 /** 736 * The full name of the earliest possible geochronologic era or lowest chronostratigraphic erathem attributable to the 737 * stratigraphic horizon from which the MaterialEntity was collected. 738 */ 739 public final static OccurrenceSearchParameter EARLIEST_ERA_OR_LOWEST_ERATHEM = new OccurrenceSearchParameter("EARLIEST_ERA_OR_LOWEST_ERATHEM", String.class); 740 741 /** 742 * The full name of the latest possible geochronologic era or highest chronostratigraphic erathem attributable to the 743 * stratigraphic horizon from which the MaterialEntity was collected. 744 */ 745 public final static OccurrenceSearchParameter LATEST_ERA_OR_HIGHEST_ERATHEM = new OccurrenceSearchParameter("LATEST_ERA_OR_HIGHEST_ERATHEM", String.class); 746 747 /** 748 * The full name of the earliest possible geochronologic period or lowest chronostratigraphic system attributable to 749 * the stratigraphic horizon from which the MaterialEntity was collected. 750 */ 751 public final static OccurrenceSearchParameter EARLIEST_PERIOD_OR_LOWEST_SYSTEM = new OccurrenceSearchParameter("EARLIEST_PERIOD_OR_LOWEST_SYSTEM", String.class); 752 753 /** 754 * The full name of the latest possible geochronologic period or highest chronostratigraphic system attributable to 755 * the stratigraphic horizon from which the MaterialEntity was collected. 756 */ 757 public final static OccurrenceSearchParameter LATEST_PERIOD_OR_HIGHEST_SYSTEM = new OccurrenceSearchParameter("LATEST_PERIOD_OR_HIGHEST_SYSTEM", String.class); 758 759 /** 760 * The full name of the earliest possible geochronologic epoch or lowest chronostratigraphic series attributable to 761 * the stratigraphic horizon from which the MaterialEntity was collected. 762 */ 763 public final static OccurrenceSearchParameter EARLIEST_EPOCH_OR_LOWEST_SERIES = new OccurrenceSearchParameter("EARLIEST_EPOCH_OR_LOWEST_SERIES", String.class); 764 765 /** 766 * The full name of the latest possible geochronologic epoch or highest chronostratigraphic series attributable to the 767 * stratigraphic horizon from which the MaterialEntity was collected. 768 */ 769 public final static OccurrenceSearchParameter LATEST_EPOCH_OR_HIGHEST_SERIES = new OccurrenceSearchParameter("LATEST_EPOCH_OR_HIGHEST_SERIES", String.class); 770 771 /** 772 * The full name of the earliest possible geochronologic age or lowest chronostratigraphic stage attributable to the 773 * stratigraphic horizon from which the MaterialEntity was collected. 774 */ 775 public final static OccurrenceSearchParameter EARLIEST_AGE_OR_LOWEST_STAGE = new OccurrenceSearchParameter("EARLIEST_AGE_OR_LOWEST_STAGE", String.class); 776 777 /** 778 * The full name of the latest possible geochronologic age or highest chronostratigraphic stage attributable to the 779 * stratigraphic horizon from which the MaterialEntity was collected. 780 */ 781 public final static OccurrenceSearchParameter LATEST_AGE_OR_HIGHEST_STAGE = new OccurrenceSearchParameter("LATEST_AGE_OR_HIGHEST_STAGE", String.class); 782 783 /** 784 * The full name of the lowest possible geological biostratigraphic zone of the stratigraphic horizon from which the 785 * MaterialEntity was collected. 786 */ 787 public final static OccurrenceSearchParameter LOWEST_BIOSTRATIGRAPHIC_ZONE = new OccurrenceSearchParameter("LOWEST_BIOSTRATIGRAPHIC_ZONE", String.class); 788 789 /** 790 * The full name of the highest possible geological biostratigraphic zone of the stratigraphic horizon from which the 791 * MaterialEntity was collected. 792 */ 793 public final static OccurrenceSearchParameter HIGHEST_BIOSTRATIGRAPHIC_ZONE = new OccurrenceSearchParameter("HIGHEST_BIOSTRATIGRAPHIC_ZONE", String.class); 794 795 /** 796 * The full name of the lithostratigraphic group from which the MaterialEntity was collected. 797 */ 798 public final static OccurrenceSearchParameter GROUP = new OccurrenceSearchParameter("GROUP", String.class); 799 800 /** 801 * The full name of the lithostratigraphic formation from which the MaterialEntity was collected. 802 */ 803 public final static OccurrenceSearchParameter FORMATION = new OccurrenceSearchParameter("FORMATION", String.class); 804 805 /** 806 * The full name of the lithostratigraphic member from which the MaterialEntity was collected. 807 */ 808 public final static OccurrenceSearchParameter MEMBER = new OccurrenceSearchParameter("MEMBER", String.class); 809 810 /** 811 * The full name of the lithostratigraphic bed from which the MaterialEntity was collected. 812 */ 813 public final static OccurrenceSearchParameter BED = new OccurrenceSearchParameter("BED", String.class); 814 815 /** 816 * A list (concatenated and separated) of identifiers (publication, global unique identifier, URI) of 817 * genetic sequence information associated with the material entity. 818 */ 819 public final static OccurrenceSearchParameter ASSOCIATED_SEQUENCES = new OccurrenceSearchParameter("ASSOCIATED_SEQUENCES", String.class); 820 821 /** 822 * Unique GBIF key for the occurrence. 823 */ 824 public final static OccurrenceSearchParameter GBIF_ID = new OccurrenceSearchParameter("GBIF_ID", String.class); 825 826 /** 827 * Geological time of an occurrence that searchs in the chronostratigraphy fields. 828 */ 829 public final static OccurrenceSearchParameter GEOLOGICAL_TIME = new OccurrenceSearchParameter("GEOLOGICAL_TIME", String.class); 830 831 /** 832 * Searches in the lithostratigraphy fields(bed, formation, group, member). 833 */ 834 public final static OccurrenceSearchParameter LITHOSTRATIGRAPHY = new OccurrenceSearchParameter("LITHOSTRATIGRAPHY", String.class); 835 836 /** 837 * Searches in the biostratigraphy fields(lowest and highest biostratigraphy). 838 */ 839 public final static OccurrenceSearchParameter BIOSTRATIGRAPHY = new OccurrenceSearchParameter("BIOSTRATIGRAPHY", String.class); 840 841 /** 842 * @return the data type expected for the value of the respective search parameter 843 */ 844 public final static OccurrenceSearchParameter DNA_SEQUENCE_ID = new OccurrenceSearchParameter("DNA_SEQUENCE_ID", String.class); 845 846 847 public static OccurrenceSearchParameter[] values(){ 848 849 Field[] values = OccurrenceSearchParameter.class.getFields(); 850 List<OccurrenceSearchParameter> c = new ArrayList<>(); 851 for (Field field: values) { 852 try { 853 c.add((OccurrenceSearchParameter) field.get(OccurrenceSearchParameter.class)); 854 } catch (IllegalAccessException e) { 855 throw new RuntimeException(e); 856 } 857 } 858 return c.toArray(new OccurrenceSearchParameter[0]); 859 } 860 861 private Class<?> type; 862 private String name; 863 864 public OccurrenceSearchParameter() {} 865 866 public OccurrenceSearchParameter(String name, Class<?> type) { 867 this.name = name; 868 this.type = type; 869 } 870 871 @Override 872 public String name() { 873 return this.name; 874 } 875 876 public Class<?> getType() { 877 return type; 878 } 879 880 public String getName() { 881 return name; 882 } 883 884 @Override 885 public Class<?> type() { 886 return this.type; 887 } 888 889 @Override 890 public String toString() { 891 return name; 892 } 893 894 @Override 895 public boolean equals(Object o) { 896 if (this == o) return true; 897 if (o == null || getClass() != o.getClass()) return false; 898 OccurrenceSearchParameter that = (OccurrenceSearchParameter) o; 899 return Objects.equals(type, that.type) && Objects.equals(name, that.name); 900 } 901 902 @JsonValue 903 public String getSerializedValue() { 904 return name; 905 } 906 907 @Override 908 public int hashCode() { 909 return Objects.hash(type, name); 910 } 911 912 /** 913 * Lookup a parameter by its name. 914 * @param name the name of the parameter 915 * @return the parameter if found, otherwise empty 916 */ 917 public static Optional<OccurrenceSearchParameter> lookup(String name) { 918 String normedType = name.toUpperCase().replaceAll("[. _-]", ""); 919 java.lang.reflect.Field[] values = OccurrenceSearchParameter.class.getFields(); 920 for (Field field: values) { 921 922 String fieldName = field.getName(); 923 String normedVal = fieldName.replaceAll("[. _-]", ""); 924 if (normedType.equals(normedVal)) { 925 try { 926 return Optional.of((OccurrenceSearchParameter) field.get(OccurrenceSearchParameter.class)); 927 } catch (IllegalAccessException e) { 928 throw new RuntimeException(e); 929 } 930 } 931 } 932 return Optional.empty(); 933 } 934 935 public static class OccurrenceSearchParameterKeyDeserializer extends KeyDeserializer { 936 937 @Override 938 public Object deserializeKey(String value, DeserializationContext deserializationContext) throws IOException { 939 Field[] values = OccurrenceSearchParameter.class.getFields(); 940 try { 941 for (Field field: values) { 942 if (field.getName().equalsIgnoreCase(value)) { 943 return (OccurrenceSearchParameter) field.get(OccurrenceSearchParameter.class); 944 } 945 } 946 } catch (IllegalAccessException e) { 947 // DO NOTHING 948 } 949 return null; 950 } 951 } 952 953 public static class OccurrenceSearchParameterDeserializer extends JsonDeserializer<OccurrenceSearchParameter> { 954 955 @Override 956 public OccurrenceSearchParameter deserialize(com.fasterxml.jackson.core.JsonParser jsonParser, com.fasterxml.jackson.databind.DeserializationContext deserializationContext) throws IOException, JacksonException { 957 958 Field[] values = OccurrenceSearchParameter.class.getFields(); 959 try { 960 String value = jsonParser.getText(); 961 for (Field field: values) { 962 if (field.getName().equalsIgnoreCase(value)) { 963 return (OccurrenceSearchParameter) field.get(OccurrenceSearchParameter.class); 964 } 965 } 966 967 } catch (IllegalAccessException e) { 968 // DO NOTHING 969 } 970 971 try { 972 ObjectNode node = jsonParser.getCodec().readTree(jsonParser); 973 String value = node.get("name").asText(); 974 for (Field field: values) { 975 if (field.getName().equalsIgnoreCase(value)) { 976 return (OccurrenceSearchParameter) field.get(OccurrenceSearchParameter.class); 977 } 978 } 979 } catch (Exception e) { 980 // DO NOTHING 981 } 982 983 return null; 984 } 985 } 986}