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.event.search;
015
016import com.fasterxml.jackson.annotation.*;
017import com.fasterxml.jackson.core.JacksonException;
018import com.fasterxml.jackson.databind.DeserializationContext;
019import com.fasterxml.jackson.databind.JsonDeserializer;
020import com.fasterxml.jackson.databind.KeyDeserializer;
021import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
022import com.fasterxml.jackson.databind.node.ObjectNode;
023import io.swagger.v3.oas.annotations.Hidden;
024import java.io.IOException;
025import java.io.Serializable;
026import java.lang.reflect.Field;
027import java.util.ArrayList;
028import java.util.List;
029import java.util.Objects;
030import java.util.Optional;
031import lombok.extern.slf4j.Slf4j;
032import org.gbif.api.annotation.Experimental;
033import org.gbif.api.model.common.search.SearchParameter;
034import org.gbif.api.model.occurrence.search.OccurrenceSearchParameter;
035import org.gbif.api.vocabulary.DurationUnit;
036import org.gbif.api.vocabulary.EventIssue;
037
038/**
039 * Supported query parameters by the occurrence search and download service. For download predicates
040 * only the numerical types support comparisons other than equals.
041 */
042@Slf4j
043@JsonDeserialize(
044    as = EventSearchParameter.class,
045    using = EventSearchParameter.EventSearchParameterDeserializer.class)
046public class EventSearchParameter implements SearchParameter, Serializable {
047
048  /** See @link {@link OccurrenceSearchParameter#DATASET_KEY} */
049  public static final EventSearchParameter DATASET_KEY =
050      new EventSearchParameter(OccurrenceSearchParameter.DATASET_KEY);
051
052  /** See @link {@link OccurrenceSearchParameter#CHECKLIST_KEY} */
053  public static final EventSearchParameter CHECKLIST_KEY =
054      new EventSearchParameter(OccurrenceSearchParameter.CHECKLIST_KEY);
055
056  /** See @link {@link OccurrenceSearchParameter#YEAR} */
057  public static final EventSearchParameter YEAR =
058      new EventSearchParameter(OccurrenceSearchParameter.YEAR);
059
060  /** See @link {@link OccurrenceSearchParameter#MONTH} */
061  public static final EventSearchParameter MONTH =
062      new EventSearchParameter(OccurrenceSearchParameter.MONTH);
063
064  /** See @link {@link OccurrenceSearchParameter#DAY} */
065  public static final EventSearchParameter DAY =
066      new EventSearchParameter(OccurrenceSearchParameter.DAY);
067
068  /** See @link {@link OccurrenceSearchParameter#START_DAY_OF_YEAR} */
069  public static final EventSearchParameter START_DAY_OF_YEAR =
070      new EventSearchParameter(OccurrenceSearchParameter.START_DAY_OF_YEAR);
071
072  /** See @link {@link OccurrenceSearchParameter#END_DAY_OF_YEAR} */
073  public static final EventSearchParameter END_DAY_OF_YEAR =
074      new EventSearchParameter(OccurrenceSearchParameter.END_DAY_OF_YEAR);
075
076  /** See @link {@link OccurrenceSearchParameter#EVENT_DATE} */
077  public static final EventSearchParameter EVENT_DATE =
078      new EventSearchParameter(OccurrenceSearchParameter.EVENT_DATE);
079
080  /**
081   * An identifier for the set of information associated with an Event (something that occurs at a
082   * place and time). Maybe a global unique identifier or an identifier specific to the data set.
083   *
084   * @link {@link OccurrenceSearchParameter#EVENT_ID}
085   */
086  public static final EventSearchParameter EVENT_ID =
087      new EventSearchParameter(OccurrenceSearchParameter.EVENT_ID);
088
089  /** See @link {@link OccurrenceSearchParameter#PARENT_EVENT_ID} */
090  public static final EventSearchParameter PARENT_EVENT_ID =
091      new EventSearchParameter(OccurrenceSearchParameter.PARENT_EVENT_ID);
092
093  /** See @link {@link OccurrenceSearchParameter#SAMPLING_PROTOCOL} */
094  public static final EventSearchParameter SAMPLING_PROTOCOL =
095      new EventSearchParameter(OccurrenceSearchParameter.SAMPLING_PROTOCOL);
096
097  /** See @link {@link OccurrenceSearchParameter#LAST_INTERPRETED} */
098  public static final EventSearchParameter LAST_INTERPRETED =
099      new EventSearchParameter(OccurrenceSearchParameter.LAST_INTERPRETED);
100
101  /** See @link {@link OccurrenceSearchParameter#MODIFIED} */
102  public static final EventSearchParameter MODIFIED =
103      new EventSearchParameter(OccurrenceSearchParameter.MODIFIED);
104
105  /** See @link {@link OccurrenceSearchParameter#DECIMAL_LATITUDE} */
106  public static final EventSearchParameter DECIMAL_LATITUDE =
107      new EventSearchParameter(OccurrenceSearchParameter.DECIMAL_LATITUDE);
108
109  /** See @link {@link OccurrenceSearchParameter#DECIMAL_LONGITUDE} */
110  public static final EventSearchParameter DECIMAL_LONGITUDE =
111      new EventSearchParameter(OccurrenceSearchParameter.DECIMAL_LONGITUDE);
112
113  /** See @link {@link OccurrenceSearchParameter#COORDINATE_UNCERTAINTY_IN_METERS} */
114  public static final EventSearchParameter COORDINATE_UNCERTAINTY_IN_METERS =
115      new EventSearchParameter(OccurrenceSearchParameter.COORDINATE_UNCERTAINTY_IN_METERS);
116
117  /** See @link {@link OccurrenceSearchParameter#COUNTRY} */
118  public static final EventSearchParameter COUNTRY =
119      new EventSearchParameter(OccurrenceSearchParameter.COUNTRY);
120
121  /** See @link {@link OccurrenceSearchParameter#GBIF_REGION} */
122  public static final EventSearchParameter GBIF_REGION =
123      new EventSearchParameter(OccurrenceSearchParameter.GBIF_REGION);
124
125  /** See @link {@link OccurrenceSearchParameter#CONTINENT} */
126  public static final EventSearchParameter CONTINENT =
127      new EventSearchParameter(OccurrenceSearchParameter.CONTINENT);
128
129  /** See @link {@link OccurrenceSearchParameter#PUBLISHING_COUNTRY} */
130  public static final EventSearchParameter PUBLISHING_COUNTRY =
131      new EventSearchParameter(OccurrenceSearchParameter.PUBLISHING_COUNTRY);
132
133  /** See @link {@link OccurrenceSearchParameter#PUBLISHED_BY_GBIF_REGION} */
134  public static final EventSearchParameter PUBLISHED_BY_GBIF_REGION =
135      new EventSearchParameter(OccurrenceSearchParameter.PUBLISHED_BY_GBIF_REGION);
136
137  /** See @link {@link OccurrenceSearchParameter#ELEVATION} */
138  public static final EventSearchParameter ELEVATION =
139      new EventSearchParameter(OccurrenceSearchParameter.ELEVATION);
140
141  /** See @link {@link OccurrenceSearchParameter#DEPTH} */
142  public static final EventSearchParameter DEPTH =
143      new EventSearchParameter(OccurrenceSearchParameter.DEPTH);
144
145  /** See @link {@link OccurrenceSearchParameter#INSTITUTION_CODE} */
146  public static final EventSearchParameter INSTITUTION_CODE =
147      new EventSearchParameter(OccurrenceSearchParameter.INSTITUTION_CODE);
148
149  /** See @link {@link OccurrenceSearchParameter#COLLECTION_CODE} */
150  public static final EventSearchParameter COLLECTION_CODE =
151    new EventSearchParameter(OccurrenceSearchParameter.COLLECTION_CODE);
152
153  /** See @link {@link OccurrenceSearchParameter#TAXON_KEY} */
154  public static final EventSearchParameter TAXON_KEY =
155      new EventSearchParameter(OccurrenceSearchParameter.TAXON_KEY);
156
157  /** See @link {@link OccurrenceSearchParameter#ACCEPTED_TAXON_KEY} */
158  public static final EventSearchParameter ACCEPTED_TAXON_KEY =
159      new EventSearchParameter(OccurrenceSearchParameter.ACCEPTED_TAXON_KEY);
160
161  /** See @link {@link OccurrenceSearchParameter#SCIENTIFIC_NAME} */
162  public static final EventSearchParameter SCIENTIFIC_NAME =
163      new EventSearchParameter(OccurrenceSearchParameter.SCIENTIFIC_NAME);
164
165  /** See @link {@link OccurrenceSearchParameter#TAXON_ID} */
166  public static final EventSearchParameter TAXON_ID =
167      new EventSearchParameter(OccurrenceSearchParameter.TAXON_ID);
168
169  /** See @link {@link OccurrenceSearchParameter#TAXONOMIC_STATUS} */
170  public static final EventSearchParameter TAXONOMIC_STATUS =
171      new EventSearchParameter(OccurrenceSearchParameter.TAXONOMIC_STATUS);
172
173  /** See @link {@link OccurrenceSearchParameter#TAXONOMIC_ISSUE} */
174  public static final EventSearchParameter TAXONOMIC_ISSUE =
175      new EventSearchParameter(OccurrenceSearchParameter.TAXONOMIC_ISSUE);
176
177  /** See @link {@link OccurrenceSearchParameter#IUCN_RED_LIST_CATEGORY} */
178  public static final EventSearchParameter IUCN_RED_LIST_CATEGORY =
179      new EventSearchParameter(OccurrenceSearchParameter.IUCN_RED_LIST_CATEGORY);
180
181  /** See @link {@link OccurrenceSearchParameter#HAS_COORDINATE} */
182  public static final EventSearchParameter HAS_COORDINATE =
183      new EventSearchParameter(OccurrenceSearchParameter.HAS_COORDINATE);
184
185  /** See @link {@link OccurrenceSearchParameter#GEOMETRY} */
186  public static final EventSearchParameter GEOMETRY =
187      new EventSearchParameter(OccurrenceSearchParameter.GEOMETRY);
188
189  /** See @link {@link OccurrenceSearchParameter#GEO_DISTANCE} */
190  public static final EventSearchParameter GEO_DISTANCE =
191      new EventSearchParameter(OccurrenceSearchParameter.GEO_DISTANCE);
192
193  /** See @link {@link OccurrenceSearchParameter#HAS_GEOSPATIAL_ISSUE} */
194  public static final EventSearchParameter HAS_GEOSPATIAL_ISSUE =
195      new EventSearchParameter(OccurrenceSearchParameter.HAS_GEOSPATIAL_ISSUE);
196
197  /** See @link {@link OccurrenceSearchParameter#MEDIA_TYPE} */
198  public static final EventSearchParameter MEDIA_TYPE =
199      new EventSearchParameter(OccurrenceSearchParameter.MEDIA_TYPE);
200
201  /** See @link {@link OccurrenceSearchParameter#REPATRIATED} */
202  public static final EventSearchParameter REPATRIATED =
203      new EventSearchParameter(OccurrenceSearchParameter.REPATRIATED);
204
205  /** See @link {@link OccurrenceSearchParameter#STATE_PROVINCE} */
206  public static final EventSearchParameter STATE_PROVINCE =
207      new EventSearchParameter(OccurrenceSearchParameter.STATE_PROVINCE);
208
209  /** See @link {@link OccurrenceSearchParameter#WATER_BODY} */
210  public static final EventSearchParameter WATER_BODY =
211      new EventSearchParameter(OccurrenceSearchParameter.WATER_BODY);
212
213  /** See @link {@link OccurrenceSearchParameter#LOCALITY} */
214  public static final EventSearchParameter LOCALITY =
215      new EventSearchParameter(OccurrenceSearchParameter.LOCALITY);
216
217  /** See @link {@link OccurrenceSearchParameter#PROTOCOL} */
218  public static final EventSearchParameter PROTOCOL =
219      new EventSearchParameter(OccurrenceSearchParameter.PROTOCOL);
220
221  /** See @link {@link OccurrenceSearchParameter#LICENSE} */
222  public static final EventSearchParameter LICENSE =
223      new EventSearchParameter(OccurrenceSearchParameter.LICENSE);
224
225  /** See @link {@link OccurrenceSearchParameter#PUBLISHING_ORG} */
226  public static final EventSearchParameter PUBLISHING_ORG =
227      new EventSearchParameter(OccurrenceSearchParameter.PUBLISHING_ORG);
228
229  /** See @link {@link OccurrenceSearchParameter#NETWORK_KEY} */
230  public static final EventSearchParameter NETWORK_KEY =
231      new EventSearchParameter(OccurrenceSearchParameter.NETWORK_KEY);
232
233  /** See @link {@link OccurrenceSearchParameter#INSTALLATION_KEY} */
234  public static final EventSearchParameter INSTALLATION_KEY =
235      new EventSearchParameter(OccurrenceSearchParameter.INSTALLATION_KEY);
236
237  /** See @link {@link OccurrenceSearchParameter#HOSTING_ORGANIZATION_KEY} */
238  public static final EventSearchParameter HOSTING_ORGANIZATION_KEY =
239      new EventSearchParameter(OccurrenceSearchParameter.HOSTING_ORGANIZATION_KEY);
240
241  /** See @link {@link OccurrenceSearchParameter#CRAWL_ID} */
242  public static final EventSearchParameter CRAWL_ID =
243      new EventSearchParameter(OccurrenceSearchParameter.CRAWL_ID);
244
245  /** See @link {@link OccurrenceSearchParameter#PROGRAMME} */
246  public static final EventSearchParameter PROGRAMME =
247      new EventSearchParameter(OccurrenceSearchParameter.PROGRAMME);
248
249  /** See @link {@link OccurrenceSearchParameter#SAMPLE_SIZE_UNIT} */
250  public static final EventSearchParameter SAMPLE_SIZE_UNIT =
251      new EventSearchParameter(OccurrenceSearchParameter.SAMPLE_SIZE_UNIT);
252
253  /** See @link {@link OccurrenceSearchParameter#SAMPLE_SIZE_VALUE} */
254  public static final EventSearchParameter SAMPLE_SIZE_VALUE =
255      new EventSearchParameter(OccurrenceSearchParameter.SAMPLE_SIZE_VALUE);
256
257  /** See @link {@link OccurrenceSearchParameter#GADM_GID} */
258  public static final EventSearchParameter GADM_GID =
259      new EventSearchParameter(OccurrenceSearchParameter.GADM_GID);
260
261  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_0_GID} */
262  public static final EventSearchParameter GADM_LEVEL_0_GID =
263      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_0_GID);
264
265  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_1_GID} */
266  public static final EventSearchParameter GADM_LEVEL_1_GID =
267      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_1_GID);
268
269  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_2_GID} */
270  public static final EventSearchParameter GADM_LEVEL_2_GID =
271      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_2_GID);
272
273  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_3_GID} */
274  public static final EventSearchParameter GADM_LEVEL_3_GID =
275      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_3_GID);
276
277  /** See @link {@link OccurrenceSearchParameter#DWCA_EXTENSION} */
278  public static final EventSearchParameter DWCA_EXTENSION =
279      new EventSearchParameter(OccurrenceSearchParameter.DWCA_EXTENSION);
280
281  /** See @link {@link OccurrenceSearchParameter#DATASET_ID} */
282  public static final EventSearchParameter DATASET_ID =
283      new EventSearchParameter(OccurrenceSearchParameter.DATASET_ID);
284
285  /** See @link {@link OccurrenceSearchParameter#DATASET_NAME} */
286  public static final EventSearchParameter DATASET_NAME =
287      new EventSearchParameter(OccurrenceSearchParameter.DATASET_NAME);
288
289  /** See @link {@link OccurrenceSearchParameter#ISLAND} */
290  public static final EventSearchParameter ISLAND =
291      new EventSearchParameter(OccurrenceSearchParameter.ISLAND);
292
293  /** See @link {@link OccurrenceSearchParameter#ISLAND_GROUP} */
294  public static final EventSearchParameter ISLAND_GROUP =
295      new EventSearchParameter(OccurrenceSearchParameter.ISLAND_GROUP);
296
297  /** See @link {@link OccurrenceSearchParameter#GEOREFERENCED_BY} */
298  public static final EventSearchParameter GEOREFERENCED_BY =
299      new EventSearchParameter(OccurrenceSearchParameter.GEOREFERENCED_BY);
300
301  /** See @link {@link OccurrenceSearchParameter#HIGHER_GEOGRAPHY} */
302  public static final EventSearchParameter HIGHER_GEOGRAPHY =
303      new EventSearchParameter(OccurrenceSearchParameter.HIGHER_GEOGRAPHY);
304
305  /** See @link {@link OccurrenceSearchParameter#FIELD_NUMBER} */
306  public static final EventSearchParameter FIELD_NUMBER =
307      new EventSearchParameter(OccurrenceSearchParameter.FIELD_NUMBER);
308
309  /** See @link {@link OccurrenceSearchParameter#GBIF_ID} */
310  public static final EventSearchParameter GBIF_ID =
311      new EventSearchParameter(OccurrenceSearchParameter.GBIF_ID);
312
313  /** An identifier for an Event and its children events. */
314  public static final EventSearchParameter EVENT_ID_HIERARCHY =
315      new EventSearchParameter("EVENT_ID_HIERARCHY", String.class);
316
317  /** An identifier for the vocabulary-backed Event Type. */
318  public static final EventSearchParameter EVENT_TYPE =
319      new EventSearchParameter("EVENT_TYPE", String.class);
320
321  /** An identifier for the verbatim Event Type. */
322  @Experimental
323  public static final EventSearchParameter VERBATIM_EVENT_TYPE =
324      new EventSearchParameter("VERBATIM_EVENT_TYPE", String.class);
325
326  /** Searches events for those that have a specific issue. */
327  public static final EventSearchParameter ISSUE =
328      new EventSearchParameter("ISSUE", EventIssue.class);
329
330  /** The event project ID.  */
331  public static final EventSearchParameter PROJECT_ID =
332    new EventSearchParameter("PROJECT_ID", String.class);
333
334  /** The event project title.  */
335  public static final EventSearchParameter PROJECT_TITLE =
336    new EventSearchParameter("PROJECT_TITLE", String.class);
337
338  /** The event funding attribution.  */
339  public static final EventSearchParameter FUNDING_ATTRIBUTION =
340    new EventSearchParameter("FUNDING_ATTRIBUTION", String.class);
341
342  /** The event funding attribution ID.  */
343  public static final EventSearchParameter FUNDING_ATTRIBUTION_ID =
344    new EventSearchParameter("FUNDING_ATTRIBUTION_ID", String.class);
345
346  /** The event location ID. */
347  public static final EventSearchParameter LOCATION_ID =
348      new EventSearchParameter("LOCATION_ID", String.class);
349
350  /** See @link {@link OccurrenceSearchParameter#MEASUREMENT_TYPE} */
351  public static final EventSearchParameter MEASUREMENT_TYPE =
352      new EventSearchParameter(OccurrenceSearchParameter.MEASUREMENT_TYPE);
353
354  /** See @link {@link OccurrenceSearchParameter#MEASUREMENT_TYPE_ID} */
355  public static final EventSearchParameter MEASUREMENT_TYPE_ID =
356      new EventSearchParameter(OccurrenceSearchParameter.MEASUREMENT_TYPE_ID);
357
358  /** Humboldt fields * */
359  public static final EventSearchParameter HUMBOLDT_SITE_COUNT =
360      new EventSearchParameter("HUMBOLDT_SITE_COUNT", Integer.class);
361
362  public static final EventSearchParameter HUMBOLDT_VERBATIM_SITE_NAMES =
363      new EventSearchParameter("HUMBOLDT_VERBATIM_SITE_NAMES", String.class);
364  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE =
365      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE", Double.class);
366  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT =
367      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT", String.class);
368  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE =
369      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE", Double.class);
370  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT =
371      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT", String.class);
372  public static final EventSearchParameter HUMBOLDT_TARGET_HABITAT_SCOPE =
373      new EventSearchParameter("HUMBOLDT_TARGET_HABITAT_SCOPE", String.class);
374  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION =
375      new EventSearchParameter("HUMBOLDT_EVENT_DURATION", String.class);
376
377  @Hidden
378  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES =
379      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES", Double.class);
380
381  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE =
382      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE", Double.class);
383  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_UNIT =
384      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_UNIT", DurationUnit.class);
385
386  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE =
387      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE", EventIssue.class);
388  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME =
389      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME", String.class);
390  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY =
391      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY", String.class);
392  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME =
393      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME", String.class);
394  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY =
395      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY", String.class);
396  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY =
397      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY", String.class);
398  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY =
399      new EventSearchParameter(
400          "HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY", String.class);
401  public static final EventSearchParameter HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS =
402      new EventSearchParameter("HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS", String.class);
403  public static final EventSearchParameter HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED =
404      new EventSearchParameter("HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED", Boolean.class);
405  public static final EventSearchParameter HUMBOLDT_IS_ABSENCE_REPORTED =
406      new EventSearchParameter("HUMBOLDT_IS_ABSENCE_REPORTED", Boolean.class);
407  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_TAXA =
408      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_TAXA", Boolean.class);
409  public static final EventSearchParameter HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED =
410      new EventSearchParameter("HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED", Boolean.class);
411  public static final EventSearchParameter HUMBOLDT_TARGET_LIFE_STAGE_SCOPE =
412      new EventSearchParameter("HUMBOLDT_TARGET_LIFE_STAGE_SCOPE", String.class);
413  public static final EventSearchParameter HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED =
414      new EventSearchParameter("HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED", Boolean.class);
415  public static final EventSearchParameter HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE =
416      new EventSearchParameter("HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE", String.class);
417  public static final EventSearchParameter
418      HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED =
419          new EventSearchParameter(
420              "HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED", Boolean.class);
421  public static final EventSearchParameter HUMBOLDT_TARGET_GROWTH_FORM_SCOPE =
422      new EventSearchParameter("HUMBOLDT_TARGET_GROWTH_FORM_SCOPE", String.class);
423  public static final EventSearchParameter HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED =
424      new EventSearchParameter("HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED", Boolean.class);
425  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_ORGANISMS =
426      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_ORGANISMS", Boolean.class);
427  public static final EventSearchParameter HUMBOLDT_COMPILATION_TYPES =
428      new EventSearchParameter("HUMBOLDT_COMPILATION_TYPES", String.class);
429  public static final EventSearchParameter HUMBOLDT_COMPILATION_SOURCE_TYPES =
430      new EventSearchParameter("HUMBOLDT_COMPILATION_SOURCE_TYPES", String.class);
431  public static final EventSearchParameter HUMBOLDT_INVENTORY_TYPES =
432      new EventSearchParameter("HUMBOLDT_INVENTORY_TYPES", String.class);
433  public static final EventSearchParameter HUMBOLDT_PROTOCOL_NAMES =
434      new EventSearchParameter("HUMBOLDT_PROTOCOL_NAMES", String.class);
435  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_REPORTED =
436      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_REPORTED", Boolean.class);
437  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED =
438      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED", Boolean.class);
439  public static final EventSearchParameter HUMBOLDT_ABUNDANCE_CAP =
440      new EventSearchParameter("HUMBOLDT_ABUNDANCE_CAP", Integer.class);
441  public static final EventSearchParameter HUMBOLDT_IS_VEGETATION_COVER_REPORTED =
442      new EventSearchParameter("HUMBOLDT_IS_VEGETATION_COVER_REPORTED", Boolean.class);
443  public static final EventSearchParameter
444      HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE =
445          new EventSearchParameter(
446              "HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE", Boolean.class);
447  public static final EventSearchParameter HUMBOLDT_HAS_VOUCHERS =
448      new EventSearchParameter("HUMBOLDT_HAS_VOUCHERS", Boolean.class);
449  public static final EventSearchParameter HUMBOLDT_VOUCHER_INSTITUTIONS =
450      new EventSearchParameter("HUMBOLDT_VOUCHER_INSTITUTIONS", String.class);
451  public static final EventSearchParameter HUMBOLDT_HAS_MATERIAL_SAMPLES =
452      new EventSearchParameter("HUMBOLDT_HAS_MATERIAL_SAMPLES", Boolean.class);
453  public static final EventSearchParameter HUMBOLDT_MATERIAL_SAMPLE_TYPES =
454      new EventSearchParameter("HUMBOLDT_MATERIAL_SAMPLE_TYPES", String.class);
455  public static final EventSearchParameter HUMBOLDT_SAMPLING_PERFORMED_BY =
456      new EventSearchParameter("HUMBOLDT_SAMPLING_PERFORMED_BY", String.class);
457  public static final EventSearchParameter HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED =
458      new EventSearchParameter("HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED", Boolean.class);
459  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_VALUE =
460      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_VALUE", Double.class);
461  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_UNIT =
462      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_UNIT", String.class);
463
464  public static EventSearchParameter[] values() {
465
466    Field[] values = EventSearchParameter.class.getFields();
467    List<EventSearchParameter> c = new ArrayList<>();
468    for (Field field : values) {
469      try {
470        c.add((EventSearchParameter) field.get(EventSearchParameter.class));
471      } catch (IllegalAccessException e) {
472        throw new RuntimeException(e);
473      }
474    }
475    return c.toArray(new EventSearchParameter[0]);
476  }
477
478  private Class<?> type;
479  private String name;
480
481  public EventSearchParameter() {}
482
483  public EventSearchParameter(OccurrenceSearchParameter occurrenceSearchParameter) {
484    this.name = occurrenceSearchParameter.getName();
485    this.type = occurrenceSearchParameter.getType();
486  }
487
488  public EventSearchParameter(String name, Class<?> type) {
489    this.name = name;
490    this.type = type;
491  }
492
493  @Override
494  public String name() {
495    return this.name;
496  }
497
498  public Class<?> getType() {
499    return type;
500  }
501
502  public String getName() {
503    return name;
504  }
505
506  @Override
507  public Class<?> type() {
508    return this.type;
509  }
510
511  @Override
512  public String toString() {
513    return name;
514  }
515
516  @Override
517  public boolean equals(Object o) {
518    if (this == o) return true;
519    if (o == null || getClass() != o.getClass()) return false;
520    EventSearchParameter that = (EventSearchParameter) o;
521    return Objects.equals(type, that.type) && Objects.equals(name, that.name);
522  }
523
524  @JsonValue
525  public String getSerializedValue() {
526    return name;
527  }
528
529  @Override
530  public int hashCode() {
531    return Objects.hash(type, name);
532  }
533
534  /**
535   * Lookup a parameter by its name.
536   *
537   * @param name the name of the parameter
538   * @return the parameter if found, otherwise empty
539   */
540  public static Optional<EventSearchParameter> lookupEventParam(String name) {
541    String normedType = name.toUpperCase().replaceAll("[. _-]", "");
542    Field[] values = EventSearchParameter.class.getFields();
543    for (Field field : values) {
544
545      String fieldName = field.getName();
546      String normedVal = fieldName.replaceAll("[. _-]", "");
547      if (normedType.equals(normedVal)) {
548        try {
549          return Optional.of((EventSearchParameter) field.get(EventSearchParameter.class));
550        } catch (IllegalAccessException e) {
551          throw new RuntimeException(e);
552        }
553      }
554    }
555    return Optional.empty();
556  }
557
558  public static class EventSearchParameterKeyDeserializer extends KeyDeserializer {
559
560    @Override
561    public Object deserializeKey(String value, DeserializationContext deserializationContext)
562        throws IOException {
563      Field[] values = EventSearchParameter.class.getFields();
564      try {
565        for (Field field : values) {
566          if (field.getName().equalsIgnoreCase(value)) {
567            return (EventSearchParameter) field.get(EventSearchParameter.class);
568          }
569        }
570      } catch (IllegalAccessException e) {
571        log.warn("Error deserializing event search parameter key", e);
572        // DO NOTHING
573      }
574      return null;
575    }
576  }
577
578  public static class EventSearchParameterDeserializer
579      extends JsonDeserializer<EventSearchParameter> {
580
581    @Override
582    public EventSearchParameter deserialize(
583        com.fasterxml.jackson.core.JsonParser jsonParser,
584        DeserializationContext deserializationContext)
585        throws IOException, JacksonException {
586
587      Field[] values = EventSearchParameter.class.getFields();
588      try {
589        String value = jsonParser.getText();
590        for (Field field : values) {
591          if (field.getName().equalsIgnoreCase(value)) {
592            return (EventSearchParameter) field.get(EventSearchParameter.class);
593          }
594        }
595
596      } catch (IllegalAccessException e) {
597        log.warn("Error deserializing event search parameter", e);
598      }
599
600      try {
601        ObjectNode node = jsonParser.getCodec().readTree(jsonParser);
602        String value = node.get("name").asText();
603        for (Field field : values) {
604          if (field.getName().equalsIgnoreCase(value)) {
605            return (EventSearchParameter) field.get(EventSearchParameter.class);
606          }
607        }
608      } catch (Exception e) {
609        log.warn("Error deserializing event search parameter from name", e);
610      }
611
612      return null;
613    }
614  }
615}