TaxonomySpecies.java
/*
* Copyright 2019 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.server.model.grin;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.genesys.blocks.model.Copyable;
import org.genesys.custom.elasticsearch.IgnoreField;
import org.genesys.custom.elasticsearch.SearchField;
import org.genesys.taxonomy.gringlobal.model.IGrinSpecies;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.time.Instant;
import java.util.Date;
/**
* Auto-generated by:
* org.apache.openjpa.jdbc.meta.ReverseMappingTool$AnnotatedCodeGenerator
*/
@Entity
@Cacheable
@Table(name = "grin_species")
@Document(indexName = "grinspecies")
@JsonIdentityInfo(scope = TaxonomySpecies.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@Getter
@Setter
@NoArgsConstructor
public class TaxonomySpecies extends CooperatorOwnedModel implements IGrinSpecies, Copyable<TaxonomySpecies> {
private static final long serialVersionUID = -6577613192196396663L;
private static final String GRIN_SP_ABBREVIATION = "sp.";
private static final String GRIN_SPP_ABBREVIATION = "spp.";
private static final String PREFIX_SUBSPECIES = "subsp. ";
private static final String PREFIX_NOTHOSUBSPECIES = "nothosubsp. ";
private static final String PREFIX_VARIETY = "var. ";
private static final String PREFIX_SUBVARIETY = "subvar. ";
private static final String PREFIX_FORMA = "f.";
@Id
@JsonProperty
@Column(name = "taxonomy_species_id")
private Long id;
@Basic
@Column(name = "alternate_name", length = 2000)
@JsonIgnore
@SearchField
private String alternateName;
@Basic
@Column(name = "common_fertilization_code", length = 20)
@JsonIgnore
private String commonFertilizationCode;
@ManyToOne(fetch = FetchType.LAZY, cascade = {})
@JoinColumn(name = "current_taxonomy_species_id")
@JsonIdentityInfo(scope = TaxonomySpecies.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@IgnoreField
@JsonIgnoreProperties({ "currentTaxonomySpecies", "taxonomyGenus" })
@NotFound(action = NotFoundAction.IGNORE)
private TaxonomySpecies currentTaxonomySpecies;
@Basic
@Column(name = "forma_authority", length = 100)
private String formaAuthority;
@Basic
@Column(name = "forma_name", length = 30)
@SearchField
private String formaName;
@Basic
@Column(name = "forma_rank_type", length = 30)
private String formaRankType;
@Basic
@Column(name = "is_forma_hybrid", nullable = false, length = 1)
private String isFormaHybrid = "N";
@Basic
@Column(name = "is_name_pending", nullable = false, length = 1)
private String isNamePending = "N";
@Basic
@Column(name = "is_specific_hybrid", nullable = false, length = 1)
private String isSpecificHybrid = "N";
@Basic
@Column(name = "is_subspecific_hybrid", nullable = false, length = 1)
private String isSubspecificHybrid = "N";
@Basic
@Column(name = "is_subvarietal_hybrid", nullable = false, length = 1)
private String isSubvarietalHybrid = "N";
@Basic
@Column(name = "is_varietal_hybrid", nullable = false, length = 1)
private String isVarietalHybrid = "N";
@Basic
@Column(name = "life_form_code", length = 20)
private String lifeFormCode;
@Basic
@Column(nullable = false, length = 100)
@SearchField
private String name;
@Basic
@Column(name = "name_authority", length = 100)
private String nameAuthority;
@Basic
@Column(name = "name_verified_date")
private Instant nameVerifiedDate;
@Basic
@Column(name = "nomen_number")
private Integer nomenNumber;
@Basic
@Column
@Lob
@JsonIgnore
private String note;
@Basic
@Column(length = 500)
@JsonIgnore
private String protologue;
@Basic
@Column(name = "protologue_virtual_path")
@JsonIgnore
private String protologueVirtualPath;
@Basic
@Column(name = "restriction_code", length = 20)
private String restrictionCode;
@Basic
@Column(name = "site_note")
@Lob
@JsonIgnore
private String siteNote;
@Basic
@Column(name = "species_authority", length = 100)
private String speciesAuthority;
@Basic
@Column(name = "species_name", nullable = false, length = 30)
@SearchField
private String speciesName;
@Basic
@Column(name = "subspecies_authority", length = 100)
private String subspeciesAuthority;
@Basic
@Column(name = "subspecies_name", length = 30)
@SearchField
private String subspeciesName;
@Basic
@Column(name = "subvariety_authority", length = 100)
private String subvarietyAuthority;
@Basic
@Column(name = "subvariety_name", length = 30)
@SearchField
private String subvarietyName;
@Basic
@Column(name = "synonym_code", length = 20)
private String synonymCode;
@ManyToOne(fetch = FetchType.EAGER, cascade = {})
@JoinColumn(name = "taxonomy_genus_id", nullable = false)
@Field(type = FieldType.Object)
@JsonIgnoreProperties({ "ownedBy" })
private TaxonomyGenus taxonomyGenus;
@Basic
@Column(name = "variety_authority", length = 100)
private String varietyAuthority;
@Basic
@Column(name = "variety_name", length = 30)
private String varietyName;
@Column(name = "subtaxa", length = 100)
@Field(type = FieldType.Text)
@SearchField
private String subtaxa;
// This is a utility for looking up all species records by name
@Column(name = "genus_species", length = 100)
@SearchField
private String genusSpecies;
@PrePersist
@PreUpdate
private void updateName() {
{
// Update genusSpecies label
this.genusSpecies = this.taxonomyGenus.getName() + " " + (GRIN_SPP_ABBREVIATION.equals(this.speciesName) ? GRIN_SP_ABBREVIATION : this.speciesName);
}
if (StringUtils.isBlank(this.name)) {
this.name = this.genusSpecies;
this.nameAuthority = this.speciesAuthority;
if (StringUtils.isNotBlank(this.subspeciesName)) {
if ("Y".equals(isSubspecificHybrid)) {
this.name += PREFIX_NOTHOSUBSPECIES + subspeciesName;
} else {
this.name += PREFIX_SUBSPECIES + this.subspeciesName;
}
this.nameAuthority = this.subspeciesAuthority;
}
if (StringUtils.isNotBlank(this.varietyName)) {
this.name += PREFIX_VARIETY + this.varietyName;
this.nameAuthority = this.varietyAuthority;
}
if (StringUtils.isNotBlank(this.subvarietyName)) {
this.name += PREFIX_SUBVARIETY + this.subvarietyName;
this.nameAuthority = this.subvarietyAuthority;
}
if (StringUtils.isNotBlank(this.formaName)) {
this.name += this.formaRankType + " " + this.formaName;
this.nameAuthority = this.formaAuthority;
}
}
{
// Always recalculate subtaxa field
this.subtaxa = null;
if (StringUtils.isNotBlank(this.subspeciesName)) {
if ("Y".equals(isSubspecificHybrid)) {
this.subtaxa = PREFIX_NOTHOSUBSPECIES + subspeciesName;
} else {
this.subtaxa = PREFIX_SUBSPECIES + subspeciesName;
}
}
if (StringUtils.isNotBlank(this.varietyName)) {
this.subtaxa += " " + PREFIX_VARIETY + varietyName;
}
if (StringUtils.isNotBlank(this.subvarietyName)) {
this.subtaxa += " " + PREFIX_SUBVARIETY + subvarietyName;
}
if (StringUtils.isNotBlank(this.formaName)) {
String prefix = StringUtils.defaultIfBlank(formaRankType, PREFIX_FORMA) + " ";
this.subtaxa = prefix + formaName;
}
if (this.subtaxa != null) {
this.subtaxa = this.subtaxa.replaceAll("\\s\\s+", " "); // remove double spaces
}
}
}
public TaxonomySpecies(final Long id) {
this.id = id;
}
@Override
public Long getGenusId() {
return this.taxonomyGenus.getId();
}
@Override
public Long getSpeciesId() {
return this.id;
}
@Override
public boolean isCurrent() {
return this.id.equals(getCurrentTaxonomySpeciesId());
}
@Override
public Long getCurrentTaxonomySpeciesId() {
return this.currentTaxonomySpecies == null ? null : this.currentTaxonomySpecies.getId();
}
@Override
public String getSubtaxaAuthority() {
if (formaName != null) {
return formaAuthority;
}
if (subvarietyName != null) {
return subvarietyAuthority;
}
if (varietyName != null) {
return varietyAuthority;
}
if (subspeciesName != null) {
return subspeciesAuthority;
}
return null;
}
public void setNameVerifiedDate(Instant nameVerifiedDate) {
this.nameVerifiedDate = nameVerifiedDate;
}
public void setNameVerifiedDate(Date nameVerifiedDate) {
setNameVerifiedDate(nameVerifiedDate == null ? null : nameVerifiedDate.toInstant());
}
/**
* Utility to create an object reference to specified {@link TaxonomySpecies#id}.
*
* @param taxonomySpeciesId may be {@code null}
* @return {@code null} if incoming id is {@code null}, reference object otherwise
*/
public static TaxonomySpecies withId(Long taxonomySpeciesId) {
return taxonomySpeciesId == null ? null : new TaxonomySpecies(taxonomySpeciesId);
}
@Override
public boolean canEqual(Object other) {
return other instanceof TaxonomySpecies;
}
}