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  /** See @link {@link OccurrenceSearchParameter#MEASUREMENT_TYPE} */
347  public static final EventSearchParameter MEASUREMENT_TYPE =
348      new EventSearchParameter(OccurrenceSearchParameter.MEASUREMENT_TYPE);
349
350  /** See @link {@link OccurrenceSearchParameter#MEASUREMENT_TYPE_ID} */
351  public static final EventSearchParameter MEASUREMENT_TYPE_ID =
352      new EventSearchParameter(OccurrenceSearchParameter.MEASUREMENT_TYPE_ID);
353
354  /** Humboldt fields * */
355  public static final EventSearchParameter HUMBOLDT_SITE_COUNT =
356      new EventSearchParameter("HUMBOLDT_SITE_COUNT", Integer.class);
357
358  public static final EventSearchParameter HUMBOLDT_VERBATIM_SITE_NAMES =
359      new EventSearchParameter("HUMBOLDT_VERBATIM_SITE_NAMES", String.class);
360  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE =
361      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_VALUE", Double.class);
362  public static final EventSearchParameter HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT =
363      new EventSearchParameter("HUMBOLDT_GEOSPATIAL_SCOPE_AREA_UNIT", String.class);
364  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE =
365      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_VALUE", Double.class);
366  public static final EventSearchParameter HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT =
367      new EventSearchParameter("HUMBOLDT_TOTAL_AREA_SAMPLED_UNIT", String.class);
368  public static final EventSearchParameter HUMBOLDT_TARGET_HABITAT_SCOPE =
369      new EventSearchParameter("HUMBOLDT_TARGET_HABITAT_SCOPE", String.class);
370  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION =
371      new EventSearchParameter("HUMBOLDT_EVENT_DURATION", String.class);
372
373  @Hidden
374  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES =
375      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE_IN_MINUTES", Double.class);
376
377  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_VALUE =
378      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_VALUE", Double.class);
379  public static final EventSearchParameter HUMBOLDT_EVENT_DURATION_UNIT =
380      new EventSearchParameter("HUMBOLDT_EVENT_DURATION_UNIT", DurationUnit.class);
381
382  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE =
383      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ISSUE", EventIssue.class);
384  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME =
385      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_NAME", String.class);
386  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY =
387      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_USAGE_KEY", String.class);
388  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME =
389      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_NAME", String.class);
390  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY =
391      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_ACCEPTED_USAGE_KEY", String.class);
392  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY =
393      new EventSearchParameter("HUMBOLDT_TARGET_TAXONOMIC_SCOPE_TAXON_KEY", String.class);
394  public static final EventSearchParameter HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY =
395      new EventSearchParameter(
396          "HUMBOLDT_TARGET_TAXONOMIC_SCOPE_IUCN_RED_LIST_CATEGORY", String.class);
397  public static final EventSearchParameter HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS =
398      new EventSearchParameter("HUMBOLDT_TAXON_COMPLETENESS_PROTOCOLS", String.class);
399  public static final EventSearchParameter HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED =
400      new EventSearchParameter("HUMBOLDT_IS_TAXONOMIC_SCOPE_FULLY_REPORTED", Boolean.class);
401  public static final EventSearchParameter HUMBOLDT_IS_ABSENCE_REPORTED =
402      new EventSearchParameter("HUMBOLDT_IS_ABSENCE_REPORTED", Boolean.class);
403  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_TAXA =
404      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_TAXA", Boolean.class);
405  public static final EventSearchParameter HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED =
406      new EventSearchParameter("HUMBOLDT_ARE_NON_TARGET_TAXA_FULLY_REPORTED", Boolean.class);
407  public static final EventSearchParameter HUMBOLDT_TARGET_LIFE_STAGE_SCOPE =
408      new EventSearchParameter("HUMBOLDT_TARGET_LIFE_STAGE_SCOPE", String.class);
409  public static final EventSearchParameter HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED =
410      new EventSearchParameter("HUMBOLDT_IS_LIFE_STAGE_SCOPE_FULLY_REPORTED", Boolean.class);
411  public static final EventSearchParameter HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE =
412      new EventSearchParameter("HUMBOLDT_TARGET_DEGREE_OF_ESTABLISHMENT_SCOPE", String.class);
413  public static final EventSearchParameter
414      HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED =
415          new EventSearchParameter(
416              "HUMBOLDT_IS_DEGREE_OF_ESTABLISHMENT_SCOPE_FULLY_REPORTED", Boolean.class);
417  public static final EventSearchParameter HUMBOLDT_TARGET_GROWTH_FORM_SCOPE =
418      new EventSearchParameter("HUMBOLDT_TARGET_GROWTH_FORM_SCOPE", String.class);
419  public static final EventSearchParameter HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED =
420      new EventSearchParameter("HUMBOLDT_IS_GROWTH_FORM_SCOPE_FULLY_REPORTED", Boolean.class);
421  public static final EventSearchParameter HUMBOLDT_HAS_NON_TARGET_ORGANISMS =
422      new EventSearchParameter("HUMBOLDT_HAS_NON_TARGET_ORGANISMS", Boolean.class);
423  public static final EventSearchParameter HUMBOLDT_COMPILATION_TYPES =
424      new EventSearchParameter("HUMBOLDT_COMPILATION_TYPES", String.class);
425  public static final EventSearchParameter HUMBOLDT_COMPILATION_SOURCE_TYPES =
426      new EventSearchParameter("HUMBOLDT_COMPILATION_SOURCE_TYPES", String.class);
427  public static final EventSearchParameter HUMBOLDT_INVENTORY_TYPES =
428      new EventSearchParameter("HUMBOLDT_INVENTORY_TYPES", String.class);
429  public static final EventSearchParameter HUMBOLDT_PROTOCOL_NAMES =
430      new EventSearchParameter("HUMBOLDT_PROTOCOL_NAMES", String.class);
431  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_REPORTED =
432      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_REPORTED", Boolean.class);
433  public static final EventSearchParameter HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED =
434      new EventSearchParameter("HUMBOLDT_IS_ABUNDANCE_CAP_REPORTED", Boolean.class);
435  public static final EventSearchParameter HUMBOLDT_ABUNDANCE_CAP =
436      new EventSearchParameter("HUMBOLDT_ABUNDANCE_CAP", Integer.class);
437  public static final EventSearchParameter HUMBOLDT_IS_VEGETATION_COVER_REPORTED =
438      new EventSearchParameter("HUMBOLDT_IS_VEGETATION_COVER_REPORTED", Boolean.class);
439  public static final EventSearchParameter
440      HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE =
441          new EventSearchParameter(
442              "HUMBOLDT_IS_LEAST_SPECIFIC_TARGET_CATEGORY_QUANTITY_INCLUSIVE", Boolean.class);
443  public static final EventSearchParameter HUMBOLDT_HAS_VOUCHERS =
444      new EventSearchParameter("HUMBOLDT_HAS_VOUCHERS", Boolean.class);
445  public static final EventSearchParameter HUMBOLDT_VOUCHER_INSTITUTIONS =
446      new EventSearchParameter("HUMBOLDT_VOUCHER_INSTITUTIONS", String.class);
447  public static final EventSearchParameter HUMBOLDT_HAS_MATERIAL_SAMPLES =
448      new EventSearchParameter("HUMBOLDT_HAS_MATERIAL_SAMPLES", Boolean.class);
449  public static final EventSearchParameter HUMBOLDT_MATERIAL_SAMPLE_TYPES =
450      new EventSearchParameter("HUMBOLDT_MATERIAL_SAMPLE_TYPES", String.class);
451  public static final EventSearchParameter HUMBOLDT_SAMPLING_PERFORMED_BY =
452      new EventSearchParameter("HUMBOLDT_SAMPLING_PERFORMED_BY", String.class);
453  public static final EventSearchParameter HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED =
454      new EventSearchParameter("HUMBOLDT_IS_SAMPLING_EFFORT_REPORTED", Boolean.class);
455  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_VALUE =
456      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_VALUE", Double.class);
457  public static final EventSearchParameter HUMBOLDT_SAMPLING_EFFORT_UNIT =
458      new EventSearchParameter("HUMBOLDT_SAMPLING_EFFORT_UNIT", String.class);
459
460  public static EventSearchParameter[] values() {
461
462    Field[] values = EventSearchParameter.class.getFields();
463    List<EventSearchParameter> c = new ArrayList<>();
464    for (Field field : values) {
465      try {
466        c.add((EventSearchParameter) field.get(EventSearchParameter.class));
467      } catch (IllegalAccessException e) {
468        throw new RuntimeException(e);
469      }
470    }
471    return c.toArray(new EventSearchParameter[0]);
472  }
473
474  private Class<?> type;
475  private String name;
476
477  public EventSearchParameter() {}
478
479  public EventSearchParameter(OccurrenceSearchParameter occurrenceSearchParameter) {
480    this.name = occurrenceSearchParameter.getName();
481    this.type = occurrenceSearchParameter.getType();
482  }
483
484  public EventSearchParameter(String name, Class<?> type) {
485    this.name = name;
486    this.type = type;
487  }
488
489  @Override
490  public String name() {
491    return this.name;
492  }
493
494  public Class<?> getType() {
495    return type;
496  }
497
498  public String getName() {
499    return name;
500  }
501
502  @Override
503  public Class<?> type() {
504    return this.type;
505  }
506
507  @Override
508  public String toString() {
509    return name;
510  }
511
512  @Override
513  public boolean equals(Object o) {
514    if (this == o) return true;
515    if (o == null || getClass() != o.getClass()) return false;
516    EventSearchParameter that = (EventSearchParameter) o;
517    return Objects.equals(type, that.type) && Objects.equals(name, that.name);
518  }
519
520  @JsonValue
521  public String getSerializedValue() {
522    return name;
523  }
524
525  @Override
526  public int hashCode() {
527    return Objects.hash(type, name);
528  }
529
530  /**
531   * Lookup a parameter by its name.
532   *
533   * @param name the name of the parameter
534   * @return the parameter if found, otherwise empty
535   */
536  public static Optional<EventSearchParameter> lookupEventParam(String name) {
537    String normedType = name.toUpperCase().replaceAll("[. _-]", "");
538    Field[] values = EventSearchParameter.class.getFields();
539    for (Field field : values) {
540
541      String fieldName = field.getName();
542      String normedVal = fieldName.replaceAll("[. _-]", "");
543      if (normedType.equals(normedVal)) {
544        try {
545          return Optional.of((EventSearchParameter) field.get(EventSearchParameter.class));
546        } catch (IllegalAccessException e) {
547          throw new RuntimeException(e);
548        }
549      }
550    }
551    return Optional.empty();
552  }
553
554  public static class EventSearchParameterKeyDeserializer extends KeyDeserializer {
555
556    @Override
557    public Object deserializeKey(String value, DeserializationContext deserializationContext)
558        throws IOException {
559      Field[] values = EventSearchParameter.class.getFields();
560      try {
561        for (Field field : values) {
562          if (field.getName().equalsIgnoreCase(value)) {
563            return (EventSearchParameter) field.get(EventSearchParameter.class);
564          }
565        }
566      } catch (IllegalAccessException e) {
567        log.warn("Error deserializing event search parameter key", e);
568        // DO NOTHING
569      }
570      return null;
571    }
572  }
573
574  public static class EventSearchParameterDeserializer
575      extends JsonDeserializer<EventSearchParameter> {
576
577    @Override
578    public EventSearchParameter deserialize(
579        com.fasterxml.jackson.core.JsonParser jsonParser,
580        DeserializationContext deserializationContext)
581        throws IOException, JacksonException {
582
583      Field[] values = EventSearchParameter.class.getFields();
584      try {
585        String value = jsonParser.getText();
586        for (Field field : values) {
587          if (field.getName().equalsIgnoreCase(value)) {
588            return (EventSearchParameter) field.get(EventSearchParameter.class);
589          }
590        }
591
592      } catch (IllegalAccessException e) {
593        log.warn("Error deserializing event search parameter", e);
594      }
595
596      try {
597        ObjectNode node = jsonParser.getCodec().readTree(jsonParser);
598        String value = node.get("name").asText();
599        for (Field field : values) {
600          if (field.getName().equalsIgnoreCase(value)) {
601            return (EventSearchParameter) field.get(EventSearchParameter.class);
602          }
603        }
604      } catch (Exception e) {
605        log.warn("Error deserializing event search parameter from name", e);
606      }
607
608      return null;
609    }
610  }
611}