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.checklistbank; 015 016import org.gbif.api.vocabulary.CitesAppendix; 017import org.gbif.api.vocabulary.Country; 018import org.gbif.api.vocabulary.DistributionStatus; 019import org.gbif.api.vocabulary.EstablishmentMeans; 020import org.gbif.api.vocabulary.LifeStage; 021import org.gbif.api.vocabulary.ThreatStatus; 022 023import java.util.Objects; 024import java.util.StringJoiner; 025 026import javax.annotation.Nullable; 027import javax.validation.constraints.Max; 028import javax.validation.constraints.Min; 029 030import io.swagger.v3.oas.annotations.media.Schema; 031 032/** 033 * Distribution Model Object represents a species distribution. 034 * 035 * @see <a href="http://rs.gbif.org/extension/gbif/1.0/distribution.xml">Distribution Definition</a> 036 */ 037@SuppressWarnings("unused") 038public class Distribution implements NameUsageExtension { 039 040 private Integer taxonKey; 041 private String locationId; 042 private String locality; 043 private Country country; 044 private DistributionStatus status; 045 private LifeStage lifeStage; 046 private String temporal; 047 private ThreatStatus threatStatus; 048 private EstablishmentMeans establishmentMeans; 049 private CitesAppendix appendixCites; 050 private String source; 051 private Integer sourceTaxonKey; 052 private Integer startDayOfYear; 053 private Integer endDayOfYear; 054 private String remarks; 055 056 /** 057 * The name usage "taxon" key this description belongs to. 058 */ 059 @Schema(description = "The name usage “taxon“ key to which this species profile belongs.") 060 @Override 061 public Integer getTaxonKey() { 062 return taxonKey; 063 } 064 065 @Override 066 public void setTaxonKey(Integer taxonKey) { 067 this.taxonKey = taxonKey; 068 } 069 070 /** 071 * The CITES (Convention on International Trade in Endangered Species of Wild Fauna and Flora) Appendix number under which the 072 * taxon is listed. It is possible to have different appendix numbers for different areas, but "global" as an area is 073 * also valid if it's the same worldwide see also http://www.cites.org/eng/app/index.shtml 074 * <blockquote> 075 * <p> 076 * <i>Example:</i> II 077 * </p> 078 * </blockquote> 079 * 080 * @return the appendixCites. 081 */ 082 @Schema(description = "The CITES (Convention on International Trade in Endangered Species of Wild Fauna and Flora) " + 083 "Appendix number under which the taxon is listed.\n\n" + 084 "It is possible to have different appendix numbers for different areas, but “global” as an area is also valid.") 085 @Nullable 086 public CitesAppendix getAppendixCites() { 087 return appendixCites; 088 } 089 090 /** 091 * @param appendixCites the appendixCites to set 092 */ 093 public void setAppendixCites(CitesAppendix appendixCites) { 094 this.appendixCites = appendixCites; 095 } 096 097 /** 098 * @return the country 099 */ 100 @Schema(description = "The country") 101 @Nullable 102 public Country getCountry() { 103 return country; 104 } 105 106 /** 107 * @param country the country to set 108 */ 109 public void setCountry(Country country) { 110 this.country = country; 111 } 112 113 /** 114 * Seasonal temporal subcontext within the eventDate context. The latest ordinal day of the year on which the 115 * distribution record is valid. 116 * <blockquote> 117 * <p> 118 * <i>Example:</i> 120 119 * </p> 120 * </blockquote> 121 * 122 * @return the endDayOfYear. 123 */ 124 @Schema(description = "Seasonal temporal subcontext within the eventDate context. " + 125 "The latest ordinal day of the year on which the distribution record is valid.") 126 @Nullable 127 @Min(1) 128 @Max(366) 129 public Integer getEndDayOfYear() { 130 return endDayOfYear; 131 } 132 133 /** 134 * @param endDayOfYear the endDayOfYear to set 135 */ 136 public void setEndDayOfYear(Integer endDayOfYear) { 137 this.endDayOfYear = endDayOfYear; 138 } 139 140 /** 141 * Term describing whether the organism occurs natively, is introduced or cultivated. 142 * <blockquote> 143 * <p> 144 * <i>Example:</i> introduced 145 * </p> 146 * </blockquote> 147 * 148 * @return the establishmentMeans 149 */ 150 @Schema(description = "Term describing whether the organism occurs natively, is introduced or cultivated.") 151 @Nullable 152 public EstablishmentMeans getEstablishmentMeans() { 153 return establishmentMeans; 154 } 155 156 /** 157 * @param establishmentMeans the establishmentMeans to set 158 */ 159 public void setEstablishmentMeans(EstablishmentMeans establishmentMeans) { 160 this.establishmentMeans = establishmentMeans; 161 } 162 163 /** 164 * The distribution information pertains solely to a specific life stage of the taxon. 165 * <blockquote> 166 * <p> 167 * <i>Example:</i> adult 168 * </p> 169 * </blockquote> 170 * 171 * @return the lifeStage 172 * 173 * @see <a href="http://rs.gbif.org/vocabulary/gbif/life_stage.xml">life stage vocabulary for recommended values</a> 174 */ 175 @Schema(description = "The distribution information pertains solely to a specific life stage of the taxon.") 176 @Nullable 177 public LifeStage getLifeStage() { 178 return lifeStage; 179 } 180 181 /** 182 * @param lifeStage the lifeStage to set 183 */ 184 public void setLifeStage(LifeStage lifeStage) { 185 this.lifeStage = lifeStage; 186 } 187 188 /** 189 * The verbatim name of the area this distribution record is about. 190 * <blockquote> 191 * <p> 192 * <i>Example:</i> Patagonia 193 * </p> 194 * </blockquote> 195 * 196 * @return the locality 197 */ 198 @Schema(description = "The verbatim name of the area this distribution record is about.") 199 @Nullable 200 public String getLocality() { 201 return locality; 202 } 203 204 /** 205 * @param locality the locality to set 206 */ 207 public void setLocality(String locality) { 208 this.locality = locality; 209 } 210 211 /** 212 * A code for the named area this distributon record is about. 213 * See http://en.wikipedia.org/wiki/ISO_3166-2 for state codes within a country, 214 * otherwise use a prefix for each code to indicate the source of the code. 215 * <p/> 216 * <blockqoute> 217 * <p> 218 * <i>Example:</i> TDWG:AGS-TF <i>Example:</i> ISO3166:AR <i>Example:</i> WOEID:564721 219 * </p> 220 * </blockquote> 221 * 222 * @return the location id 223 */ 224 @Schema(description = " A code for the named area this distributon record is about.") 225 public String getLocationId() { 226 return locationId; 227 } 228 229 /** 230 * @param locationId the locationId to set 231 */ 232 public void setLocationId(String locationId) { 233 this.locationId = locationId; 234 } 235 236 /** 237 * Additional notes on the distribution. 238 * 239 * @return the notes 240 */ 241 @Schema(description = "Additional notes on the distribution.") 242 @Nullable 243 public String getRemarks() { 244 return remarks; 245 } 246 247 public void setRemarks(String remarks) { 248 this.remarks = remarks; 249 } 250 251 /** 252 * Source reference for this distribution record. Can be proper publication citation, a webpage URL, etc. 253 * <blockquote> 254 * <p> 255 * <i>Example:</i> "Euro+Med Plantbase - the information resource for Euro-Mediterranean plant diversity (2006-). 256 * Published on the Internet http://ww2.bgbm.org/EuroPlusMed/ July, 2009" 257 * </p> 258 * </blockquote> 259 * 260 * @return the source 261 */ 262 @Schema(description = "Bibliographic citation referencing a source for the distribution.") 263 @Nullable 264 @Override 265 public String getSource() { 266 return source; 267 } 268 269 /** 270 * @param source the source to set 271 */ 272 @Override 273 public void setSource(String source) { 274 this.source = source; 275 } 276 277 @Schema(description = "The name usage key of the taxon in the checklist including this distribution.") 278 @Nullable 279 @Override 280 public Integer getSourceTaxonKey() { 281 return sourceTaxonKey; 282 } 283 284 @Override 285 public void setSourceTaxonKey(Integer sourceTaxonKey) { 286 this.sourceTaxonKey = sourceTaxonKey; 287 } 288 289 /** 290 * Seasonal temporal subcontext within the eventDate context. Useful for migratory species. The earliest ordinal day 291 * of the year on which the distribution record is valid. Numbering starts with 1 for 1 January and ends with 365 or 366 292 * for 31 December. 293 * <blockquote> 294 * <p> 295 * <i>Example:</i> 90 296 * </p> 297 * </blockquote> 298 * 299 * @return the startDayOfYear. 300 */ 301 @Schema(description = "Seasonal temporal subcontext within the eventDate context. Useful for migratory species.\n\n" + 302 "The earliest ordinal day of the year on which the distribution record is valid. Numbering starts with 1 for " + 303 "1 January and ends with 365 or 366 for 31 December.") 304 @Nullable 305 @Min(1) 306 @Max(366) 307 public Integer getStartDayOfYear() { 308 return startDayOfYear; 309 } 310 311 /** 312 * @param startDayOfYear the startDayOfYear to set 313 */ 314 public void setStartDayOfYear(Integer startDayOfYear) { 315 this.startDayOfYear = startDayOfYear; 316 } 317 318 /** 319 * Term describing the occurrence status of the organism in the given area based on how frequent the species occurs. 320 * <blockquote> 321 * <p> 322 * <i>Example:</i> absent 323 * </p> 324 * </blockquote> 325 * 326 * @return the status. 327 * 328 * @see <a href="http://rs.gbif.org/vocabulary/gbif/distribution_status_2020-05-14.xml">occurrence status vocabulary</a> for recommended values 329 */ 330 @Schema(description = "Term describing the occurrence status of the organism in the given area based on how frequent the species occurs.") 331 @Nullable 332 public DistributionStatus getStatus() { 333 return status; 334 } 335 336 /** 337 * @param status the status to set 338 */ 339 public void setStatus(DistributionStatus status) { 340 this.status = status; 341 } 342 343 /** 344 * Relevant temporal context for this entire distribution record including all properties preferably given as a year 345 * range or single year on which the distribution record is valid. For the same area and taxon there could therefore 346 * be several records with different temporal context, e.g. in 5-year intervals for invasive species. 347 * <blockquote> 348 * <p><i>Example:</i> "1930"; "1939-1945"</p> 349 * </blockquote> 350 * @return the temporal 351 */ 352 @Schema(description = "Relevant temporal context for this entire distribution record including all properties, " + 353 "preferably given as a year range or single year on which the distribution record is valid.\n\n" + 354 "For the same area and taxon there could therefore be several records with different temporal context, " + 355 "e.g. in 5-year intervals for invasive species.") 356 @Nullable 357 public String getTemporal() { 358 return temporal; 359 } 360 361 /** 362 * @param temporal the temporal to set 363 */ 364 public void setTemporal(String temporal) { 365 this.temporal = temporal; 366 } 367 368 /** 369 * Threat status of a species as defined by IUCN 370 * (http://www.iucnredlist.org/static/categories_criteria_3_1#categories). 371 * <blockquote> 372 * <p> 373 * <i>Examples:</i> "EX" - "EW" - "CR" 374 * </p> 375 * </blockquote> 376 * 377 * @return the threatStatus. 378 * 379 * @see <a href="http://rs.gbif.org/vocabulary/iucn/threat_status.xml">threat status vocabulary for recommended 380 * values</a> 381 */ 382 @Schema(description = "Threat status of a species as defined by IUCN.") 383 @Nullable 384 public ThreatStatus getThreatStatus() { 385 return threatStatus; 386 } 387 388 /** 389 * @param threatStatus the threatStatus to set 390 */ 391 public void setThreatStatus(ThreatStatus threatStatus) { 392 this.threatStatus = threatStatus; 393 } 394 395 @Override 396 public boolean equals(Object o) { 397 if (this == o) { 398 return true; 399 } 400 if (o == null || getClass() != o.getClass()) { 401 return false; 402 } 403 Distribution that = (Distribution) o; 404 return Objects.equals(taxonKey, that.taxonKey) && 405 Objects.equals(locationId, that.locationId) && 406 Objects.equals(locality, that.locality) && 407 country == that.country && 408 status == that.status && 409 lifeStage == that.lifeStage && 410 Objects.equals(temporal, that.temporal) && 411 threatStatus == that.threatStatus && 412 establishmentMeans == that.establishmentMeans && 413 appendixCites == that.appendixCites && 414 Objects.equals(source, that.source) && 415 Objects.equals(sourceTaxonKey, that.sourceTaxonKey) && 416 Objects.equals(startDayOfYear, that.startDayOfYear) && 417 Objects.equals(endDayOfYear, that.endDayOfYear); 418 } 419 420 @Override 421 public int hashCode() { 422 return Objects 423 .hash(taxonKey, locationId, locality, country, status, lifeStage, temporal, threatStatus, 424 establishmentMeans, appendixCites, source, sourceTaxonKey, startDayOfYear, endDayOfYear); 425 } 426 427 @Override 428 public String toString() { 429 return new StringJoiner(", ", Distribution.class.getSimpleName() + "[", "]") 430 .add("taxonKey=" + taxonKey) 431 .add("locationId='" + locationId + "'") 432 .add("locality='" + locality + "'") 433 .add("country=" + country) 434 .add("status=" + status) 435 .add("lifeStage=" + lifeStage) 436 .add("temporal='" + temporal + "'") 437 .add("threatStatus=" + threatStatus) 438 .add("establishmentMeans=" + establishmentMeans) 439 .add("appendixCites=" + appendixCites) 440 .add("source='" + source + "'") 441 .add("sourceTaxonKey=" + sourceTaxonKey) 442 .add("startDayOfYear=" + startDayOfYear) 443 .add("endDayOfYear=" + endDayOfYear) 444 .add("remarks='" + remarks + "'") 445 .toString(); 446 } 447}