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