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