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