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#PROJECT_ID} */
255  public static final EventSearchParameter PROJECT_ID =
256      new EventSearchParameter(OccurrenceSearchParameter.PROJECT_ID);
257
258  /** See @link {@link OccurrenceSearchParameter#PROGRAMME} */
259  public static final EventSearchParameter PROGRAMME =
260      new EventSearchParameter(OccurrenceSearchParameter.PROGRAMME);
261
262  /** See @link {@link OccurrenceSearchParameter#SAMPLE_SIZE_UNIT} */
263  public static final EventSearchParameter SAMPLE_SIZE_UNIT =
264      new EventSearchParameter(OccurrenceSearchParameter.SAMPLE_SIZE_UNIT);
265
266  /** See @link {@link OccurrenceSearchParameter#SAMPLE_SIZE_VALUE} */
267  public static final EventSearchParameter SAMPLE_SIZE_VALUE =
268      new EventSearchParameter(OccurrenceSearchParameter.SAMPLE_SIZE_VALUE);
269
270  /** See @link {@link OccurrenceSearchParameter#GADM_GID} */
271  public static final EventSearchParameter GADM_GID =
272      new EventSearchParameter(OccurrenceSearchParameter.GADM_GID);
273
274  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_0_GID} */
275  public static final EventSearchParameter GADM_LEVEL_0_GID =
276      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_0_GID);
277
278  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_1_GID} */
279  public static final EventSearchParameter GADM_LEVEL_1_GID =
280      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_1_GID);
281
282  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_2_GID} */
283  public static final EventSearchParameter GADM_LEVEL_2_GID =
284      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_2_GID);
285
286  /** See @link {@link OccurrenceSearchParameter#GADM_LEVEL_3_GID} */
287  public static final EventSearchParameter GADM_LEVEL_3_GID =
288      new EventSearchParameter(OccurrenceSearchParameter.GADM_LEVEL_3_GID);
289
290  /** See @link {@link OccurrenceSearchParameter#DWCA_EXTENSION} */
291  public static final EventSearchParameter DWCA_EXTENSION =
292      new EventSearchParameter(OccurrenceSearchParameter.DWCA_EXTENSION);
293
294  /** See @link {@link OccurrenceSearchParameter#DATASET_ID} */
295  public static final EventSearchParameter DATASET_ID =
296      new EventSearchParameter(OccurrenceSearchParameter.DATASET_ID);
297
298  /** See @link {@link OccurrenceSearchParameter#DATASET_NAME} */
299  public static final EventSearchParameter DATASET_NAME =
300      new EventSearchParameter(OccurrenceSearchParameter.DATASET_NAME);
301
302  /** See @link {@link OccurrenceSearchParameter#ISLAND} */
303  public static final EventSearchParameter ISLAND =
304      new EventSearchParameter(OccurrenceSearchParameter.ISLAND);
305
306  /** See @link {@link OccurrenceSearchParameter#ISLAND_GROUP} */
307  public static final EventSearchParameter ISLAND_GROUP =
308      new EventSearchParameter(OccurrenceSearchParameter.ISLAND_GROUP);
309
310  /** See @link {@link OccurrenceSearchParameter#GEOREFERENCED_BY} */
311  public static final EventSearchParameter GEOREFERENCED_BY =
312      new EventSearchParameter(OccurrenceSearchParameter.GEOREFERENCED_BY);
313
314  /** See @link {@link OccurrenceSearchParameter#HIGHER_GEOGRAPHY} */
315  public static final EventSearchParameter HIGHER_GEOGRAPHY =
316      new EventSearchParameter(OccurrenceSearchParameter.HIGHER_GEOGRAPHY);
317
318  /** See @link {@link OccurrenceSearchParameter#FIELD_NUMBER} */
319  public static final EventSearchParameter FIELD_NUMBER =
320      new EventSearchParameter(OccurrenceSearchParameter.FIELD_NUMBER);
321
322  /** See @link {@link OccurrenceSearchParameter#GBIF_ID} */
323  public static final EventSearchParameter GBIF_ID =
324      new EventSearchParameter(OccurrenceSearchParameter.GBIF_ID);
325
326  /** An identifier for an Event and its children events. */
327  public static final EventSearchParameter EVENT_ID_HIERARCHY =
328      new EventSearchParameter("EVENT_ID_HIERARCHY", String.class);
329
330  /** An identifier for the vocabulary-backed Event Type. */
331  public static final EventSearchParameter EVENT_TYPE =
332      new EventSearchParameter("EVENT_TYPE", String.class);
333
334  /** An identifier for the verbatim Event Type. */
335  @Experimental
336  public static final EventSearchParameter VERBATIM_EVENT_TYPE =
337      new EventSearchParameter("VERBATIM_EVENT_TYPE", String.class);
338
339  /** Searches events for those that have a specific issue. */
340  public static final EventSearchParameter ISSUE =
341      new EventSearchParameter("ISSUE", EventIssue.class);
342
343  /** Humboldt fields * */
344  public static final EventSearchParameter HUMBOLDT_SITE_COUNT =
345      new EventSearchParameter("HUMBOLDT_SITE_COUNT", Integer.class);
346
347  public static final EventSearchParameter HUMBOLDT_VERBATIM_SITE_NAMES =
348      new EventSearchParameter("HUMBOLDT_VERBATIM_SITE_NAMES", String.class);
349  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE =
350      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE", Double.class);
351  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT =
352      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT", String.class);
353  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE =
354      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE", Double.class);
355  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT =
356      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT", String.class);
357  public static final EventSearchParameter HUMBOLDT_TARGET_HABITAT_SCOPE =
358      new EventSearchParameter("HUMBOLDT_TARGET_HABITAT_SCOPE", String.class);
359  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION =
360      new EventSearchParameter("HUMBOLDT_EVENT_DURATION", String.class);
361
362  @Hidden
363  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES =
364      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES", Double.class);
365
366  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE =
367      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE", Double.class);
368  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_UNIT =
369      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_UNIT", DurationUnit.class);
370
371  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE =
372      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE", EventIssue.class);
373  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME =
374      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME", String.class);
375  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY =
376      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY", String.class);
377  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME =
378      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME", String.class);
379  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY =
380      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY", String.class);
381  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY =
382      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY", String.class);
383  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY =
384      new EventSearchParameter(
385          "HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY", String.class);
386  public static final EventSearchParameter HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS =
387      new EventSearchParameter("HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS", String.class);
388  public static final EventSearchParameter HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED =
389      new EventSearchParameter("HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED", Boolean.class);
390  public static final EventSearchParameter HUMBOLDT_IS_ABSENCE_REPORTED =
391      new EventSearchParameter("HUMBOLDT_IS_ABSENCE_REPORTED", Boolean.class);
392  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_TAXA =
393      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_TAXA", Boolean.class);
394  public static final EventSearchParameter HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED =
395      new EventSearchParameter("HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED", Boolean.class);
396  public static final EventSearchParameter HUMBOLDT_TARGET_LIFE_STAGE_SCOPE =
397      new EventSearchParameter("HUMBOLDT_TARGET_LIFE_STAGE_SCOPE", String.class);
398  public static final EventSearchParameter HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED =
399      new EventSearchParameter("HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED", Boolean.class);
400  public static final EventSearchParameter HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE =
401      new EventSearchParameter("HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE", String.class);
402  public static final EventSearchParameter
403      HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED =
404          new EventSearchParameter(
405              "HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED", Boolean.class);
406  public static final EventSearchParameter HUMBOLDT_TARGET_GROWTH_FORM_SCOPE =
407      new EventSearchParameter("HUMBOLDT_TARGET_GROWTH_FORM_SCOPE", String.class);
408  public static final EventSearchParameter HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED =
409      new EventSearchParameter("HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED", Boolean.class);
410  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_ORGANISMS =
411      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_ORGANISMS", Boolean.class);
412  public static final EventSearchParameter HUMBOLDT_COMPILATION_TYPES =
413      new EventSearchParameter("HUMBOLDT_COMPILATION_TYPES", String.class);
414  public static final EventSearchParameter HUMBOLDT_COMPILATION_SOURCE_TYPES =
415      new EventSearchParameter("HUMBOLDT_COMPILATION_SOURCE_TYPES", String.class);
416  public static final EventSearchParameter HUMBOLDT_INVENTORY_TYPES =
417      new EventSearchParameter("HUMBOLDT_INVENTORY_TYPES", String.class);
418  public static final EventSearchParameter HUMBOLDT_PROTOCOL_NAMES =
419      new EventSearchParameter("HUMBOLDT_PROTOCOL_NAMES", String.class);
420  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_REPORTED =
421      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_REPORTED", Boolean.class);
422  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED =
423      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED", Boolean.class);
424  public static final EventSearchParameter HUMBOLDT_ABUNDANCE_CAP =
425      new EventSearchParameter("HUMBOLDT_ABUNDANCE_CAP", Integer.class);
426  public static final EventSearchParameter HUMBOLDT_IS_VEGETATION_COVER_REPORTED =
427      new EventSearchParameter("HUMBOLDT_IS_VEGETATION_COVER_REPORTED", Boolean.class);
428  public static final EventSearchParameter
429      HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE =
430          new EventSearchParameter(
431              "HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE", Boolean.class);
432  public static final EventSearchParameter HUMBOLDT_HAS_VOUCHERS =
433      new EventSearchParameter("HUMBOLDT_HAS_VOUCHERS", Boolean.class);
434  public static final EventSearchParameter HUMBOLDT_VOUCHER_INSTITUTIONS =
435      new EventSearchParameter("HUMBOLDT_VOUCHER_INSTITUTIONS", String.class);
436  public static final EventSearchParameter HUMBOLDT_HAS_MATERIAL_SAMPLES =
437      new EventSearchParameter("HUMBOLDT_HAS_MATERIAL_SAMPLES", Boolean.class);
438  public static final EventSearchParameter HUMBOLDT_MATERIAL_SAMPLE_TYPES =
439      new EventSearchParameter("HUMBOLDT_MATERIAL_SAMPLE_TYPES", String.class);
440  public static final EventSearchParameter HUMBOLDT_SAMPLING_PERFORMED_BY =
441      new EventSearchParameter("HUMBOLDT_SAMPLING_PERFORMED_BY", String.class);
442  public static final EventSearchParameter HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED =
443      new EventSearchParameter("HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED", Boolean.class);
444  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_VALUE =
445      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_VALUE", Double.class);
446  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_UNIT =
447      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_UNIT", String.class);
448
449  public static EventSearchParameter[] values() {
450
451    Field[] values = EventSearchParameter.class.getFields();
452    List<EventSearchParameter> c = new ArrayList<>();
453    for (Field field : values) {
454      try {
455        c.add((EventSearchParameter) field.get(EventSearchParameter.class));
456      } catch (IllegalAccessException e) {
457        throw new RuntimeException(e);
458      }
459    }
460    return c.toArray(new EventSearchParameter[0]);
461  }
462
463  private Class<?> type;
464  private String name;
465
466  public EventSearchParameter() {}
467
468  public EventSearchParameter(OccurrenceSearchParameter occurrenceSearchParameter) {
469    this.name = occurrenceSearchParameter.getName();
470    this.type = occurrenceSearchParameter.getType();
471  }
472
473  public EventSearchParameter(String name, Class<?> type) {
474    this.name = name;
475    this.type = type;
476  }
477
478  @Override
479  public String name() {
480    return this.name;
481  }
482
483  public Class<?> getType() {
484    return type;
485  }
486
487  public String getName() {
488    return name;
489  }
490
491  @Override
492  public Class<?> type() {
493    return this.type;
494  }
495
496  @Override
497  public String toString() {
498    return name;
499  }
500
501  @Override
502  public boolean equals(Object o) {
503    if (this == o) return true;
504    if (o == null || getClass() != o.getClass()) return false;
505    EventSearchParameter that = (EventSearchParameter) o;
506    return Objects.equals(type, that.type) && Objects.equals(name, that.name);
507  }
508
509  @JsonValue
510  public String getSerializedValue() {
511    return name;
512  }
513
514  @Override
515  public int hashCode() {
516    return Objects.hash(type, name);
517  }
518
519  /**
520   * Lookup a parameter by its name.
521   *
522   * @param name the name of the parameter
523   * @return the parameter if found, otherwise empty
524   */
525  public static Optional<EventSearchParameter> lookupEventParam(String name) {
526    String normedType = name.toUpperCase().replaceAll("[. _-]", "");
527    Field[] values = EventSearchParameter.class.getFields();
528    for (Field field : values) {
529
530      String fieldName = field.getName();
531      String normedVal = fieldName.replaceAll("[. _-]", "");
532      if (normedType.equals(normedVal)) {
533        try {
534          return Optional.of((EventSearchParameter) field.get(EventSearchParameter.class));
535        } catch (IllegalAccessException e) {
536          throw new RuntimeException(e);
537        }
538      }
539    }
540    return Optional.empty();
541  }
542
543  public static class EventSearchParameterKeyDeserializer extends KeyDeserializer {
544
545    @Override
546    public Object deserializeKey(String value, DeserializationContext deserializationContext)
547        throws IOException {
548      Field[] values = EventSearchParameter.class.getFields();
549      try {
550        for (Field field : values) {
551          if (field.getName().equalsIgnoreCase(value)) {
552            return (EventSearchParameter) field.get(EventSearchParameter.class);
553          }
554        }
555      } catch (IllegalAccessException e) {
556        log.warn("Error deserializing event search parameter key", e);
557        // DO NOTHING
558      }
559      return null;
560    }
561  }
562
563  public static class EventSearchParameterDeserializer
564      extends JsonDeserializer<EventSearchParameter> {
565
566    @Override
567    public EventSearchParameter deserialize(
568        com.fasterxml.jackson.core.JsonParser jsonParser,
569        DeserializationContext deserializationContext)
570        throws IOException, JacksonException {
571
572      Field[] values = EventSearchParameter.class.getFields();
573      try {
574        String value = jsonParser.getText();
575        for (Field field : values) {
576          if (field.getName().equalsIgnoreCase(value)) {
577            return (EventSearchParameter) field.get(EventSearchParameter.class);
578          }
579        }
580
581      } catch (IllegalAccessException e) {
582        log.warn("Error deserializing event search parameter", e);
583      }
584
585      try {
586        ObjectNode node = jsonParser.getCodec().readTree(jsonParser);
587        String value = node.get("name").asText();
588        for (Field field : values) {
589          if (field.getName().equalsIgnoreCase(value)) {
590            return (EventSearchParameter) field.get(EventSearchParameter.class);
591          }
592        }
593      } catch (Exception e) {
594        log.warn("Error deserializing event search parameter from name", e);
595      }
596
597      return null;
598    }
599  }
600}