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