001/*
002 * Copyright 2020 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.model.checklistbank.search;
017
018import org.gbif.api.model.checklistbank.Description;
019import org.gbif.api.model.checklistbank.VernacularName;
020import org.gbif.api.model.common.LinneanClassification;
021import org.gbif.api.model.common.LinneanClassificationKeys;
022import org.gbif.api.util.ClassificationUtils;
023import org.gbif.api.vocabulary.Habitat;
024import org.gbif.api.vocabulary.NameType;
025import org.gbif.api.vocabulary.NomenclaturalStatus;
026import org.gbif.api.vocabulary.Origin;
027import org.gbif.api.vocabulary.Rank;
028import org.gbif.api.vocabulary.TaxonomicStatus;
029import org.gbif.api.vocabulary.ThreatStatus;
030
031import java.util.ArrayList;
032import java.util.LinkedHashMap;
033import java.util.List;
034import java.util.Objects;
035import java.util.StringJoiner;
036import java.util.UUID;
037
038import javax.validation.constraints.NotNull;
039
040import com.fasterxml.jackson.annotation.JsonProperty;
041
042
043/**
044 * Class used for returning results of a full text search operation.
045 * This class contains additional attributes that are required for displaying/providing textual information.
046 */
047@SuppressWarnings("unused")
048public class NameUsageSearchResult implements LinneanClassification, LinneanClassificationKeys {
049
050  private Integer key;
051  private Integer nameKey;
052  private UUID datasetKey;
053  private UUID constituentKey;
054  private Integer nubKey;
055  private Integer parentKey;
056  private String parent;
057  private Integer acceptedKey;
058  private String accepted;
059  private Integer basionymKey;
060  private String basionym;
061
062  // for LinneanClassification
063  private String kingdom;
064  private String phylum;
065  @JsonProperty("class")
066  private String clazz;
067  private String order;
068  private String family;
069  private String genus;
070  private String subgenus;
071  private String species;
072  // for LinneanClassificationKeys
073  private Integer kingdomKey;
074  private Integer phylumKey;
075  private Integer classKey;
076  private Integer orderKey;
077  private Integer familyKey;
078  private Integer genusKey;
079  private Integer subgenusKey;
080  private Integer speciesKey;
081
082  private String scientificName;
083  private String canonicalName;
084  private String authorship;
085  private String publishedIn;
086  private String accordingTo;
087
088  private NameType nameType;
089  private TaxonomicStatus taxonomicStatus;
090  private Rank rank;
091  private Origin origin;
092
093  private int numDescendants;
094  private long numOccurrences;
095
096  private String taxonID;
097  private Boolean extinct;
098  private List<Habitat> habitats = new ArrayList<>();
099  private List<NomenclaturalStatus> nomenclaturalStatus = new ArrayList<>();
100  private List<ThreatStatus> threatStatuses = new ArrayList<>();
101  private List<Description> descriptions = new ArrayList<>();
102  private List<VernacularName> vernacularNames = new ArrayList<>();
103
104  /**
105   * @return the name key for retrieving a parsed name object
106   */
107  public Integer getNameKey() {
108    return nameKey;
109  }
110
111  public void setNameKey(Integer nameKey) {
112    this.nameKey = nameKey;
113  }
114
115  public String getAccepted() {
116    return accepted;
117  }
118
119  public void setAccepted(String accepted) {
120    this.accepted = accepted;
121  }
122
123  public Integer getAcceptedKey() {
124    return acceptedKey;
125  }
126
127  public void setAcceptedKey(Integer acceptedKey) {
128    this.acceptedKey = acceptedKey;
129  }
130
131  public String getAccordingTo() {
132    return accordingTo;
133  }
134
135  public void setAccordingTo(String accordingTo) {
136    this.accordingTo = accordingTo;
137  }
138
139  public String getAuthorship() {
140    return authorship;
141  }
142
143  public void setAuthorship(String authorship) {
144    this.authorship = authorship;
145  }
146
147  public String getBasionym() {
148    return basionym;
149  }
150
151  public void setBasionym(String basionym) {
152    this.basionym = basionym;
153  }
154
155  public Integer getBasionymKey() {
156    return basionymKey;
157  }
158
159  public void setBasionymKey(Integer basionymKey) {
160    this.basionymKey = basionymKey;
161  }
162
163  public String getCanonicalName() {
164    return canonicalName;
165  }
166
167  public void setCanonicalName(String canonicalName) {
168    this.canonicalName = canonicalName;
169  }
170
171  public UUID getDatasetKey() {
172    return datasetKey;
173  }
174
175  public void setDatasetKey(UUID datasetKey) {
176    this.datasetKey = datasetKey;
177  }
178
179  public UUID getConstituentKey() {
180    return constituentKey;
181  }
182
183  public void setConstituentKey(UUID constituentKey) {
184    this.constituentKey = constituentKey;
185  }
186
187  /**
188   * @return the list of Description
189   */
190  @NotNull
191  public List<Description> getDescriptions() {
192    return descriptions;
193  }
194
195  /**
196   * @param descriptions the list of Description
197   */
198  public void setDescriptions(List<Description> descriptions) {
199    this.descriptions = descriptions;
200  }
201
202  public Integer getKey() {
203    return key;
204  }
205
206  public void setKey(Integer key) {
207    this.key = key;
208  }
209
210  public NameType getNameType() {
211    return nameType;
212  }
213
214  public void setNameType(NameType nameType) {
215    this.nameType = nameType;
216  }
217
218  public Integer getNubKey() {
219    return nubKey;
220  }
221
222  public void setNubKey(Integer nubKey) {
223    this.nubKey = nubKey;
224  }
225
226  public int getNumDescendants() {
227    return numDescendants;
228  }
229
230  public void setNumDescendants(int numDescendants) {
231    this.numDescendants = numDescendants;
232  }
233
234  public long getNumOccurrences() {
235    return numOccurrences;
236  }
237
238  public void setNumOccurrences(long numOccurrences) {
239    this.numOccurrences = numOccurrences;
240  }
241
242  public Origin getOrigin() {
243    return origin;
244  }
245
246  public void setOrigin(Origin origin) {
247    this.origin = origin;
248  }
249
250  public String getParent() {
251    return parent;
252  }
253
254  public void setParent(String parent) {
255    this.parent = parent;
256  }
257
258  public Integer getParentKey() {
259    return parentKey;
260  }
261
262  public void setParentKey(Integer parentKey) {
263    this.parentKey = parentKey;
264  }
265
266  public String getPublishedIn() {
267    return publishedIn;
268  }
269
270  public void setPublishedIn(String publishedIn) {
271    this.publishedIn = publishedIn;
272  }
273
274  public Rank getRank() {
275    return rank;
276  }
277
278  public void setRank(Rank rank) {
279    this.rank = rank;
280  }
281
282  public String getScientificName() {
283    return scientificName;
284  }
285
286  public void setScientificName(String scientificName) {
287    this.scientificName = scientificName;
288  }
289
290  public String getTaxonID() {
291    return taxonID;
292  }
293
294  public void setTaxonID(String taxonID) {
295    this.taxonID = taxonID;
296  }
297
298  public TaxonomicStatus getTaxonomicStatus() {
299    return taxonomicStatus;
300  }
301
302  public void setTaxonomicStatus(TaxonomicStatus taxonomicStatus) {
303    this.taxonomicStatus = taxonomicStatus;
304  }
305
306  public List<ThreatStatus> getThreatStatuses() {
307    return threatStatuses;
308  }
309
310  public void setThreatStatuses(List<ThreatStatus> threatStatuses) {
311    this.threatStatuses = threatStatuses;
312  }
313
314  public List<NomenclaturalStatus> getNomenclaturalStatus() {
315    return nomenclaturalStatus;
316  }
317
318  public void setNomenclaturalStatus(List<NomenclaturalStatus> nomenclaturalStatus) {
319    this.nomenclaturalStatus = nomenclaturalStatus;
320  }
321
322  /**
323   * @return the list of VernacularName
324   */
325  @NotNull
326  public List<VernacularName> getVernacularNames() {
327    return vernacularNames;
328  }
329
330  /**
331   * @param vernacularNames the VernacularName list to set
332   */
333  public void setVernacularNames(List<VernacularName> vernacularNames) {
334    this.vernacularNames = vernacularNames;
335  }
336
337  public Boolean isExtinct() {
338    return extinct;
339  }
340
341  public void setExtinct(Boolean extinct) {
342    this.extinct = extinct;
343  }
344
345  public List<Habitat> getHabitats() {
346    return habitats;
347  }
348
349  public void setHabitats(List<Habitat> habitats) {
350    this.habitats = habitats;
351  }
352
353  @Override
354  public String getKingdom() {
355    return kingdom;
356  }
357
358  @Override
359  public void setKingdom(String kingdom) {
360    this.kingdom = kingdom;
361  }
362
363  @Override
364  public String getPhylum() {
365    return phylum;
366  }
367
368  @Override
369  public void setPhylum(String phylum) {
370    this.phylum = phylum;
371  }
372
373  @Override
374  public String getClazz() {
375    return clazz;
376  }
377
378  @Override
379  public void setClazz(String clazz) {
380    this.clazz = clazz;
381  }
382
383  @Override
384  public String getOrder() {
385    return order;
386  }
387
388  @Override
389  public void setOrder(String order) {
390    this.order = order;
391  }
392
393  @Override
394  public String getFamily() {
395    return family;
396  }
397
398  @Override
399  public void setFamily(String family) {
400    this.family = family;
401  }
402
403  @Override
404  public String getGenus() {
405    return genus;
406  }
407
408  @Override
409  public void setGenus(String genus) {
410    this.genus = genus;
411  }
412
413  @Override
414  public String getSubgenus() {
415    return subgenus;
416  }
417
418  @Override
419  public void setSubgenus(String subgenus) {
420    this.subgenus = subgenus;
421  }
422
423  @Override
424  public String getSpecies() {
425    return species;
426  }
427
428  @Override
429  public void setSpecies(String species) {
430    this.species = species;
431  }
432
433  @Override
434  public Integer getKingdomKey() {
435    return kingdomKey;
436  }
437
438  @Override
439  public void setKingdomKey(Integer kingdomKey) {
440    this.kingdomKey = kingdomKey;
441  }
442
443  @Override
444  public Integer getPhylumKey() {
445    return phylumKey;
446  }
447
448  @Override
449  public void setPhylumKey(Integer phylumKey) {
450    this.phylumKey = phylumKey;
451  }
452
453  @Override
454  public Integer getClassKey() {
455    return classKey;
456  }
457
458  @Override
459  public void setClassKey(Integer classKey) {
460    this.classKey = classKey;
461  }
462
463  @Override
464  public Integer getOrderKey() {
465    return orderKey;
466  }
467
468  @Override
469  public void setOrderKey(Integer orderKey) {
470    this.orderKey = orderKey;
471  }
472
473  @Override
474  public Integer getFamilyKey() {
475    return familyKey;
476  }
477
478  @Override
479  public void setFamilyKey(Integer familyKey) {
480    this.familyKey = familyKey;
481  }
482
483  @Override
484  public Integer getGenusKey() {
485    return genusKey;
486  }
487
488  @Override
489  public void setGenusKey(Integer genusKey) {
490    this.genusKey = genusKey;
491  }
492
493  @Override
494  public Integer getSubgenusKey() {
495    return subgenusKey;
496  }
497
498  @Override
499  public void setSubgenusKey(Integer subgenusKey) {
500    this.subgenusKey = subgenusKey;
501  }
502
503  @Override
504  public Integer getSpeciesKey() {
505    return speciesKey;
506  }
507
508  @Override
509  public void setSpeciesKey(Integer speciesKey) {
510    this.speciesKey = speciesKey;
511  }
512
513  @Override
514  public String getHigherRank(Rank rank) {
515    return ClassificationUtils.getHigherRank(this, rank);
516  }
517
518  @Override
519  public Integer getHigherRankKey(Rank rank) {
520    return ClassificationUtils.getHigherRankKey(this, rank);
521  }
522
523  /**
524   * An ordered map with entries for all higher Linnean ranks down to the actual direct parent of this usage.
525   * The map starts with the highest rank, e.g. the kingdom and maps the name usage key to its canonical name.
526   * The name usage itself is never included, even though a higher rank might point to the usage itself.
527   *
528   * @return map of higher ranks
529   */
530  @NotNull
531  public LinkedHashMap<Integer, String> getHigherClassificationMap() {
532    return ClassificationUtils.getHigherClassificationMap(this, key, parentKey, parent);
533  }
534
535  /**
536   * Convenience method using the taxonomicStatus field.
537   *
538   * @return true if its a synonym
539   */
540  public boolean isSynonym() {
541    return taxonomicStatus != null && taxonomicStatus.isSynonym();
542  }
543
544  @Override
545  public boolean equals(Object o) {
546    if (this == o) {
547      return true;
548    }
549    if (o == null || getClass() != o.getClass()) {
550      return false;
551    }
552    NameUsageSearchResult that = (NameUsageSearchResult) o;
553    return numDescendants == that.numDescendants &&
554      numOccurrences == that.numOccurrences &&
555      Objects.equals(key, that.key) &&
556      Objects.equals(nameKey, that.nameKey) &&
557      Objects.equals(datasetKey, that.datasetKey) &&
558      Objects.equals(constituentKey, that.constituentKey) &&
559      Objects.equals(nubKey, that.nubKey) &&
560      Objects.equals(parentKey, that.parentKey) &&
561      Objects.equals(parent, that.parent) &&
562      Objects.equals(acceptedKey, that.acceptedKey) &&
563      Objects.equals(accepted, that.accepted) &&
564      Objects.equals(basionymKey, that.basionymKey) &&
565      Objects.equals(basionym, that.basionym) &&
566      Objects.equals(kingdom, that.kingdom) &&
567      Objects.equals(phylum, that.phylum) &&
568      Objects.equals(clazz, that.clazz) &&
569      Objects.equals(order, that.order) &&
570      Objects.equals(family, that.family) &&
571      Objects.equals(genus, that.genus) &&
572      Objects.equals(subgenus, that.subgenus) &&
573      Objects.equals(species, that.species) &&
574      Objects.equals(kingdomKey, that.kingdomKey) &&
575      Objects.equals(phylumKey, that.phylumKey) &&
576      Objects.equals(classKey, that.classKey) &&
577      Objects.equals(orderKey, that.orderKey) &&
578      Objects.equals(familyKey, that.familyKey) &&
579      Objects.equals(genusKey, that.genusKey) &&
580      Objects.equals(subgenusKey, that.subgenusKey) &&
581      Objects.equals(speciesKey, that.speciesKey) &&
582      Objects.equals(scientificName, that.scientificName) &&
583      Objects.equals(canonicalName, that.canonicalName) &&
584      Objects.equals(authorship, that.authorship) &&
585      Objects.equals(publishedIn, that.publishedIn) &&
586      Objects.equals(accordingTo, that.accordingTo) &&
587      nameType == that.nameType &&
588      taxonomicStatus == that.taxonomicStatus &&
589      rank == that.rank &&
590      origin == that.origin &&
591      Objects.equals(taxonID, that.taxonID) &&
592      Objects.equals(extinct, that.extinct) &&
593      Objects.equals(habitats, that.habitats) &&
594      Objects.equals(nomenclaturalStatus, that.nomenclaturalStatus) &&
595      Objects.equals(threatStatuses, that.threatStatuses) &&
596      Objects.equals(descriptions, that.descriptions) &&
597      Objects.equals(vernacularNames, that.vernacularNames);
598  }
599
600  @Override
601  public int hashCode() {
602    return Objects
603      .hash(key, nameKey, datasetKey, constituentKey, nubKey, parentKey, parent, acceptedKey,
604        accepted, basionymKey, basionym, kingdom, phylum, clazz, order, family, genus, subgenus,
605        species, kingdomKey, phylumKey, classKey, orderKey, familyKey, genusKey, subgenusKey,
606        speciesKey, scientificName, canonicalName, authorship, publishedIn, accordingTo, nameType,
607        taxonomicStatus, rank, origin, numDescendants, numOccurrences, taxonID, extinct, habitats,
608        nomenclaturalStatus, threatStatuses, descriptions, vernacularNames);
609  }
610
611  @Override
612  public String toString() {
613    return new StringJoiner(", ", NameUsageSearchResult.class.getSimpleName() + "[", "]")
614      .add("key=" + key)
615      .add("nameKey=" + nameKey)
616      .add("datasetKey=" + datasetKey)
617      .add("constituentKey=" + constituentKey)
618      .add("nubKey=" + nubKey)
619      .add("parentKey=" + parentKey)
620      .add("parent='" + parent + "'")
621      .add("acceptedKey=" + acceptedKey)
622      .add("accepted='" + accepted + "'")
623      .add("basionymKey=" + basionymKey)
624      .add("basionym='" + basionym + "'")
625      .add("kingdom='" + kingdom + "'")
626      .add("phylum='" + phylum + "'")
627      .add("clazz='" + clazz + "'")
628      .add("order='" + order + "'")
629      .add("family='" + family + "'")
630      .add("genus='" + genus + "'")
631      .add("subgenus='" + subgenus + "'")
632      .add("species='" + species + "'")
633      .add("kingdomKey=" + kingdomKey)
634      .add("phylumKey=" + phylumKey)
635      .add("classKey=" + classKey)
636      .add("orderKey=" + orderKey)
637      .add("familyKey=" + familyKey)
638      .add("genusKey=" + genusKey)
639      .add("subgenusKey=" + subgenusKey)
640      .add("speciesKey=" + speciesKey)
641      .add("scientificName='" + scientificName + "'")
642      .add("canonicalName='" + canonicalName + "'")
643      .add("authorship='" + authorship + "'")
644      .add("publishedIn='" + publishedIn + "'")
645      .add("accordingTo='" + accordingTo + "'")
646      .add("nameType=" + nameType)
647      .add("taxonomicStatus=" + taxonomicStatus)
648      .add("rank=" + rank)
649      .add("origin=" + origin)
650      .add("numDescendants=" + numDescendants)
651      .add("numOccurrences=" + numOccurrences)
652      .add("taxonID='" + taxonID + "'")
653      .add("extinct=" + extinct)
654      .add("habitats=" + habitats)
655      .add("nomenclaturalStatus=" + nomenclaturalStatus)
656      .add("threatStatuses=" + threatStatuses)
657      .add("descriptions=" + descriptions)
658      .add("vernacularNames=" + vernacularNames)
659      .toString();
660  }
661}