diff --git a/src/main/java/org/genesys2/server/listener/sample/FirstRunListener.java b/src/main/java/org/genesys2/server/listener/sample/FirstRunListener.java index 8552b60c4bae74971cf8d1bb2b5d86f3cc66a422..4c1c8de94373e1d5ad4d352d308af78326ad947e 100644 --- a/src/main/java/org/genesys2/server/listener/sample/FirstRunListener.java +++ b/src/main/java/org/genesys2/server/listener/sample/FirstRunListener.java @@ -18,39 +18,34 @@ package org.genesys2.server.listener.sample; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.oauth.model.OAuthClient; import org.genesys.blocks.oauth.model.OAuthRole; import org.genesys.blocks.oauth.persistence.OAuthClientRepository; import org.genesys2.server.listener.RunAsAdminListener; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.persistence.domain.AccessionRepository; -import org.genesys2.server.service.BatchRESTService; import org.genesys2.server.service.CropService; import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GeoRegionService; import org.genesys2.server.service.GeoService; import org.genesys2.server.service.InstituteService; +import org.genesys2.server.service.worker.AccessionUploader; import org.genesys2.server.service.worker.InstituteUpdater; -import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; -import org.genesys2.util.InvalidDOIException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.data.domain.PageRequest; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; + /** * Import country data and WIEWS institutes if none exist at startup * @@ -70,31 +65,34 @@ public class FirstRunListener extends RunAsAdminListener { private String defaultOAuthClientSecret; @Autowired - GeoService geoService; + private GeoService geoService; @Autowired - InstituteService instituteService; + private InstituteService instituteService; @Autowired - InstituteUpdater instituteUpdater; + private InstituteUpdater instituteUpdater; @Autowired - GeoRegionService geoRegionService; + private GeoRegionService geoRegionService; @Autowired - CropService cropService; + private CropService cropService; @Autowired - OAuthClientRepository oauthClientRepository; + private OAuthClientRepository oauthClientRepository; @Autowired - AccessionRepository accessionRepository; + private AccessionRepository accessionRepository; @Autowired - BatchRESTService batchService; + private AccessionUploader uploader; @Autowired private GenesysService genesysService; + + @Autowired + private PasswordEncoder passwordEncoder; @Override protected void init() throws Exception { @@ -150,7 +148,7 @@ public class FirstRunListener extends RunAsAdminListener { LOG.warn("Creating default OAuth client id={} secret={}", defaultOAuthClientId, defaultOAuthClientSecret); final OAuthClient client = new OAuthClient(); client.setClientId(defaultOAuthClientId); - client.setClientSecret(defaultOAuthClientSecret); + client.setClientSecret(passwordEncoder.encode(defaultOAuthClientSecret)); client.setTitle("Default OAuth client"); client.setDescription("This OAuth client was automatically created by the system."); client.getAuthorizedGrantTypes().add("authorization_code"); @@ -177,33 +175,23 @@ public class FirstRunListener extends RunAsAdminListener { final ObjectMapper mapper = new ObjectMapper(); try (InputStream stream = r.getInputStream()) { - final JsonNode json = mapper.readTree(stream); + final ArrayNode updates = (ArrayNode) mapper.readTree(stream); FaoInstitute institute = instituteService.getInstitute(instCode); if (institute == null) { throw new Exception("No Institute with instCode=" + instCode); } - final Map batch = new HashMap<>(); - ((ArrayNode) json).forEach(node -> { - try { - batch.put(AccessionHeaderJson.fromJson(node), (ObjectNode) node); - } catch (InvalidDOIException e) { - LOG.warn("Invalid DOI found in accession dummy data: {}", r.getFilename(), e); - } - }); - - if (batch.size() > 0) { - LOG.warn("Upserting {} accession records for {}", batch.size(), instCode); - batchService.ensureTaxonomies(institute, batch); - batchService.upsertAccessionData(institute, batch); + if (updates.size() > 0) { + LOG.warn("Upserting {} accession records for {}", updates.size(), instCode); + uploader.upsertAccessions(institute, updates); genesysService.updateAccessionCount(institute); } } catch (JsonParseException e) { LOG.error("Could not read dummy data for {} from {}. JSON is not valid.", instCode, r.getFilename(), e); } catch (Exception e) { - LOG.error("Could not create dummy data. {}", e.getMessage()); + LOG.error("Could not create dummy data. {}", e.getMessage(), e); } } } diff --git a/src/main/java/org/genesys2/server/model/elastic/AccessionDetails.java b/src/main/java/org/genesys2/server/model/elastic/AccessionDetails.java index a0fe69c6a6e8441ecb4f7a0bafa37aafa0dd9d28..29e1580a4052319250e678ab96e1caadbea8a080 100644 --- a/src/main/java/org/genesys2/server/model/elastic/AccessionDetails.java +++ b/src/main/java/org/genesys2/server/model/elastic/AccessionDetails.java @@ -11,18 +11,15 @@ import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.genesys2.server.model.genesys.AccessionAlias; import org.genesys2.server.model.genesys.AccessionAlias.AliasType; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.genesys.AccessionExchange; import org.genesys2.server.model.genesys.AccessionGeo; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.model.genesys.AccessionRemark; import org.genesys2.server.model.genesys.SvalbardDeposit; -import org.genesys2.server.model.impl.AccessionList; import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.Organization; import org.genesys2.server.service.IndexAliasConstants; -import org.genesys2.util.MCPDUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.annotation.Id; @@ -56,7 +53,7 @@ public class AccessionDetails { private Boolean available; private Date createdDate; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) - private List duplSite; + private Set duplSite; private Boolean mlsStatus; private Boolean art15; private Integer sampStat; @@ -87,7 +84,7 @@ public class AccessionDetails { private Geo geo; @Field(type = FieldType.Object) private Collect coll; - private String pedigree; + private String ancest; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) private String donorCode; private String donorName; @@ -100,7 +97,7 @@ public class AccessionDetails { private boolean historic; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) - private String bredCode; + private Set bredCode; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) private String acceUrl; @@ -117,24 +114,29 @@ public class AccessionDetails { ad.uuid = accession.getUuid(); ad.createdDate = accession.getCreatedDate(); ad.lastModifiedDate = accession.getLastModifiedDate(); - ad.acceNumb = accession.getAccessionName(); + ad.acceNumb = accession.getAccessionNumber(); ad.seqNo = accession.getSeqNo(); ad.acqDate = accession.getAcquisitionDate(); ad.acqSrc = accession.getAcquisitionSource(); - ad.available = accession.getAvailability(); - ad.historic = accession.getHistoric(); + ad.available = accession.isAvailable(); + ad.historic = accession.isHistoric(); ad.orgCty = Country.from(accession.getCountryOfOrigin()); - ad.duplSite = MCPDUtil.toList(accession.getDuplSite()); + ad.duplSite = accession.getAccessionId().getDuplSite(); ad.institute = Institute.from(accession.getInstitute()); ad.mlsStatus = accession.getMlsStatus(); ad.art15 = accession.getInTrust(); - ad.sampStat = accession.getSampleStatus(); - ad.storage = new ArrayList(accession.getStoRage()); + ad.sampStat = accession.getSampStat(); + ad.storage = new ArrayList(accession.getAccessionId().getStorage()); ad.lists = new HashSet(); ad.cropName=accession.getCropName(); ad.inSgsv = accession.getInSvalbard() != null && accession.getInSvalbard() == true ? true : false; ad.cropName = accession.getCropName(); ad.doi = accession.getDoi(); + ad.donorCode = accession.getDonorCode(); + ad.donorName = accession.getDonorName(); + ad.donorNumb = accession.getDonorNumb(); + ad.ancest = accession.getAncest(); + ad.bredCode = accession.getAccessionId().getBreederCode(); if (accession.getAccessionId().getPdci() != null) { ad.pdciScore = accession.getAccessionId().getPdci().getScore(); @@ -216,21 +218,6 @@ public class AccessionDetails { this.coll = Collect.from(collect); } - public void breeding(AccessionBreeding breeding) { - if (breeding == null) - return; - this.pedigree = StringUtils.defaultIfBlank(breeding.getPedigree(), null); - this.bredCode = StringUtils.defaultIfBlank(breeding.getBreederCode(), null); - } - - public void exch(AccessionExchange exch) { - if (exch == null) - return; - this.donorCode = StringUtils.defaultIfBlank(exch.getDonorInstitute(), null); - this.donorName = StringUtils.defaultIfBlank(exch.getDonorName(), null); - this.donorNumb = StringUtils.defaultIfBlank(exch.getAccNumbDonor(), null); - } - public Long getVersion() { return version; } @@ -303,11 +290,11 @@ public class AccessionDetails { this.createdDate = createdDate; } - public List getDuplSite() { + public Set getDuplSite() { return duplSite; } - public void setDuplSite(List duplSite) { + public void setDuplSite(Set duplSite) { this.duplSite = duplSite; } @@ -415,20 +402,20 @@ public class AccessionDetails { this.coll = coll; } - public String getBredCode() { + public Set getBredCode() { return bredCode; } - public void setBredCode(String bredCode) { + public void setBredCode(Set bredCode) { this.bredCode = bredCode; } public String getPedigree() { - return pedigree; + return ancest; } public void setPedigree(String pedigree) { - this.pedigree = pedigree; + this.ancest = pedigree; } public String getDonorCode() { diff --git a/src/main/java/org/genesys2/server/model/elastic/Collect.java b/src/main/java/org/genesys2/server/model/elastic/Collect.java index 0dfe24e0ee85ca259b07c6c6de9a67506f552412..ef99d894c2ca9190cad34ce74a518da64fb59479 100644 --- a/src/main/java/org/genesys2/server/model/elastic/Collect.java +++ b/src/main/java/org/genesys2/server/model/elastic/Collect.java @@ -1,12 +1,10 @@ package org.genesys2.server.model.elastic; import java.util.Date; -import java.util.HashSet; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.genesys2.server.model.genesys.AccessionCollect; -import org.genesys2.util.MCPDUtil; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldIndex; import org.springframework.data.elasticsearch.annotations.FieldType; @@ -16,9 +14,9 @@ public class Collect { private Set collCode; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) private String collDate; - private String collInstAddr; + private Set collInstAddr; private String collMissId; - private String collName; + private Set collName; @Field(index = FieldIndex.not_analyzed, type = FieldType.String) private String collNumb; private String collSite; @@ -30,14 +28,13 @@ public class Collect { return null; Collect c = new Collect(); - if (StringUtils.isNotBlank(collect.getCollCode())) - c.collCode = new HashSet(MCPDUtil.toList(collect.getCollCode())); + c.collCode = collect.getCollCode(); c.collDate = StringUtils.defaultIfBlank(collect.getCollDate(), null); - c.collInstAddr = StringUtils.defaultIfBlank(collect.getCollInstAddress(), null); - c.collMissId = StringUtils.defaultIfBlank(collect.getCollMissId(), null); - c.collName = StringUtils.defaultIfBlank(collect.getCollName(), null); - c.collNumb = StringUtils.defaultIfBlank(collect.getCollNumb(), null); - c.collSite = StringUtils.defaultIfBlank(collect.getCollSite(), null); + c.collInstAddr = collect.getCollInstAddress(); + c.collMissId = collect.getCollMissId(); + c.collName = collect.getCollName(); + c.collNumb = collect.getCollNumb(); + c.collSite = collect.getCollSite(); c.collSrc = collect.getCollSrc(); return c; } @@ -58,11 +55,11 @@ public class Collect { this.collDate = collDate; } - public String getCollInstAddr() { + public Set getCollInstAddr() { return collInstAddr; } - public void setCollInstAddr(String collInstAddr) { + public void setCollInstAddr(Set collInstAddr) { this.collInstAddr = collInstAddr; } @@ -74,11 +71,11 @@ public class Collect { this.collMissId = collMissId; } - public String getCollName() { + public Set getCollName() { return collName; } - public void setCollName(String collName) { + public void setCollName(Set collName) { this.collName = collName; } diff --git a/src/main/java/org/genesys2/server/model/genesys/Accession.java b/src/main/java/org/genesys2/server/model/genesys/Accession.java index b722d9d7edec7a8e11f51c4bf9aed2ef96b27953..4c58401ed7d92c3e36d781f964a39459617af853 100644 --- a/src/main/java/org/genesys2/server/model/genesys/Accession.java +++ b/src/main/java/org/genesys2/server/model/genesys/Accession.java @@ -16,56 +16,33 @@ package org.genesys2.server.model.genesys; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.FetchType; import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.OrderBy; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.genesys.blocks.auditlog.annotations.Audited; +import org.springframework.data.elasticsearch.annotations.Document; /** * Active accession records with all possible constraints. - * + * * @author mobreza * */ @Entity @Table(name = "accession", - // Unique constraints - uniqueConstraints = { @UniqueConstraint(name = "UQ_accession_genus_inst", columnNames = { "instituteId", "taxGenus", "acceNumb" }), @UniqueConstraint(name = "UQ_accession_doi", columnNames = {"doi"})}, - // Indexes - indexes = { @Index(name = "IX_seqNo", columnList = "seqNo"), @Index(name = "IX_accession_lastModifiedDate", columnList = "lastModifiedDate") }) + // Unique constraints + uniqueConstraints = { @UniqueConstraint(name = "UQ_accession_genus_inst", columnNames = { "instituteId", "genus", "acceNumb" }), + @UniqueConstraint(name = "UQ_accession_doi", columnNames = { "doi" }) }, + // Indexes + indexes = { @Index(name = "IX_acceNumb", columnList = "acceNumb"), @Index(name = "IX_seqNo", columnList = "seqNo"), @Index(name = "IX_accession_lastModifiedDate", columnList = "lastModifiedDate") }) @Audited +@Document(indexName = "genesys") public class Accession extends AccessionData { /** - * + * */ private static final long serialVersionUID = -4847875217506974494L; - public static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); - - @Column(name = "storage", nullable = false) - @ElementCollection(fetch = FetchType.LAZY) - @CollectionTable(name = "accessionstorage", joinColumns = @JoinColumn(name = "accessionId", referencedColumnName = "id")) - @OrderBy("storage") - private List stoRage = new ArrayList(); - - public List getStoRage() { - return stoRage; - } - - public void setStoRage(List stoRage) { - this.stoRage = stoRage; - } - } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionAlias.java b/src/main/java/org/genesys2/server/model/genesys/AccessionAlias.java index 629d2b99db4eb56cd6026bf06c8b22c73920287d..888953d1bc109394b07a810c22a17faf063d6935 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionAlias.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionAlias.java @@ -16,38 +16,47 @@ package org.genesys2.server.model.genesys; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; import javax.persistence.Table; import javax.persistence.Version; +import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.auditlog.annotations.Audited; import org.genesys.blocks.model.BasicModel; +import org.genesys.blocks.model.SelfCleaning; /** * Accession "alias" */ @Entity -@Table(name = "accessionalias") +//@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "accessionId", "aliasType", "name" }) }) +@Table(name = "accession_alias") @Audited -public class AccessionAlias extends BasicModel implements AccessionRelated { +public class AccessionAlias extends BasicModel implements AccessionRelated, SelfCleaning { - private static final long serialVersionUID = 4990299133164025782L; + private static Pattern USED_BY_PATTERN = Pattern.compile("^((\\p{Alnum}+):(.+))?$"); + public static enum AliasType { ACCENAME(0), DONORNUMB(1), BREDNUMB(2), DATABASEID(3), LOCALNAME(4), OTHERNUMB(5), COLLNUMB(6); private int id; - private AliasType(int id) { + private AliasType(final int id) { this.id = id; } - public static AliasType getType(Integer id) { + public static AliasType getType(final Integer id) { if (id == null) { return null; } @@ -76,11 +85,8 @@ public class AccessionAlias extends BasicModel implements AccessionRelated { @Column(name = "name", length = 150) private String name; - @Column(length = 10) - private String instCode; - @Column - private int aliasType = AliasType.ACCENAME.id; + private AliasType aliasType = AliasType.ACCENAME; @Column(length = 2) private String lang; @@ -91,11 +97,31 @@ public class AccessionAlias extends BasicModel implements AccessionRelated { public AccessionAlias() { } + public AccessionAlias(AliasType aliasType, String name) { + this.aliasType = aliasType; + Matcher m = USED_BY_PATTERN.matcher(name); + if (m.matches()) { + this.usedBy = StringUtils.trimToNull(m.group(2)); + this.name = StringUtils.trimToNull(m.group(3)); + } else { + if (name.startsWith(":")) { + name = StringUtils.trimToNull(name.substring(1)); + } + this.name = name; + } + } + + @PrePersist + @PreUpdate + private void prePersist() { + trimStringsToNull(); + } + public long getVersion() { return version; } - public void setVersion(long version) { + public void setVersion(final long version) { this.version = version; } @@ -104,7 +130,7 @@ public class AccessionAlias extends BasicModel implements AccessionRelated { return accession; } - public void setAccession(AccessionId accession) { + public void setAccession(final AccessionId accession) { this.accession = accession; } @@ -112,31 +138,23 @@ public class AccessionAlias extends BasicModel implements AccessionRelated { return name; } - public void setName(String name) { + public void setName(final String name) { this.name = name; } - public String getInstCode() { - return instCode; - } - - public void setInstCode(String instCode) { - this.instCode = instCode; - } - public AliasType getAliasType() { - return AliasType.getType(this.aliasType); + return this.aliasType; } - public void setAliasType(AliasType aliasType) { - this.aliasType = aliasType.getId(); + public void setAliasType(final AliasType aliasType) { + this.aliasType = aliasType; } public String getLang() { return lang; } - public void setLang(String lang) { + public void setLang(final String lang) { this.lang = lang; } @@ -144,12 +162,27 @@ public class AccessionAlias extends BasicModel implements AccessionRelated { return usedBy; } - public void setUsedBy(String usedBy) { + public void setUsedBy(final String usedBy) { this.usedBy = usedBy; } @Override public String toString() { - return "name=" + name + " instCode=" + instCode + " type=" + aliasType; + return "name=" + name + " usedBy=" + usedBy + " type=" + aliasType; + } + + public boolean equalTo(AccessionAlias other) { + if (aliasType != null && other.aliasType != null) { + if (aliasType != other.aliasType) + return false; + } else { + return false; + } + + if (StringUtils.compare(this.name, other.name) != 0) { + return false; + } + + return true; } } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionBreeding.java b/src/main/java/org/genesys2/server/model/genesys/AccessionBreeding.java deleted file mode 100644 index 489ae5b171fbd46a70f8aa95bb362bea5cc32d2f..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionBreeding.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.model.genesys; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.Lob; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Version; - -import org.apache.commons.lang.StringUtils; -import org.genesys.blocks.auditlog.annotations.Audited; -import org.genesys.blocks.model.BasicModel; -import org.hibernate.annotations.Type; - -/** - * AllAcqBreeding generated by hbm2java - */ -@Entity -@Table(name = "accessionbreeding") -@Audited -public class AccessionBreeding extends BasicModel implements AccessionRelated { - - - private static final long serialVersionUID = 7659867116143459074L; - - @Version - private long version = 0; - - @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) - @JoinColumn(name = "accessionId", unique = true, nullable = false, updatable = false) - private AccessionId accession; - - @Column(name = "breederCode", length = 8) - private String breederCode; - - @Column(name = "pedigree") - @Lob - @Type(type = "org.hibernate.type.TextType") - private String pedigree; - - public AccessionBreeding() { - } - - public long getVersion() { - return version; - } - - public void setVersion(long version) { - this.version = version; - } - - @Override - public AccessionId getAccession() { - return accession; - } - - public void setAccession(AccessionId accession) { - this.accession = accession; - } - - public String getBreederCode() { - return this.breederCode; - } - - public void setBreederCode(final String breederCode) { - this.breederCode = breederCode; - } - - public String getPedigree() { - return this.pedigree; - } - - public void setPedigree(final String pedigree) { - this.pedigree = pedigree; - } - - public boolean isEmpty() { - if (StringUtils.isNotBlank(pedigree)) - return false; - - if (StringUtils.isNotBlank(breederCode)) - return false; - - return true; - } - -} diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionCollect.java b/src/main/java/org/genesys2/server/model/genesys/AccessionCollect.java index 5e5a41d46114cc3e30f1103e532fa4bc3608531d..0e11b7bae5a019885dcda97c62b728f06408b85e 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionCollect.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionCollect.java @@ -16,36 +16,42 @@ package org.genesys2.server.model.genesys; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.CollectionTable; import javax.persistence.Column; +import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.OneToOne; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; import javax.persistence.Table; import javax.persistence.Version; import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.auditlog.annotations.Audited; import org.genesys.blocks.model.BasicModel; +import org.genesys.blocks.model.SelfCleaning; import org.hibernate.annotations.Type; /** * Collecting data */ @Entity -@Table(name = "accessioncollect") +@Table(name = "accession_collect") @Audited -public class AccessionCollect extends BasicModel implements AccessionRelated { +public class AccessionCollect extends BasicModel implements AccessionRelated, SelfCleaning { - private static final long serialVersionUID = 6848317825287346724L; @Version private long version = 0; - @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) - @JoinColumn(name = "accessionId", unique = true, nullable = false, updatable = false) + @OneToOne(mappedBy = "coll", optional = false, fetch = FetchType.LAZY, cascade = {}) private AccessionId accession; @Column(name = "collDate", length = 8) @@ -57,18 +63,20 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { @Column(name = "collMissId", length = 128) private String collMissId; - @Column(name = "collCode", length = 128) - private String collCode; + @Column(name = "collCode", nullable = false, length = 128) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_collect_code", joinColumns = @JoinColumn(name = "collectId", referencedColumnName = "id")) + private Set collCode; - @Column(name = "collName") - @Lob - @Type(type = "org.hibernate.type.TextType") - private String collName; + @Column(name = "collName", nullable = false, length = 258) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_collect_name", joinColumns = @JoinColumn(name = "collectId", referencedColumnName = "id")) + private Set collName; - @Column(name = "collInstAddress") - @Lob - @Type(type = "org.hibernate.type.TextType") - private String collInstAddress; + @Column(name = "collInstAddress", nullable = false, length = 128) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_collect_instaddr", joinColumns = @JoinColumn(name = "collectId", referencedColumnName = "id")) + private Set collInstAddress; @Column(name = "collSite") @Lob @@ -78,11 +86,30 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { @Column private Integer collSrc; + @PrePersist + @PreUpdate + private void prePersist() { + trimStringsToNull(); + + // remove blank collCode + if (collCode != null && !collCode.isEmpty()) { + Set notBlank = collCode.stream().filter(str -> StringUtils.isNotBlank(str)).collect(Collectors.toSet()); + collCode.clear(); + collCode.addAll(notBlank); + } + // remove blank collName + if (collName != null && !collName.isEmpty()) { + Set notBlank = collName.stream().filter(str -> StringUtils.isNotBlank(str)).collect(Collectors.toSet()); + collName.clear(); + collName.addAll(notBlank); + } + } + public long getVersion() { return version; } - public void setVersion(long version) { + public void setVersion(final long version) { this.version = version; } @@ -91,7 +118,7 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return accession; } - public void setAccession(AccessionId accession) { + public void setAccession(final AccessionId accession) { this.accession = accession; } @@ -99,7 +126,7 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return collDate; } - public void setCollDate(String collDate) { + public void setCollDate(final String collDate) { this.collDate = collDate; } @@ -107,7 +134,7 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return collNumb; } - public void setCollNumb(String collNumb) { + public void setCollNumb(final String collNumb) { this.collNumb = collNumb; } @@ -115,31 +142,31 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return collMissId; } - public void setCollMissId(String collMissId) { + public void setCollMissId(final String collMissId) { this.collMissId = collMissId; } - public String getCollCode() { + public Set getCollCode() { return collCode; } - public void setCollCode(String collCode) { + public void setCollCode(final Set collCode) { this.collCode = collCode; } - public String getCollName() { + public Set getCollName() { return collName; } - public void setCollName(String collName) { + public void setCollName(final Set collName) { this.collName = collName; } - public String getCollInstAddress() { + public Set getCollInstAddress() { return collInstAddress; } - public void setCollInstAddress(String collInstAddress) { + public void setCollInstAddress(final Set collInstAddress) { this.collInstAddress = collInstAddress; } @@ -147,7 +174,7 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return collSite; } - public void setCollSite(String collSite) { + public void setCollSite(final String collSite) { this.collSite = collSite; } @@ -155,35 +182,39 @@ public class AccessionCollect extends BasicModel implements AccessionRelated { return collSrc; } - public void setCollSrc(Integer collSrc) { + public void setCollSrc(final Integer collSrc) { this.collSrc = collSrc; } public boolean isEmpty() { - if (StringUtils.isNotBlank(collDate)) - return false; - - if (StringUtils.isNotBlank(collNumb)) + if (StringUtils.isNotBlank(collDate)) { return false; + } - if (StringUtils.isNotBlank(collMissId)) + if (StringUtils.isNotBlank(collNumb)) { return false; + } - if (StringUtils.isNotBlank(collName)) + if (StringUtils.isNotBlank(collMissId)) { return false; + } - if (StringUtils.isNotBlank(collName)) + if (collName != null && collName.stream().filter(x -> StringUtils.isNotBlank(x)).count() > 0) { return false; + } - if (StringUtils.isNotBlank(collInstAddress)) + if (collInstAddress != null && collInstAddress.stream().filter(x -> StringUtils.isNotBlank(x)).count() > 0) { return false; + } - if (StringUtils.isNotBlank(collSite)) + if (StringUtils.isNotBlank(collSite)) { return false; + } - if (collSrc != null) + if (collSrc != null) { return false; - + } + return true; } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionData.java b/src/main/java/org/genesys2/server/model/genesys/AccessionData.java index 21b489c22022a7231f47cdad8c399e99cfb4f302..a6b11a193b33a9ede361487b005a3089ac0f5ae6 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionData.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionData.java @@ -18,8 +18,6 @@ package org.genesys2.server.model.genesys; import java.io.Serializable; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.UUID; @@ -27,6 +25,7 @@ import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.FetchType; import javax.persistence.JoinColumn; +import javax.persistence.Lob; import javax.persistence.ManyToOne; import javax.persistence.MappedSuperclass; import javax.persistence.MapsId; @@ -37,22 +36,27 @@ import javax.persistence.Transient; import org.genesys.blocks.model.AuditedVersionedModel; import org.genesys.blocks.model.IdUUID; +import org.genesys.blocks.model.SelfCleaning; import org.genesys2.server.model.impl.Country; import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.util.MCPDUtil; import org.genesys2.util.NumberUtils; +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonUnwrapped; @MappedSuperclass -public abstract class AccessionData extends AuditedVersionedModel implements IdUUID, Serializable { +public abstract class AccessionData extends AuditedVersionedModel implements IdUUID, Serializable, SelfCleaning { private static final long serialVersionUID = -3428918862058441943L; - public static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); - @MapsId @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER, optional = false, orphanRemoval = false) @JoinColumn(name = "id") + @JsonUnwrapped private AccessionId accessionId; @Column(name = "doi") @@ -61,12 +65,15 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU @Column(name = "instCode", length = 10, nullable = false) private String instituteCode; + @Column(nullable = false, length = 100) + private String genus; + @ManyToOne(cascade = {}, optional = false) @JoinColumn(name = "instituteId") private FaoInstitute institute; @Column(name = "acceNumb", nullable = false, length = 128) - private String accessionName; + private String accessionNumber; @Column(name = "seqNo", nullable = false) private double seqNo = 0; @@ -78,29 +85,27 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU @JoinColumn(name = "cropId") private Crop crop; - // @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) @ManyToOne(cascade = {}, optional = false) @JoinColumn(name = "taxonomyId2") + @JsonIgnoreProperties(value = { "id", "version" }) private Taxonomy2 taxonomy; + // FIXME: Remove? @Column(name = "acqSrc", length = 3) private String acquisitionSource; @Column(name = "acqDate", length = 12) private String acquisitionDate; - @Column(name = "orgCty", length = 3) - private String origin; + @Column(name = "origCty", length = 3) + private String origCty; @ManyToOne(cascade = {}, optional = true) @JoinColumn(name = "orgCtyId", nullable = true) private Country countryOfOrigin; - @Column(name = "duplSite", length = 64) - private String duplSite; - @Column(name = "sampStat", length = 3) - private Integer sampleStatus; + private Integer sampStat; @Column(name = "inSGSV") private Boolean inSvalbard; @@ -109,7 +114,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU private Boolean inTrust; @Column(name = "available") - private Boolean availability; + private Boolean available; @Column(name = "historic", nullable = false) private boolean historic = false; @@ -117,31 +122,58 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU @Column(name = "mlsStat") private Boolean mlsStatus; - @Column(name = "taxGenus", nullable = false) - private long taxGenus; - - @Column(name = "storage", length = 64, nullable = true) - private String storage; + @Column(name = "storageStr", length = 100, nullable = true) + private String storageStr; @Column(name = "acceurl", length = 300, nullable = true) private String acceUrl; + @Column(name = "names") + @Lob + @Type(type = "org.hibernate.type.TextType") + private String accNames; + + @Column(name = "otherIds") + @Lob + @Type(type = "org.hibernate.type.TextType") + private String otherIds; + + @Column(name = "donorCode", length = 9) + private String donorCode; + + @Column(name = "donorName", length = 300) + private String donorName; + + @Column(name = "donorNumb", length = 200) + private String donorNumb; + + @Column(name = "ancest") + @Lob + @Type(type = "org.hibernate.type.TextType") + private String ancest; + + @Column(name = "duplSiteStr", length = 100) + private String duplSiteStr; + /** - * Update MCPD {@link #storage} + * Update MCPD {@link #storageStr} */ @PrePersist @PreUpdate private void prePersist() { - if (this.countryOfOrigin != null) - this.origin = this.countryOfOrigin.getCode3(); - else - this.origin = null; - + trimStringsToNull(); + + this.seqNo = NumberUtils.numericValue(this.accessionNumber); + + if (this.countryOfOrigin != null) { + this.origCty = this.countryOfOrigin.getCode3(); + } else { + this.origCty = null; + } + this.genus = getTaxonomy().getGenus(); this.instituteCode = getInstitute().getCode(); - this.storage = MCPDUtil.toMcpdArray(getStoRage()); - - // Update the ACCENUMB number - this.seqNo = NumberUtils.numericValue(this.accessionName); + this.storageStr = MCPDUtil.toMcpdArray(accessionId.getStorage()); + this.duplSiteStr = MCPDUtil.toMcpdArray(accessionId.getDuplSite()); } public FaoInstitute getInstitute() { @@ -160,18 +192,22 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU this.instituteCode = instituteCode; } - public String getAccessionName() { - return this.accessionName; + public String getAccessionNumber() { + return this.accessionNumber; } - public void setAccessionName(final String accessionName) { - this.accessionName = accessionName; + public void setAccessionNumber(final String accessionNumber) { + this.accessionNumber = accessionNumber; } public Taxonomy2 getTaxonomy() { return this.taxonomy; } + public void setTaxonomy(final Taxonomy2 taxonomy) { + this.taxonomy = taxonomy; + } + public String getAcquisitionSource() { return this.acquisitionSource; } @@ -188,36 +224,36 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU this.acquisitionDate = acquisitionDate; } - public String getOrigin() { - return this.origin; + public String getOrigCty() { + return this.origCty; } - protected void setOrigin(final String origin) { - this.origin = origin; + protected void setOrigCty(final String origCty) { + this.origCty = origCty; } public Country getCountryOfOrigin() { return countryOfOrigin; } - public void setCountryOfOrigin(Country countryOfOrigin) { + public void setCountryOfOrigin(final Country countryOfOrigin) { this.countryOfOrigin = countryOfOrigin; } - public String getDuplSite() { - return this.duplSite; + public String getDuplSiteStr() { + return this.duplSiteStr; } - public void setDuplSite(final String duplSite) { - this.duplSite = duplSite; + protected void setDuplSiteStr(final String duplSite) { + this.duplSiteStr = duplSite; } - public Integer getSampleStatus() { - return this.sampleStatus; + public Integer getSampStat() { + return this.sampStat; } - public void setSampleStatus(final Integer sampleStatus) { - this.sampleStatus = sampleStatus; + public void setSampStat(final Integer sampleStatus) { + this.sampStat = sampleStatus; } public Boolean getInSvalbard() { @@ -236,12 +272,12 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU this.inTrust = inTrust; } - public Boolean getAvailability() { - return this.availability; + public Boolean isAvailable() { + return available; } - - public void setAvailability(final Boolean availability) { - this.availability = availability; + + public void setAvailable(Boolean available) { + this.available = available; } public Boolean getMlsStatus() { @@ -252,44 +288,27 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU this.mlsStatus = mlsStatus; } - public long getTaxGenus() { - return taxGenus; - } - - protected void setTaxGenus(long taxGenus) { - this.taxGenus = taxGenus; - } - - public void setTaxonomy(Taxonomy2 taxonomy2) { - this.taxonomy = taxonomy2; - this.taxGenus = taxonomy2.getTaxGenus(); - } - - public abstract List getStoRage(); - - public abstract void setStoRage(List stoRage); - /** * Returns {@link #getStoRage()} as MCPD string - * + * * @return MCPD array string */ - public String getStorage() { - return storage; + public String getStorageStr() { + return storageStr; } /** - * Use {@link #setStoRage(List)} instead. + * Use {@link #setStorage(List)} instead. */ - protected void setStorage(String storage) { - this.storage = storage; + protected void setStorageStr(final String storage) { + this.storageStr = storage; } - public boolean getHistoric() { + public boolean isHistoric() { return historic; } - public void setHistoric(boolean historic) { + public void setHistoric(final boolean historic) { this.historic = historic; } @@ -297,7 +316,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return accessionId; } - public void setAccessionId(AccessionId accessionId) { + public void setAccessionId(final AccessionId accessionId) { this.accessionId = accessionId; } @@ -316,7 +335,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return this.acceUrl; } - public void setAcceUrl(String acceUrl) { + public void setAcceUrl(final String acceUrl) { this.acceUrl = acceUrl; } @@ -324,7 +343,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return seqNo; } - public void setSeqNo(double acceNumbNumb) { + public void setSeqNo(final double acceNumbNumb) { this.seqNo = acceNumbNumb; } @@ -332,7 +351,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return cropName; } - public void setCropName(String cropName) { + public void setCropName(final String cropName) { this.cropName = cropName; } @@ -340,7 +359,7 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return crop; } - public void setCrop(Crop crop) { + public void setCrop(final Crop crop) { this.crop = crop; } @@ -348,7 +367,82 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU return doi; } - public void setDoi(String doi) { + public void setDoi(final String doi) { this.doi = doi; } + + public String getAccNames() { + return accNames; + } + + public void setAccNames(String accNames) { + this.accNames = accNames; + } + + public String getOtherIds() { + return otherIds; + } + + public void setOtherIds(String otherIds) { + this.otherIds = otherIds; + } + + public String getAncest() { + return ancest; + } + + public void setAncest(String ancest) { + this.ancest = ancest; + } + + public String getDonorCode() { + return donorCode; + } + + public void setDonorCode(String donorCode) { + this.donorCode = donorCode; + } + + public String getDonorName() { + return donorName; + } + + public void setDonorName(String donorName) { + this.donorName = donorName; + } + + public String getDonorNumb() { + return donorNumb; + } + + public void setDonorNumb(String donorNumb) { + this.donorNumb = donorNumb; + } + + @Transient + @JsonIgnore + // TODO Remove + public String getAccessionName() { + return this.accessionNumber; + } + + @Transient + @JsonIgnore + public Integer getSampleStatus() { + return this.sampStat; + } + + @Transient + @JsonIgnore + // For EL + public Boolean getAvailable() { + return this.available; + } + + @Transient + @JsonIgnore + // For EL + public Boolean getHistoric() { + return this.historic; + } } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionExchange.java b/src/main/java/org/genesys2/server/model/genesys/AccessionExchange.java deleted file mode 100644 index 2f2196e0c6d536916dcb6a121f3c2fe3b117ff47..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionExchange.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.model.genesys; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Version; - -import org.apache.commons.lang.StringUtils; -import org.genesys.blocks.auditlog.annotations.Audited; -import org.genesys.blocks.model.BasicModel; - -/** - * AllAcqExchange generated by hbm2java - */ -@Entity -@Table(name = "accessionexchange") -@Audited -public class AccessionExchange extends BasicModel implements AccessionRelated { - - - private static final long serialVersionUID = -2509737429801931061L; - - @Version - private long version = 0; - - @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) - @JoinColumn(name = "accessionId", unique = true, nullable = false, updatable = false) - private AccessionId accession; - - @Column(name = "donorInst", length = 8) - private String donorInstitute; - - @Column(name = "donorName", length = 200) - private String donorName; - - @Column(name = "acceNumb", length = 200) - private String accNumbDonor; - - public AccessionExchange() { - } - - public long getVersion() { - return version; - } - - public void setVersion(long version) { - this.version = version; - } - - @Override - public AccessionId getAccession() { - return accession; - } - - public void setAccession(AccessionId accession) { - this.accession = accession; - } - - public String getDonorInstitute() { - return this.donorInstitute; - } - - public void setDonorInstitute(final String donorInstitute) { - this.donorInstitute = donorInstitute; - } - - public String getAccNumbDonor() { - return this.accNumbDonor; - } - - public void setAccNumbDonor(final String accNumbDonor) { - this.accNumbDonor = accNumbDonor; - } - - public String getDonorName() { - return donorName; - } - - public void setDonorName(String donorName) { - this.donorName = donorName; - } - - public boolean isEmpty() { - if (StringUtils.isNotBlank(accNumbDonor)) - return false; - if (StringUtils.isNotBlank(donorName)) - return false; - if (StringUtils.isNotBlank(donorInstitute)) - return false; - - return true; - } -} diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionGeo.java b/src/main/java/org/genesys2/server/model/genesys/AccessionGeo.java index 044b3391d40629cc129b0d536bf2ef7b82cdb280..879916cb95c050620ad43195e6ed0d0c4b96080d 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionGeo.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionGeo.java @@ -19,7 +19,7 @@ package org.genesys2.server.model.genesys; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; -import javax.persistence.JoinColumn; +import javax.persistence.Index; import javax.persistence.OneToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; @@ -29,22 +29,21 @@ import javax.persistence.Version; import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.auditlog.annotations.Audited; import org.genesys.blocks.model.BasicModel; +import org.genesys.blocks.model.SelfCleaning; import org.genesys.worldclim.WorldClimUtil; import org.genesys2.server.model.impl.GeoReferencedEntity; @Entity -@Table(name = "accessiongeo") +@Table(name = "accession_geo", indexes = { @Index(unique = false, columnList = "latitude, longitude"), @Index(unique = false, columnList = "tileIndex") }) @Audited -public class AccessionGeo extends BasicModel implements GeoReferencedEntity, AccessionRelated { +public class AccessionGeo extends BasicModel implements GeoReferencedEntity, AccessionRelated, SelfCleaning { - private static final long serialVersionUID = 8046638388176612388L; @Version private long version = 0; - @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) - @JoinColumn(name = "accessionId", unique = true, nullable = false, updatable = false) + @OneToOne(mappedBy = "geo", optional = false, fetch = FetchType.LAZY, cascade = {}) private AccessionId accession; @Column(name = "longitude") @@ -55,7 +54,9 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc private Double elevation; private Double uncertainty; + @Column(length = 100) private String datum; + @Column(length = 100) private String method; private Long tileIndex; @@ -66,14 +67,15 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc @PrePersist @PreUpdate private void prePersist() { + trimStringsToNull(); tileIndex = WorldClimUtil.getTileIndex(5, this.longitude, this.latitude); } - + public long getVersion() { return version; } - public void setVersion(long version) { + public void setVersion(final long version) { this.version = version; } @@ -82,7 +84,7 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc return accession; } - public void setAccession(AccessionId accession) { + public void setAccession(final AccessionId accession) { this.accession = accession; } @@ -109,11 +111,11 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc return elevation; } - public void setElevation(Double elevation) { + public void setElevation(final Double elevation) { this.elevation = elevation; } - public void setUncertainty(Double uncertainty) { + public void setUncertainty(final Double uncertainty) { this.uncertainty = uncertainty; } @@ -121,7 +123,7 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc return uncertainty; } - public void setDatum(String datum) { + public void setDatum(final String datum) { this.datum = datum; } @@ -131,10 +133,10 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc /** * Set geodetic method - * + * * @param method */ - public void setMethod(String method) { + public void setMethod(final String method) { this.method = method; } @@ -146,17 +148,20 @@ public class AccessionGeo extends BasicModel implements GeoReferencedEntity, Acc return tileIndex; } - public void setTileIndex(Long tileIndex) { + public void setTileIndex(final Long tileIndex) { this.tileIndex = tileIndex; } public boolean isEmpty() { - if (StringUtils.isNotBlank(datum)) + if (StringUtils.isNotBlank(datum)) { return false; - if (StringUtils.isNotBlank(method)) + } + if (StringUtils.isNotBlank(method)) { return false; - if (this.latitude != null || this.longitude != null || this.elevation != null || this.uncertainty != null) + } + if (this.latitude != null || this.longitude != null || this.elevation != null || this.uncertainty != null) { return false; + } return true; } } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionHistoric.java b/src/main/java/org/genesys2/server/model/genesys/AccessionHistoric.java index a64ab05dae8e28ce49ebbe97f339a4a13182a49d..ce75f994d49c1787909e27a9cb26171e1a4f65cc 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionHistoric.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionHistoric.java @@ -16,53 +16,31 @@ package org.genesys2.server.model.genesys; -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.FetchType; import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.OrderBy; import javax.persistence.Table; /** * No constraints here. - * + * * @author mobreza * */ @Entity -@Table(name = "accessionhistoric", indexes = { @Index(name = "IX_seqNo", columnList = "seqNo") }) +@Table(name = "accession_historic", indexes = { @Index(name = "IX_accessionhistoric_seqNo", columnList = "seqNo") }) public class AccessionHistoric extends AccessionData { /** - * + * */ private static final long serialVersionUID = -301411904252738547L; - @Column(name = "storage", nullable = false) - @ElementCollection(fetch = FetchType.LAZY) - @CollectionTable(name = "accessionstorageh", joinColumns = @JoinColumn(name = "accessionId", referencedColumnName = "id")) - @OrderBy("storage") - private List stoRage = new ArrayList(); public AccessionHistoric() { } - public AccessionHistoric(Accession accession) { + public AccessionHistoric(final Accession accession) { SelfCopy.copy(accession, this); } - public List getStoRage() { - return stoRage; - } - - public void setStoRage(List stoRage) { - this.stoRage = stoRage; - } - } diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionId.java b/src/main/java/org/genesys2/server/model/genesys/AccessionId.java index 2a5741ebb5436b83675f3c70b0a69328ff468083..4203a080e4f68dab2757b868a47400bd2992e865 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionId.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionId.java @@ -20,7 +20,10 @@ import java.util.List; import java.util.Set; import java.util.UUID; +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; import javax.persistence.Column; +import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Inheritance; @@ -30,14 +33,19 @@ import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.OneToOne; +import javax.persistence.OrderBy; import javax.persistence.PrePersist; import javax.persistence.Table; import org.genesys.blocks.model.AuditedVersionedModel; import org.genesys.blocks.model.IdUUID; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys.blocks.model.JsonViews; import org.hibernate.annotations.Type; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonView; + /** * Entity holds the assigned accession identifiers regardless of active or * historic records. @@ -48,7 +56,7 @@ import org.hibernate.annotations.Type; public class AccessionId extends AuditedVersionedModel implements IdUUID { /** - * + * */ private static final long serialVersionUID = -6224417080504343264L; @@ -57,15 +65,55 @@ public class AccessionId extends AuditedVersionedModel implements IdUUID { protected UUID uuid; @OneToMany(cascade = {}, fetch = FetchType.LAZY, mappedBy = "accession", orphanRemoval = false) + @JsonIgnore private List traits; @ManyToMany(cascade = {}, fetch = FetchType.LAZY) - @JoinTable(name = "accelistitems", joinColumns = @JoinColumn(name = "acceid"), inverseJoinColumns = @JoinColumn(name = "listid")) + @JoinTable(name = "accession_listitem", joinColumns = @JoinColumn(name = "acceid"), inverseJoinColumns = @JoinColumn(name = "listid")) + @JsonIgnore private Set lists; - @OneToOne(mappedBy = "accession", fetch = FetchType.LAZY, optional = true, orphanRemoval = true) + @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, optional = true, orphanRemoval = true) + @JoinColumn(name = "pdciId", unique = true) + @JsonIgnoreProperties({ "accession" }) + @JsonView({ JsonViews.Root.class }) private PDCI pdci; + @Column(name = "storage", nullable = false) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_storage", joinColumns = @JoinColumn(name = "accessionId", referencedColumnName = "id")) + @OrderBy("storage") + private Set storage = null; + + @Column(name = "duplSite", nullable = false, length = 9) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_duplsite", joinColumns = @JoinColumn(name = "accessionId", referencedColumnName = "id")) + @OrderBy("duplSite") + private Set duplSite; + + @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, optional = true, orphanRemoval = true) + @JoinColumn(name = "geoId", unique = true) + @JsonIgnoreProperties({ "accession" }) + private AccessionGeo geo; + + @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL }, optional = true, orphanRemoval = true) + @JoinColumn(name = "collId", unique = true) + @JsonIgnoreProperties({ "accession" }) + private AccessionCollect coll; + + @OneToMany(mappedBy = "accession", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true) + @JsonIgnoreProperties({ "accession" }) + private List aliases; + + @OneToMany(mappedBy = "accession", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, orphanRemoval = true) + @JsonIgnoreProperties({ "accession" }) + private List remarks; + + @Column(name = "breederCode", nullable = false, length = 9) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "accession_breedercode", joinColumns = @JoinColumn(name = "accessionId", referencedColumnName = "id")) + private Set breederCode; + @PrePersist private void prepersist() { if (uuid == null) { @@ -78,7 +126,7 @@ public class AccessionId extends AuditedVersionedModel implements IdUUID { return this.uuid; } - public void setUuid(UUID uuid) { + public void setUuid(final UUID uuid) { this.uuid = uuid; } @@ -86,20 +134,71 @@ public class AccessionId extends AuditedVersionedModel implements IdUUID { return lists; } - public void setLists(Set lists) { + public void setLists(final Set lists) { this.lists = lists; } public PDCI getPdci() { return pdci; } + + public void setPdci(PDCI pdci) { + this.pdci = pdci; + } + + public Set getStorage() { + return storage; + } + + public void setStorage(final Set stoRage) { + this.storage = stoRage; + } + + public AccessionGeo getGeo() { + return geo; + } + + public void setGeo(AccessionGeo geo) { + this.geo = geo; + } + + public AccessionCollect getColl() { + return coll; + } + + public void setColl(AccessionCollect coll) { + this.coll = coll; + } - // - // public List getTraits() { - // return traits; - // } - // - // public void setTraits(List traits) { - // this.traits = traits; - // } + public List getAliases() { + return aliases; + } + + public void setAliases(List aliases) { + this.aliases = aliases; + } + + public List getRemarks() { + return remarks; + } + + public void setRemarks(List remarks) { + this.remarks = remarks; + } + + public Set getBreederCode() { + return breederCode; + } + + public void setBreederCode(Set breederCode) { + this.breederCode = breederCode; + } + + public Set getDuplSite() { + return duplSite; + } + + public void setDuplSite(Set duplSite) { + this.duplSite = duplSite; + } } diff --git a/src/main/java/org/genesys2/server/model/impl/AccessionList.java b/src/main/java/org/genesys2/server/model/genesys/AccessionList.java similarity index 91% rename from src/main/java/org/genesys2/server/model/impl/AccessionList.java rename to src/main/java/org/genesys2/server/model/genesys/AccessionList.java index 50f74bbc26b7893bfcf3bb4b289866b133bf481d..9bef9883e0fbc96e00faa8ac1eef432386e2c2ce 100644 --- a/src/main/java/org/genesys2/server/model/impl/AccessionList.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionList.java @@ -14,7 +14,7 @@ * limitations under the License. **/ -package org.genesys2.server.model.impl; +package org.genesys2.server.model.genesys; import java.util.Set; import java.util.UUID; @@ -30,14 +30,13 @@ import javax.persistence.Table; import org.genesys.blocks.model.AuditedVersionedModel; import org.genesys.blocks.security.model.AclAwareModel; -import org.genesys2.server.model.genesys.AccessionId; import org.hibernate.annotations.Type; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldIndex; import org.springframework.data.elasticsearch.annotations.FieldType; @Entity -@Table(name = "accelist") +@Table(name = "accession_list") public class AccessionList extends AuditedVersionedModel implements AclAwareModel { private static final long serialVersionUID = 991886970995006680L; @@ -47,7 +46,7 @@ public class AccessionList extends AuditedVersionedModel implements AclAwareMode protected UUID uuid; @ManyToMany(cascade = {}, fetch = FetchType.LAZY) - @JoinTable(name = "accelistitems", joinColumns = @JoinColumn(name = "listid"), inverseJoinColumns = @JoinColumn(name = "acceid")) + @JoinTable(name = "accession_listitem", joinColumns = @JoinColumn(name = "listid"), inverseJoinColumns = @JoinColumn(name = "acceid")) private Set accessionIds; @Column(name = "title", nullable = false) @@ -69,8 +68,9 @@ public class AccessionList extends AuditedVersionedModel implements AclAwareMode @PrePersist protected void pre() { - if (uuid == null) + if (uuid == null) { uuid = UUID.randomUUID(); + } } public AccessionList() { diff --git a/src/main/java/org/genesys2/server/model/genesys/AccessionRemark.java b/src/main/java/org/genesys2/server/model/genesys/AccessionRemark.java index 5cab7ecb237099572597406999855fcfec69e821..877c93d466807ee12e98e8032f7439a39f469ef2 100644 --- a/src/main/java/org/genesys2/server/model/genesys/AccessionRemark.java +++ b/src/main/java/org/genesys2/server/model/genesys/AccessionRemark.java @@ -16,31 +16,39 @@ package org.genesys2.server.model.genesys; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; 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 javax.persistence.Version; +import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.auditlog.annotations.Audited; import org.genesys.blocks.model.BasicModel; +import org.genesys.blocks.model.SelfCleaning; import org.hibernate.annotations.Type; /** * Accession "alias" */ @Entity -@Table(name = "accessionremark") +@Table(name = "accession_remark") @Audited -public class AccessionRemark extends BasicModel implements AccessionRelated { +public class AccessionRemark extends BasicModel implements AccessionRelated, SelfCleaning { /** - * + * */ private static final long serialVersionUID = 815335916194920054L; + private static Pattern REMARKFIELD_PATTERN = Pattern.compile("^((\\p{Alnum}+):(.+))?$"); @Version private long version = 0; @@ -50,7 +58,7 @@ public class AccessionRemark extends BasicModel implements AccessionRelated { private AccessionId accession; @Lob - @Column(name = "remark") + @Column(name = "remark", nullable = false) @Type(type = "org.hibernate.type.TextType") private String remark; @@ -60,11 +68,30 @@ public class AccessionRemark extends BasicModel implements AccessionRelated { public AccessionRemark() { } + public AccessionRemark(String str) { + Matcher m = REMARKFIELD_PATTERN.matcher(str); + if (m.matches()) { + this.fieldName = StringUtils.trimToNull(m.group(2)); + this.remark = StringUtils.trimToNull(m.group(3)); + } else { + if (str.startsWith(":")) { + str = str.substring(1); + } + this.remark = StringUtils.trimToNull(str); + } + } + + @PrePersist + @PreUpdate + private void prePersist() { + trimStringsToNull(); + } + public long getVersion() { return version; } - public void setVersion(long version) { + public void setVersion(final long version) { this.version = version; } @@ -73,7 +100,7 @@ public class AccessionRemark extends BasicModel implements AccessionRelated { return accession; } - public void setAccession(AccessionId accession) { + public void setAccession(final AccessionId accession) { this.accession = accession; } @@ -81,7 +108,7 @@ public class AccessionRemark extends BasicModel implements AccessionRelated { return remark; } - public void setRemark(String remark) { + public void setRemark(final String remark) { this.remark = remark; } @@ -89,8 +116,26 @@ public class AccessionRemark extends BasicModel implements AccessionRelated { return fieldName; } - public void setFieldName(String fieldName) { + public void setFieldName(final String fieldName) { this.fieldName = fieldName; } + public boolean equalTo(AccessionRemark other) { + if (other == null) { + return false; + } + if (StringUtils.compare(fieldName, other.fieldName) != 0) { + return false; + } + if (StringUtils.compare(remark, other.remark) != 0) { + return false; + } + + return true; + } + + @Override + public String toString() { + return "" + this.fieldName + ":" + this.remark; + } } diff --git a/src/main/java/org/genesys2/server/model/genesys/PDCI.java b/src/main/java/org/genesys2/server/model/genesys/PDCI.java index f5e8a00c5b57739bcfeedcbabf4ebe0577ae0c91..bd8d433a547196a2e0114efe99b4b47da7edcf64 100644 --- a/src/main/java/org/genesys2/server/model/genesys/PDCI.java +++ b/src/main/java/org/genesys2/server/model/genesys/PDCI.java @@ -22,7 +22,6 @@ import java.util.Set; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Index; -import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.PrePersist; import javax.persistence.PreUpdate; @@ -36,13 +35,12 @@ import org.genesys.blocks.model.VersionedModel; public class PDCI extends VersionedModel implements AccessionRelated { private static final long serialVersionUID = -1312366054528702261L; - public static final String[] independentItems = { "genus", "species", "spAuthor", "subTaxa", "subtAuthor", "cropName", "acqDate", "sampStat", "donorCode", "donorNumb", "otherNumb", "duplSite", - "storage", "donorName", "duplInstName", "acceUrl", "mlsStat" }; - public static final String[] dependentItems = { "origCty", "collSite", "latitude", "longitude", "elevation", "collDate", "bredCode", "ancest", "collSrc", "acceName", "collNumb", "collCode", - "collName" }; + public static final String[] independentItems = { "genus", "species", "spAuthor", "subTaxa", "subtAuthor", "cropName", "acqDate", "sampStat", "donorCode", "donorNumb", + "otherNumb", "duplSite", "storage", "donorName", "duplInstName", "acceUrl", "mlsStat" }; + public static final String[] dependentItems = { "origCty", "collSite", "latitude", "longitude", "elevation", "collDate", "bredCode", "ancest", "collSrc", "acceName", + "collNumb", "collCode", "collName" }; - @OneToOne(cascade = {}, fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "accessionId") + @OneToOne(mappedBy = "pdci", cascade = {}, fetch = FetchType.LAZY, optional = false) private AccessionId accession; private Float score = null; @@ -92,7 +90,7 @@ public class PDCI extends VersionedModel implements AccessionRelated { return accession; } - public void setAccession(AccessionId accession) { + public void setAccession(final AccessionId accession) { this.accession = accession; } @@ -212,119 +210,119 @@ public class PDCI extends VersionedModel implements AccessionRelated { return bredCode; } - public void setAcqDate(int score) { + public void setAcqDate(final int score) { this.acqDate = score; } - public void setSampStat(int score) { + public void setSampStat(final int score) { this.sampStat = score; } - public void setDonorCode(int score) { + public void setDonorCode(final int score) { this.donorCode = score; } - public void setGenus(int score) { + public void setGenus(final int score) { this.genus = score; } - public void setSpecies(int score) { + public void setSpecies(final int score) { this.species = score; } - public void setSpAuthor(int score) { + public void setSpAuthor(final int score) { this.spAuthor = score; } - public void setSubTaxa(int score) { + public void setSubTaxa(final int score) { this.subTaxa = score; } - public void setSubtAuthor(int score) { + public void setSubtAuthor(final int score) { this.subtAuthor = score; } - public void setDonorNumb(int score) { + public void setDonorNumb(final int score) { this.donorNumb = score; } - public void setOtherNumb(int score) { + public void setOtherNumb(final int score) { this.otherNumb = score; } - public void setDuplSite(int score) { + public void setDuplSite(final int score) { this.duplSite = score; } - public void setStorage(int score) { + public void setStorage(final int score) { this.storage = score; } - public void setDonorName(int score) { + public void setDonorName(final int score) { this.donorName = score; } - public void setDuplInstName(int score) { + public void setDuplInstName(final int score) { this.duplInstName = score; } - public void setAcceUrl(int score) { + public void setAcceUrl(final int score) { this.acceUrl = score; } - public void setMlsStat(int score) { + public void setMlsStat(final int score) { this.mlsStat = score; } - public void setOrigCty(int score) { + public void setOrigCty(final int score) { this.origCty = score; } - public void setLatitude(int score) { + public void setLatitude(final int score) { this.latitude = score; } - public void setLongitude(int score) { + public void setLongitude(final int score) { this.longitude = score; } - public void setCollSite(int score) { + public void setCollSite(final int score) { this.collSite = score; } - public void setElevation(int score) { + public void setElevation(final int score) { this.elevation = score; } - public void setCollDate(int score) { + public void setCollDate(final int score) { this.collDate = score; } - public void setCollSrc(int score) { + public void setCollSrc(final int score) { this.collSrc = score; } - public void setCollNumb(int score) { + public void setCollNumb(final int score) { this.collNumb = score; } - public void setCollCode(int score) { + public void setCollCode(final int score) { this.collCode = score; } - public void setCollName(int score) { + public void setCollName(final int score) { this.collName = score; } - public void setAncest(int score) { + public void setAncest(final int score) { this.ancest = score; } - public void setAcceName(int score) { + public void setAcceName(final int score) { this.acceName = score; } - public void setBredCode(int score) { + public void setBredCode(final int score) { this.bredCode = score; } @@ -335,7 +333,7 @@ public class PDCI extends VersionedModel implements AccessionRelated { return score; } - public void setScore(Float score) { + public void setScore(final Float score) { this.score = score; } @@ -346,12 +344,12 @@ public class PDCI extends VersionedModel implements AccessionRelated { return scoreHist; } - public void setScoreHist(Float scoreHist) { + public void setScoreHist(final Float scoreHist) { this.scoreHist = scoreHist; } private Float calculateScore() { - float total = getTotal(); + final float total = getTotal(); return total / 100f; } @@ -393,7 +391,7 @@ public class PDCI extends VersionedModel implements AccessionRelated { return score; } - public void setCropName(int score) { + public void setCropName(final int score) { this.cropName = score; } @@ -410,10 +408,10 @@ public class PDCI extends VersionedModel implements AccessionRelated { } public static Set getPdciItems() { - Set descriptors = new HashSet(); - for (java.lang.reflect.Method method : PDCI.class.getMethods()) { + final Set descriptors = new HashSet<>(); + for (final java.lang.reflect.Method method : PDCI.class.getMethods()) { if (method.getName().startsWith("get") && method.getReturnType() == int.class) { - String str = method.getName().substring(3); + final String str = method.getName().substring(3); descriptors.add(str.substring(0, 1).toLowerCase() + str.substring(1)); } } diff --git a/src/main/java/org/genesys2/server/model/genesys/SelfCopy.java b/src/main/java/org/genesys2/server/model/genesys/SelfCopy.java index 084357e73f077ece941defc3b6ddbf6298bfdc24..6440054e8972fb598935c7ed7c79bd2f6c7e52bb 100644 --- a/src/main/java/org/genesys2/server/model/genesys/SelfCopy.java +++ b/src/main/java/org/genesys2/server/model/genesys/SelfCopy.java @@ -9,12 +9,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SelfCopy { - private static final Logger LOG = LoggerFactory.getLogger(SelfCopy.class); - private static Map gettersSetters = new HashMap(); + private static final Logger LOG = LoggerFactory.getLogger(SelfCopy.class); + private static Map gettersSetters = new HashMap<>(); static { - Method[] allMethods = AccessionData.class.getMethods(); - for (Method getter : allMethods) { + final Method[] allMethods = AccessionData.class.getMethods(); + for (final Method getter : allMethods) { String name = getter.getName(); boolean isGet = false; @@ -31,7 +31,7 @@ public class SelfCopy { LOG.trace("Finding setter for getter {}", getter); } try { - Method setter = AccessionData.class.getMethod("set" + name, getter.getReturnType()); + final Method setter = AccessionData.class.getMethod("set" + name, getter.getReturnType()); gettersSetters.put(getter, setter); LOG.debug("Found setter {}", setter); } catch (NoSuchMethodException | SecurityException e) { @@ -41,10 +41,10 @@ public class SelfCopy { } } - public static void copy(AccessionData source, AccessionData target) { - for (Method getter : gettersSetters.keySet()) { + public static void copy(final AccessionData source, final AccessionData target) { + for (final Method getter : gettersSetters.keySet()) { try { - Object val = getter.invoke(source); + final Object val = getter.invoke(source); gettersSetters.get(getter).invoke(target, val); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { LOG.warn(e.getMessage(), e); diff --git a/src/main/java/org/genesys2/server/model/genesys/Taxonomy2.java b/src/main/java/org/genesys2/server/model/genesys/Taxonomy2.java index a119d7cd2ee304266273e21ed0e01ada4fbb10fa..228bbe694145e6657fa91f8fb6b131ee59f8f2ba 100644 --- a/src/main/java/org/genesys2/server/model/genesys/Taxonomy2.java +++ b/src/main/java/org/genesys2/server/model/genesys/Taxonomy2.java @@ -212,4 +212,52 @@ public class Taxonomy2 extends GlobalVersionedAuditedModel { spAuthor, subtaxa, subtAuthor); } + + /** + * Clean up nulls and stuff... + * + * @return + */ + public Taxonomy2 sanitize() { + if (species == null) { + species = "sp."; + } + if ("sp".equalsIgnoreCase(species)) { + species = "sp."; + } + if (spAuthor == null) { + spAuthor = ""; + } + if (subtaxa == null) { + subtaxa = ""; + } + if (subtAuthor == null) { + subtAuthor = ""; + } + return this; + } + + public boolean equalTo(Taxonomy2 other) { + if (other == null) { + return false; + } + if (!genus.equalsIgnoreCase(other.genus)) { + return false; + } + if (!species.equalsIgnoreCase(other.species)) { + return false; + } + if (!spAuthor.equalsIgnoreCase(other.spAuthor)) { + return false; + } + if (!subtaxa.equalsIgnoreCase(other.subtaxa)) { + return false; + } + if (!subtAuthor.equalsIgnoreCase(other.subtAuthor)) { + return false; + } + + return true; + } + } diff --git a/src/main/java/org/genesys2/server/model/impl/GrinTaxonomy.java b/src/main/java/org/genesys2/server/model/impl/GrinTaxonomy.java index 84c49edec4ed9bd8806fa99ccd1974609a37bbfd..8e3521a1482396543b82d76f88f828bcfc0cb392 100644 --- a/src/main/java/org/genesys2/server/model/impl/GrinTaxonomy.java +++ b/src/main/java/org/genesys2/server/model/impl/GrinTaxonomy.java @@ -20,6 +20,7 @@ import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -32,9 +33,9 @@ import org.genesys.blocks.model.VersionedModel; * @author matijaobreza */ @Entity +@Table(name = "grin_taxonomy") public class GrinTaxonomy extends VersionedModel { - private static final long serialVersionUID = -1294689196992826336L; @Column(unique = true, nullable = false) diff --git a/src/main/java/org/genesys2/server/model/json/AccessionJson.java b/src/main/java/org/genesys2/server/model/json/AccessionJson.java index a59dc4b76c0f63055dcdaaf15cebd774ab732740..59baf4edbf4f698839210207730f854e8c08becc 100644 --- a/src/main/java/org/genesys2/server/model/json/AccessionJson.java +++ b/src/main/java/org/genesys2/server/model/json/AccessionJson.java @@ -16,6 +16,7 @@ package org.genesys2.server.model.json; +import java.util.Set; import java.util.UUID; import org.genesys2.server.model.json.Api1Constants.Accession; @@ -53,11 +54,11 @@ public class AccessionJson { @JsonProperty(value = Accession.AVAILABLE) private Boolean available; @JsonProperty(value = Accession.STORAGE) - private Integer[] storage; + private Set storage; @JsonProperty(value = Accession.SAMPSTAT) private Integer sampStat; @JsonProperty(value = Accession.DUPLSITE) - private String[] duplSite; + private Set duplSite; @JsonProperty(value = Accession.BREDCODE) private String bredCode; @JsonProperty(value = Accession.ANCEST) @@ -201,12 +202,12 @@ public class AccessionJson { this.available = available; } - public Integer[] getStorage() { + public Set getStorage() { return storage; } - public void setStorage(Integer[] storage) { - this.storage = storage; + public void setStorage(Set set) { + this.storage = set; } public Integer getSampStat() { @@ -217,12 +218,12 @@ public class AccessionJson { this.sampStat = sampStat; } - public String[] getDuplSite() { + public Set getDuplSite() { return duplSite; } - public void setDuplSite(String[] duplSite) { - this.duplSite = duplSite; + public void setDuplSite(Set set) { + this.duplSite = set; } public String getBredCode() { diff --git a/src/main/java/org/genesys2/server/model/json/CollectingJson.java b/src/main/java/org/genesys2/server/model/json/CollectingJson.java index 177d71d65972fe11e6e9893f048f781c1ace9d23..b1bf6abd71d23ebbdfcc2adeb6eed1d73af3f117 100644 --- a/src/main/java/org/genesys2/server/model/json/CollectingJson.java +++ b/src/main/java/org/genesys2/server/model/json/CollectingJson.java @@ -16,6 +16,8 @@ package org.genesys2.server.model.json; +import java.util.Set; + import org.genesys2.server.model.json.Api1Constants.Collecting; import com.fasterxml.jackson.annotation.JsonProperty; @@ -30,11 +32,11 @@ public class CollectingJson { @JsonProperty(value = Collecting.COLLSRC) private Integer collSrc; @JsonProperty(value = Collecting.COLLCODE) - private String collCode; + private Set collCode; @JsonProperty(value = Collecting.COLLNAME) - private String collName; + private Set collName; @JsonProperty(value = Collecting.COLLINSTADDRESS) - private String collInstAddress; + private Set collInstAddress; @JsonProperty(value = Collecting.COLLMISSID) private String collMissId; @@ -70,28 +72,28 @@ public class CollectingJson { this.collSrc = integer; } - public String getCollCode() { + public Set getCollCode() { return collCode; } - public void setCollCode(String collCode) { - this.collCode = collCode; + public void setCollCode(Set set) { + this.collCode = set; } - public String getCollName() { + public Set getCollName() { return collName; } - public void setCollName(String collName) { - this.collName = collName; + public void setCollName(Set set) { + this.collName = set; } - public String getCollInstAddress() { + public Set getCollInstAddress() { return collInstAddress; } - public void setCollInstAddress(String collInstAddress) { - this.collInstAddress = collInstAddress; + public void setCollInstAddress(Set set) { + this.collInstAddress = set; } public String getCollMissId() { diff --git a/src/main/java/org/genesys2/server/model/json/GenesysJsonFactory.java b/src/main/java/org/genesys2/server/model/json/GenesysJsonFactory.java index e62c65c9d5b08b16b54a4ba08d0b9ab932f45696..bf3ca75f077bf6ba8b7068d537b4dba70e8a97a9 100644 --- a/src/main/java/org/genesys2/server/model/json/GenesysJsonFactory.java +++ b/src/main/java/org/genesys2/server/model/json/GenesysJsonFactory.java @@ -18,9 +18,7 @@ package org.genesys2.server.model.json; import java.util.List; -import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionData; import org.genesys2.server.model.genesys.AccessionGeo; @@ -39,7 +37,7 @@ public class GenesysJsonFactory { aj.setGenesysId(accession.getAccessionId().getId()); aj.setInstCode(accession.getInstitute().getCode()); - aj.setAcceNumb(accession.getAccessionName()); + aj.setAcceNumb(accession.getAccessionNumber()); aj.setUuid(accession.getUuid()); final Taxonomy2 tax = accession.getTaxonomy(); @@ -57,14 +55,14 @@ public class GenesysJsonFactory { aj.setAcqDate(accession.getAcquisitionDate()); aj.setMlsStat(accession.getMlsStatus()); aj.setInTrust(accession.getInTrust()); - aj.setAvailable(accession.getAvailability()); - aj.setHistoric(accession.getHistoric()); + aj.setAvailable(accession.isAvailable()); + aj.setHistoric(accession.isHistoric()); // private Integer[] storage; - aj.setStorage(accession.getStoRage().toArray(ArrayUtils.EMPTY_INTEGER_OBJECT_ARRAY)); + aj.setStorage(accession.getAccessionId().getStorage()); // private Integer sampStat; - aj.setSampStat(accession.getSampleStatus()); + aj.setSampStat(accession.getSampStat()); // private String[] duplSite; - aj.setDuplSite(toStrArr(accession.getDuplSite())); + aj.setDuplSite(accession.getAccessionId().getDuplSite()); // private String bredCode; // private String ancest; @@ -133,13 +131,6 @@ public class GenesysJsonFactory { return r; } - public static void addBreeding(final AccessionJson aj, final AccessionBreeding breeding) { - if (breeding != null) { - aj.setBredCode(breeding.getBreederCode()); - aj.setAncest(breeding.getPedigree()); - } - } - public static void addCollecting(final AccessionJson aj, final AccessionCollect collect) { aj.setColl(from(collect)); } diff --git a/src/main/java/org/genesys2/server/model/json/UserAccessionList.java b/src/main/java/org/genesys2/server/model/json/UserAccessionList.java index b1e753560b30ba97965b94f76af7c2094d0a5b5d..ba5b5afa004a2d0aeaf8ddaadabe5ca8cc4b3ce5 100644 --- a/src/main/java/org/genesys2/server/model/json/UserAccessionList.java +++ b/src/main/java/org/genesys2/server/model/json/UserAccessionList.java @@ -19,7 +19,7 @@ package org.genesys2.server.model.json; import java.io.Serializable; import java.util.UUID; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; public class UserAccessionList implements Serializable { private static final long serialVersionUID = -2092185410372557368L; diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionBreedingRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionBreedingRepository.java deleted file mode 100644 index f671ad8296933028db792c6b7c0ab977e7696b61..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionBreedingRepository.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.persistence.domain; - -import java.util.Collection; -import java.util.List; - -import org.genesys2.server.model.genesys.AccessionBreeding; -import org.genesys2.server.model.genesys.AccessionId; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; - -public interface AccessionBreedingRepository extends JpaRepository { - - AccessionBreeding findByAccession(AccessionId accession); - - @Modifying - @Query("delete from AccessionBreeding ab where ab.accession.id in ?1") - void deleteForAccessions(Collection accessionIds); - - @Query("from AccessionBreeding ab where ab.accession.id in ?1") - List findAllFor(Collection accessionIds); -} diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionExchangeRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionExchangeRepository.java deleted file mode 100644 index 6367ba1424b255f3fe799b45b5b86a813d8d560e..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionExchangeRepository.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.persistence.domain; - -import java.util.Collection; -import java.util.List; - -import org.genesys2.server.model.genesys.AccessionExchange; -import org.genesys2.server.model.genesys.AccessionId; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; - -public interface AccessionExchangeRepository extends JpaRepository { - - AccessionExchange findByAccession(AccessionId accession); - - @Modifying - @Query("delete from AccessionExchange ae where ae.accession.id in ?1") - void deleteForAccessions(Collection accessionIds); - - @Query("from AccessionExchange ae where ae.accession.id in ?1") - List findAllFor(Collection accessionIds); -} diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionHistoricRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionHistoricRepository.java index 65b6e6a27954cf5c3cd170dfcc92908f0aa7ae3a..5abbd72398c47288977173200354fb7a8d364496 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionHistoricRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionHistoricRepository.java @@ -26,9 +26,9 @@ import org.springframework.data.jpa.repository.Query; public interface AccessionHistoricRepository extends JpaRepository { - List findByInstituteAndAccessionName(FaoInstitute faoInstitute, String acceNumb); + List findByInstituteAndAccessionNumber(FaoInstitute faoInstitute, String acceNumb); - List findByAccessionName(String acceNumb); + List findByAccessionNumber(String acceNumb); @Query("select a from AccessionHistoric a where a.accessionId.uuid = ?1") AccessionHistoric findOneByUuid(UUID uuid); diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionListCustomRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionListCustomRepository.java index e77a5df61367c51489eb5e2f50b560e45517a7f3..b44b2dd0eb8a6509a425b35cc073c5fca3220bc1 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionListCustomRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionListCustomRepository.java @@ -18,7 +18,7 @@ package org.genesys2.server.persistence.domain; import java.util.Collection; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; public interface AccessionListCustomRepository { diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java index 56b1be0a1ddf4092f7cdb9dab04e6634030e8421..960a177a7ad22edd338517479ec2fa143dc2d208 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java @@ -21,7 +21,7 @@ import java.util.Set; import java.util.UUID; import org.genesys2.server.model.genesys.AccessionId; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepositoryCustomImpl.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepositoryCustomImpl.java index 3bd784ca948dd736b2d0a1002365d40151489eac..e3fc70b11ecca6c19f4c1f5a5b6916c34f23c0b8 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepositoryCustomImpl.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepositoryCustomImpl.java @@ -22,8 +22,8 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.model.genesys.Method; -import org.genesys2.server.model.impl.AccessionList; import org.genesys2.server.service.impl.DirectMysqlQuery; import org.genesys2.server.service.impl.DirectMysqlQuery.MethodResolver; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepository.java index 0d64b83ee0c2bcd68924b4c5f5b983a045804927..0097d85390cd9bcce90b0b1bb4e85a5f9a3a9837 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepository.java @@ -35,7 +35,7 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -public interface AccessionRepository extends JpaRepository, AccessionCustomRepository { +public interface AccessionRepository extends JpaRepository, AccessionRepositoryCustom { @Query("select a.id from Accession a") public List listAccessionsIds(Pageable pageable); @@ -81,9 +81,9 @@ public interface AccessionRepository extends JpaRepository, Acc @Query("select a from Accession a where a.institute in ( ?1 )") Page findByInstitute(List institutes, Pageable pageable); - List findByInstituteAndAccessionName(FaoInstitute faoInstitute, String accessionName); + List findByInstituteAndAccessionNumber(FaoInstitute faoInstitute, String accessionNumber); - public List findByInstituteAndAccessionName(FaoInstitute institute, List acceNumbs); + public List findByInstituteAndAccessionNumber(FaoInstitute institute, List acceNumbs); @Query("from Accession a where a.id in ( ?1 )") Page findById(Collection accessionIds, Pageable pageable); @@ -98,16 +98,16 @@ public interface AccessionRepository extends JpaRepository, Acc @Query("select a from Accession a where a.taxonomy in ( ?1 )") Page findByTaxonomy(Collection taxonomies, Pageable pageable); - @Query("select a from Accession a where a.institute.code = ?1 and a.accessionName = ?2") - Accession findByInstituteCodeAndAccessionName(String instCode, String accessionName); + @Query("select a from Accession a where a.institute.code = ?1 and a.accessionNumber = ?2") + Accession findByInstituteCodeAndAccessionNumber(String instCode, String accessionNumber); - @Query("select distinct a from Accession a where a.accessionName=?2 and (a.institute.code=?1 or a.institute.codeSGSV=?1) and a.taxonomy.genus=?3") + @Query("select distinct a from Accession a where a.accessionNumber=?2 and (a.institute.code=?1 or a.institute.codeSGSV=?1) and a.taxonomy.genus=?3") Accession findOneSGSV(String instCode, String acceNumb, String genus); - @Query("select count(a.id) from Accession a where a.id in ( ?1 ) and a.historic = false and (a.availability is null or a.availability = true) and a.institute.allowMaterialRequests = true") + @Query("select count(a.id) from Accession a where a.id in ( ?1 ) and a.historic = false and (a.available is null or a.available = true) and a.institute.allowMaterialRequests = true") long countAvailableForDistribution(Set accessionIds); - @Query("select a.id from Accession a where a.id in ( ?1 ) and a.historic = false and (a.availability is null or a.availability = true) and a.institute.allowMaterialRequests = true") + @Query("select a.id from Accession a where a.id in ( ?1 ) and a.historic = false and (a.available is null or a.available = true) and a.institute.allowMaterialRequests = true") Set filterAvailableForDistribution(Set accessionIds); @Query("select distinct a.institute from Accession a where a.id in ( ?1 )") @@ -126,7 +126,7 @@ public interface AccessionRepository extends JpaRepository, Acc @Query("select a from Accession a where a.accessionId.uuid = ?1") public Accession findOneByUuid(UUID uuid); - public List findByAccessionName(String acceNumb); + public List findByAccessionNumber(String acceNumb); @Query("select a from Accession a") Stream streamAll(); diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionCustomRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustom.java similarity index 86% rename from src/main/java/org/genesys2/server/persistence/domain/AccessionCustomRepository.java rename to src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustom.java index 33c02b09155688e449895a8659cbdb70d4c3f068..264b756ac1399dadafe77d36e58f6a99016cecc4 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionCustomRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustom.java @@ -24,9 +24,14 @@ import org.genesys2.server.model.impl.AccessionIdentifier3; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.service.impl.NonUniqueAccessionException; -public interface AccessionCustomRepository { +public interface AccessionRepositoryCustom { + + List find(List accessions); + + List findById(List identifiers); List find(FaoInstitute institute, Set accessionIds) throws NonUniqueAccessionException; Accession findOne(FaoInstitute institute, String doi, String acceNumb, String genus); + } diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustomImpl.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustomImpl.java index 711bcabb3a6fda27a76a6af4d2a9efb7d81d4284..ba70b5bbf2c98b4b853284c85cf350c81db79467 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustomImpl.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionRepositoryCustomImpl.java @@ -17,6 +17,7 @@ package org.genesys2.server.persistence.domain; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,8 +45,9 @@ import org.springframework.transaction.annotation.Transactional; @Repository @Transactional(readOnly = true) -public class AccessionRepositoryCustomImpl implements AccessionCustomRepository, InitializingBean { +public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom, InitializingBean { public static final Logger LOG = LoggerFactory.getLogger(AccessionRepositoryCustomImpl.class); + private static final Predicate[] EMPTY_PREDICATE_ARRAY = new Predicate[] {}; @PersistenceContext private EntityManager em; @@ -57,6 +59,84 @@ public class AccessionRepositoryCustomImpl implements AccessionCustomRepository, this.criteriaBuilder = em.getCriteriaBuilder(); } + @Override + public List find(List forUpdate) { + if (forUpdate == null || forUpdate.isEmpty()) { + return Collections.emptyList(); + } + + CriteriaQuery cq = criteriaBuilder.createQuery(Accession.class); + Root root = cq.from(Accession.class); + cq.distinct(true); + cq.select(root); + + Join tax = root.join("taxonomy"); + Join inst = root.join("institute"); + List restrictions = new ArrayList(); + + Set uniqueDois = forUpdate.stream().map(aid -> aid.getDoi()).filter(doi -> doi != null).distinct().collect(Collectors.toSet()); + Set acceNumbs = forUpdate.stream().map(aid -> aid.getAccessionNumber()).filter(acceNumb -> acceNumb != null).distinct().collect(Collectors.toSet()); + + if (uniqueDois.size() > 0) { + restrictions.add(root.get("doi").in(uniqueDois)); + LOG.trace("*** {} dois={}", uniqueDois); + } + + // A lot of .. (acceNumb=? and genus=?) + for (Accession ah : forUpdate) { + restrictions.add(criteriaBuilder.and(criteriaBuilder.equal(inst.get("code"), ah.getInstituteCode()), criteriaBuilder.equal(root.get("accessionNumber"), ah + .getAccessionNumber()), criteriaBuilder.equal(tax.get("genus"), ah.getTaxonomy().getGenus()))); + } + + cq.where(criteriaBuilder.or(restrictions.toArray(EMPTY_PREDICATE_ARRAY))); + List res = em.createQuery(cq).getResultList(); + + if (LOG.isDebugEnabled()) + LOG.trace("*** Loaded accessions {} of {}", res.size(), acceNumbs.size()); + + return res; + } + + + @Override + public List findById(List identifiers) { + if (identifiers == null || identifiers.isEmpty()) { + return Collections.emptyList(); + } + + CriteriaQuery cq = criteriaBuilder.createQuery(Accession.class); + Root root = cq.from(Accession.class); + cq.distinct(true); + cq.select(root); + + Join tax = root.join("taxonomy"); + Join inst = root.join("institute"); + List restrictions = new ArrayList(); + + Set uniqueDois = identifiers.stream().map(aid -> aid.getDoi()).filter(doi -> doi != null).distinct().collect(Collectors.toSet()); + Set acceNumbs = identifiers.stream().map(aid -> aid.getAccessionNumber()).filter(acceNumb -> acceNumb != null).distinct().collect(Collectors.toSet()); + + if (uniqueDois.size() > 0) { + restrictions.add(root.get("doi").in(uniqueDois)); + LOG.trace("*** {} dois={}", uniqueDois); + } + + // A lot of .. (acceNumb=? and genus=?) + for (AccessionIdentifier3 aid3 : identifiers) { + restrictions.add(criteriaBuilder.and(criteriaBuilder.equal(inst.get("code"), aid3.getHoldingInstitute()), criteriaBuilder.equal(root.get("accessionNumber"), aid3 + .getAccessionNumber()), criteriaBuilder.equal(tax.get("genus"), aid3.getGenus()))); + } + + cq.where(criteriaBuilder.or(restrictions.toArray(EMPTY_PREDICATE_ARRAY))); + List res = em.createQuery(cq).getResultList(); + + if (LOG.isDebugEnabled()) + LOG.trace("*** Loaded accessions {} of {}", res.size(), acceNumbs.size()); + + return res; + } + + @Override public List find(FaoInstitute institute, Set accessionIds) throws NonUniqueAccessionException { boolean uniqueAcceNumbs = institute.hasUniqueAcceNumbs(); @@ -90,7 +170,7 @@ public class AccessionRepositoryCustomImpl implements AccessionCustomRepository, restrictions.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("accessionName"), ah.getAccessionNumber()), criteriaBuilder.equal(tax.get("genus"), ah.getGenus()))); } } - cq.where(criteriaBuilder.and(criteriaBuilder.equal(root.get("institute"), institute), criteriaBuilder.or(restrictions.toArray(new Predicate[] {})))); + cq.where(criteriaBuilder.and(criteriaBuilder.equal(root.get("institute"), institute), criteriaBuilder.or(restrictions.toArray(EMPTY_PREDICATE_ARRAY)))); List res = em.createQuery(cq).getResultList(); @@ -100,12 +180,12 @@ public class AccessionRepositoryCustomImpl implements AccessionCustomRepository, if (uniqueAcceNumbs) { Set s = new HashSet(); for (Accession a : res) { - if (s.contains(a.getAccessionName())) { - LOG.error("Duplicate accession name instCode=" + a.getInstituteCode() + " acceNumb=" + a.getAccessionName()); - throw new NonUniqueAccessionException(a.getInstituteCode(), a.getAccessionName()); + if (s.contains(a.getAccessionNumber())) { + LOG.error("Duplicate accession name instCode=" + a.getInstituteCode() + " acceNumb=" + a.getAccessionNumber()); + throw new NonUniqueAccessionException(a.getInstituteCode(), a.getAccessionNumber()); } - s.add(a.getAccessionName()); + s.add(a.getAccessionNumber()); } } diff --git a/src/main/java/org/genesys2/server/service/AccessionListService.java b/src/main/java/org/genesys2/server/service/AccessionListService.java index 0e7888b59530993089a2b385fb304f5152a069ea..e9e8f759021795462f2da916e7aeec2f34af57af 100644 --- a/src/main/java/org/genesys2/server/service/AccessionListService.java +++ b/src/main/java/org/genesys2/server/service/AccessionListService.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.UUID; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; public interface AccessionListService { diff --git a/src/main/java/org/genesys2/server/service/BatchRESTService.java b/src/main/java/org/genesys2/server/service/BatchRESTService.java deleted file mode 100644 index aa2dda0b127f7dc56439e1a325b465ab69c29db6..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/service/BatchRESTService.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright 2015 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.genesys2.server.service; - -import java.util.List; -import java.util.Map; - -import org.genesys2.server.model.impl.FaoInstitute; -import org.genesys2.server.service.impl.RESTApiException; -import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; -import org.genesys2.server.servlet.controller.rest.model.AccessionNamesJson; - -import com.fasterxml.jackson.databind.node.ObjectNode; - -public interface BatchRESTService { - - List upsertAccessionData(FaoInstitute institute, Map batch) throws RESTApiException; - - List upsertAccessionNames(FaoInstitute institute, List batch) throws RESTApiException; - - List deleteAccessions(FaoInstitute institute, List batch) throws RESTApiException; - - int deleteAccessionsById(FaoInstitute institute, List batch); - - void ensureTaxonomies(FaoInstitute institute, Map batch) throws RESTApiException; -} diff --git a/src/main/java/org/genesys2/server/service/GenesysService.java b/src/main/java/org/genesys2/server/service/GenesysService.java index 2fe569141ee38e37e3553f7d772ffafa69e51db1..c46d9671f7ca5fef9f77891d3ff9aa6c2b37786b 100644 --- a/src/main/java/org/genesys2/server/service/GenesysService.java +++ b/src/main/java/org/genesys2/server/service/GenesysService.java @@ -27,10 +27,8 @@ import java.util.UUID; import org.genesys2.server.model.elastic.AccessionDetails; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.AccessionAlias; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.genesys.AccessionExchange; import org.genesys2.server.model.genesys.AccessionGeo; import org.genesys2.server.model.genesys.AccessionHistoric; import org.genesys2.server.model.genesys.AccessionId; @@ -95,18 +93,6 @@ public interface GenesysService { AllAccnames listAccessionNames(AccessionId accession); - List listAccessionAliases(AccessionId accession); - - AccessionExchange getAccessionExchange(AccessionId accession); - - AccessionCollect getAccessionCollect(AccessionId accession); - - AccessionBreeding getAccessionBreeding(AccessionId accession); - - AccessionGeo getAccessionGeo(AccessionId accession); - - List listAccessionRemarks(AccessionId accession); - List listMetadata(AccessionId accession); Page listMetadata(Pageable pageable); @@ -154,36 +140,18 @@ public interface GenesysService { Set filterAvailableForDistribution(Set accessionIds); - AccessionData saveAccession(AccessionData accession); - List saveAccessions(Iterable accession); FaoInstitute updateAccessionCount(FaoInstitute institute); List getSvalbardData(AccessionId accession); - List saveCollecting(List all); - - List saveGeo(List all); - - List saveBreeding(List all); - - List saveExchange(List all); - void refreshMetadataMethods(); long countDatasets(FaoInstitute faoInstitute); void writeAccessions(AppliedFilters filters, OutputStream outputStream) throws IOException; - List saveAliases(List aliases); - - List removeAliases(List aliases); - - void upsertAliases(long accessionId, String acceNames, String otherIds); - - Set removeAliases(Set toRemove); - List listAccessionsGeo(Set copy); List removeAccessions(FaoInstitute institute, List toDelete); @@ -220,22 +188,10 @@ public interface GenesysService { int countAccessions(AppliedFilters filters); - List saveRemarks(List toSaveRemarks); - - List removeRemarks(List toRemoveRemarks); - AccessionDetails getAccessionDetails(long accessionId); List getAccessionDetails(Set acceIds); - List removeCollecting(List toRemove); - - List removeGeo(List toRemove); - - List removeExchange(List toRemove); - - List removeBreeding(List toRemove); - List listAccessionsIds(Taxonomy2 taxonomy); List columnsAvailableForDisplay(); @@ -256,9 +212,7 @@ public interface GenesysService { public AccessionData accession = null; public AccessionGeo geo = null; public AccessionCollect collect = null; - public AccessionBreeding bred = null; public List names = null; - public AccessionExchange exch = null; public List remarks = null; public List sgsvDeposits = null; } @@ -271,16 +225,10 @@ public interface GenesysService { AccessionHistoric getHistoricAccession(UUID uuid); - PDCI loadPDCI(Long accessionId); - - PDCI updatePDCI(Long id); - PDCIStatistics statisticsPDCI(FaoInstitute faoInstitute); List loadPDCI(List batch); - List updatePDCI(Set ids); - PDCIStatistics statisticsPDCI(Organization organization); PhenoStatistics statisticsPheno(FaoInstitute faoInstitute); diff --git a/src/main/java/org/genesys2/server/service/TaxonomyService.java b/src/main/java/org/genesys2/server/service/TaxonomyService.java index 641d9cf4dd6e40a902dfe6c7d7f24b081f33b1ec..ba90db45d47ed4c98113780b42e0d1fa8beaa9a9 100644 --- a/src/main/java/org/genesys2/server/service/TaxonomyService.java +++ b/src/main/java/org/genesys2/server/service/TaxonomyService.java @@ -48,4 +48,6 @@ public interface TaxonomyService { List autocompleteSubtaxa(String ac, Crop crop, List genus, List species); void cleanupTaxonomies(); + + Taxonomy2 ensureTaxonomy(Taxonomy2 source); } diff --git a/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java index 0cdccc43928c8fadb842abbbe8dda68d339048bd..a3d7f04d9d0187ce59cc9beadfe4dd6e8aa560c4 100644 --- a/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java @@ -26,7 +26,7 @@ import org.apache.commons.lang.ArrayUtils; import org.genesys.blocks.security.SecurityContextUtil; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.model.impl.User; import org.genesys2.server.persistence.domain.AccessionListRepository; import org.genesys2.server.service.AccessionListService; diff --git a/src/main/java/org/genesys2/server/service/impl/BatchRESTServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/BatchRESTServiceImpl.java deleted file mode 100644 index b079aeb19d190cbe2bb25b300e9b30d563b66e85..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/service/impl/BatchRESTServiceImpl.java +++ /dev/null @@ -1,1217 +0,0 @@ -/** - * Copyright 2015 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.genesys2.server.service.impl; - -import static org.genesys2.util.NumberUtils.areEqual; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Predicate; -import org.apache.commons.lang3.StringUtils; -import org.genesys.glis.v1.TermConstants; -import org.genesys.glis.v1.api.GenesysApi; -import org.genesys.glis.v1.model.UpdateTargets; -import org.genesys.glis.v1.model.UpdatedTarget; -import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.genesys.AccessionAlias; -import org.genesys2.server.model.genesys.AccessionAlias.AliasType; -import org.genesys2.server.model.genesys.AccessionBreeding; -import org.genesys2.server.model.genesys.AccessionCollect; -import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.genesys.AccessionExchange; -import org.genesys2.server.model.genesys.AccessionGeo; -import org.genesys2.server.model.genesys.AccessionId; -import org.genesys2.server.model.genesys.AccessionRemark; -import org.genesys2.server.model.genesys.Taxonomy2; -import org.genesys2.server.model.impl.Country; -import org.genesys2.server.model.impl.Crop; -import org.genesys2.server.model.impl.FaoInstitute; -import org.genesys2.server.model.json.Api1Constants; -import org.genesys2.server.persistence.domain.AccessionRepository; -import org.genesys2.server.service.AccessionOpResponse; -import org.genesys2.server.service.AccessionOpResponse.UpsertResult; -import org.genesys2.server.service.BatchRESTService; -import org.genesys2.server.service.CropService; -import org.genesys2.server.service.GenesysService; -import org.genesys2.server.service.GeoService; -import org.genesys2.server.service.InstituteService; -import org.genesys2.server.service.OrganizationService; -import org.genesys2.server.service.TaxonomyService; -import org.genesys2.server.servlet.controller.rest.PleaseRetryException; -import org.genesys2.server.servlet.controller.rest.model.AccessionAliasJson; -import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; -import org.genesys2.server.servlet.controller.rest.model.AccessionNamesJson; -import org.genesys2.util.DOIUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class BatchRESTServiceImpl implements BatchRESTService { - - private final Logger LOG = LoggerFactory.getLogger(getClass()); - - @Autowired - GenesysService genesysService; - - @Autowired - GeoService geoService; - - @Autowired - TaxonomyService taxonomyService; - - @Autowired - CropService cropService; - - @Autowired - OrganizationService organizationService; - - @Autowired - InstituteService instituteService; - - @Autowired - AccessionRepository accessionRepository; - - @Autowired - private TaxonomyManager taxonomyManager; - - @Autowired(required = false) - private GenesysApi glisGenesysApi; - - @Override - // Read-only, everything happens in manager - @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')") - public void ensureTaxonomies(FaoInstitute institute, Map batch) throws RESTApiException { - for (final AccessionHeaderJson dataJson : batch.keySet()) { - final ObjectNode accnJson = batch.get(dataJson); - - final Taxonomy2 current = new Taxonomy2(); - // Load JSON values into "current" - current.setGenus(stringIfProvided(accnJson.get(Api1Constants.Accession.GENUS), current.getGenus())); - current.setGenus(stringIfProvided(accnJson.get(Api1Constants.Accession.GENUS_NEW), current.getGenus())); - current.setSpecies(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SPECIES), current.getSpecies()), "sp.")); - current.setSpAuthor(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SPAUTHOR), current.getSpAuthor()), StringUtils.EMPTY)); - current.setSubtaxa(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SUBTAXA), current.getSubtaxa()), StringUtils.EMPTY)); - current.setSubtAuthor(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SUBTAUTHOR), current.getSubtAuthor()), StringUtils.EMPTY)); - - if (current.getGenus() == null) { - throw new RESTApiException("'genus' must be provided. Offending JSON = " + accnJson.toString()); - } - - if (current.getGenus().contains("sp.")) { - throw new RESTApiException("'genus' cannot contain 'sp.' text. Offending JSON = " + accnJson.toString()); - } - - // Sanitize - sanitizeTaxonomy(current); - - LOG.trace("Ensuring {}", current); - - Taxonomy2 ensuredTaxonomy = null; - try { - ensuredTaxonomy = taxonomyService.find(current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - } catch (Throwable e) { - LOG.warn("*** lower(t.genus)=lower({}) and lower(t.species)=lower({}) and lower(t.spauthor)=lower({}) and lower(t.subtaxa)=lower({}) and lower(subtauthor)=lower({})", - current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - } - if (ensuredTaxonomy == null) { - LOG.warn("Adding new taxonomy: {}", current); - ensuredTaxonomy = taxonomyManager.ensureTaxonomy2(current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - LOG.info("Registered: {}", ensuredTaxonomy); - - ensuredTaxonomy = taxonomyService.find(current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - - if (ensuredTaxonomy == null) { - throw new PleaseRetryException("Something is wrong with taxonomyManager for " + current.toString()); - } - } - } - } - - /** - * Sanitize incoming taxonomy record - */ - private void sanitizeTaxonomy(Taxonomy2 taxonomy) { - if (taxonomy == null) { - return; - } - - if ("sp".equalsIgnoreCase(taxonomy.getSpecies())) { - taxonomy.setSpecies("sp."); - } - } - - @Override - @Transactional - @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')") - public List upsertAccessionData(FaoInstitute institute, Map batch) throws RESTApiException { - LOG.info("Batch processing {} entries for {}", batch.size(), institute.getCode()); - - // Modify date - Date modifyDate = new Date(); - - final boolean useUniqueAcceNumbs = institute.hasUniqueAcceNumbs(); - - final List upsertResponses = new ArrayList(); - - final List toSave = new ArrayList(); - final List toSaveColl = new ArrayList(); - final List toRemoveColl = new ArrayList(); - final List toSaveGeo = new ArrayList(); - final List toRemoveGeo = new ArrayList(); - final List toSaveBreed = new ArrayList(); - final List toRemoveBreed = new ArrayList(); - final List toSaveExch = new ArrayList(); - final List toRemoveExch = new ArrayList(); - final List toSaveRemarks = new ArrayList(); - final List toRemoveRemarks = new ArrayList(); - - final Map acceNames = new HashMap(); - final Map otherNumbs = new HashMap(); - final Map donorNumbs = new HashMap(); - final Map collNumbs = new HashMap(); - - List loaded = null; - - try { - loaded = accessionRepository.find(institute, batch.keySet()); - } catch (NonUniqueAccessionException e) { - LOG.warn(e.getMessage()); - throw new RESTApiException(e.getMessage()); - } - - for (final AccessionHeaderJson dataJson : batch.keySet()) { - LOG.trace("Loading accession {}", dataJson); - - AccessionOpResponse upsertResponse = new AccessionOpResponse(dataJson.instCode, dataJson.acceNumb, dataJson.genus); - upsertResponses.add(upsertResponse); - UpsertResult upsertResult = null; - - if (!institute.getCode().equals(dataJson.instCode)) { - throw new RESTApiException("Accession does not belong to instCode=" + institute.getCode() + " acn=" + dataJson); - } - - Accession accession = loaded.stream().filter(a -> { - if (StringUtils.isNotBlank(a.getDoi())) { - if (a.getDoi().equals(dataJson.doi)) - return true; - } - - if (useUniqueAcceNumbs) { - return a.getAccessionName().equalsIgnoreCase(dataJson.acceNumb); - } else { - return a.getAccessionName().equalsIgnoreCase(dataJson.acceNumb) && a.getTaxonomy().getGenus().equalsIgnoreCase(dataJson.genus); - } - }).findFirst().orElse(null); - - final ObjectNode accnJson = batch.get(dataJson); - - if (accession == null) { - if (LOG.isDebugEnabled()) - LOG.debug("New accession {}", dataJson); - - accession = new Accession(); - accession.setAccessionId(new AccessionId()); - - accession.setInstitute(institute); - accession.setDoi(dataJson.doi); - accession.setAccessionName(dataJson.acceNumb); - - if (accnJson.get(Api1Constants.Accession.GENUS) == null && accnJson.get(Api1Constants.Accession.GENUS_NEW) == null) { - throw new RESTApiException("Cannot create new accession without specifying genus. Offending JSON = " + accnJson.toString()); - } - - upsertResult = new UpsertResult(UpsertResult.Type.INSERT); - - } else { - if (LOG.isTraceEnabled()) - LOG.trace("*** Updating accession {}", dataJson); - - upsertResult = new UpsertResult(UpsertResult.Type.UPDATE); - upsertResult.setUUID(accession.getUuid()); - } - - if (accession.getAccessionId().isPersisted() || useUniqueAcceNumbs && accnJson.get(Api1Constants.Accession.GENUS) != null || accnJson.get( - Api1Constants.Accession.GENUS_NEW) != null || accnJson.get(Api1Constants.Accession.SPECIES) != null || accnJson.get(Api1Constants.Accession.SPAUTHOR) != null || accnJson - .get(Api1Constants.Accession.SUBTAXA) != null || accnJson.get(Api1Constants.Accession.SUBTAUTHOR) != null) { - - updateTaxonomy(accession, accnJson); - } - - updateDoi(accession, accnJson.get(Api1Constants.Accession.DOI)); - if (accession.getDoi() != null) { - // Update ACCENUMB if DOI is provided - accession.setAccessionName(dataJson.acceNumb); - } - updateCrop(accession, accnJson.get(Api1Constants.Accession.CROPNAME)); - updateAcceNumb(accession, accnJson.get(Api1Constants.Accession.ACCENUMB_NEW)); - updateOrgCty(accession, accnJson.get(Api1Constants.Accession.ORIGCTY)); - updateUuid(accession, accnJson.get(Api1Constants.Accession.UUID)); - updateRemarks(accession, accnJson.get(Api1Constants.Accession.REMARKS), toSaveRemarks, toRemoveRemarks); - updateStorage(accession, accnJson); - - // TODO Move other setters to methods - - JsonNode value = accnJson.get(Api1Constants.Accession.ACQDATE); - if (value != null) { - final String acqDate = value.isNull() ? null : value.textValue(); - accession.setAcquisitionDate(acqDate); - } - value = accnJson.get(Api1Constants.Accession.MLSSTAT); - if (value != null) { - if (!value.isNull() && !value.isBoolean()) { - throw new RESTApiDataTypeException("If provided, 'mlsStat' must be a boolean"); - } - final Boolean inMls = value.isNull() ? null : value.asBoolean(); - accession.setMlsStatus(inMls); - } - value = accnJson.get(Api1Constants.Accession.INTRUST); - if (value != null) { - if (!value.isNull() && !value.isBoolean()) { - throw new RESTApiDataTypeException("If provided, 'inTrust' must be a boolean"); - } - final Boolean inTrust = value.isNull() ? null : value.asBoolean(); - accession.setInTrust(inTrust); - } - value = accnJson.get(Api1Constants.Accession.AVAILABLE); - if (value != null) { - if (!value.isNull() && !value.isBoolean()) { - throw new RESTApiDataTypeException("If provided, 'available' must be a boolean"); - } - final Boolean availability = value.isNull() ? null : value.asBoolean(); - accession.setAvailability(availability); - } - value = accnJson.get(Api1Constants.Accession.HISTORIC); - if (value != null) { - if (value.isNull() || !value.isBoolean()) { - throw new RESTApiDataTypeException("If provided, 'historic' must be a boolean"); - } - final boolean historic = value.asBoolean(); - accession.setHistoric(historic); - } - - value = accnJson.get(Api1Constants.Accession.ACCENAME); - if (value != null) { - acceNames.put(accession.getAccessionId(), toMcpdArray(accnJson, Api1Constants.Accession.ACCENAME)); - } - - value = accnJson.get(Api1Constants.Accession.OTHERNUMB); - if (value != null) { - otherNumbs.put(accession.getAccessionId(), toMcpdArray(accnJson, Api1Constants.Accession.OTHERNUMB)); - } - - value = accnJson.get(Api1Constants.Accession.SAMPSTAT); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'sampStat' must be a number"); - } - final Integer sampStat = value.isNull() || !value.isNumber() ? null : value.asInt(); - accession.setSampleStatus(sampStat); - } - - value = accnJson.get(Api1Constants.Accession.DUPLSITE); - if (value != null) { - final String duplSite = arrayToString(toMcpdArray(accnJson, Api1Constants.Accession.DUPLSITE)); - accession.setDuplSite(StringUtils.defaultIfBlank(duplSite, null)); - } - - value = accnJson.get(Api1Constants.Accession.ACCEURL); - if (value != null) { - if (!value.isNull() && !value.isTextual()) { - throw new RESTApiDataTypeException("If provided, 'acceUrl' must be a String"); - } - final String acceUrl = value.isNull() ? null : value.textValue(); - accession.setAcceUrl(acceUrl); - } - - if (accnJson.has(Api1Constants.Accession.COLL)) { - final ObjectNode collecting = (ObjectNode) accnJson.get(Api1Constants.Accession.COLL); - AccessionCollect accnColl = genesysService.getAccessionCollect(accession.getAccessionId()); - if (accnColl == null) { - accnColl = new AccessionCollect(); - accnColl.setAccession(accession.getAccessionId()); - } - value = collecting.get(Api1Constants.Collecting.COLLDATE); - if (value != null) { - accnColl.setCollDate(StringUtils.defaultIfBlank(value.textValue(), null)); - } - value = collecting.get(Api1Constants.Collecting.COLLNUMB); - if (value != null) { - accnColl.setCollNumb(StringUtils.defaultIfBlank(value.textValue(), null)); - collNumbs.put(accession.getAccessionId(), toMcpdArray(collecting, Api1Constants.Collecting.COLLNUMB)); - } - value = collecting.get(Api1Constants.Collecting.COLLSRC); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'collSrc' must be a number"); - } - accnColl.setCollSrc(value.isNumber() ? value.intValue() : null); - } - value = collecting.get(Api1Constants.Collecting.COLLCODE); - if (value != null) { - accnColl.setCollCode(arrayToString(toMcpdArray(collecting, Api1Constants.Collecting.COLLCODE))); - } - value = collecting.get(Api1Constants.Collecting.COLLNAME); - if (value != null) { - accnColl.setCollName(arrayToString(toMcpdArray(collecting, Api1Constants.Collecting.COLLNAME))); - } - value = collecting.get(Api1Constants.Collecting.COLLINSTADDRESS); - if (value != null) { - accnColl.setCollInstAddress(arrayToString(toMcpdArray(collecting, Api1Constants.Collecting.COLLINSTADDRESS))); - } - value = collecting.get(Api1Constants.Collecting.COLLSITE); - if (value != null) { - accnColl.setCollSite(StringUtils.defaultIfBlank(value.textValue(), null)); - } - value = collecting.get(Api1Constants.Collecting.COLLMISSID); - if (value != null) { - accnColl.setCollMissId(StringUtils.defaultIfBlank(value.textValue(), null)); - } - - if (!accnColl.isEmpty()) { - toSaveColl.add(accnColl); - } else if (accnColl.isPersisted()) { - toRemoveColl.add(accnColl); - } - } - - if (accnJson.has(Api1Constants.Accession.GEO)) { - final ObjectNode geo = (ObjectNode) accnJson.get(Api1Constants.Accession.GEO); - AccessionGeo accnGeo = genesysService.getAccessionGeo(accession.getAccessionId()); - if (accnGeo == null) { - accnGeo = new AccessionGeo(); - accnGeo.setAccession(accession.getAccessionId()); - } - value = geo.get(Api1Constants.Geo.LATITUDE); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'latitude' must be a number"); - } - accnGeo.setLatitude(value.isNumber() ? value.asDouble() : null); - } - value = geo.get(Api1Constants.Geo.LONGITUDE); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'longitude' must be a number"); - } - accnGeo.setLongitude(value.isNumber() ? value.asDouble() : null); - } - value = geo.get(Api1Constants.Geo.ELEVATION); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'elevation' must be a number"); - } - accnGeo.setElevation(value.isNumber() ? value.asDouble() : null); - } - value = geo.get(Api1Constants.Geo.COORDUNCERT); - if (value != null) { - if (!value.isNull() && !value.isNumber()) { - throw new RESTApiDataTypeException("If provided, 'coordUncert' must be a number"); - } - accnGeo.setUncertainty(value.isNumber() ? value.asDouble() : null); - } - value = geo.get(Api1Constants.Geo.COORDDATUM); - if (value != null) { - accnGeo.setDatum(StringUtils.defaultIfBlank(value.textValue(), null)); - } - value = geo.get(Api1Constants.Geo.GEOREFMETH); - if (value != null) { - accnGeo.setMethod(StringUtils.defaultIfBlank(value.textValue(), null)); - } - if (!accnGeo.isEmpty()) { - toSaveGeo.add(accnGeo); - } else if (accnGeo.isPersisted()) { - toRemoveGeo.add(accnGeo); - } - } - - if (accnJson.has(Api1Constants.Accession.BREDCODE) || accnJson.has(Api1Constants.Accession.ANCEST)) { - AccessionBreeding accnBred = genesysService.getAccessionBreeding(accession.getAccessionId()); - if (accnBred == null) { - accnBred = new AccessionBreeding(); - accnBred.setAccession(accession.getAccessionId()); - } - value = accnJson.get(Api1Constants.Accession.BREDCODE); - if (value != null) { - accnBred.setBreederCode(arrayToString(toMcpdArray(accnJson, Api1Constants.Accession.BREDCODE))); - } - value = accnJson.get(Api1Constants.Accession.ANCEST); - if (value != null) { - accnBred.setPedigree(StringUtils.defaultIfBlank(value.textValue(), null)); - } - if (!accnBred.isEmpty()) { - toSaveBreed.add(accnBred); - } else if (accnBred.isPersisted()) { - toRemoveBreed.add(accnBred); - } - } - - if (accnJson.has(Api1Constants.Accession.DONORCODE) || accnJson.has(Api1Constants.Accession.DONORNUMB) || accnJson.has(Api1Constants.Accession.DONORNAME)) { - AccessionExchange accnExch = genesysService.getAccessionExchange(accession.getAccessionId()); - if (accnExch == null) { - accnExch = new AccessionExchange(); - accnExch.setAccession(accession.getAccessionId()); - } - value = accnJson.get(Api1Constants.Accession.DONORCODE); - if (value != null) { - accnExch.setDonorInstitute(StringUtils.defaultIfBlank(value.textValue(), null)); - } - value = accnJson.get(Api1Constants.Accession.DONORNUMB); - if (value != null) { - accnExch.setAccNumbDonor(StringUtils.defaultIfBlank(value.textValue(), null)); - } - value = accnJson.get(Api1Constants.Accession.DONORNAME); - if (value != null) { - accnExch.setDonorName(StringUtils.defaultIfBlank(value.textValue(), null)); - } - - final ArrayNode donorNumb = accnJson.arrayNode(); - String donorNumbStr = StringUtils.EMPTY; - if (accnExch.getDonorInstitute() != null) { - donorNumbStr = accnExch.getDonorInstitute(); - } - - if (accnExch.getAccNumbDonor() != null) { - donorNumb.add(donorNumbStr + ":" + accnExch.getAccNumbDonor()); - donorNumbs.put(accession.getAccessionId(), donorNumb); - } else { - donorNumbs.put(accession.getAccessionId(), null); - } - - if (!accnExch.isEmpty()) { - toSaveExch.add(accnExch); - } else if (accnExch.isPersisted()) { - toRemoveExch.add(accnExch); - } - } - - accession.setLastModifiedDate(modifyDate); - toSave.add(accession); - // Set upsert result - upsertResponse.setResult(upsertResult); - } - - List savedData = null; - - if (toSave.size() > 0) { - LOG.info("Storing {} accessions.", toSave.size()); - List saved = genesysService.saveAccessions(institute, toSave); - - // Iterate savedData to extract UUIDs - upsertResponses.stream().forEach(response -> { - Accession accession = saved.stream().filter(a -> useUniqueAcceNumbs ? (a.getAccessionName().equalsIgnoreCase(response.getAcceNumb())) - : (a.getAccessionName().equalsIgnoreCase(response.getAcceNumb()) && a.getTaxonomy().getGenus().equalsIgnoreCase(response.getGenus()))).findFirst().orElse(null); - - UpsertResult result = response.getResult(); - if (accession != null) { - if (result.getUuid() == null) { - result.setAction(UpsertResult.Type.INSERT); - } else { - result.setAction(UpsertResult.Type.UPDATE); - } - result.setUUID(accession.getUuid()); - } - }); - - savedData = saved; - } - - if (toSaveColl.size() > 0) { - genesysService.saveCollecting(toSaveColl); - } - if (toRemoveColl.size() > 0) { - genesysService.removeCollecting(toRemoveColl); - } - - if (toSaveGeo.size() > 0) { - genesysService.saveGeo(toSaveGeo); - } - if (toRemoveGeo.size() > 0) { - genesysService.removeGeo(toRemoveGeo); - } - - if (toSaveBreed.size() > 0) { - genesysService.saveBreeding(toSaveBreed); - } - if (toRemoveBreed.size() > 0) { - genesysService.removeBreeding(toRemoveBreed); - } - - if (toSaveExch.size() > 0) { - genesysService.saveExchange(toSaveExch); - } - if (toRemoveExch.size() > 0) { - genesysService.removeExchange(toRemoveExch); - } - - if (toSaveRemarks.size() > 0) { - genesysService.saveRemarks(toSaveRemarks); - } - if (toRemoveRemarks.size() > 0) { - genesysService.removeRemarks(toRemoveRemarks); - } - - updateAccessionAliases(acceNames, AliasType.ACCENAME, false); - updateAccessionAliases(otherNumbs, AliasType.OTHERNUMB, true); - updateAccessionAliases(donorNumbs, AliasType.DONORNUMB, true); - updateAccessionAliases(collNumbs, AliasType.COLLNUMB, false); - - LOG.info("Done saving data"); - - // Update PDCI - genesysService.updatePDCI(savedData.stream().map(a -> a.getId()).collect(Collectors.toSet())); - LOG.debug("Done updating PDCI"); - - // Update GLIS - if (glisGenesysApi != null) { - UpdateTargets targets = new UpdateTargets(); - targets.addKwsItem(TermConstants.PASSPORT_DATA); - savedData.stream().map(a -> a.getDoi()).filter(doi -> doi != null).forEach(doi -> targets.addDoisItem(doi)); - - if (targets.getDois() != null && targets.getDois().size() > 0) { - try { - LOG.debug("Updating GLIS for {} accessions with DOIs", targets.getDois().size()); - List glisResponse = glisGenesysApi.registerGenesysAsTarget(targets); - glisResponse.forEach(updatedTarget -> { - if (StringUtils.equals("OK", updatedTarget.getResult())) { - LOG.trace("GLIS for {} result={}", updatedTarget.getDoi(), updatedTarget.getResult()); - } else if (StringUtils.equals("KO", updatedTarget.getResult())) { - LOG.info("GLIS for {} result={} msg={}", updatedTarget.getDoi(), updatedTarget.getResult()); - } - }); - } catch (Throwable e) { - LOG.error("Error updating GLIS targets: {}", e.getMessage(), e); - } - } - } - - return upsertResponses; - } - - /** - * Update accession DOI in Genesys. If DOI exists in Genesys, it must be provided by the client and must match current value. If DOI does not exist in Genesys, - * it will be registered. - * - * @param accession - * @param value - * @return - * @throws RESTApiException - */ - private boolean updateDoi(AccessionData accession, JsonNode value) throws RESTApiException { - if (accession.getDoi() == null) { - // Genesys does not have DOI for the accession - if (value != null) { - if (value.isTextual()) { - if (DOIUtils.isValidDoi(value.textValue())) { - accession.setDoi(value.textValue()); - return true; - } else { - throw new RESTApiException("Invalid DOI value " + value.textValue()); - } - } else { - throw new RESTApiDataTypeException("DOI must be a string."); - } - } - return false; - } else { - // Genesys has DOI for the accession - if (value == null || !value.isTextual()) { - throw new RESTApiException("DOI must be resubmitted for accession with DOI " + accession.getDoi() + " ACCENUMB=" + accession.getAccessionName()); - } else { - if (StringUtils.equals(accession.getDoi(), value.textValue())) { - return false; - } else { - throw new RESTApiException("Provided DOI does not match existing DOI " + accession.getDoi() + " ACCENUMB=" + accession.getAccessionName()); - } - } - } - } - - private boolean updateCrop(Accession accession, JsonNode value) throws RESTApiDataTypeException { - if (value != null) { - if (value.isNull()) { - if (!StringUtils.equals(null, accession.getCropName())) { - accession.setCropName(null); - accession.setCrop(null); - return true; - } - } - - if (!value.isTextual()) { - throw new RESTApiDataTypeException("cropName must be a String"); - } - - final String cropName = StringUtils.trimToNull(value.textValue()); - accession.setCropName(cropName); - - if (StringUtils.isNotBlank(cropName)) { - // has cropName, check if needs updating - Crop newCrop = cropService.getCrop(cropName); - if (accession.getCrop() == null || newCrop == null || (newCrop != null && accession.getCrop().getId() != newCrop.getId())) { - accession.setCrop(newCrop); - return true; - } - } else if (accession.getCrop() != null) { - // blank but has crop assigned - accession.setCrop(null); - return true; - } - } - return false; - } - - private boolean updateStorage(AccessionData accession, ObjectNode accnJson) throws RESTApiDataTypeException { - boolean updated = false; - - // MUST BE ARRAY - if (accnJson.has(Api1Constants.Accession.STORAGE)) { - updateAccessionStorage(accession, toMcpdArray(accnJson, Api1Constants.Accession.STORAGE)); - } - - return updated; - } - - private static boolean updateAccessionStorage(AccessionData accession, ArrayNode arr) { - boolean updated = false; - - List as = accession.getStoRage(); - List toRemove = new ArrayList(as); - - // Sometimes { "storage": null } is provided. - if (arr != null) { - Iterator it = arr.elements(); - - while (it.hasNext()) { - JsonNode storageElem = it.next(); - int stor = Integer.parseInt(storageElem.asText()); - if (!as.contains(stor)) { - updated = true; - as.add(stor); - } else { - // Cast needed to remove the object - toRemove.remove((Integer) stor); - } - } - } - - if (toRemove.size() > 0) { - as.removeAll(toRemove); - updated = true; - } - - return updated; - } - - private boolean updateRemarks(AccessionData accession, JsonNode jsonNode, List toSaveRemarks, List toRemoveRemarks) - throws RESTApiDataTypeException { - if (jsonNode == null || jsonNode.isNull()) { - return false; - } - - if (!jsonNode.isArray()) { - throw new RESTApiDataTypeException("'remarks' must be an array"); - } - ArrayNode arr = (ArrayNode) jsonNode; - Iterator it = arr.elements(); - List existingRemarks = genesysService.listAccessionRemarks(accession.getAccessionId()); - - if (existingRemarks != null) - toRemoveRemarks.addAll(existingRemarks); - - while (it.hasNext()) { - JsonNode n = it.next(); - if (n == null || n.isNull()) { - continue; - } - - String remarkText = n.textValue(); - if (StringUtils.isBlank(remarkText)) - continue; - - String fieldName = null, remark = null; - int pos = remarkText.indexOf(':'); - if (pos >= 0 && !remarkText.substring(0, pos).trim().contains(" ")) { - String[] mcpdRemark = remarkText.split(":", 2); - if (mcpdRemark.length == 2) { - fieldName = StringUtils.defaultIfBlank(mcpdRemark[0].trim(), null); - remark = StringUtils.defaultIfBlank(mcpdRemark[1].trim(), null); - } else { - remark = StringUtils.defaultIfBlank(mcpdRemark[0].trim(), null); - } - } else { - remark = StringUtils.defaultIfBlank(remarkText, null); - } - - if (remark == null && fieldName == null) { - continue; - } - - LOG.trace("fieldName={} remark={}", fieldName, remark); - - AccessionRemark ar = findRemark(existingRemarks, fieldName, remark); - if (ar == null) { - ar = new AccessionRemark(); - ar.setAccession(accession.getAccessionId()); - ar.setFieldName(fieldName); - ar.setRemark(remark); - toSaveRemarks.add(ar); - } else { - toRemoveRemarks.remove(ar); - } - } - - return false; - } - - private AccessionRemark findRemark(List existingRemarks, String fieldName, String remark) { - if (existingRemarks == null) - return null; - for (AccessionRemark ar : existingRemarks) { - if (StringUtils.equals(ar.getFieldName(), fieldName) && StringUtils.equals(ar.getRemark(), remark)) - return ar; - } - return null; - } - - private boolean updateAcceNumb(AccessionData accession, JsonNode value) throws RESTApiDataTypeException, RESTApiException { - if (value != null) { - // Rename is possible only if accession exists - if (!accession.getAccessionId().isPersisted()) { - throw new RESTApiException("Cannot rename a new accession entry"); - } - - if (!value.isTextual()) { - throw new RESTApiDataTypeException("newAcceNumb must be a String"); - } - - if (value.isNull()) { - throw new RESTApiValueException("newAcceNumb cannot be null"); - } - - final String newAcceNumb = value.textValue(); - if (!StringUtils.equals(newAcceNumb, accession.getAccessionName())) { - accession.setAccessionName(newAcceNumb); - return true; - } - } - return false; - } - - private boolean updateOrgCty(AccessionData accession, JsonNode value) throws RESTApiDataTypeException, RESTApiValueException { - if (value != null) { - if (!value.isNull() && !value.isTextual()) { - throw new RESTApiDataTypeException("orgCty must be a String"); - } - - final String orgCty = value.textValue(); - if (!StringUtils.equals(orgCty, accession.getOrigin())) { - Country country = null; - if (orgCty != null) { - country = geoService.getCountry(orgCty); - if (country == null) { - // TODO this should become a warning - // throw new - // RESTApiValueException("No country with ISO3 code: " + - // orgCty); - } - } - accession.setCountryOfOrigin(country); - return true; - } - } - return false; - } - - private boolean updateUuid(AccessionData accession, JsonNode value) throws RESTApiValueException { - // We don't allow UUID updates - /* - * if (value != null) { final UUID uuid = value.isNull() ? null : UUID.fromString(value.textValue()); if (accession.getUuid() == null && uuid != null) { - * accession.getAccessionId().setUuid(uuid); return true; } } - */ - // No change - return false; - } - - /** - * Inspect incoming JSON and change taxonomy if required - * - * @param accession - * @param accnJson - * - * @return true if taxonomy was modified - * @throws RESTApiException - */ - private boolean updateTaxonomy(AccessionData accession, JsonNode accnJson) throws RESTApiException { - if (accession.getTaxonomy() != null && (!accnJson.has(Api1Constants.Accession.GENUS_NEW) && !accnJson.has(Api1Constants.Accession.SPECIES))) { - if (LOG.isDebugEnabled()) - LOG.debug("Not updating taxonomy without newGenus or species data"); - - return false; - } - - // Load JSON values into "current" - final Taxonomy2 current = new Taxonomy2(); - current.setGenus(stringIfProvided(accnJson.get(Api1Constants.Accession.GENUS), current.getGenus())); - current.setGenus(stringIfProvided(accnJson.get(Api1Constants.Accession.GENUS_NEW), current.getGenus())); - current.setSpecies(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SPECIES), StringUtils.EMPTY), "sp.")); - current.setSpAuthor(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SPAUTHOR), StringUtils.EMPTY), StringUtils.EMPTY)); - current.setSubtaxa(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SUBTAXA), StringUtils.EMPTY), StringUtils.EMPTY)); - current.setSubtAuthor(StringUtils.defaultIfBlank(stringIfProvided(accnJson.get(Api1Constants.Accession.SUBTAUTHOR), StringUtils.EMPTY), StringUtils.EMPTY)); - - sanitizeTaxonomy(current); - - Taxonomy2 ensuredTaxonomy = null; - try { - ensuredTaxonomy = taxonomyService.find(current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - } catch (Throwable e) { - LOG.warn("*** lower(t.genus)=lower({}) and lower(t.species)=lower({}) and lower(t.spauthor)=lower({}) and lower(t.subtaxa)=lower({}) and lower(subtauthor)=lower({})", - current.getGenus(), current.getSpecies(), current.getSpAuthor(), current.getSubtaxa(), current.getSubtAuthor()); - } - - if (ensuredTaxonomy == null) { - LOG.warn("Could not find taxonomy for upsert {}", current); - // throw new PleaseRetryException("Could not find taxonomy " + - // current.getTaxonName()); - throw new RESTApiException("Could not find taxonomy. Provide GENUS, SPECIES, SPAUTHOR, SUBTAXA and SUBTAUTHOR fields"); - } - - if (!ensuredTaxonomy.sameAs(accession.getTaxonomy())) { - accession.setTaxonomy(ensuredTaxonomy); - return true; - } else { - return false; - } - } - - /** - * Return - * - * @param jsonNode - * @param currentValue - * @return - * @throws RESTApiDataTypeException - */ - private String stringIfProvided(JsonNode jsonNode, String currentValue) throws RESTApiException { - if (jsonNode != null) { - if (!jsonNode.isNull() && !jsonNode.isTextual()) { - // We expect a String node - throw new RESTApiDataTypeException("Not a String"); - } - if (jsonNode.isNull()) { - return null; - } - return StringUtils.defaultIfBlank(jsonNode.textValue().trim(), currentValue); - } - return currentValue; - } - - private String arrayToString(ArrayNode arr) { - if (arr == null || arr.isNull()) { - return null; - } - - final StringBuffer mcpdArr = new StringBuffer(20); - - for (final JsonNode st : arr) { - if (st != null && !st.isNull()) { - if (mcpdArr.length() > 0) { - mcpdArr.append(";"); - } - mcpdArr.append(st.asText()); - } - } - - return StringUtils.defaultIfBlank(mcpdArr.toString(), null); - } - - /** - * Converts textValue to JSON array node if required. - * - * @param accnJson - * @param key - * @return - * @throws RESTApiDataTypeException - */ - private ArrayNode toMcpdArray(ObjectNode accnJson, String key) throws RESTApiDataTypeException { - final JsonNode value = accnJson.get(key); - - if (value == null || value.isNull()) { - return null; - } else if (value.isArray()) { - return (ArrayNode) value; - } else if (value.isTextual()) { - final ArrayNode arr = accnJson.arrayNode(); - for (final String s : value.textValue().split("[,;]")) { - if (StringUtils.isBlank(s)) { - continue; - } - arr.add(s.trim()); - } - return arr; - } else { - throw new RESTApiDataTypeException("If provided, '" + key + "' must be an array"); - } - } - - /** - * Convert to {@link AccessionAlias} - * - * @param acceNames - * @param existingAliases - */ - private void updateAccessionAliases(Map acceNames, AliasType aliasType, boolean splitInstCode) { - final List toSave = new ArrayList(); - final List toRemove = new ArrayList(); - - for (final AccessionId accession : acceNames.keySet()) { - final List existingAliases = genesysService.listAccessionAliases(accession); - - final ArrayNode acceName = acceNames.get(accession); - final List aliases = new ArrayList(); - if (acceName != null) { - for (final JsonNode item : acceName) { - if (item.isTextual() && StringUtils.isNotBlank(item.textValue())) { - final AccessionAliasJson alias = new AccessionAliasJson(); - final String val = item.textValue().trim(); - if (splitInstCode && val.contains(":")) { - final String[] s = val.split(":", 2); - alias.usedBy = StringUtils.trimToNull(s[0]); - alias.name = StringUtils.trimToNull(s[1]); - } else { - alias.name = StringUtils.trimToNull(val); - } - alias.type = aliasType.getId(); - aliases.add(alias); - } - } - } - - // upsert aliases (send in a copy of the existing aliases list) - upsertAccessionAliases(accession, aliases, aliasType, toRemove, toSave, new ArrayList(existingAliases)); - } - - if (toSave.size() > 0) { - // LOG.info("Saving aliases count=" + toSave.size()); - genesysService.saveAliases(toSave); - } - if (toRemove.size() > 0) { - LOG.info("Removing aliases count={}", toRemove.size()); - genesysService.removeAliases(toRemove); - } - } - - @Override - @Transactional - @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')") - public List upsertAccessionNames(FaoInstitute institute, List batch) throws RESTApiException { - LOG.info("Batch processing {} entries for {}", batch.size(), institute); - - final List upsertResponses = new ArrayList(); - - final List toSave = new ArrayList(); - final List toRemove = new ArrayList(); - - for (final AccessionNamesJson dataJson : batch) { - AccessionOpResponse upsertResponse = new AccessionOpResponse(dataJson.instCode, dataJson.acceNumb, dataJson.genus); - upsertResponses.add(upsertResponse); - UpsertResult upsertResult = null; - - if (!institute.getCode().equals(dataJson.instCode)) { - throw new RESTApiException("Accession does not belong to instCode=" + institute.getCode() + " acn=" + dataJson); - } - - Accession accession = null; - try { - accession = genesysService.getAccession(dataJson); - } catch (NonUniqueAccessionException e) { - LOG.warn(e.getMessage()); - throw new RESTApiException(e.getMessage()); - } - - if (accession == null) { - LOG.warn("No such accession {}", dataJson); - upsertResponse.setError("No such asccession " + dataJson); - continue; - } else { - upsertResult = new UpsertResult(UpsertResult.Type.UPDATE); - upsertResult.setUUID(accession.getUuid()); - } - // LOG.info("Updating " + dataJson + " with=" + dataJson.aliases); - - final List aliases = dataJson.aliases; - final List existingAliases = genesysService.listAccessionAliases(accession.getAccessionId()); - upsertAccessionAliases(accession.getAccessionId(), aliases, null, toRemove, toSave, existingAliases); - - // Set upsert result - upsertResponse.setResult(upsertResult); - } - - if (toSave.size() > 0) { - LOG.info("Saving aliases for instCode={} count={}", institute.getCode(), toSave.size()); - genesysService.saveAliases(toSave); - } - if (toRemove.size() > 0) { - LOG.info("Removing aliases for instCode={} count={}", institute.getCode(), toRemove.size()); - genesysService.removeAliases(toRemove); - } - - return upsertResponses; - } - - private void upsertAccessionAliases(AccessionId accession, List aliases, final AliasType aliasType, List toRemove, - List toSave, Iterable existingAliases) { - - // Allows us to focus only on a particular alias type - if (aliasType != null) { - LOG.trace("Filtering accession aliases by {}", aliasType); - CollectionUtils.filter(existingAliases, new Predicate() { - @Override - public boolean evaluate(AccessionAlias alias) { - return areEqual(aliasType, alias.getAliasType()); - } - }); - } - - // Find aliases to remove - for (final AccessionAlias aa : existingAliases) { - if (null == CollectionUtils.find(aliases, new Predicate() { - - @Override - public boolean evaluate(AccessionAliasJson alias) { - return StringUtils.equals(alias.name, aa.getName()); - } - })) { - toRemove.add(aa); - } - } - // Add or update - for (final AccessionAliasJson aa : aliases) { - AccessionAlias accessionAlias = CollectionUtils.find(existingAliases, new Predicate() { - @Override - public boolean evaluate(AccessionAlias alias) { - return StringUtils.equals(alias.getName(), aa.name); - } - }); - - if (accessionAlias == null) { - accessionAlias = new AccessionAlias(); - accessionAlias.setAccession(accession); - } - - accessionAlias.setName(aa.name); - accessionAlias.setInstCode(StringUtils.trimToNull(aa.instCode)); - accessionAlias.setUsedBy(StringUtils.trimToNull(aa.usedBy)); - accessionAlias.setAliasType(aliasType != null ? aliasType : AliasType.getType(aa.type)); - - toSave.add(accessionAlias); - } - } - - @Override - @Transactional - @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'DELETE') or hasPermission(#institute, 'ADMINISTRATION')") - public List deleteAccessions(FaoInstitute institute, List batch) throws RESTApiException { - LOG.info("Batch deleting {} entries for {}", batch.size(), institute); - - final List upsertResponses = new ArrayList(); - final List toDelete = new ArrayList(batch.size()); - - for (final AccessionHeaderJson dataJson : batch) { - if (LOG.isDebugEnabled()) { - LOG.debug("Loading accession {}", dataJson); - } - - AccessionOpResponse upsertResponse = new AccessionOpResponse(dataJson.instCode, dataJson.acceNumb, dataJson.genus); - upsertResponses.add(upsertResponse); - UpsertResult upsertResult; - - if (!institute.getCode().equals(dataJson.instCode)) { - throw new RESTApiException("Accession does not belong to instCode=" + institute.getCode() + " acn=" + dataJson); - } - - Accession accession; - try { - accession = genesysService.getAccession(dataJson); - } catch (NonUniqueAccessionException e) { - LOG.warn(e.getMessage()); - throw new RESTApiException(e.getMessage()); - } - - if (accession != null) { - toDelete.add(accession); - upsertResult = new UpsertResult(UpsertResult.Type.DELETE); - upsertResult.setUUID(accession.getUuid()); - } else { - upsertResult = new UpsertResult(UpsertResult.Type.NOOP); - } - - upsertResponse.setResult(upsertResult); - } - - if (toDelete.size() > 0) { - genesysService.removeAccessions(institute, toDelete); - } - - return upsertResponses; - } - - @Override - @Transactional - @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'DELETE') or hasPermission(#institute, 'ADMINISTRATION')") - public int deleteAccessionsById(FaoInstitute institute, List batch) { - LOG.info("Batch deleting {} entries for {}", batch.size(), institute); - final List toDelete = new ArrayList(batch.size()); - - if (toDelete.size() > 0) { - genesysService.removeAccessions(institute, toDelete); - } - for (final Long accessionId : batch) { - - AccessionData accession; - - accession = genesysService.getAccession(accessionId.longValue()); - if (accession != null) { - if (!institute.getCode().equals(accession.getInstituteCode())) { - LOG.warn("Accession does not belong to instCode={} acn={}", institute.getCode(), accession.getAccessionId().getId()); - } else if (accession instanceof Accession) { - toDelete.add((Accession) accession); - } else { - LOG.warn("Not appropriate for delete operation: {}", accession.getClass()); - } - } - } - - if (toDelete.size() > 0) { - genesysService.removeAccessions(institute, toDelete); - } - return toDelete.size(); - } -} diff --git a/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java index 96625cea15eda6f525289d65c55074835aeccc3d..30d95892d49d68b9625e2fc4b82897f44b1de7aa 100644 --- a/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/DownloadServiceImpl.java @@ -27,8 +27,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; - -import com.opencsv.CSVWriter; +import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Cell; @@ -41,10 +40,8 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook; // import org.apache.poi.xssf.usermodel.XSSFHyperlink; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.genesys2.server.model.genesys.AccessionAlias; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.genesys.AccessionExchange; import org.genesys2.server.model.genesys.AccessionGeo; import org.genesys2.server.model.genesys.AccessionId; import org.genesys2.server.model.genesys.AccessionRemark; @@ -58,6 +55,7 @@ import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GenesysService.AllStuff; import org.genesys2.server.service.impl.FilterHandler.AppliedFilters; import org.genesys2.server.servlet.controller.JspHelper; +import org.genesys2.util.MCPDUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -69,6 +67,8 @@ import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.opencsv.CSVWriter; + @Service public class DownloadServiceImpl implements DownloadService { @@ -203,7 +203,7 @@ public class DownloadServiceImpl implements DownloadService { for (AllStuff all : alls) { Row row = sheet.createRow(i + 1); - writeMCPDRow(sheet, row, all.accession, all.geo, all.collect, all.bred, all.names, all.exch, all.remarks); + writeMCPDRow(sheet, row, all.accession, all.geo, all.collect, all.names, all.remarks); i++; } @@ -233,12 +233,12 @@ public class DownloadServiceImpl implements DownloadService { } } - private void writeMCPDRow(Sheet sheet, Row row, AccessionData accession, AccessionGeo geo, AccessionCollect collect, AccessionBreeding bred, List names, AccessionExchange exch, + private void writeMCPDRow(Sheet sheet, Row row, AccessionData accession, AccessionGeo geo, AccessionCollect collect, List names, List remarks) { // Process and write result row.createCell(COL_INSTCODE).setCellValue(accession.getInstitute().getCode()); - row.createCell(COL_ACCENUMB).setCellValue(accession.getAccessionName()); + row.createCell(COL_ACCENUMB).setCellValue(accession.getAccessionNumber()); if (collect != null) { createCell(row, COL_COLLNUMB, collect.getCollNumb()); @@ -250,10 +250,8 @@ public class DownloadServiceImpl implements DownloadService { createCell(row, COL_COLLDATE, collect.getCollDate()); } - if (bred != null) { - createCell(row, COL_BREDCODE, bred.getBreederCode()); - createCell(row, COL_ANCEST, bred.getPedigree()); - } + createCell(row, COL_BREDCODE, accession.getAccessionId().getBreederCode()); + createCell(row, COL_ANCEST, accession.getAncest()); Taxonomy2 taxonomy = accession.getTaxonomy(); if (taxonomy != null) { @@ -282,7 +280,7 @@ public class DownloadServiceImpl implements DownloadService { } - createCell(row, COL_SAMPSTAT, accession.getSampleStatus()); + createCell(row, COL_SAMPSTAT, accession.getSampStat()); if (StringUtils.isNotBlank(accession.getAcquisitionSource())) { Cell c = row.createCell(COL_COLLSRC); @@ -293,8 +291,8 @@ public class DownloadServiceImpl implements DownloadService { } } - createCell(row, COL_DUPLSITE, accession.getDuplSite()); - createCell(row, COL_STORAGE, accession.getStorage()); + createCell(row, COL_DUPLSITE, accession.getAccessionId().getDuplSite()); + createCell(row, COL_STORAGE, accession.getAccessionId().getStorage()); createCell(row, COL_MLSSTAT, accession.getMlsStatus()); if (names != null && names.size() > 0) { @@ -322,11 +320,9 @@ public class DownloadServiceImpl implements DownloadService { createCell(row, COL_OTHERNUMB, otherNumb); } - if (exch != null) { - createCell(row, COL_DONORCODE, exch.getDonorInstitute()); - createCell(row, COL_DONORNAME, exch.getDonorName()); - // row.createCell(COL_DONORNUMB).setCellValue(exch.getAccNumbDonor()); - } + createCell(row, COL_DONORCODE, accession.getDonorCode()); + createCell(row, COL_DONORNAME, accession.getDonorName()); + // row.createCell(COL_DONORNUMB).setCellValue(exch.getAccNumbDonor()); if (accession.getUuid() != null) { createCell(row, COL_UUID, accession.getUuid().toString()); @@ -338,7 +334,7 @@ public class DownloadServiceImpl implements DownloadService { // cell.setHyperlink(hypr); } - createCell(row, COL_HISTORIC, accession.getHistoric()); + createCell(row, COL_HISTORIC, accession.isHistoric()); if (StringUtils.isNotBlank(accession.getAcceUrl())) { createCell(row, COL_ACCEURL, accession.getAcceUrl()); @@ -379,6 +375,7 @@ public class DownloadServiceImpl implements DownloadService { } } + @Override @Transactional(readOnly = true) public void writeXlsxPDCI(final AppliedFilters filters, final OutputStream outputStream) throws IOException { @@ -555,6 +552,14 @@ public class DownloadServiceImpl implements DownloadService { return c; } + private Cell createCell(Row row, int column, Set values) { + if (values==null || values.isEmpty()) + return null; + Cell c = row.createCell(column); + c.setCellValue(MCPDUtil.toMcpdArray(values)); + return c; + } + private String addName(String otherNames, String name, String usedBy) { if (StringUtils.isBlank(name)) { return otherNames; diff --git a/src/main/java/org/genesys2/server/service/impl/GenesysRESTServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/GenesysRESTServiceImpl.java index 2e08dbd338bb27f3d2c2d57913ea15f9f2c20e6f..366e92e0d2d31f9edfc964549affbf80fec6bf5f 100644 --- a/src/main/java/org/genesys2/server/service/impl/GenesysRESTServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/GenesysRESTServiceImpl.java @@ -22,7 +22,6 @@ import java.util.List; import org.apache.commons.lang3.StringUtils; import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionGeo; import org.genesys2.server.model.genesys.AccessionRemark; @@ -54,16 +53,13 @@ public class GenesysRESTServiceImpl implements GenesysRESTService { final AccessionJson aj = GenesysJsonFactory.from(accession); - final AccessionBreeding breeding = genesysService.getAccessionBreeding(accession.getAccessionId()); - GenesysJsonFactory.addBreeding(aj, breeding); - - final AccessionCollect collect = genesysService.getAccessionCollect(accession.getAccessionId()); + final AccessionCollect collect = accession.getAccessionId().getColl(); GenesysJsonFactory.addCollecting(aj, collect); - final AccessionGeo geo = genesysService.getAccessionGeo(accession.getAccessionId()); + final AccessionGeo geo = accession.getAccessionId().getGeo(); GenesysJsonFactory.addGeo(aj, geo); - List remarks = genesysService.listAccessionRemarks(accession.getAccessionId()); + List remarks = accession.getAccessionId().getRemarks(); GenesysJsonFactory.addRemarks(aj, remarks); return aj; diff --git a/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java index d911314ca915c6ac43bc8bab710d22db54170c5d..7244573ab67e759fec02f1bf8844a1db53bda855 100644 --- a/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/GenesysServiceImpl.java @@ -38,28 +38,17 @@ import java.util.zip.ZipOutputStream; import javax.persistence.EntityManager; -import com.opencsv.CSVWriter; -import com.opencsv.ResultSetHelper; -import com.opencsv.ResultSetHelperService; - import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Predicate; -import org.apache.commons.lang3.StringUtils; import org.genesys.blocks.security.SecurityContextUtil; import org.genesys.blocks.security.model.AclSid; import org.genesys.blocks.security.service.CustomAclService; import org.genesys2.server.model.elastic.AccessionDetails; import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.genesys.AccessionAlias; import org.genesys2.server.model.genesys.AccessionAlias.AliasType; -import org.genesys2.server.model.genesys.AccessionBreeding; -import org.genesys2.server.model.genesys.AccessionCollect; import org.genesys2.server.model.genesys.AccessionData; -import org.genesys2.server.model.genesys.AccessionExchange; import org.genesys2.server.model.genesys.AccessionGeo; import org.genesys2.server.model.genesys.AccessionHistoric; import org.genesys2.server.model.genesys.AccessionId; -import org.genesys2.server.model.genesys.AccessionRemark; import org.genesys2.server.model.genesys.AccessionTrait; import org.genesys2.server.model.genesys.AllAccnames; import org.genesys2.server.model.genesys.ExperimentAccessionTrait; @@ -79,15 +68,10 @@ import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.model.impl.Organization; import org.genesys2.server.model.json.Api1Constants; -import org.genesys2.server.persistence.domain.AccessionAliasRepository; -import org.genesys2.server.persistence.domain.AccessionBreedingRepository; -import org.genesys2.server.persistence.domain.AccessionCollectRepository; -import org.genesys2.server.persistence.domain.AccessionExchangeRepository; import org.genesys2.server.persistence.domain.AccessionGeoRepository; import org.genesys2.server.persistence.domain.AccessionHistoricRepository; import org.genesys2.server.persistence.domain.AccessionIdRepository; import org.genesys2.server.persistence.domain.AccessionNameRepository; -import org.genesys2.server.persistence.domain.AccessionRemarkRepository; import org.genesys2.server.persistence.domain.AccessionRepository; import org.genesys2.server.persistence.domain.AccessionTraitRepository; import org.genesys2.server.persistence.domain.CropTaxonomyRepository; @@ -128,6 +112,10 @@ import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import com.opencsv.CSVWriter; +import com.opencsv.ResultSetHelper; +import com.opencsv.ResultSetHelperService; + @Service @Transactional(readOnly = true) public class GenesysServiceImpl implements GenesysService, DatasetService { @@ -153,15 +141,9 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Autowired private AccessionIdRepository accessionIdRepository; - @Autowired - private AccessionBreedingRepository accessionBreedingRepository; - @Autowired - private AccessionCollectRepository accessionCollectRepository; @Autowired private AccessionNameRepository accessionNamesRepository; @Autowired - private AccessionExchangeRepository accessionExchangeRepository; - @Autowired private AccessionGeoRepository accessionGeoRepository; @Autowired private AccessionTraitRepository accessionTraitRepository; @@ -184,17 +166,10 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { private GenesysLowlevelRepository genesysLowlevelRepository; @Autowired private SvalbardRepository svalbardRepository; - @Autowired - private AccessionAliasRepository accessionAliasRepository; - @Autowired - private AccessionRemarkRepository accessionRemarkRepository; @Autowired private CropService cropService; - @Autowired(required = false) - private PDCICalculator pdciCalculator; - @Autowired private PDCIRepository repoPdci; @@ -318,7 +293,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Override public Accession getAccession(String instCode, String acceNumb) throws NonUniqueAccessionException { try { - Accession accession = accessionRepository.findByInstituteCodeAndAccessionName(instCode, acceNumb); + Accession accession = accessionRepository.findByInstituteCodeAndAccessionNumber(instCode, acceNumb); return lazyLoadAccession(accession); } catch (IncorrectResultSizeDataAccessException e) { LOG.error("Duplicate accession name instCode={} acceNumb={}", instCode, acceNumb); @@ -332,7 +307,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Override public List listAccessions(final String acceNumb) { List accessions = new ArrayList<>(); - for (final Accession accession : accessionRepository.findByAccessionName(acceNumb)) { + for (final Accession accession : accessionRepository.findByAccessionNumber(acceNumb)) { accessions.add(lazyLoadAccession(accession)); } return accessions; @@ -370,13 +345,40 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return lazyLoadAccession(accession); } - private Accession lazyLoadAccession(Accession accession) { + private T lazyLoadAccession(T accession) { if (accession != null) { - accession.getStoRage().size(); + AccessionId accessionId = accession.getAccessionId(); + + if (accessionId.getStorage() != null) + accessionId.getStorage().size(); + if (accessionId.getAliases() != null) + accessionId.getAliases().size(); + if (accessionId.getBreederCode() != null) + accessionId.getBreederCode().size(); + if (accessionId.getDuplSite() != null) + accessionId.getDuplSite().size(); + if (accessionId.getRemarks() != null) + accessionId.getRemarks().size(); + if (accession.getCountryOfOrigin() != null) accession.getCountryOfOrigin().getId(); if (accession.getCrop() != null) accession.getCrop().getId(); + + if (accessionId.getColl() != null) { + if (accessionId.getColl().getCollCode() != null) + accessionId.getColl().getCollCode().size(); + if (accessionId.getColl().getCollInstAddress() != null) + accessionId.getColl().getCollInstAddress().size(); + if (accessionId.getColl().getCollName() != null) + accessionId.getColl().getCollName().size(); + } + if (accessionId.getGeo() != null) { + accessionId.getGeo().getId(); + } + + if (accessionId.getPdci() != null) + accessionId.getPdci().getId(); } return accession; } @@ -410,9 +412,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { AccessionDetails ad = AccessionDetails.from(all.accession); ad.networks(organizationService.getOrganizations(all.accession.getInstitute())); ad.aliases(all.names); - ad.exch(all.exch); ad.collect(all.collect); - ad.breeding(all.bred); ad.geo(all.geo); ad.sgsvDeposits(all.sgsvDeposits); ad.remarks(all.remarks); @@ -427,6 +427,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return ad; } + /// FIXME Remove @Override public List getAccessionDetails(Collection accessionIds) { List set = new ArrayList(accessionIds.size()); @@ -459,23 +460,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Override public List listAccessions(FaoInstitute faoInstitute, String accessionName) { - return accessionRepository.findByInstituteAndAccessionName(faoInstitute, accessionName); - } - - @Override - public AccessionBreeding getAccessionBreeding(AccessionId accession) { - if (accession == null || !accession.isPersisted()) { - return null; - } - return accessionBreedingRepository.findByAccession(accession); - } - - @Override - public AccessionGeo getAccessionGeo(AccessionId accession) { - if (accession == null || !accession.isPersisted()) { - return null; - } - return accessionGeoRepository.findByAccession(accession); + return accessionRepository.findByInstituteAndAccessionNumber(faoInstitute, accessionName); } @Override @@ -494,50 +479,21 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return svalbardRepository.findByAccession(accession); } - @Override - public AccessionCollect getAccessionCollect(AccessionId accession) { - if (accession == null || !accession.isPersisted()) { - return null; - } - return accessionCollectRepository.findByAccession(accession); - } - - @Override - public AccessionExchange getAccessionExchange(AccessionId accession) { - if (accession == null || !accession.isPersisted()) { - return null; - } - return accessionExchangeRepository.findByAccession(accession); - } - - @Override - public List listAccessionRemarks(AccessionId accession) { - if (accession == null || !accession.isPersisted()) { - return null; - } - return accessionRemarkRepository.findByAccession(accession); - } @Override public AllAccnames listAccessionNames(AccessionId accession) { return accessionNamesRepository.findByAccession(accession); } - @Override - public List listAccessionAliases(AccessionId accession) { - return accessionAliasRepository.findByAccession(accession); - } - public AllStuff loadAllStuff(AccessionData accession) { if (accession == null) return null; + lazyLoadAccession(accession); AllStuff all = new AllStuff(accession); - all.bred = getAccessionBreeding(accession.getAccessionId()); - all.collect = getAccessionCollect(accession.getAccessionId()); - all.exch = getAccessionExchange(accession.getAccessionId()); - all.geo = getAccessionGeo(accession.getAccessionId()); - all.names = listAccessionAliases(accession.getAccessionId()); - all.remarks = listAccessionRemarks(accession.getAccessionId()); + all.collect = accession.getAccessionId().getColl(); + all.geo = accession.getAccessionId().getGeo(); + all.names = accession.getAccessionId().getAliases(); + all.remarks = accession.getAccessionId().getRemarks(); all.sgsvDeposits = getSvalbardData(accession.getAccessionId()); return all; } @@ -554,81 +510,36 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { accessionRepository.findAll(accessionIds).stream().forEach(a -> { AllStuff all = map.get(a.getAccessionId().getId()); + lazyLoadAccession(a); all.accession = a; - if (a.getAccessionId().getLists() != null) - a.getAccessionId().getLists().size(); - if (a.getStoRage() != null) - // Lazy load stoRage - a.getStoRage().size(); - all.names = new ArrayList<>(); - all.remarks = new ArrayList<>(); + all.collect = a.getAccessionId().getColl(); + all.geo = a.getAccessionId().getGeo(); + all.names = a.getAccessionId().getAliases(); + all.remarks = a.getAccessionId().getRemarks(); all.sgsvDeposits = new ArrayList<>(); }); accessionHistoricRepository.findAll(accessionIds).stream().forEach(a -> { AllStuff all = map.get(a.getAccessionId().getId()); + lazyLoadAccession(a); all.accession = a; - if (a.getAccessionId().getLists() != null) - // Lazy load lists - a.getAccessionId().getLists().size(); - if (a.getStoRage() != null) - // Lazy load stoRage - a.getStoRage().size(); - all.names = new ArrayList<>(); - all.remarks = new ArrayList<>(); + all.collect = a.getAccessionId().getColl(); + all.geo = a.getAccessionId().getGeo(); + all.names = a.getAccessionId().getAliases(); + all.remarks = a.getAccessionId().getRemarks(); all.sgsvDeposits = new ArrayList<>(); }); - accessionCollectRepository.findAllFor(accessionIds).stream().forEach(c -> { - AllStuff all = map.get(c.getAccession().getId()); - all.collect = c; - }); - - accessionGeoRepository.findAllFor(accessionIds).stream().forEach(g -> { - AllStuff all = map.get(g.getAccession().getId()); - all.geo = g; - }); - - accessionBreedingRepository.findAllFor(accessionIds).stream().forEach(b -> { - AllStuff all = map.get(b.getAccession().getId()); - all.bred = b; - }); - - accessionExchangeRepository.findAllFor(accessionIds).stream().forEach(e -> { - AllStuff all = map.get(e.getAccession().getId()); - all.exch = e; - }); - svalbardRepository.findAllFor(accessionIds).stream().forEach(d -> { AllStuff all = map.get(d.getAccession().getId()); all.sgsvDeposits.add(d); }); - accessionAliasRepository.findAllFor(accessionIds).stream().forEach(aa -> { - if (aa == null) { - LOG.warn("aa is null"); - return; - } - AllStuff all = map.get(aa.getAccession().getId()); - if (all == null) { - LOG.warn("{} not in the list! {}", aa.getAccession().getId(), aa); - } else { - all.names.add(aa); - } - }); - - accessionRemarkRepository.findAllFor(accessionIds).stream().forEach(ar -> { - AllStuff all = map.get(ar.getAccession().getId()); - all.remarks.add(ar); - }); - alls.stream().forEach(all -> { detach(all.accession); detach(all.geo); detach(all.collect); - detach(all.bred); detach(all.names); - detach(all.exch); detach(all.remarks); }); @@ -771,7 +682,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { public Page listAccessionsByOrganization(Organization organization, Pageable pageable) { final List members = organizationService.getMembers(organization); if (members == null || members.size() == 0) { - return new PageImpl(Accession.EMPTY_LIST); + return new PageImpl(Collections.emptyList()); } return accessionRepository.findByInstitute(members, pageable); } @@ -827,22 +738,6 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return accessions; } - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public AccessionData saveAccession(AccessionData accession) { - if (LOG.isDebugEnabled()) - LOG.debug("Updating {}", accession); - - LOG.debug("Saving {} ST={}", accession, accession.getStorage()); - AccessionData res = null; - if (accession instanceof AccessionHistoric) { - res = accessionHistoricRepository.save((AccessionHistoric) accession); - } else { - res = accessionRepository.save((Accession) accession); - } - return res; - } @Override @Transactional(readOnly = false) @@ -875,10 +770,10 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { if (institute.getId().equals(accn.getInstitute().getId())) { accessionIds.add(accn.getAccessionId().getId()); } else { - throw new RuntimeException("Accession " + accn.getAccessionName() + " does not belong to " + institute.getCode()); + throw new RuntimeException("Accession " + accn.getAccessionNumber() + " does not belong to " + institute.getCode()); } if (accn.getDoi() != null) { - throw new RuntimeException("Refusing to delete accession that has DOI assigned - accession " + accn.getAccessionName() + " has DOI " + accn.getDoi()); + throw new RuntimeException("Refusing to delete accession that has DOI assigned - accession " + accn.getAccessionNumber() + " has DOI " + accn.getDoi()); } } @@ -964,86 +859,6 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return svalbardDeposits; } - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List saveCollecting(List all) { - accessionCollectRepository.save(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List removeCollecting(List all) { - accessionCollectRepository.delete(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List saveGeo(List all) { - accessionGeoRepository.save(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List removeGeo(List all) { - accessionGeoRepository.delete(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List saveBreeding(List all) { - accessionBreedingRepository.save(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List removeBreeding(List all) { - accessionBreedingRepository.delete(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List saveExchange(List all) { - accessionExchangeRepository.save(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List removeExchange(List all) { - accessionExchangeRepository.delete(all); - return all; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List saveRemarks(List toSaveRemarks) { - accessionRemarkRepository.save(toSaveRemarks); - return toSaveRemarks; - } - - @Override - @Transactional(readOnly = false) - // @CacheEvict(value = "statistics", allEntries = true) - public List removeRemarks(List toRemoveRemarks) { - accessionRemarkRepository.delete(toRemoveRemarks); - return toRemoveRemarks; - } - @Override public long countAvailableForDistribution(Set accessionIds) { if (accessionIds == null || accessionIds.size() == 0) { @@ -1570,128 +1385,6 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { genesysLowlevelRepository.refreshMetadataMethods(); } - @Override - @Transactional - // @CacheEvict(value = "statistics", allEntries = true) - public List saveAliases(List aliases) { - if (aliases.size() > 0) { - accessionAliasRepository.save(aliases); - } - return aliases; - } - - @Override - @Transactional - // @CacheEvict(value = "statistics", allEntries = true) - public List removeAliases(List aliases) { - if (aliases.size() > 0) { - accessionAliasRepository.delete(aliases); - } - return aliases; - } - - @Override - @Transactional - @PreAuthorize("hasRole('ADMINISTRATOR')") - // @CacheEvict(value = "statistics", allEntries = true) - public void upsertAliases(long accessionId, String acceNames, String otherIds) { - final AccessionData accession = getAccession(accessionId); - if (accession == null) { - LOG.error("No such accession {}", accessionId); - return; - } - - // LOG.info("Updating acceNames=" + acceNames); - final List aliases = new ArrayList(); - if (StringUtils.isNotBlank(acceNames)) { - final String[] acceName = acceNames.split(";"); - for (final String oi : acceName) { - if (StringUtils.isBlank(oi)) { - continue; - } - final AccessionAlias alias = new AccessionAlias(); - alias.setAccession(accession.getAccessionId()); - alias.setName(oi.trim()); - alias.setAliasType(AliasType.ACCENAME); - aliases.add(alias); - } - } - ensureAliases(accession, aliases, AliasType.ACCENAME); - - // LOG.info("Updating otherIds=" + otherIds); - aliases.clear(); - if (StringUtils.isNotBlank(otherIds)) { - final String[] otherId = otherIds.split(";"); - for (final String oi : otherId) { - if (StringUtils.isBlank(oi)) { - continue; - } - final String[] oin = oi.split(":", 2); - final AccessionAlias alias = new AccessionAlias(); - alias.setAccession(accession.getAccessionId()); - if (oin.length == 1) { - if (StringUtils.isBlank(oin[0])) { - continue; - } - alias.setName(oin[0].trim()); - } else { - if (StringUtils.isBlank(oin[1])) { - continue; - } - alias.setUsedBy(StringUtils.defaultIfBlank(oin[0].trim(), null)); - - if (alias.getUsedBy() != null && alias.getUsedBy().length() > 7) { - LOG.warn("Invalid instCode: {} in={}", alias.getUsedBy(), oi); - continue; - } - - alias.setName(oin[1].trim()); - } - alias.setAliasType(AliasType.OTHERNUMB); - aliases.add(alias); - } - } - ensureAliases(accession, aliases, AliasType.OTHERNUMB); - } - - private void ensureAliases(AccessionData accession, List aliases, AliasType aliasType) { - final List existingAliases = accessionAliasRepository.findByAccessionAndAliasType(accession.getAccessionId(), aliasType.getId()); - - // Find aliases to remove - for (final AccessionAlias aa : existingAliases) { - if (null == CollectionUtils.find(aliases, new Predicate() { - @Override - public boolean evaluate(AccessionAlias alias) { - return StringUtils.equals(alias.getName(), aa.getName()); - } - })) { - accessionAliasRepository.delete(aa); - } - } - // Add or update - for (final AccessionAlias aa : aliases) { - final AccessionAlias accessionAlias = CollectionUtils.find(existingAliases, new Predicate() { - @Override - public boolean evaluate(AccessionAlias alias) { - return StringUtils.equals(alias.getName(), aa.getName()); - } - }); - - if (accessionAlias == null) { - accessionAliasRepository.save(aa); - } - } - } - - @Override - @Transactional - // @CacheEvict(value = "statistics", allEntries = true) - public Set removeAliases(Set toRemove) { - for (final Long id : toRemove) { - this.accessionAliasRepository.delete(id); - } - return toRemove; - } @Override public List columnsAvailableForDisplay() { @@ -1725,15 +1418,7 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { @Override public AccessionHistoric getHistoricAccession(UUID uuid) { AccessionHistoric ah = accessionHistoricRepository.findOneByUuid(uuid); - if (ah != null) { - ah.getStoRage().size(); - } - return ah; - } - - @Override - public PDCI loadPDCI(Long accessionId) { - return accessionId == null ? null : repoPdci.findByAccessionId(accessionId); + return lazyLoadAccession(ah); } @Override @@ -1741,46 +1426,6 @@ public class GenesysServiceImpl implements GenesysService, DatasetService { return repoPdci.findByAccessionId(accessionIds); } - @Override - @Transactional - // @CacheEvict(value = "statistics", allEntries = true) - public List updatePDCI(final Set ids) { - if (LOG.isDebugEnabled()) - LOG.debug("Calculating PDCI for {} accessions", ids.size()); - - final List pdcis = Collections.synchronizedList(new ArrayList(ids.size())); - - getAccessionDetails(ids).stream().forEach(ad -> { - PDCI pdci = repoPdci.findByAccessionId(ad.getId()); - if (pdci == null) { - pdci = new PDCI(); - pdci.setAccession(accessionIdRepository.findOne(ad.getId())); - } - pdciCalculator.updatePdci(pdci, ad); - pdcis.add(pdci); - }); - - LOG.info("Updated {} PDCIs", pdcis.size()); - repoPdci.save(pdcis); - return pdcis; - } - - @Override - @Transactional - public PDCI updatePDCI(Long accessionId) { - if (pdciCalculator == null || accessionId == null) { - return null; - } - - PDCI pdci = repoPdci.findByAccessionId(accessionId); - if (pdci == null) { - pdci = new PDCI(); - pdci.setAccession(accessionIdRepository.findOne(accessionId)); - } - - return repoPdci.save(pdciCalculator.updatePdci(pdci, accessionId)); - } - @Override @Cacheable(unless = "#result == null", value = "statistics", key = "'stats.' + #root.methodName + '-' + #faoInstitute.id") public PDCIStatistics statisticsPDCI(FaoInstitute faoInstitute) { diff --git a/src/main/java/org/genesys2/server/service/impl/InstituteFilesServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/InstituteFilesServiceImpl.java index 9d971b36ce5fdded29b69423076d74730bff2046..574b4a63fd575860dd49127b94a45d62b81d456c 100644 --- a/src/main/java/org/genesys2/server/service/impl/InstituteFilesServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/InstituteFilesServiceImpl.java @@ -68,7 +68,7 @@ public class InstituteFilesServiceImpl implements InstituteFilesService { } private static final String getGalleryPath(final FaoInstitute institute, final Accession accession) throws InvalidRepositoryPathException { - return getGalleryPath(institute.getCode(), accession.getAccessionName()); + return getGalleryPath(institute.getCode(), accession.getAccessionNumber()); } public static final String getGalleryPath(final String instCode, final String acceNumb) throws InvalidRepositoryPathException { @@ -93,7 +93,7 @@ public class InstituteFilesServiceImpl implements InstituteFilesService { @Override @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')") public ImageGallery createImageGallery(FaoInstitute institute, Accession accession) throws InvalidRepositoryPathException { - return createImageGallery(institute.getCode(), accession.getAccessionName()); + return createImageGallery(institute.getCode(), accession.getAccessionNumber()); } @Override diff --git a/src/main/java/org/genesys2/server/service/impl/PDCICalculator.java b/src/main/java/org/genesys2/server/service/impl/PDCICalculator.java deleted file mode 100644 index 7f5d952a421a164bab215cfe18f55e20127c6a8b..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/service/impl/PDCICalculator.java +++ /dev/null @@ -1,445 +0,0 @@ -/** - * Copyright 2015 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.genesys2.server.service.impl; - -import java.util.ArrayList; - -import org.apache.commons.lang3.StringUtils; -import org.genesys2.server.model.elastic.AccessionDetails; -import org.genesys2.server.model.elastic.Alias; -import org.genesys2.server.model.elastic.Collect; -import org.genesys2.server.model.elastic.Geo; -import org.genesys2.server.model.elastic.Taxonomy; -import org.genesys2.server.model.genesys.AccessionAlias.AliasType; -import org.genesys2.server.model.genesys.PDCI; -import org.genesys2.server.service.GenesysService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Calculates PDCI value for an accession. - * - *

- * Theo van Hintum, Frank Menting and Elisabeth van Strien (2011). Quality - * indicators for passport data in ex situ genebanks. Plant Genetic - * Resources, 9, pp 478-485. - * - * doi:10.1017/S1479262111000682 - *

- */ -@Component -public class PDCICalculator implements InitializingBean { - public static final Logger LOG = LoggerFactory.getLogger(PDCICalculator.class); - - @Autowired - private GenesysService genesysService; - - @Override - public void afterPropertiesSet() throws Exception { - } - - public PDCI makePDCI(long accessionId) { - return calculatePDCI(new PDCI(), accessionId); - } - - public PDCI updatePdci(PDCI pdci, long accessionId) { - return calculatePDCI(pdci, accessionId); - } - - private PDCI calculatePDCI(PDCI pdci, long accessionId) { - AccessionDetails accessionDetails = genesysService.getAccessionDetails(accessionId); - if (accessionDetails == null) { - LOG.warn("No such accession {}", accessionId); - return null; - } - - return updatePdci(pdci, accessionDetails); - } - - public PDCI updatePdci(PDCI pdci, AccessionDetails accessionDetails) { - pdci.reset(); - - independentDescriptors(pdci, accessionDetails); - - switch (accessionDetails.getSampStat() == null ? -1 : accessionDetails.getSampStat() / 100) { - case 1: - case 2: - wildOrWeedy(pdci, accessionDetails); - break; - - case 3: - landrace(pdci, accessionDetails); - break; - case 4: - breedingMaterial(pdci, accessionDetails); - break; - case 5: - cultivar(pdci, accessionDetails); - default: - otherTypes(pdci, accessionDetails); - } - - return pdci; - } - - private void independentDescriptors(PDCI pdci, AccessionDetails accessionDetails) { - - taxonomic(pdci, accessionDetails.getTaxonomy()); - - if (StringUtils.isNotBlank(accessionDetails.getCropName())) { - pdci.setCropName(45); - } - - if (StringUtils.isNotBlank(accessionDetails.getAcqDate())) { - pdci.setAcqDate(10); - } - if (accessionDetails.getSampStat() != null) { - pdci.setSampStat(80); - } - if (StringUtils.isNotBlank(accessionDetails.getDonorCode())) { - pdci.setDonorCode(40); - } - if (StringUtils.isNotBlank(accessionDetails.getDonorNumb())) { - if (StringUtils.isBlank(accessionDetails.getDonorCode()) && StringUtils.isBlank(accessionDetails.getDonorName())) { - pdci.setDonorNumb(30); - } else { - pdci.setDonorNumb(40); - } - } - - if (names(accessionDetails.getAliases(), AliasType.OTHERNUMB)) { - pdci.setOtherNumb(35); - } - - if (accessionDetails.getDuplSite() != null && accessionDetails.getDuplSite().size() > 0) { - pdci.setDuplSite(30); - } else { - // Missing DUPLINSTNAME in Genesys, would add 15 - pdci.setDuplInstName(0); - } - - if (accessionDetails.getStorage() != null && accessionDetails.getStorage().size() > 0) { - pdci.setStorage(15); - } - - if (StringUtils.isNotBlank(accessionDetails.getDonorName())) { - if (StringUtils.isBlank(accessionDetails.getDonorCode())) { - pdci.setDonorName(20); - } else { - pdci.setDonorName(0); - } - } - - if (accessionDetails.getAcceUrl() != null) { - // pdci.setAcceUrl(40); - } - - if (accessionDetails.getMlsStatus() != null) { - pdci.setMlsStat(15); - } - } - - private void taxonomic(PDCI pdci, Taxonomy taxonomy) { - if (taxonomy != null) { - if (!StringUtils.isBlank(taxonomy.getGenus())) { - pdci.setGenus(120); - if (!StringUtils.isBlank(taxonomy.getSpecies()) && !StringUtils.equalsIgnoreCase("sp.", taxonomy.getSpecies())) { - pdci.setSpecies(80); - - if (!StringUtils.isBlank(taxonomy.getSpAuthor())) { - pdci.setSpAuthor(5); - } - if (!StringUtils.isBlank(taxonomy.getSubtaxa())) { - pdci.setSubTaxa(40); - - if (!StringUtils.isBlank(taxonomy.getSubtAuthor())) { - pdci.setSubtAuthor(5); - } - } - } - } - } - } - - private void wildOrWeedy(PDCI pdci, AccessionDetails accessionDetails) { - Geo geo = accessionDetails.getGeo(); - Collect coll = accessionDetails.getColl(); - - if (accessionDetails.getOrgCty() != null) { - pdci.setOrigCty(80); - } - - boolean hasLatLng = false; - - if (geo != null) { - if (geo.getLatitude() != null && geo.getLongitude() != null) { - if (geo.getLatitude() < -90 || geo.getLatitude() > 90 || geo.getLongitude() < -180 || geo.getLongitude() > 180) { - // Ignore coordinates - } else { - pdci.setLatitude(60); - pdci.setLongitude(60); - hasLatLng = true; - } - } - - if (geo.getElevation() != null) { - pdci.setElevation(20); - } - } - - if (coll != null) { - if (StringUtils.isNotBlank(coll.getCollSite())) { - if (hasLatLng) - pdci.setCollSite(20); - else - pdci.setCollSite(70); - } - - if (StringUtils.isNotBlank(coll.getCollDate())) { - pdci.setCollDate(30); - } - if (coll.getCollSrc() != null) { - pdci.setCollSrc(30); - } - - if (StringUtils.isNotBlank(coll.getCollNumb())) { - pdci.setCollNumb(60); - } - if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { - pdci.setCollCode(40); - } else { - if (StringUtils.isNotBlank(coll.getCollName())) { - pdci.setCollName(20); - } - } - } - } - - private void landrace(PDCI pdci, AccessionDetails accessionDetails) { - Geo geo = accessionDetails.getGeo(); - Collect coll = accessionDetails.getColl(); - - if (accessionDetails.getOrgCty() != null) { - pdci.setOrigCty(80); - } - - boolean hasLatLng = false; - - if (geo != null) { - if (geo.getLatitude() != null && geo.getLongitude() != null) { - pdci.setLatitude(40); - pdci.setLongitude(40); - hasLatLng = true; - } - - if (geo.getElevation() != null) { - pdci.setElevation(15); - } - } - - if (coll != null) { - if (StringUtils.isNotBlank(coll.getCollSite())) { - if (hasLatLng) - pdci.setCollSite(15); - else - pdci.setCollSite(45); - } - - if (StringUtils.isNotBlank(coll.getCollDate())) { - pdci.setCollDate(30); - } - - if (StringUtils.isNotBlank(accessionDetails.getPedigree())) { - pdci.setAncest(10); - } - - if (coll.getCollSrc() != null) { - pdci.setCollSrc(50); - } - - if (names(accessionDetails.getAliases(), AliasType.ACCENAME)) { - pdci.setAcceName(50); - } - - if (StringUtils.isNotBlank(coll.getCollNumb())) { - pdci.setCollNumb(40); - } - if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { - pdci.setCollCode(30); - } else { - if (StringUtils.isNotBlank(coll.getCollName())) { - pdci.setCollName(15); - } - } - } - } - - private void breedingMaterial(PDCI pdci, AccessionDetails accessionDetails) { - Collect coll = accessionDetails.getColl(); - - if (accessionDetails.getOrgCty() != null) { - pdci.setOrigCty(40); - } - - if (StringUtils.isNotBlank(accessionDetails.getBredCode())) { - pdci.setBredCode(110); - } - - if (StringUtils.isNotBlank(accessionDetails.getPedigree())) { - pdci.setAncest(150); - } - - if (coll != null) { - if (StringUtils.isNotBlank(coll.getCollSite())) { - } - - if (StringUtils.isNotBlank(coll.getCollDate())) { - } - - if (coll.getCollSrc() != null) { - pdci.setCollSrc(20); - } - - if (names(accessionDetails.getAliases(), AliasType.ACCENAME)) { - pdci.setAcceName(80); - } - - if (StringUtils.isNotBlank(coll.getCollNumb())) { - } - - if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { - } - } - } - - private void cultivar(PDCI pdci, AccessionDetails accessionDetails) { - Collect coll = accessionDetails.getColl(); - - if (accessionDetails.getOrgCty() != null) { - pdci.setOrigCty(40); - } - - if (StringUtils.isNotBlank(accessionDetails.getBredCode())) { - pdci.setBredCode(80); - } - - if (StringUtils.isNotBlank(accessionDetails.getPedigree())) { - pdci.setAncest(100); - } - - if (coll != null) { - if (StringUtils.isNotBlank(coll.getCollSite())) { - } - - if (StringUtils.isNotBlank(coll.getCollDate())) { - } - - if (coll.getCollSrc() != null) { - pdci.setCollSrc(20); - } - - if (names(accessionDetails.getAliases(), AliasType.ACCENAME)) { - pdci.setAcceName(160); - } - - if (StringUtils.isNotBlank(coll.getCollNumb())) { - } - - if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { - } - } - } - - private void otherTypes(PDCI pdci, AccessionDetails accessionDetails) { - Geo geo = accessionDetails.getGeo(); - Collect coll = accessionDetails.getColl(); - - if (accessionDetails.getOrgCty() != null) { - pdci.setOrigCty(40); - } - - boolean hasLatLng = false; - - if (geo != null) { - if (geo.getLatitude() != null && geo.getLongitude() != null) { - pdci.setLatitude(15); - pdci.setLongitude(15); - hasLatLng = true; - } - - if (geo.getElevation() != null) { - pdci.setElevation(5); - } - } - - if (StringUtils.isNotBlank(accessionDetails.getBredCode())) { - pdci.setBredCode(10); - } - - if (StringUtils.isNotBlank(accessionDetails.getPedigree())) { - pdci.setBredCode(40); - } - - if (names(accessionDetails.getAliases(), AliasType.ACCENAME)) { - pdci.setAcceName(40); - } - - if (coll != null) { - if (StringUtils.isNotBlank(coll.getCollSite())) { - if (hasLatLng) - pdci.setCollSite(10); - else - pdci.setCollSite(20); - } - - if (StringUtils.isNotBlank(coll.getCollDate())) { - pdci.setCollDate(10); - } - - if (coll.getCollSrc() != null) { - pdci.setCollSrc(25); - } - - if (StringUtils.isNotBlank(coll.getCollNumb())) { - pdci.setCollNumb(20); - } - if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { - pdci.setCollCode(20); - } else { - if (StringUtils.isNotBlank(coll.getCollName())) { - pdci.setCollName(10); - } - } - } - } - - private boolean names(ArrayList aliases, AliasType type) { - if (aliases == null || aliases.size() == 0) - return false; - - for (Alias alias : aliases) { - if (alias.getType() == type) { - return true; - } - } - return false; - } - -} diff --git a/src/main/java/org/genesys2/server/service/impl/ResolverServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/ResolverServiceImpl.java index ea61df780ab0c73d94e2e059e7b7e6934904e0df..065e4d8c5029a9eda088c15553b1a12ebbcfab52 100644 --- a/src/main/java/org/genesys2/server/service/impl/ResolverServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/ResolverServiceImpl.java @@ -45,11 +45,11 @@ public class ResolverServiceImpl implements ResolverService { public List findMatches(FaoInstitute faoInstitute, String acceNumb) { List matches = new ArrayList(); if (faoInstitute != null) { - matches.addAll(repoAccession.findByInstituteAndAccessionName(faoInstitute, acceNumb)); - matches.addAll(repoAccessionHistoric.findByInstituteAndAccessionName(faoInstitute, acceNumb)); + matches.addAll(repoAccession.findByInstituteAndAccessionNumber(faoInstitute, acceNumb)); + matches.addAll(repoAccessionHistoric.findByInstituteAndAccessionNumber(faoInstitute, acceNumb)); } else { - matches.addAll(repoAccession.findByAccessionName(acceNumb)); - matches.addAll(repoAccessionHistoric.findByAccessionName(acceNumb)); + matches.addAll(repoAccession.findByAccessionNumber(acceNumb)); + matches.addAll(repoAccessionHistoric.findByAccessionNumber(acceNumb)); } return matches; } diff --git a/src/main/java/org/genesys2/server/service/impl/TaxonomyServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/TaxonomyServiceImpl.java index 9c02017d3329b1d2c5c249418a3709515acc697d..c62ffab4ab46e4361525183b92645957276702e8 100644 --- a/src/main/java/org/genesys2/server/service/impl/TaxonomyServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/TaxonomyServiceImpl.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -215,4 +216,25 @@ public class TaxonomyServiceImpl implements TaxonomyService { taxonomy2Repository.removeUnusedIds(allIds); } } + + + @Override + @Transactional(timeout = 50, isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) + public Taxonomy2 ensureTaxonomy(Taxonomy2 example) { + example.sanitize(); + Taxonomy2 existing = taxonomy2Repository.findByGenusAndSpeciesAndSpAuthorAndSubtaxaAndSubtAuthor(example.getGenus(), example.getSpecies(), example.getSpAuthor(), example.getSubtaxa(), example.getSubtAuthor()); + if (existing == null) { + LOG.debug("Adding taxonomy {} {} {} {} {}", example.getGenus(), example.getSpecies(), example.getSpAuthor(), example.getSubtaxa(), example.getSubtAuthor()); + Taxonomy2 newTaxa = new Taxonomy2(); + newTaxa.setGenus(example.getGenus()); + newTaxa.setSpecies(example.getSpecies()); + newTaxa.setSpAuthor(example.getSpAuthor()); + newTaxa.setSubtaxa(example.getSubtaxa()); + newTaxa.setSubtAuthor(example.getSubtAuthor()); + return taxonomy2Repository.save(newTaxa.sanitize()); + } else { + return existing; + } + } + } diff --git a/src/main/java/org/genesys2/server/service/AccessionOpResponse.java b/src/main/java/org/genesys2/server/service/worker/AccessionOpResponse.java similarity index 63% rename from src/main/java/org/genesys2/server/service/AccessionOpResponse.java rename to src/main/java/org/genesys2/server/service/worker/AccessionOpResponse.java index f91f5e41a8558f78e4257ccf321de3dd08c34e61..2a7ad092377cc67a83cdd148c9342ca5e5f813c2 100644 --- a/src/main/java/org/genesys2/server/service/AccessionOpResponse.java +++ b/src/main/java/org/genesys2/server/service/worker/AccessionOpResponse.java @@ -1,20 +1,4 @@ -/** - * Copyright 2015 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.genesys2.server.service; +package org.genesys2.server.service.worker; import java.io.Serializable; import java.util.UUID; @@ -37,7 +21,7 @@ public class AccessionOpResponse implements Serializable { private UUID uuid; public static enum Type { - NOOP, INSERT, UPDATE, DELETE + NOOP, INSERT, UPDATE, DELETE, ERROR } /** @@ -60,8 +44,9 @@ public class AccessionOpResponse implements Serializable { return uuid; } - public void setUUID(UUID uuid) { + public UpsertResult setUUID(UUID uuid) { this.uuid = uuid; + return this; } } @@ -91,11 +76,13 @@ public class AccessionOpResponse implements Serializable { return result; } - public void setResult(UpsertResult result) { + public AccessionOpResponse setResult(UpsertResult result) { this.result = result; + return this; } - public void setError(String error) { + public AccessionOpResponse setError(String error) { this.error = error; + return this; } } diff --git a/src/main/java/org/genesys2/server/service/worker/AccessionUploader.java b/src/main/java/org/genesys2/server/service/worker/AccessionUploader.java new file mode 100644 index 0000000000000000000000000000000000000000..d09fdf3c525f1b14b42468d4de06d9a396df56f0 --- /dev/null +++ b/src/main/java/org/genesys2/server/service/worker/AccessionUploader.java @@ -0,0 +1,446 @@ +/* + * Copyright 2018 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.genesys2.server.service.worker; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.ArrayUtils; +import org.genesys2.server.model.genesys.Accession; +import org.genesys2.server.model.genesys.AccessionAlias; +import org.genesys2.server.model.genesys.AccessionAlias.AliasType; +import org.genesys2.server.model.genesys.AccessionCollect; +import org.genesys2.server.model.genesys.AccessionGeo; +import org.genesys2.server.model.genesys.AccessionId; +import org.genesys2.server.model.genesys.AccessionRemark; +import org.genesys2.server.model.genesys.PDCI; +import org.genesys2.server.model.genesys.Taxonomy2; +import org.genesys2.server.model.impl.Country; +import org.genesys2.server.model.impl.FaoInstitute; +import org.genesys2.server.persistence.domain.AccessionRepository; +import org.genesys2.server.persistence.domain.FaoInstituteRepository; +import org.genesys2.server.service.GeoService; +import org.genesys2.server.service.TaxonomyService; +import org.genesys2.server.service.worker.AccessionOpResponse.UpsertResult; +import org.genesys2.server.servlet.controller.rest.PleaseRetryException; +import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; +import org.genesys2.util.PDCICalculator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ReflectionUtils; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.google.common.collect.Iterators; + +/** + * The Class AccessionUploader. + */ +@Component +@Transactional +public class AccessionUploader implements InitializingBean { + private static final Logger LOG = LoggerFactory.getLogger(AccessionUploader.class); + + private ObjectMapper objectMapper; + + @Autowired + private AccessionRepository accessionRepository; + + @Autowired + private TaxonomyService taxonomyService; + + @Autowired + private FaoInstituteRepository faoInstituteRepository; + + @Autowired + private GeoService geoService; + + private static final String[] ACCESSIONID_FIELDS = { "breederCode", "storage", "duplSite" }; + + @Override + public void afterPropertiesSet() throws Exception { + objectMapper = new ObjectMapper(); + objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); + // ignore stuff we don't understand + objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + // explicit json views: every fields needs to be annotated, therefore enabled + // objectMapper.enable(MapperFeature.DEFAULT_VIEW_INCLUSION); + + // Custom deserializers + SimpleModule testModule = new SimpleModule("Custom Deserializers"); + testModule.addDeserializer(AccessionRemark.class, new JsonDeserializers.AccessionRemarkDeserializer(AccessionRemark.class)); + objectMapper.registerModule(testModule); + } + + /** + * Upsert accessions. + * + * @param faoInstitute the fao institute + * @param updates the updates + * @throws IOException + */ + @Transactional(timeout = 200, isolation = Isolation.READ_UNCOMMITTED, rollbackFor = Throwable.class) + @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE')") + public List upsertAccessions(FaoInstitute institute, ArrayNode updates) { + assert (updates.isArray()); + ObjectReader reader = objectMapper.readerFor(Accession.class); + + final List accessions = new ArrayList<>(updates.size()); + final List responses = new ArrayList<>(updates.size()); + List toSave = new ArrayList<>(updates.size()); + + for (JsonNode accn : updates) { + LOG.trace("Received: {}", accn); + try { + Accession accession = reader.readValue(accn); + accessions.add(accession); + responses.add(new AccessionOpResponse(accession.getInstituteCode(), accession.getAccessionNumber(), accession.getTaxonomy().getGenus())); + } catch (IOException e) { + LOG.error("Could not parse input: {}", e.getMessage(), e); + accessions.add(null); + responses.add(new AccessionOpResponse(accn.get("instituteCode").asText(), accn.get("accessionNumber").asText(), accn.get("taxonomy").get("genus").asText()) + .setResult(new UpsertResult(UpsertResult.Type.ERROR)).setError(e.getMessage())); + } + } + + List forUpdate = new ArrayList<>(accessions.size()); + forUpdate.addAll(accessions); + + // Security check + for (int i = 0; i < accessions.size(); i++) { + Accession accession = accessions.get(i); + if (!institute.getCode().equals(accession.getInstituteCode())) { + throw new InvalidApiUsageException("Accession does not belong to institute " + institute.getCode()); + } + } + + List existingAccessions = accessionRepository.find(forUpdate); + LOG.debug("Have {} accessions for update and {} exist", forUpdate.size(), existingAccessions.size()); + + for (int i = 0; i < forUpdate.size(); i++) { + final JsonNode update = updates.get(i); + + // Should we? + final Accession forU = forUpdate.get(i); + if (forU == null) { + LOG.debug("Skipping update of {}", update); + continue; + } + + final Accession updateA = accessions.get(i); + AccessionOpResponse response = responses.get(i); + LOG.trace("Upserting: {}", update); + + Accession accession = existingAccessions.stream().filter(existing -> { + return (existing.getDoi() != null && existing.getDoi().equals(updateA.getDoi())) || (existing.getInstituteCode().equals(updateA.getInstituteCode()) && existing + .getAccessionNumber().equals(updateA.getAccessionNumber()) && existing.getTaxonomy().getGenus().equals(updateA.getTaxonomy().getGenus())); + }).findFirst().orElse(null); + + if (accession == null) { + LOG.trace("New accesson"); + response.setResult(new UpsertResult(UpsertResult.Type.INSERT)); + accession = new Accession(); + accession.setAccessionId(new AccessionId()); + accession.setInstitute(faoInstituteRepository.findByCode(updateA.getInstituteCode())); + } else { + LOG.trace("Updating accession {}", accession); + response.setResult(new UpsertResult(UpsertResult.Type.UPDATE).setUUID(accession.getUuid())); + } + + try { + accession = applyChanges(update, updateA, accession); + + PDCI pdci = accession.getAccessionId().getPdci(); + if (pdci == null) { + pdci = new PDCI(); + pdci.setAccession(accession.getAccessionId()); + accession.getAccessionId().setPdci(pdci); + } + PDCICalculator.updatePdci(pdci, accession); + + toSave.add(accession); + } catch (PleaseRetryException e) { + throw e; + } catch (InvalidApiUsageException e) { + LOG.error(e.getMessage(), e); + response.setError(e.getMessage()); + } + } + + toSave = accessionRepository.save(toSave); + LOG.trace("Saved: {}", toSave); + + return responses; + } + + /** + * Check incoming JSON and update values accordingly + * + * @param update + * @param updateA + * @param accession + * @return + */ + private Accession applyChanges(JsonNode update, Accession updateA, Accession accession) { + update.fieldNames().forEachRemaining(fieldName -> { + LOG.trace("Updating {}", fieldName); + + if ("taxonomy".equals(fieldName)) { + updateTaxonomy(update.get("taxonomy"), updateA.getTaxonomy(), accession); + + } else if ("orgCty".equals(fieldName)) { + updateOrigCty(updateA.getOrigCty(), accession); + + } else if ("geo".equals(fieldName)) { + updateGeo(update.get("geo"), updateA.getAccessionId().getGeo(), accession.getAccessionId()); + + } else if ("remarks".equals(fieldName)) { + updateRemarks(update.get("remarks"), updateA.getAccessionId().getRemarks(), accession.getAccessionId()); + + } else if ("coll".equals(fieldName)) { + updateColl(update.get("coll"), updateA.getAccessionId().getColl(), accession.getAccessionId()); + + } else if ("acceName".equals(fieldName) || "otherNumb".equals(fieldName)) { + updateAliases(fieldName, update.get(fieldName), accession.getAccessionId()); + + } else if (ArrayUtils.contains(ACCESSIONID_FIELDS, fieldName)) { + try { + copy(AccessionId.class, updateA.getAccessionId(), accession.getAccessionId(), Iterators.forArray(fieldName)); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new InvalidApiUsageException(e.getMessage(), e); + } + + } else { + try { + copy(Accession.class, updateA, accession, Iterators.forArray(fieldName)); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new InvalidApiUsageException(e.getMessage(), e); + } + } + }); + return accession; + } + + private void updateAliases(String fieldName, JsonNode jsonNode, AccessionId accession) { + if (jsonNode == null) { + return; + } + + final List existing = accession.getAliases() != null ? accession.getAliases() : new ArrayList<>(); + + AliasType aliasType = AccessionAlias.AliasType.valueOf(fieldName.toUpperCase()); + List names = new ArrayList<>(); + + if (jsonNode.isArray()) { + ArrayNode ns = (ArrayNode) jsonNode; + ns.forEach(n -> names.add(new AccessionAlias(aliasType, n.textValue()))); + + } else if (jsonNode.isTextual()) { + names.add(new AccessionAlias(aliasType, jsonNode.textValue())); + } else if (jsonNode.isNull()) { + // NOOP + } else { + throw new InvalidApiUsageException("Don't know what to do with " + fieldName + "=" + jsonNode); + } + + List toAdd = names.stream().filter(name -> existing.stream().filter(ex -> ex.equalTo(name)).count() == 0).collect(Collectors.toList()); + List toRemove = existing.stream().filter(alias -> alias.getAliasType() == aliasType).filter(alias -> names.stream().filter(name -> alias.equalTo(name)) + .count() == 0).collect(Collectors.toList()); + + if (!toRemove.isEmpty() || !toAdd.isEmpty()) { + LOG.trace("Removing: {} Adding: {}", toRemove, toAdd); + } + existing.removeAll(toRemove); + existing.addAll(toAdd); + + if (existing != null) { + accession.setAliases(existing); + existing.stream().forEach(alias -> alias.setAccession(accession)); + } + } + + private void updateOrigCty(String origCty, Accession accession) { + if (origCty == null) { + accession.setCountryOfOrigin(null); + + } else if (accession.getCountryOfOrigin() == null || !accession.getCountryOfOrigin().getCode3().equals(origCty)) { + Country country = geoService.getCountry(origCty); + + if (country == null) { + // TODO + // throw new InvalidApiUsageException("No country with ISO3 code " + origCty); + } + + accession.setCountryOfOrigin(country); + } + } + + private void updateTaxonomy(JsonNode jsonNode, Taxonomy2 source, Accession accession) { + Taxonomy2 taxonomy = accession.getTaxonomy(); + source.sanitize(); + + if (jsonNode.has("newGenus")) { + if (!jsonNode.has("species")) { + throw new InvalidApiUsageException("Cannot specify newGenus without species."); + } + source.setGenus(jsonNode.get("newGenus").textValue()); + } + + if (taxonomy == null) { + LOG.trace("Ensuring taxonomy {}", jsonNode); + taxonomy = taxonomyService.ensureTaxonomy(source); + accession.setTaxonomy(taxonomy); + } else if (taxonomy.equalTo(source)) { + // NOOP + } else { + LOG.trace("Ensuring taxonomy {}", jsonNode); + taxonomy = taxonomyService.ensureTaxonomy(source); + accession.setTaxonomy(taxonomy); + } + } + + private void updateColl(JsonNode jsonNode, AccessionCollect source, AccessionId accession) { + AccessionCollect coll = accession.getColl(); + if (coll == null) { + coll = new AccessionCollect(); + coll.setAccession(accession); + } + + try { + copy(AccessionCollect.class, source, coll, jsonNode.fieldNames()); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new InvalidApiUsageException(e.getMessage(), e); + } + + // removes empty + accession.setColl(coll.isEmpty() ? null : coll); + } + + private void updateGeo(JsonNode jsonNode, AccessionGeo source, AccessionId accession) { + AccessionGeo geo = accession.getGeo(); + if (geo == null) { + geo = new AccessionGeo(); + geo.setAccession(accession); + } + + try { + copy(AccessionGeo.class, source, geo, jsonNode.fieldNames()); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new InvalidApiUsageException(e.getMessage(), e); + } + + // removes empty + accession.setGeo(geo.isEmpty() ? null : geo); + } + + private void updateRemarks(JsonNode jsonNode, List remarks, AccessionId accession) { + final List existing = accession.getRemarks(); + if (existing != null) { + if (remarks == null || remarks.isEmpty()) { + existing.clear(); + } else { + List toAdd = remarks.stream().filter(rem -> existing.stream().filter(ex -> ex.equalTo(rem)).count() == 0).collect(Collectors.toList()); + List toRemove = existing.stream().filter(ex -> remarks.stream().filter(rem -> ex.equalTo(rem)).count() == 0).collect(Collectors.toList()); + if (!toRemove.isEmpty() || !toAdd.isEmpty()) { + LOG.info("Removing: {} Adding: {}", toRemove, toAdd); + } + existing.removeAll(toRemove); + existing.addAll(toAdd); + } + } else { + accession.setRemarks(remarks); + } + + // Make sure we take current remarks! + if (accession.getRemarks() != null) { + accession.getRemarks().stream().forEach(remark -> remark.setAccession(accession)); + } + } + + private void copy(Class clazz, T source, T target, Iterator fieldNames) throws IllegalArgumentException, IllegalAccessException { + String fieldName = null; + while (fieldNames.hasNext() && (fieldName = fieldNames.next()) != null) { + // LOG.debug("Copying {}.{}", clazz.getName(), fieldName); + Field field = ReflectionUtils.findField(clazz, fieldName); + if (field != null) { + ReflectionUtils.makeAccessible(field); + final Object srcValue = field.get(source); + field.set(target, srcValue); + LOG.trace("Set {} to {}", fieldName, srcValue); + } else { + LOG.warn("No such field {}.{}", clazz.getName(), fieldName); + } + } + } + + @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE')") + public List deleteAccessions(FaoInstitute institute, List identifiers) { + // Security check + for (int i = 0; i < identifiers.size(); i++) { + AccessionHeaderJson accession = identifiers.get(i); + if (!institute.getCode().equals(accession.instCode)) { + throw new InvalidApiUsageException("Accession does not belong to institute " + institute.getCode()); + } + } + + final List responses = new ArrayList<>(identifiers.size()); + List existingAccessions = accessionRepository.findById(identifiers); + List toRemove = new ArrayList<>(identifiers.size()); + + for (int i = 0; i < identifiers.size(); i++) { + final AccessionHeaderJson deletion = identifiers.get(i); + LOG.trace("Deleting: {}", deletion); + + AccessionOpResponse response; + responses.add(response = new AccessionOpResponse(deletion.getHoldingInstitute(), deletion.getAccessionNumber(), deletion.getGenus())); + + Accession accession = existingAccessions.stream().filter(existing -> { + return (existing.getDoi() != null && existing.getDoi().equals(deletion.getDoi())) || (existing.getInstituteCode().equals(deletion.getHoldingInstitute()) && existing + .getAccessionNumber().equals(deletion.getAccessionNumber()) && existing.getTaxonomy().getGenus().equals(deletion.getGenus())); + }).findFirst().orElse(null); + + if (accession == null) { + response.setResult(new UpsertResult(UpsertResult.Type.NOOP)); + } else { + LOG.trace("Deleting accession {}", accession); + toRemove.add(accession); + response.setResult(new UpsertResult(UpsertResult.Type.DELETE).setUUID(accession.getUuid())); + } + } + + if (!toRemove.isEmpty()) { + accessionRepository.delete(toRemove); + LOG.trace("Deleted: {}", toRemove); + } + + return responses; + } + +} diff --git a/src/main/java/org/genesys2/server/service/worker/InvalidApiUsageException.java b/src/main/java/org/genesys2/server/service/worker/InvalidApiUsageException.java new file mode 100644 index 0000000000000000000000000000000000000000..ccb7e4d2cb43bb6a3efee67675edbb375f51fc05 --- /dev/null +++ b/src/main/java/org/genesys2/server/service/worker/InvalidApiUsageException.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017 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.genesys2.server.service.worker; + +/** + * Parent exception for cases where data does not match business logic. + * + * @author Matija Obreza + */ +public class InvalidApiUsageException extends RuntimeException { + + private static final long serialVersionUID = 525397094935272124L; + + /** + * Instantiates a new invalid api usage exception. + */ + public InvalidApiUsageException() { + super(); + } + + /** + * Instantiates a new invalid api usage exception. + * + * @param message the message + */ + public InvalidApiUsageException(final String message) { + super(message); + } + + /** + * Instantiates a new invalid api usage exception. + * + * @param message the message + * @param cause the cause + */ + public InvalidApiUsageException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Instantiates a new invalid api usage exception. + * + * @param cause the cause + */ + public InvalidApiUsageException(final Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/org/genesys2/server/service/worker/JsonDeserializers.java b/src/main/java/org/genesys2/server/service/worker/JsonDeserializers.java new file mode 100644 index 0000000000000000000000000000000000000000..1fa729bc1e5d228f358495f2bbb77dfdad5066bd --- /dev/null +++ b/src/main/java/org/genesys2/server/service/worker/JsonDeserializers.java @@ -0,0 +1,35 @@ +package org.genesys2.server.service.worker; + +import java.io.IOException; + +import org.genesys2.server.model.genesys.AccessionRemark; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class JsonDeserializers { + + /** + * Deserialize "FIELD:text" + */ + public static class AccessionRemarkDeserializer extends StdDeserializer { + private static final long serialVersionUID = 1L; + + protected AccessionRemarkDeserializer(Class vc) { + super(vc); + } + + @Override + public AccessionRemark deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { + String str = p.getText(); + if (str == null || str.length() == 0) { + return null; + } + AccessionRemark ar = new AccessionRemark(str); + return ar; + } + } + +} diff --git a/src/main/java/org/genesys2/server/servlet/controller/AccessionController.java b/src/main/java/org/genesys2/server/servlet/controller/AccessionController.java index 155e9f4b1dff2d2f1c13f7c4a02c15c9d81aa0ea..99c32b41d22e6b6894dce066dd5dc9c048242b58 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/AccessionController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/AccessionController.java @@ -26,18 +26,14 @@ import java.util.UUID; import javax.servlet.http.HttpServletResponse; import org.genesys.blocks.auditlog.service.AuditTrailService; -import org.genesys.blocks.security.SecurityContextUtil; import org.genesys.filerepository.InvalidRepositoryPathException; import org.genesys.filerepository.model.ImageGallery; import org.genesys.filerepository.service.ImageGalleryService; import org.genesys2.server.model.dataset.DS; import org.genesys2.server.model.elastic.AccessionDetails; import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.genesys.AccessionBreeding; import org.genesys2.server.model.genesys.AccessionCollect; -import org.genesys2.server.model.genesys.AccessionExchange; import org.genesys2.server.model.genesys.AccessionGeo; -import org.genesys2.server.model.genesys.PDCI; import org.genesys2.server.model.genesys.Taxonomy2; import org.genesys2.server.model.impl.Crop; import org.genesys2.server.model.impl.FaoInstitute; @@ -51,7 +47,6 @@ import org.genesys2.server.service.StatisticsService; import org.genesys2.server.service.TaxonomyService; import org.genesys2.server.service.TraitService; import org.genesys2.server.service.impl.NonUniqueAccessionException; -import org.genesys2.server.service.impl.PDCICalculator; import org.genesys2.spring.ResourceNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -89,9 +84,6 @@ public class AccessionController extends BaseController { @Autowired private DSService dsService; - @Autowired(required = false) - private PDCICalculator pdciCalculator; - @Autowired private StatisticsService statisticsService; @@ -150,30 +142,26 @@ public class AccessionController extends BaseController { model.addAttribute("auditAccession", auditService.auditLogs(accession)); model.addAttribute("accessionNames", genesysService.listAccessionNames(accession.getAccessionId())); - model.addAttribute("accessionAliases", genesysService.listAccessionAliases(accession.getAccessionId())); + model.addAttribute("accessionAliases", accession.getAccessionId().getAliases()); - AccessionExchange accessionExchange = genesysService.getAccessionExchange(accession.getAccessionId()); - model.addAttribute("accessionExchange", accessionExchange); + model.addAttribute("accessionExchange", accession); - AccessionCollect accessionCollect = genesysService.getAccessionCollect(accession.getAccessionId()); + AccessionCollect accessionCollect = accession.getAccessionId().getColl(); model.addAttribute("accessionCollect", accessionCollect); - AccessionBreeding accessionBreeding = genesysService.getAccessionBreeding(accession.getAccessionId()); - model.addAttribute("accessionBreeding", accessionBreeding); + model.addAttribute("accessionBreeding", accession); - AccessionGeo accessionGeo = genesysService.getAccessionGeo(accession.getAccessionId()); + AccessionGeo accessionGeo = accession.getAccessionId().getGeo(); model.addAttribute("accessionGeo", accessionGeo); if (SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) { // only for authenticated users - model.addAttribute("auditAccessionExchange", auditService.auditLogs(accessionExchange)); model.addAttribute("auditAccessionCollect", auditService.auditLogs(accessionCollect)); - model.addAttribute("auditAccessionBreeding", auditService.auditLogs(accessionBreeding)); model.addAttribute("auditAccessionGeo", auditService.auditLogs(accessionGeo)); } model.addAttribute("svalbardDeposits", genesysService.getSvalbardData(accession.getAccessionId())); - model.addAttribute("accessionRemarks", genesysService.listAccessionRemarks(accession.getAccessionId())); + model.addAttribute("accessionRemarks", accession.getAccessionId().getRemarks()); model.addAttribute("metadatas", genesysService.listMetadata(accession.getAccessionId())); model.addAttribute("methods", traitService.listMethods(accession.getAccessionId())); @@ -196,36 +184,14 @@ public class AccessionController extends BaseController { } } - // PDCI - if (pdciCalculator != null) { - try { - // FIXME Duplicated loading of all accession information - PDCI pdci = pdciCalculator.makePDCI(accession.getId()); - - PDCI existingPdci = genesysService.loadPDCI(accession.getId()); - - if (existingPdci == null) { - existingPdci = genesysService.updatePDCI(accession.getId()); - } - - if (existingPdci != null && pdci.getTotal() != existingPdci.getTotal()) { - LOG.info("Forcing recalculation of PDCI"); - genesysService.updatePDCI(accession.getId()); - } + model.addAttribute("pdci", accession.getAccessionId().getPdci()); + model.addAttribute("institutePDCI", statisticsService.statisticsPDCI(accession.getInstitute())); - model.addAttribute("pdci", pdci); - model.addAttribute("institutePDCI", statisticsService.statisticsPDCI(accession.getInstitute())); - - } catch (Throwable e) { - LOG.warn(e.getMessage(), e); - } - } - ImageGallery imageGallery = null; try { imageGallery = this.instituteFilesService.loadImageGallery(accession.getInstitute(), accession); } catch (InvalidRepositoryPathException e) { - LOG.warn("Error loading image gallery for accession={}. {}", accession.getAccessionName(), e.getMessage()); + LOG.warn("Error loading image gallery for accession={}. {}", accession.getAccessionNumber(), e.getMessage()); } if (imageGallery != null) { imageGalleryService.ensureThumbnails(imageGallery, 200, 200); diff --git a/src/main/java/org/genesys2/server/servlet/controller/ArchiveController.java b/src/main/java/org/genesys2/server/servlet/controller/ArchiveController.java index 3a31e77b79967b9aa457d3d6d36e4b2936921766..899135f65b8fea4d66955411bd2135b55e0431f8 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/ArchiveController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/ArchiveController.java @@ -74,14 +74,14 @@ public class ArchiveController extends BaseController { } model.addAttribute("accession", accession); model.addAttribute("accessionNames", genesysService.listAccessionNames(accession.getAccessionId())); - model.addAttribute("accessionAliases", genesysService.listAccessionAliases(accession.getAccessionId())); - model.addAttribute("accessionExchange", genesysService.getAccessionExchange(accession.getAccessionId())); - model.addAttribute("accessionCollect", genesysService.getAccessionCollect(accession.getAccessionId())); - model.addAttribute("accessionBreeding", genesysService.getAccessionBreeding(accession.getAccessionId())); - AccessionGeo accessionGeo = genesysService.getAccessionGeo(accession.getAccessionId()); + model.addAttribute("accessionAliases", accession.getAccessionId().getAliases()); + model.addAttribute("accessionExchange", accession); + model.addAttribute("accessionCollect", accession.getAccessionId().getColl()); + model.addAttribute("accessionBreeding", accession); + AccessionGeo accessionGeo = accession.getAccessionId().getGeo(); model.addAttribute("accessionGeo", accessionGeo); model.addAttribute("svalbardData", genesysService.getSvalbardData(accession.getAccessionId())); - model.addAttribute("accessionRemarks", genesysService.listAccessionRemarks(accession.getAccessionId())); + model.addAttribute("accessionRemarks", accession.getAccessionId().getRemarks()); model.addAttribute("metadatas", genesysService.listMetadata(accession.getAccessionId())); model.addAttribute("methods", traitService.listMethods(accession.getAccessionId())); diff --git a/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java b/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java index 010f1841be619aef71592a96a206947e65a6ecdf..acd77ac0fbe7b901888bc222fdc160e0044e239d 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java @@ -31,7 +31,7 @@ import java.util.UUID; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.model.impl.Project; import org.genesys2.server.service.AccessionListService; import org.genesys2.server.service.CRMException; diff --git a/src/main/java/org/genesys2/server/servlet/controller/SelectionController.java b/src/main/java/org/genesys2/server/servlet/controller/SelectionController.java index 270970e53d32e5b655f1ddb693cf9d9451c1fe00..3efe32ba8728b9cb6c02f676954bd9156edd1da7 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/SelectionController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/SelectionController.java @@ -29,7 +29,7 @@ import org.apache.commons.lang3.StringUtils; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.AccessionData; import org.genesys2.server.model.genesys.AccessionGeo; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.model.json.UserAccessionList; import org.genesys2.server.service.AccessionListService; import org.genesys2.server.service.DownloadService; @@ -260,7 +260,7 @@ public class SelectionController extends BaseController { g.lat = acnGeo.getLatitude(); g.lng = acnGeo.getLongitude(); AccessionData a = genesysService.getAccession(g.id); - g.accessionName = a.getAccessionName(); + g.accessionName = a.getAccessionNumber(); g.instCode = a.getInstituteCode(); geo.add(g); } diff --git a/src/main/java/org/genesys2/server/servlet/controller/admin/AdminController.java b/src/main/java/org/genesys2/server/servlet/controller/admin/AdminController.java index d615f3838c8287040c2d8feb6fb19473ed00cd31..37a8efeb9ff774f43ba917c6c166a3116d71fd07 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/admin/AdminController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/admin/AdminController.java @@ -17,10 +17,6 @@ package org.genesys2.server.servlet.controller.admin; import java.io.IOException; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -31,14 +27,9 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.xml.parsers.ParserConfigurationException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang.time.StopWatch; import org.genesys2.server.persistence.domain.AccessionIdRepository; import org.genesys2.server.persistence.domain.AccessionRepository; -import org.genesys2.server.persistence.domain.GenesysLowlevelRepository; import org.genesys2.server.service.ContentService; import org.genesys2.server.service.CountryNamesUpdater; import org.genesys2.server.service.CropService; @@ -52,12 +43,10 @@ import org.genesys2.server.service.worker.ElasticUpdater; import org.genesys2.server.service.worker.ITPGRFAStatusUpdater; import org.genesys2.server.service.worker.InstituteUpdater; import org.genesys2.server.service.worker.SGSVUpdate; -import org.genesys2.server.service.worker.WorldClimUpdater; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.task.TaskExecutor; -import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -66,24 +55,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.xml.sax.SAXException; +import com.fasterxml.jackson.databind.ObjectMapper; + @Controller @RequestMapping("/admin") @PreAuthorize("hasRole('ADMINISTRATOR')") public class AdminController { - private final class PDCIUpdater implements Runnable { - private Set batch; - - public PDCIUpdater(Set accessionIdsCopy) { - batch = accessionIdsCopy; - } - - @Override - public void run() { - genesysService.updatePDCI(batch); - } - } - public static final Logger LOG = LoggerFactory.getLogger(AdminController.class); @Autowired @@ -116,12 +94,6 @@ public class AdminController { @Autowired private InstituteService instituteService; - @Autowired - private GenesysLowlevelRepository genesysLowlevelRepository; - - @Autowired - private WorldClimUpdater worldClimUpdater; - @Autowired private GeoRegionService geoRegionService; @@ -139,9 +111,6 @@ public class AdminController { @Autowired private AccessionRepository accessionRepository; - @Autowired - private AccessionIdRepository accessionIdRepository; - @Autowired private ContentService contentService; @@ -200,123 +169,6 @@ public class AdminController { return "redirect:/admin/"; } - @RequestMapping(method = RequestMethod.POST, value = "/convertNames") - public String convertNames() { - // Convert {@link AllAccenames} to Aliases - final List list = new ArrayList(100000); - genesysLowlevelRepository.listAccessionsAccenames(new RowCallbackHandler() { - @Override - public void processRow(ResultSet rs) throws SQLException { - final long accessionId = rs.getLong(1); - final String acceNames = rs.getString(2); - final String otherIds = rs.getString(3); - list.add(new Object[] { accessionId, acceNames, otherIds }); - if (list.size() % 10000 == 0) { - LOG.info("Loaded names: {}", list.size()); - } - } - }); - - int i = 0; - for (final Object[] o : list) { - if (++i % 1000 == 0) { - LOG.info("Conversion progress {} of {}", i, list.size()); - } - genesysService.upsertAliases((long) o[0], (String) o[1], (String) o[2]); - } - - list.clear(); - - System.err.println("FOOBAR!"); - - final Set toRemove = new HashSet(); - - // Remove stupid stuff - // List aliasesToRemove = new ArrayList(); - genesysLowlevelRepository.listAccessionsAlias(new RowCallbackHandler() { - private long prevAccnId = -1; - private final List aliases = new ArrayList(10); - - @Override - public void processRow(ResultSet rs) throws SQLException { - System.err.println(".."); - // n.accessionId, n.instCode, n.name, n.aliasType, n.lang, - // n.version - if (prevAccnId == rs.getLong(1) || prevAccnId == -1) { - prevAccnId = rs.getLong(1); - System.err.println("Add... " + prevAccnId + " " + rs.getLong(1)); - } else { - cleanup(prevAccnId, aliases); - aliases.clear(); - prevAccnId = rs.getLong(1); - } - aliases.add(new Object[] { rs.getLong(7), rs.getString(2), rs.getString(3), rs.getInt(4), rs.getString(5) }); - } - - private void cleanup(long accessionId, List existingAliases) { - System.err.println("CLEANUP:"); - for (final Object[] alias : existingAliases) { - System.err.println("" + accessionId + " = " + ArrayUtils.toString(alias, "NULL")); - } - - for (int i = 0; i < existingAliases.size() - 1; i++) { - final Object[] name1 = existingAliases.get(i); - if (toRemove.contains(name1[0])) { - continue; - } - System.err.println("Base " + i + " " + ArrayUtils.toString(name1)); - for (int j = i + 1; j < existingAliases.size(); j++) { - System.err.println("Inspecting " + j); - final Object[] name2 = existingAliases.get(j); - if (toRemove.contains(name2[0])) { - continue; - } - final int res = whatToKeep(name1, name2); - if (res == -1) { - System.err.println("Would remove " + i + " " + ArrayUtils.toString(name1)); - toRemove.add((long) name1[0]); - } else if (res == 1) { - System.err.println("Would remove " + j + " " + ArrayUtils.toString(name2)); - toRemove.add((long) name2[0]); - } - } - } - } - - private int whatToKeep(Object[] name1, Object[] name2) { - if (StringUtils.equals((String) name1[2], (String) name2[2])) { - final float score1 = score(name1), score2 = score(name2); - if (score1 < score2) { - return -1; - } else { - return 1; - } - } else { - return 0; - } - } - - private float score(Object[] name1) { - float score = 1.0f; - if (name1[1] != null) { - score += 2; - if ((int) name1[3] == 5) { - score *= 2; - } - } else { - if ((int) name1[3] == 0) { - score += 1; - } - } - return score; - } - }); - - this.genesysService.removeAliases(toRemove); - - return "redirect:/admin/"; - } - @RequestMapping(method = RequestMethod.POST, value = "/sanitize") public String sanitize() { LOG.info("Sanitizing content"); @@ -357,48 +209,6 @@ public class AdminController { return "redirect:/admin/"; } - @RequestMapping(value = "/pdci", method = RequestMethod.POST, params = { "action=missing-pdci" }) - public String generatePDCI() { - final Set batch = Collections.synchronizedSet(new HashSet<>()); - - Collection idsMissingPdci = accessionIdRepository.findMissingPDCI(); - LOG.info("Emm, {} are missing PDCI", idsMissingPdci.size()); - - idsMissingPdci.parallelStream().forEach(accessionId -> { - batch.add(accessionId); - synchronized (batch) { - if (batch.size() >= 1000) { - taskExecutor.execute(new PDCIUpdater(new HashSet(batch))); - batch.clear(); - } - } - }); - - taskExecutor.execute(new PDCIUpdater(batch)); - return "redirect:/admin/"; - } - - @RequestMapping(value = "/pdci", method = RequestMethod.POST, params = { "action=full-recalc" }) - public String recreatePDCI() { - final Set batch = Collections.synchronizedSet(new HashSet<>()); - - Collection idsMissingPdci = accessionIdRepository.findAllIds(); - LOG.info("Emm, {} will have their PDCI recalculated", idsMissingPdci.size()); - - idsMissingPdci.parallelStream().forEach(accessionId -> { - batch.add(accessionId); - synchronized (batch) { - if (batch.size() >= 1000) { - taskExecutor.execute(new PDCIUpdater(new HashSet(batch))); - batch.clear(); - } - } - }); - - taskExecutor.execute(new PDCIUpdater(batch)); - return "redirect:/admin/"; - } - @RequestMapping(value = "/admin-action", method = RequestMethod.POST, params = "georegion") public String updateGeoReg() throws IOException, ParserConfigurationException, SAXException { geoRegionService.updateGeoRegionData(); diff --git a/src/main/java/org/genesys2/server/servlet/controller/rdf/AccessionControllerRdf.java b/src/main/java/org/genesys2/server/servlet/controller/rdf/AccessionControllerRdf.java index bf4ba2b653559359b2c0b137866e6618f588b7a4..ee0c85aa3643183613d9943f9921c3fc082578e8 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/rdf/AccessionControllerRdf.java +++ b/src/main/java/org/genesys2/server/servlet/controller/rdf/AccessionControllerRdf.java @@ -65,10 +65,10 @@ public class AccessionControllerRdf { model.addAttribute("accession", accession); model.addAttribute("accessionNames", genesysService.listAccessionNames(accession.getAccessionId())); - model.addAttribute("accessionExchange", genesysService.getAccessionExchange(accession.getAccessionId())); - model.addAttribute("accessionCollect", genesysService.getAccessionCollect(accession.getAccessionId())); - model.addAttribute("accessionBreeding", genesysService.getAccessionBreeding(accession.getAccessionId())); - model.addAttribute("accessionGeo", genesysService.getAccessionGeo(accession.getAccessionId())); + model.addAttribute("accessionExchange", accession); + model.addAttribute("accessionCollect", accession.getAccessionId().getColl()); + model.addAttribute("accessionBreeding", accession); + model.addAttribute("accessionGeo", accession.getAccessionId().getGeo()); model.addAttribute("metadatas", genesysService.listMetadata(accession.getAccessionId())); model.addAttribute("methods", traitService.listMethods(accession.getAccessionId())); diff --git a/src/main/java/org/genesys2/server/servlet/controller/rest/AccessionController.java b/src/main/java/org/genesys2/server/servlet/controller/rest/AccessionController.java index 7f34727937c46a85ac4c4431d9f1f884d2ce1268..ba896a50180c7b5b4a0ae1407096a90e626e275e 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/rest/AccessionController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/rest/AccessionController.java @@ -18,24 +18,17 @@ package org.genesys2.server.servlet.controller.rest; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import javax.persistence.RollbackException; +import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils; import org.genesys2.server.model.elastic.AccessionDetails; import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.model.json.AccessionJson; -import org.genesys2.server.service.AccessionOpResponse; -import org.genesys2.server.service.BatchRESTService; import org.genesys2.server.service.ElasticService; import org.genesys2.server.service.GenesysFilterService; import org.genesys2.server.service.GenesysRESTService; @@ -48,10 +41,12 @@ import org.genesys2.server.service.impl.NonUniqueAccessionException; import org.genesys2.server.service.impl.RESTApiException; import org.genesys2.server.service.impl.RESTApiValueException; import org.genesys2.server.service.impl.SearchException; +import org.genesys2.server.service.worker.AccessionOpResponse; +import org.genesys2.server.service.worker.AccessionOpResponse.UpsertResult; +import org.genesys2.server.service.worker.AccessionUploader; +import org.genesys2.server.service.worker.InvalidApiUsageException; import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; -import org.genesys2.server.servlet.controller.rest.model.AccessionNamesJson; import org.genesys2.spring.ResourceNotFoundException; -import org.genesys2.util.InvalidDOIException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.DataIntegrityViolationException; @@ -59,9 +54,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.http.MediaType; -import org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; +import org.springframework.transaction.TransactionException; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -70,10 +65,17 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + @Controller("restAccessionController") @PreAuthorize("isAuthenticated()") @RequestMapping(value = { "/api/v0/acn", "/json/v0/acn" }) public class AccessionController extends RestController { + private static final int UPLOAD_RETRIES = 10; private final ObjectMapper mapper = new ObjectMapper(); @@ -84,7 +86,7 @@ public class AccessionController extends RestController { private GenesysFilterService filterService; @Autowired - BatchRESTService batchRESTService; + private AccessionUploader uploader; @Autowired InstituteService instituteService; @@ -194,10 +196,10 @@ public class AccessionController extends RestController { * @throws RESTApiException */ @RequestMapping(value = "/{instCode}/upsert", method = { RequestMethod.POST, RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public @ResponseBody Object upsertInstituteAccession(@PathVariable("instCode") String instCode, @RequestBody JsonNode json) throws JsonProcessingException, IOException, - RESTApiException { + public @ResponseBody Object upsertInstituteAccession(@PathVariable("instCode") String instCode, @RequestBody ArrayNode updates) throws Exception { - LOG.trace("Received:\n {}", json); + LOG.trace("Received:\n {}", updates); + upgradeToV2(updates); // User's permission to WRITE to this WIEWS institute are checked in // BatchRESTService. @@ -206,91 +208,48 @@ public class AccessionController extends RestController { throw new ResourceNotFoundException(); } -// final JsonNode json = mapper.readTree(content); - final Map batch = new HashMap(); - - if (json.isArray()) { - for (final JsonNode j : json) { - try { - final AccessionHeaderJson dataJson = AccessionHeaderJson.fromJson(j); - if (!instCode.equals(dataJson.instCode)) { - throw new RuntimeException("Accession does not belong to instCode=" + instCode + " acn=" + dataJson); - } - batch.put(dataJson, (ObjectNode) j); - } catch (InvalidDOIException e) { - throw new RESTApiException("Invalid DOI", e); - } - } - } else { + for (int tryCount = 0; tryCount < UPLOAD_RETRIES; tryCount++) { try { - final AccessionHeaderJson dataJson = AccessionHeaderJson.fromJson(json); - if (!instCode.equals(dataJson.instCode)) { - throw new RuntimeException("Accession does not belong to instCode=" + instCode + " acn=" + dataJson); - } - batch.put(dataJson, (ObjectNode) json); - } catch (InvalidDOIException e) { - throw new RESTApiException("Invalid DOI", e); + return uploader.upsertAccessions(institute, updates); + } catch (TransactionException | RollbackException | CannotAcquireLockException | DataIntegrityViolationException e) { + return upsert1By1(institute, updates); + } catch (PleaseRetryException e) { + LOG.error("Retry {} of {} tries due to: {}", tryCount, UPLOAD_RETRIES, e.getMessage()); + // Wait a bit + Thread.sleep((long) (RandomUtils.nextDouble(10, 100) * tryCount)); } } + throw new InvalidApiUsageException("Just couldn't do it."); + } - Throwable cause = null; - - try { - for (int i = 0; i < 10; i++) { + private List upsert1By1(FaoInstitute institute, ArrayNode updates) throws Exception { + List response = new ArrayList<>(); + ArrayNode single = new ObjectMapper().createArrayNode(); + for (JsonNode update : updates) { + single.removeAll(); + single.add(update); + Throwable lastException = null; + for (int tryCount = 0; tryCount < UPLOAD_RETRIES; tryCount++) { try { - if (i > 0) { - LOG.info("Retry {} of 10", i); - } - // Step 1: Ensure all taxonomic data provided by client is persisted - batchRESTService.ensureTaxonomies(institute, batch); - // Step 2: Upsert data - List response = null; - try { - response = batchRESTService.upsertAccessionData(institute, batch); - } catch (RESTApiException | DataIntegrityViolationException e) { - LOG.info("Retrying upsert one by one due to {}", e.getMessage()); - response = upsertAccessionData1by1(institute, batch); + response.addAll(uploader.upsertAccessions(institute, single)); + lastException = null; + break; + } catch (TransactionException | RollbackException | CannotAcquireLockException | DataIntegrityViolationException | PleaseRetryException e) { + lastException = e; + if (tryCount > 1) { + LOG.info("Retry {} of {} tries due to: {}", tryCount, UPLOAD_RETRIES, e.getMessage()); + } else { + LOG.debug("Retrying {} of {} tries due to: {}", tryCount, UPLOAD_RETRIES, e.getMessage()); } - // Force update institute#accessionCount (outside previous - // transaction) - genesysService.updateAccessionCount(institute); - return response; - } catch (PleaseRetryException | HibernateOptimisticLockingFailureException e) { - LOG.info("Will retry upsert. Error: {}", e.getMessage()); - cause = e; + // Wait a bit + Thread.sleep((long) (RandomUtils.nextDouble(10, 100) * tryCount)); } } - } catch (RESTApiException e) { - throw e; - } catch (Throwable e) { - LOG.error("Failed to upsert accession data", e); - cause = e; - } - throw new RESTApiException("Could not upsert accession data. " + cause.getMessage(), cause); - } - - private List upsertAccessionData1by1(FaoInstitute institute, Map batch) { - LOG.info("Attempting insert 1 by 1"); - - final Map batchOfOne = new HashMap(); - List response = new ArrayList(); - for (AccessionHeaderJson acceJ : batch.keySet()) { - - try { - - batchOfOne.clear(); - batchOfOne.put(acceJ, batch.get(acceJ)); - AccessionOpResponse accessionResponse = batchRESTService.upsertAccessionData(institute, batchOfOne).get(0); - response.add(accessionResponse); - - } catch (RESTApiException | DataIntegrityViolationException e) { - if (LOG.isInfoEnabled()) { - LOG.info("Error upserting {}: {}", acceJ.instCode, e.getMessage()); - } - - AccessionOpResponse accessionResponse = new AccessionOpResponse(acceJ.instCode, acceJ.acceNumb, acceJ.genus); - accessionResponse.setError(getDetailedErrorMessage(e)); - response.add(accessionResponse); + if (lastException != null) { + LOG.warn("Upsert failed due to: {} data={}", lastException.getMessage(), update, lastException); + // record error + response.add(new AccessionOpResponse(update.get("instituteCode").asText(), update.get("accessionNumber").asText(), update.get("taxonomy").get("genus").asText()) + .setResult(new UpsertResult(UpsertResult.Type.ERROR)).setError(lastException.getMessage())); } } return response; @@ -305,68 +264,6 @@ public class AccessionController extends RestController { return sb.toString(); } - /** - * Update accessions in the system - * - * @return - * @throws RESTApiException - * @throws IOException - * @throws JsonProcessingException - */ - @RequestMapping(value = "/{instCode}/names", method = { RequestMethod.POST, RequestMethod.PUT }, consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaType.APPLICATION_JSON_VALUE }) - public @ResponseBody List upsertAccessionNames(@PathVariable("instCode") String instCode, @RequestBody List batch) - throws RESTApiException { - // User's permission to WRITE to this WIEWS institute are checked in - // BatchRESTService. - final FaoInstitute institute = instituteService.getInstitute(instCode); - if (institute == null) { - throw new ResourceNotFoundException(); - } - - try { - List response = null; - - try { - response = batchRESTService.upsertAccessionNames(institute, batch); - } catch (RESTApiException e) { - LOG.info("Retrying upsert names one by one due to {}", e.getMessage()); - response = upsertAccessionNames1by1(institute, batch); - } - return response; - - } catch (Throwable e) { - throw new RESTApiException("Could not upsert accession names data. " + e.getMessage(), e); - } - } - - private List upsertAccessionNames1by1(FaoInstitute institute, List batch) { - LOG.info("Attempting upsert accession names 1 by 1"); - - final List batchOfOne = new ArrayList(1); - List response = new ArrayList(); - for (AccessionNamesJson acceJ : batch) { - - try { - - batchOfOne.clear(); - batchOfOne.add(acceJ); - AccessionOpResponse accessionResponse = batchRESTService.upsertAccessionNames(institute, batchOfOne).get(0); - response.add(accessionResponse); - - } catch (RESTApiException e) { - if (LOG.isInfoEnabled()) { - LOG.info("Error upserting {}: {}", acceJ.instCode, e.getMessage()); - } - - AccessionOpResponse accessionResponse = new AccessionOpResponse(acceJ.instCode, acceJ.acceNumb, acceJ.genus); - accessionResponse.setError(getDetailedErrorMessage(e)); - response.add(accessionResponse); - } - } - return response; - } - /** * Delete accessions by acceNumb (and genus)? * @@ -388,10 +285,10 @@ public class AccessionController extends RestController { try { List response = null; try { - response = batchRESTService.deleteAccessions(institute, batch); + response = uploader.deleteAccessions(institute, batch); LOG.info("Deleted {} accessions from {}", response.size(), instCode); - } catch (RESTApiException e) { - LOG.info("Retrying upsert one by one due to {}", e.getMessage()); + } catch (TransactionException | RollbackException | CannotAcquireLockException | DataIntegrityViolationException e) { + LOG.info("Retrying delete one by one due to {}", e.getMessage()); response = deleteAccessions1by1(institute, batch); } // Force update institute#accessionCount (outside previous @@ -415,10 +312,10 @@ public class AccessionController extends RestController { batchOfOne.clear(); batchOfOne.add(acceJ); - AccessionOpResponse accessionResponse = batchRESTService.deleteAccessions(institute, batchOfOne).get(0); + AccessionOpResponse accessionResponse = uploader.deleteAccessions(institute, batchOfOne).get(0); response.add(accessionResponse); - } catch (RESTApiException e) { + } catch (Throwable e) { if (LOG.isInfoEnabled()) { LOG.info("Error deleting {}: {}", acceJ.instCode, e.getMessage()); } @@ -431,29 +328,6 @@ public class AccessionController extends RestController { return response; } - /** - * Delete accessions by acceNumb (and genus)? - * - * @return - * @throws RESTApiException - * @throws IOException - * @throws JsonProcessingException - */ - @RequestMapping(value = "/{instCode}/delete", method = { RequestMethod.POST }, consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public @ResponseBody int deleteAccessionsById(@PathVariable("instCode") String instCode, @RequestBody List batch) throws RESTApiException { - // User's permission to WRITE to this WIEWS institute are checked in - // BatchRESTService. - final FaoInstitute institute = instituteService.getInstitute(instCode); - if (institute == null) { - throw new ResourceNotFoundException(); - } - - final int deleted = batchRESTService.deleteAccessionsById(institute, batch); - LOG.info("Deleted {} accessions from {}", deleted, instCode); - genesysService.updateAccessionCount(institute); - return deleted; - } - @RequestMapping(value = "/search", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) public @ResponseBody Page search(@RequestParam("page") final int page, @RequestParam("query") final String query) throws SearchException { return elasticService.search(StringUtils.defaultIfBlank(query, "*"), new PageRequest(page - 1, 20)); @@ -515,4 +389,58 @@ public class AccessionController extends RestController { public Integer maxRecords; public String otherOptions; } + + + + private void upgradeToV2(ArrayNode updates) { + for (JsonNode update : updates) { + upgradeToV2((ObjectNode) update); + } + } + + private void upgradeToV2(ObjectNode update) { + upgradeRename(update, "instCode", "instituteCode"); + upgradeRename(update, "acceNumb", "accessionNumber"); + upgradeRename(update, "spauthor", "spAuthor"); + upgradeRename(update, "subtauthor", "subtAuthor"); + upgradeRename(update, "acqDate", "acquisitionDate"); + upgradeRename(update, "bredCode", "breederCode"); + upgradeRename(update, "mlsStat", "mlsStatus"); + + if (update.has("geo")) { + ObjectNode geo = (ObjectNode) update.get("geo"); + upgradeRename(geo, "coordUncert", "uncertainty"); + upgradeRename(geo, "coordDatum", "datum"); + upgradeRename(geo, "georefMeth", "method"); + } + + ObjectNode taxonomy; + if (update.has("taxonomy")) { + taxonomy = (ObjectNode) update.get("taxonomy"); + } else { + taxonomy = update.putObject("taxonomy"); + } + + upgradeTaxonomy(update, taxonomy, "genus"); + upgradeTaxonomy(update, taxonomy, "species"); + upgradeTaxonomy(update, taxonomy, "spAuthor"); + upgradeTaxonomy(update, taxonomy, "subtaxa"); + upgradeTaxonomy(update, taxonomy, "subtAuthor"); + } + + private void upgradeRename(ObjectNode update, String v1name, String v2name) { + if (update.has(v1name)) { + update.set(v2name, update.remove(v1name)); + } + } + + private void upgradeTaxonomy(ObjectNode source, ObjectNode taxonomy, String fieldName) { + if (source.has(fieldName)) { + if (taxonomy.has(fieldName)) { + source.remove(fieldName); + } else { + taxonomy.set(fieldName, source.remove(fieldName)); + } + } + } } diff --git a/src/main/java/org/genesys2/server/servlet/controller/rest/PleaseRetryException.java b/src/main/java/org/genesys2/server/servlet/controller/rest/PleaseRetryException.java index ff924b2fb4a70c0931d27bfa23d431c47b840c48..06e956e7ff3f4a2a9dfec3bee35df3bfd4f18a59 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/rest/PleaseRetryException.java +++ b/src/main/java/org/genesys2/server/servlet/controller/rest/PleaseRetryException.java @@ -1,8 +1,8 @@ package org.genesys2.server.servlet.controller.rest; -import org.genesys2.server.service.impl.RESTApiException; +import org.genesys2.server.service.worker.InvalidApiUsageException; -public class PleaseRetryException extends RESTApiException { +public class PleaseRetryException extends InvalidApiUsageException { /** * diff --git a/src/main/java/org/genesys2/server/servlet/controller/rest/serialization/AccessionSerializer.java b/src/main/java/org/genesys2/server/servlet/controller/rest/serialization/AccessionSerializer.java deleted file mode 100644 index bb23ec24148d13d859ccc7abbec97c8e2122fea7..0000000000000000000000000000000000000000 --- a/src/main/java/org/genesys2/server/servlet/controller/rest/serialization/AccessionSerializer.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.servlet.controller.rest.serialization; - -import java.io.IOException; - -import org.genesys2.server.model.genesys.Accession; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -// FIXME not used -public class AccessionSerializer extends JsonSerializer { - - @Override - public void serialize(Accession accession, JsonGenerator jgen, SerializerProvider sp) throws IOException, JsonProcessingException { - if (accession == null) { - jgen.writeNull(); - } else { - jgen.writeStartObject(); - jgen.writeObjectField("id", accession.getId()); - jgen.writeObjectField("version", accession.getVersion()); - jgen.writeStringField("accessionName", accession.getAccessionName()); - jgen.writeObjectField("countryOfOrigin", accession.getCountryOfOrigin()); - jgen.writeObjectField("taxonomy", accession.getTaxonomy()); - jgen.writeObjectField("institute", accession.getInstitute()); - jgen.writeEndObject(); - } - } - -} diff --git a/src/main/java/org/genesys2/util/MCPDUtil.java b/src/main/java/org/genesys2/util/MCPDUtil.java index f96c4022dc499605fe50ba8c30c1441f17a86d70..1d667ed502f70a7ec6a6c6d1fa4da8c394118486 100644 --- a/src/main/java/org/genesys2/util/MCPDUtil.java +++ b/src/main/java/org/genesys2/util/MCPDUtil.java @@ -17,6 +17,7 @@ package org.genesys2.util; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -25,6 +26,9 @@ import org.apache.commons.lang3.StringUtils; public class MCPDUtil { static Pattern mcpdSplit = Pattern.compile("\\s*;\\s*"); + public static final Pattern MCPDDATE_PATTERN = Pattern.compile("^[1-9]\\d{3}(\\d|-){4}$"); + public static final Pattern WIEWSCODE_PATTERN = Pattern.compile("^\\p{Upper}{3}(\\d){3,4}$"); + /** * Convert a List to MCPD "array string" with semicolon as separator. @@ -32,7 +36,7 @@ public class MCPDUtil { * @param integers * @return */ - public static String toMcpdArray(List objects) { + public static String toMcpdArray(Collection objects) { if (objects == null || objects.size() == 0) return null; @@ -73,4 +77,12 @@ public class MCPDUtil { return Arrays.stream(mcpdSplit.split(strings)).filter(str -> StringUtils.isNotBlank(str)).collect(Collectors.toList()); } + + public static boolean isMcpdDate(String date) { + return date == null ? false : MCPDDATE_PATTERN.matcher(date).matches(); + } + + public static boolean isWiewsCode(String code) { + return code == null ? false : WIEWSCODE_PATTERN.matcher(code).matches(); + } } diff --git a/src/main/java/org/genesys2/util/PDCICalculator.java b/src/main/java/org/genesys2/util/PDCICalculator.java new file mode 100644 index 0000000000000000000000000000000000000000..13c08bebbfaf9d1b3dcef935fc1b21224b522196 --- /dev/null +++ b/src/main/java/org/genesys2/util/PDCICalculator.java @@ -0,0 +1,447 @@ +package org.genesys2.util; + +import java.util.Collection; + +import org.apache.commons.lang.StringUtils; +import org.genesys2.server.model.genesys.Accession; +import org.genesys2.server.model.genesys.AccessionAlias; +import org.genesys2.server.model.genesys.AccessionAlias.AliasType; +import org.genesys2.server.model.genesys.AccessionCollect; +import org.genesys2.server.model.genesys.AccessionGeo; +import org.genesys2.server.model.genesys.AccessionId; +import org.genesys2.server.model.genesys.PDCI; +import org.genesys2.server.model.genesys.Taxonomy2; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Calculates PDCI value for an accession. + * + *

+ * Theo van Hintum, Frank Menting and Elisabeth van Strien (2011). Quality + * indicators for passport data in ex situ genebanks. Plant Genetic + * Resources, 9, pp 478-485. + * + * doi:10.1017/S1479262111000682 + *

+ */ +public class PDCICalculator { + public static final Logger LOG = LoggerFactory.getLogger(PDCICalculator.class); + + public static PDCI updatePdci(PDCI pdci, Accession accession) { + pdci.reset(); + + independentDescriptors(pdci, accession); + + switch (accession.getSampStat() == null ? -1 : accession.getSampStat() / 100) { + case 1: + case 2: + wildOrWeedy(pdci, accession); + break; + + case 3: + landrace(pdci, accession); + break; + case 4: + breedingMaterial(pdci, accession); + break; + case 5: + cultivar(pdci, accession); + default: + otherTypes(pdci, accession); + } + + return pdci; + } + + private static void independentDescriptors(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + + taxonomic(pdci, accession.getTaxonomy()); + + if (StringUtils.isNotBlank(accession.getCropName())) { + pdci.setCropName(45); + } + + if (StringUtils.isNotBlank(accession.getAcquisitionDate())) { + if (MCPDUtil.isMcpdDate(accession.getAcquisitionDate())) { + pdci.setAcqDate(10); + } else { + pdci.setAcqDate(5); + } + } + if (accession.getSampStat() != null) { + pdci.setSampStat(80); + } + if (StringUtils.isNotBlank(accession.getDonorCode())) { + if (! accession.getDonorCode().equals(accession.getInstituteCode())) { + if (MCPDUtil.isWiewsCode(accession.getDonorCode())) { + pdci.setDonorCode(40); + } else { + pdci.setDonorCode(20); + } + } else { + // Punish + } + } + if (StringUtils.isNotBlank(accession.getDonorNumb())) { + if (StringUtils.isBlank(accession.getDonorCode()) || accession.getInstituteCode().equals(accession.getDonorCode()) || StringUtils.isBlank(accession.getDonorName())) { + pdci.setDonorNumb(30); + } else { + pdci.setDonorNumb(40); + } + } + + if (names(accessionId.getAliases(), AliasType.OTHERNUMB)) { + pdci.setOtherNumb(35); + } + + if (accessionId.getDuplSite() != null && accessionId.getDuplSite().size() > 0) { + if (accessionId.getDuplSite().stream().filter(code -> ! MCPDUtil.isWiewsCode(code)).count() == 0) { + pdci.setDuplSite(30); + } else { + pdci.setDuplSite(15); + } + } else { + // Missing DUPLINSTNAME in Genesys, would add 15 + pdci.setDuplInstName(0); + } + + if (accessionId.getStorage() != null && accessionId.getStorage().size() > 0) { + pdci.setStorage(15); + } + + if (StringUtils.isNotBlank(accession.getDonorName())) { + if (StringUtils.isBlank(accession.getDonorCode())) { + pdci.setDonorName(20); + } else { + pdci.setDonorName(0); + } + } + + if (accession.getAcceUrl() != null) { + pdci.setAcceUrl(40); + } + + if (accession.getMlsStatus() != null) { + pdci.setMlsStat(15); + } + } + + private static void taxonomic(PDCI pdci, Taxonomy2 taxonomy) { + if (taxonomy != null) { + if (!StringUtils.isBlank(taxonomy.getGenus())) { + pdci.setGenus(120); + if (!StringUtils.isBlank(taxonomy.getSpecies()) && !StringUtils.equalsIgnoreCase("sp.", taxonomy.getSpecies())) { + pdci.setSpecies(80); + + if (!StringUtils.isBlank(taxonomy.getSpAuthor())) { + pdci.setSpAuthor(5); + } + if (!StringUtils.isBlank(taxonomy.getSubtaxa())) { + pdci.setSubTaxa(40); + + if (!StringUtils.isBlank(taxonomy.getSubtAuthor())) { + pdci.setSubtAuthor(5); + } + } + } + } + } + } + + private static void wildOrWeedy(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + + AccessionGeo geo = accessionId.getGeo(); + AccessionCollect coll = accessionId.getColl(); + + if (accession.getOrigCty() != null) { + pdci.setOrigCty(80); + } + + boolean hasLatLng = false; + + if (geo != null) { + if (geo.getLatitude() != null && geo.getLongitude() != null) { + if (geo.getLatitude() < -90 || geo.getLatitude() > 90 || geo.getLongitude() < -180 || geo.getLongitude() > 180) { + // Ignore coordinates + } else { + pdci.setLatitude(60); + pdci.setLongitude(60); + hasLatLng = true; + } + } + + if (geo.getElevation() != null) { + pdci.setElevation(20); + } + } + + if (coll != null) { + if (StringUtils.isNotBlank(coll.getCollSite())) { + if (hasLatLng) + pdci.setCollSite(20); + else + pdci.setCollSite(70); + } + + if (StringUtils.isNotBlank(coll.getCollDate())) { + if (MCPDUtil.isMcpdDate(coll.getCollDate())) { + pdci.setCollDate(30); + } else { + pdci.setCollDate(15); + } + } + if (coll.getCollSrc() != null) { + pdci.setCollSrc(30); + } + + if (StringUtils.isNotBlank(coll.getCollNumb())) { + pdci.setCollNumb(60); + } + if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { + pdci.setCollCode(40); + } else { + if (coll.getCollName() != null && coll.getCollName().size() > 0) { + pdci.setCollName(20); + } + } + } + } + + private static void landrace(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + AccessionGeo geo = accessionId.getGeo(); + AccessionCollect coll = accessionId.getColl(); + + if (accession.getOrigCty() != null) { + pdci.setOrigCty(80); + } + + boolean hasLatLng = false; + + if (geo != null) { + if (geo.getLatitude() != null && geo.getLongitude() != null) { + pdci.setLatitude(40); + pdci.setLongitude(40); + hasLatLng = true; + } + + if (geo.getElevation() != null) { + pdci.setElevation(15); + } + } + + if (coll != null) { + if (StringUtils.isNotBlank(coll.getCollSite())) { + if (hasLatLng) + pdci.setCollSite(15); + else + pdci.setCollSite(45); + } + + if (StringUtils.isNotBlank(coll.getCollDate())) { + if (MCPDUtil.isMcpdDate(coll.getCollDate())) { + pdci.setCollDate(30); + } else { + pdci.setCollDate(15); + } + } + + if (StringUtils.isNotBlank(accession.getAncest())) { + pdci.setAncest(10); + } + + if (coll.getCollSrc() != null) { + pdci.setCollSrc(50); + } + + if (names(accession.getAccessionId().getAliases(), AliasType.ACCENAME)) { + pdci.setAcceName(50); + } + + if (StringUtils.isNotBlank(coll.getCollNumb())) { + pdci.setCollNumb(40); + } + if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { + pdci.setCollCode(30); + } else { + if (coll.getCollName() != null && coll.getCollName().size() > 0) { + pdci.setCollName(15); + } + } + } + } + + private static void breedingMaterial(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + AccessionCollect coll = accessionId.getColl(); + + if (accession.getOrigCty() != null) { + pdci.setOrigCty(40); + } + + if (accessionId.getBreederCode() != null && accessionId.getBreederCode().size() > 0) { + if (accessionId.getBreederCode().stream().filter(code -> ! MCPDUtil.isWiewsCode(code)).count() == 0) { + pdci.setBredCode(110); + } else { + pdci.setBredCode(55); + } + } + + if (StringUtils.isNotBlank(accession.getAncest())) { + pdci.setAncest(150); + } + + if (coll != null) { + if (StringUtils.isNotBlank(coll.getCollSite())) { + } + + if (StringUtils.isNotBlank(coll.getCollDate())) { + } + + if (coll.getCollSrc() != null) { + pdci.setCollSrc(20); + } + + if (names(accession.getAccessionId().getAliases(), AliasType.ACCENAME)) { + pdci.setAcceName(80); + } + + if (StringUtils.isNotBlank(coll.getCollNumb())) { + } + + if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { + } + } + } + + private static void cultivar(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + AccessionCollect coll = accessionId.getColl(); + + if (accession.getOrigCty() != null) { + pdci.setOrigCty(40); + } + + if (accessionId.getBreederCode() != null && accessionId.getBreederCode().size() > 0) { + if (accessionId.getBreederCode().stream().filter(code -> ! MCPDUtil.isWiewsCode(code)).count() == 0) { + pdci.setBredCode(80); + } else { + pdci.setBredCode(40); + } + } + + if (StringUtils.isNotBlank(accession.getAncest())) { + pdci.setAncest(100); + } + + if (coll != null) { + if (StringUtils.isNotBlank(coll.getCollSite())) { + } + + if (StringUtils.isNotBlank(coll.getCollDate())) { + } + + if (coll.getCollSrc() != null) { + pdci.setCollSrc(20); + } + + if (names(accession.getAccessionId().getAliases(), AliasType.ACCENAME)) { + pdci.setAcceName(160); + } + + if (StringUtils.isNotBlank(coll.getCollNumb())) { + } + + if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { + } + } + } + + private static void otherTypes(PDCI pdci, Accession accession) { + AccessionId accessionId = accession.getAccessionId(); + AccessionGeo geo = accessionId.getGeo(); + AccessionCollect coll = accessionId.getColl(); + + if (accession.getOrigCty() != null) { + pdci.setOrigCty(40); + } + + boolean hasLatLng = false; + + if (geo != null) { + if (geo.getLatitude() != null && geo.getLongitude() != null) { + pdci.setLatitude(15); + pdci.setLongitude(15); + hasLatLng = true; + } + + if (geo.getElevation() != null) { + pdci.setElevation(5); + } + } + + if (accessionId.getBreederCode() != null && accessionId.getBreederCode().size() > 0) { + if (accessionId.getBreederCode().stream().filter(code -> ! MCPDUtil.isWiewsCode(code)).count() == 0) { + pdci.setBredCode(10); + } else { + pdci.setBredCode(5); + } + } + + if (StringUtils.isNotBlank(accession.getAncest())) { + pdci.setAncest(40); + } + + if (names(accession.getAccessionId().getAliases(), AliasType.ACCENAME)) { + pdci.setAcceName(40); + } + + if (coll != null) { + if (StringUtils.isNotBlank(coll.getCollSite())) { + if (hasLatLng) + pdci.setCollSite(10); + else + pdci.setCollSite(20); + } + + if (StringUtils.isNotBlank(coll.getCollDate())) { + if (MCPDUtil.isMcpdDate(coll.getCollDate())) { + pdci.setCollDate(10); + } else { + pdci.setCollDate(5); + } + } + + if (coll.getCollSrc() != null) { + pdci.setCollSrc(25); + } + + if (StringUtils.isNotBlank(coll.getCollNumb())) { + pdci.setCollNumb(20); + } + if (coll.getCollCode() != null && coll.getCollCode().size() > 0) { + pdci.setCollCode(20); + } else { + if (coll.getCollName() != null && coll.getCollName().size() > 0) { + pdci.setCollName(10); + } + } + } + } + + private static boolean names(Collection aliases, AliasType type) { + if (aliases == null || aliases.size() == 0) + return false; + + for (AccessionAlias alias : aliases) { + if (alias.getAliasType() == type) { + return true; + } + } + return false; + } + +} diff --git a/src/main/resources/dummy-data/IND002.json b/src/main/resources/dummy-data/IND002.json index 471b9dddf6e30474e9ecfd9feba247af65c4b9ea..64d803c33901bf2e49eb2f9071f7dc991638835c 100644 --- a/src/main/resources/dummy-data/IND002.json +++ b/src/main/resources/dummy-data/IND002.json @@ -1,19 +1,19 @@ -[ - { - "instCode": "IND002", - "acceNumb": "IS 1", - "acqDate": "19740510", - "acqSrc": "40", - "available": true, - "art15": true, - "sampStat": 300, - "storage": [12, 13], - "origCty": "MEX", +[{ + "instituteCode": "IND002", + "accessionNumber": "IS 1", + "acquisitionDate": "19740510", + "acquisitionSource": "40", + "available": true, + "inTrust": true, + "sampStat": 300, + "storage": [12, 13], + "origCty": "MEX", + "taxonomy": { "genus": "Sorghum", "species": "bicolor", "spAuthor": "(L.) Moench", "subtaxa": "bicolor", - "subtAuthor": null, - "cropName": "sorghum" - } -] + "subtAuthor": null + }, + "cropName": "sorghum" +}] diff --git a/src/main/resources/dummy-data/PER001.json b/src/main/resources/dummy-data/PER001.json index 7493d12585de02ff3f5c31c6d82ed3454cb01276..207562f86dbebd03277021304aedc5aef82fa436 100644 --- a/src/main/resources/dummy-data/PER001.json +++ b/src/main/resources/dummy-data/PER001.json @@ -1,18 +1,22 @@ [{ - "instCode": "PER001", + "instituteCode": "PER001", "doi": "10.18730/2BYS", - "acceNumb": "CIP 400004", - "genus": "Ipomoea", + "accessionNumber": "CIP 400004", + "taxonomy": { + "genus": "Ipomoea" + }, "orgCty": "PER" }, { - "instCode": "PER001", + "instituteCode": "PER001", "doi": "10.18730/2BRK", - "acceNumb": "CIP 374080.5", - "acceName": [ "Perricholi "], - "genus": "Solanum", - "orgCty": "PER", - "acqDate": "19931026", - "availability": true + "accessionNumber": "CIP 374080.5", + "acceName": ["Perricholi"], + "taxonomy": { + "genus": "Solanum" + }, + "origCty": "PER", + "acquisitionDate": "19931026", + "available": true } ] diff --git a/src/main/resources/liquibase.properties b/src/main/resources/liquibase.properties index f2e9ad1401cbc6031de4b1060f7a0e91f3d9c260..8373f7b3ef575f3b54b1754731e098358590fc18 100644 --- a/src/main/resources/liquibase.properties +++ b/src/main/resources/liquibase.properties @@ -9,12 +9,12 @@ changeLogFile=src/main/resources/liquibase/liquibase-changeLog.yml ## Uncomment for mvn liquibase:diff #diffChangeLogFile=src/main/resources/liquibase/liquibase-diff-changeLog.yml -## Current database -#url=jdbc:mysql://localhost/genesys20171011?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false&hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy +## Existing database +#url=jdbc:mysql://localhost/genesysold?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false&hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy #username=root #password= #driver=com.mysql.jdbc.Driver -## Base database +## Upgraded database #referenceUrl=jdbc:mysql://localhost/genesys?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false&hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy #referenceDriver=com.mysql.jdbc.Driver #referenceUsername=root diff --git a/src/main/resources/liquibase/liquibase-changeLog.yml b/src/main/resources/liquibase/liquibase-changeLog.yml index dbc39900f54e2c4bdcb1feb70e51baac00e2ee91..2ce9f859d37950ff8df0a60039611ab33e6822be 100644 --- a/src/main/resources/liquibase/liquibase-changeLog.yml +++ b/src/main/resources/liquibase/liquibase-changeLog.yml @@ -1225,3 +1225,478 @@ databaseChangeLog: sql: delete from accessionexchange where acceNumb is null and donorInst is null and donorName is null; - sql: sql: delete from auditlog where classPk = (select id from classpk where classname='org.genesys2.server.model.genesys.PDCI'); + + +# +# Upgrade Genesys model: relationships flips +# +- changeSet: + id: 1531216028000-1 + author: mobreza (generated) + changes: + - renameTable: + newTableName: accession_alias + oldTableName: accessionalias + - renameTable: + newTableName: accession_collect + oldTableName: accessioncollect + - renameTable: + newTableName: accession_geo + oldTableName: accessiongeo + - renameTable: + newTableName: accession_historic + oldTableName: accessionhistoric + - renameTable: + newTableName: accession_list + oldTableName: accelist + - renameTable: + newTableName: accession_listitem + oldTableName: accelistitems + - renameTable: + newTableName: accession_remark + oldTableName: accessionremark + - renameTable: + newTableName: grin_taxonomy + oldTableName: GrinTaxonomy + + +- changeSet: + id: 1531216028024-2 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: accessionId + type: BIGINT + - column: + constraints: + nullable: false + name: breederCode + type: VARCHAR(9) + tableName: accession_breedercode + - addPrimaryKey: + columnNames: accessionId, breederCode + constraintName: PRIMARY + tableName: accession_breedercode + - addForeignKeyConstraint: + baseColumnNames: accessionId + baseTableName: accession_breedercode + constraintName: FK_i24m3cu3iutcu874affqlph62 + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: acce + +- changeSet: + id: 1531216028024-4 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: collectId + type: BIGINT + - column: + constraints: + nullable: false + name: collCode + type: VARCHAR(128) + tableName: accession_collect_code + - addPrimaryKey: + columnNames: collectId, collCode + constraintName: PRIMARY + tableName: accession_collect_code + - addForeignKeyConstraint: + baseColumnNames: collectId + baseTableName: accession_collect_code + constraintName: FK_p16on5ehgaa05ut41f87umkfa + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: accession_collect + +- changeSet: + id: 1531216028024-5 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: collectId + type: BIGINT + - column: + constraints: + nullable: false + name: collInstAddress + type: VARCHAR(128) + tableName: accession_collect_instaddr + - addPrimaryKey: + columnNames: collectId, collInstAddress + constraintName: PRIMARY + tableName: accession_collect_instaddr + - addForeignKeyConstraint: + baseColumnNames: collectId + baseTableName: accession_collect_instaddr + constraintName: FK_t9qrwws135bnmm0kh8fywg5j2 + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: accession_collect + + +- changeSet: + id: 1531216028024-6 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: collectId + type: BIGINT + - column: + constraints: + nullable: false + name: collName + type: VARCHAR(258) + tableName: accession_collect_name + - addPrimaryKey: + columnNames: collectId, collName + constraintName: PRIMARY + tableName: accession_collect_name + - addForeignKeyConstraint: + baseColumnNames: collectId + baseTableName: accession_collect_name + constraintName: FK_g6h5uuvq16105ljx8r1jjxojr + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: accession_collect + +- changeSet: + id: 1531216028024-7 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: accessionId + type: BIGINT + - column: + constraints: + nullable: false + name: duplSite + type: VARCHAR(9) + tableName: accession_duplsite + - addPrimaryKey: + columnNames: accessionId, duplSite + constraintName: PRIMARY + tableName: accession_duplsite + - addForeignKeyConstraint: + baseColumnNames: accessionId + baseTableName: accession_duplsite + constraintName: FK_2se3c4vyb38ci81qch7siopbu + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: acce + +- changeSet: + id: 1531216028024-13 + author: mobreza (generated) + changes: + - createTable: + columns: + - column: + constraints: + nullable: false + name: accessionId + type: BIGINT + - column: + constraints: + nullable: false + name: storage + type: INT + tableName: accession_storage + - addPrimaryKey: + columnNames: accessionId, storage + constraintName: PRIMARY + tableName: accession_storage + - addForeignKeyConstraint: + baseColumnNames: accessionId + baseTableName: accession_storage + constraintName: FK_2lk4y987jla0fka5nafkwmrbq + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: acce + +- changeSet: + id: 1531216028024-15 + author: mobreza + changes: + - addColumn: + tableName: accession + columns: + - column: + # constraints: + # nullable: false + name: genus + type: VARCHAR(100) + - column: + name: ancest + type: LONGTEXT + - column: + name: donorCode + type: VARCHAR(9) + - column: + name: donorName + type: VARCHAR(300) + - column: + name: donorNumb + type: VARCHAR(200) + - column: + name: names + type: LONGTEXT + - column: + name: otherIds + type: LONGTEXT + +- changeSet: + id: 1531216028024-15a + author: mobreza (generated) + changes: + - renameColumn: + columnDataType: varchar(100) + newColumnName: duplSiteStr + oldColumnName: duplSite + remarks: MCPD DUPLSITE as string + tableName: accession + - renameColumn: + columnDataType: varchar(100) + newColumnName: storageStr + oldColumnName: storage + remarks: MCPD STORAGE as string + tableName: accession + - renameColumn: + columnDataType: varchar(3) + newColumnName: origCty + oldColumnName: orgCty + remarks: MCPD storage as string + tableName: accession + +- changeSet: + id: 1531216028024-15b + author: mobreza (generated) + changes: + - addColumn: + tableName: accession_historic + columns: + - column: + # constraints: + # nullable: false + name: genus + type: VARCHAR(100) + - column: + name: ancest + type: LONGTEXT + - column: + name: donorCode + type: VARCHAR(9) + - column: + name: donorName + type: VARCHAR(300) + - column: + name: donorNumb + type: VARCHAR(200) + - column: + name: names + type: LONGTEXT + - column: + name: otherIds + type: LONGTEXT + +- changeSet: + id: 1531216028024-15c + author: mobreza (generated) + changes: + - renameColumn: + columnDataType: varchar(100) + newColumnName: duplSiteStr + oldColumnName: duplSite + remarks: MCPD DUPLSITE as string + tableName: accession_historic + - renameColumn: + columnDataType: varchar(100) + newColumnName: storageStr + oldColumnName: storage + remarks: MCPD STORAGE as string + tableName: accession_historic + - renameColumn: + columnDataType: varchar(3) + newColumnName: origCty + oldColumnName: orgCty + remarks: MCPD storage as string + tableName: accession_historic + + +- changeSet: + id: 1531216028024-16 + author: mobreza (generated) + changes: + - addColumn: + columns: + - column: + name: collId + type: BIGINT + - column: + name: geoId + type: BIGINT + - column: + name: pdciId + type: BIGINT + tableName: acce + - addUniqueConstraint: + columnNames: collId + constraintName: UK_8qrr86qim9fyaevm0gmneylnw + tableName: acce + - addUniqueConstraint: + columnNames: geoId + constraintName: UK_a4cq6l63j6xie0fwv806lfyhu + tableName: acce + - addUniqueConstraint: + columnNames: pdciId + constraintName: UK_ncmba94f9sebh9h056jqhukum + tableName: acce + +- changeSet: + id: 1531219203066-4 + author: mobreza (generated) + changes: + - createIndex: + columns: + - column: + name: acceNumb + indexName: IX_acceNumb + tableName: accession + +- changeSet: + id: 1531219203066-7 + author: mobreza (generated) + changes: + - dropForeignKeyConstraint: + baseTableName: accession_collect + constraintName: FK_3xjhvjcunn2ievi36gmuvf6nk + - dropUniqueConstraint: + constraintName: UK_3xjhvjcunn2ievi36gmuvf6nk + tableName: accession_collect + - addForeignKeyConstraint: + baseColumnNames: collId + baseTableName: acce + constraintName: FK_8qrr86qim9fyaevm0gmneylnw + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: accession_collect + +- changeSet: + id: 1531219203066-8 + author: mobreza (generated) + changes: + - dropForeignKeyConstraint: + baseTableName: accession_geo + constraintName: FK_mrtltk1iiohn7x6p6b9saxfee + - dropUniqueConstraint: + constraintName: UK_mrtltk1iiohn7x6p6b9saxfee + tableName: accession_geo + - addForeignKeyConstraint: + baseColumnNames: geoId + baseTableName: acce + constraintName: FK_a4cq6l63j6xie0fwv806lfyhu + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: accession_geo + +- changeSet: + id: 1531219203066-9 + author: mobreza (generated) + changes: + - dropForeignKeyConstraint: + baseTableName: pdci + constraintName: FK_c3fnk9quh9lou6hd1v5hpanbw + - dropUniqueConstraint: + constraintName: UK_offskcy4kgtcg89hcd8w9phmh + tableName: pdci + - addForeignKeyConstraint: + baseColumnNames: pdciId + baseTableName: acce + constraintName: FK_ncmba94f9sebh9h056jqhukum + deferrable: false + initiallyDeferred: false + onDelete: NO ACTION + onUpdate: NO ACTION + referencedColumnNames: id + referencedTableName: pdci + +- changeSet: + id: 1531219203066-35 + author: mobreza (generated) + changes: + - modifyDataType: + columnName: datum + newDataType: varchar(100) + tableName: accession_geo + - modifyDataType: + columnName: method + newDataType: varchar(100) + tableName: accession_geo + - createIndex: + columns: + - column: + name: latitude + - column: + name: longitude + indexName: UK_98cgokk6e16eqowc7iemvshid + tableName: accession_geo + - createIndex: + columns: + - column: + name: tileIndex + indexName: UK_25vrycbl69i8q41ewm4p9m13r + tableName: accession_geo + +- changeSet: + id: 1531219203066-43 + author: mobreza (generated) + changes: + - addNotNullConstraint: + columnDataType: clob + columnName: remark + tableName: accession_remark diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties index 790215de1538f484d55f06474c134337fe85b6bc..b74e997c4b37f09a74a494bad95b209617d5b106 100644 --- a/src/main/resources/log4j.properties +++ b/src/main/resources/log4j.properties @@ -47,3 +47,7 @@ log4j.category.liquibase=debug #log4j.category.org.genesys2.server.servlet.filter=debug #log4j.category.org.genesys2.server.servlet.filter.NewGUIFilter=debug #log4j.category.org.genesys2.spring.config.NewGUIViewResolver=trace + + +# Internal Hibernate logging is at ERROR +log4j.category.org.hibernate.engine.jdbc=fatal diff --git a/src/main/webapp/WEB-INF/jsp/accession/details.jsp b/src/main/webapp/WEB-INF/jsp/accession/details.jsp index 4dd47d921a032b45390598703badd14365dc2732..3d4c5ab1ec7e892853e6e4482e7a0e2274f7f90e 100644 --- a/src/main/webapp/WEB-INF/jsp/accession/details.jsp +++ b/src/main/webapp/WEB-INF/jsp/accession/details.jsp @@ -235,7 +235,7 @@

- +

@@ -266,9 +266,9 @@

- +

- +
@@ -282,9 +282,6 @@

- - "> - @@ -297,7 +294,7 @@ - +

@@ -305,7 +302,7 @@

- +

@@ -315,7 +312,6 @@
-

@@ -324,13 +320,13 @@

- - + + - +

- - + +
@@ -341,12 +337,11 @@

- +

- +
-
@@ -603,45 +598,45 @@ - -
-

- -

-
- -
-
-

- -

-
-
-

- -

- -
-
-
- -
-
-

- -

-
-
-

- -

- -
-
-
-
-
-
+
+

+ +

+
+ +
+
+

+ +

+
+
+ +

+ +

+
+ +
+
+
+ +
+
+

+ +

+
+
+

+ +

+ +
+
+
+
+
diff --git a/src/test/java/org/genesys2/server/model/impl/AccessionCacheTest.java b/src/test/java/org/genesys2/server/model/impl/AccessionCacheTest.java index 9d07d14bfec5601290bc3cc0113b159c5cac2aae..09a9057a1cbb7d7ddda92cb1af07b07a9817dc2e 100644 --- a/src/test/java/org/genesys2/server/model/impl/AccessionCacheTest.java +++ b/src/test/java/org/genesys2/server/model/impl/AccessionCacheTest.java @@ -33,7 +33,6 @@ import org.genesys.blocks.security.service.CustomAclService; import org.genesys.blocks.security.service.impl.CustomAclServiceImpl; import org.genesys2.server.aspect.AsAdminAspect; import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.service.BatchRESTService; import org.genesys2.server.service.ContentService; import org.genesys2.server.service.CropService; import org.genesys2.server.service.GenesysService; @@ -43,7 +42,6 @@ import org.genesys2.server.service.InstituteService; import org.genesys2.server.service.OrganizationService; import org.genesys2.server.service.TaxonomyService; import org.genesys2.server.service.UserService; -import org.genesys2.server.service.impl.BatchRESTServiceImpl; import org.genesys2.server.service.impl.ContentServiceImpl; import org.genesys2.server.service.impl.CropServiceImpl; import org.genesys2.server.service.impl.GenesysServiceImpl; @@ -102,11 +100,6 @@ public class AccessionCacheTest { return new TaxonomyServiceImpl(); } - @Bean - public BatchRESTService batchRESTService() { - return new BatchRESTServiceImpl(); - } - @Bean public CropService cropService() { return new CropServiceImpl(); diff --git a/src/test/java/org/genesys2/server/model/impl/AccessionStorageTest.java b/src/test/java/org/genesys2/server/model/impl/AccessionStorageTest.java deleted file mode 100644 index b7b37c1f9bd166a12384b5ba2dfe3a4654b1dc5c..0000000000000000000000000000000000000000 --- a/src/test/java/org/genesys2/server/model/impl/AccessionStorageTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.model.impl; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.service.GenesysService; -import org.genesys2.server.test.BatchRESTServiceTest; -import org.genesys2.server.test.PropertyPlacholderInitializer; -import org.genesys2.util.MCPDUtil; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = BatchRESTServiceTest.Config.class, initializers = PropertyPlacholderInitializer.class) -@ActiveProfiles("dev") -@Ignore -public class AccessionStorageTest { - - @Autowired - private GenesysService genesysService; - - @Test - public void nullStorage() { - Accession a = new Accession(); - a.setAccessionName("A-1"); - genesysService.saveAccession(a); - } - - @Test - public void blankStorage() { - Accession a = new Accession(); - a.setAccessionName("A-" + System.currentTimeMillis()); - List stoRage = new ArrayList(); - a.setStoRage(stoRage); - genesysService.saveAccession(a); - - Long accessionId = a.getId(); - Accession b = genesysService.getAccession(accessionId); - assertTrue(b.getStorage() == null); - assertTrue(b.getStoRage() != null); - assertThat("Accession#stoRage size is not 0", b.getStoRage().size(), is(0)); - } - - @Test - public void oneStorage() { - Accession a = new Accession(); - a.setAccessionName("A-" + System.currentTimeMillis()); - List stoRage = new ArrayList(); - stoRage.add(1); - a.setStoRage(stoRage); - genesysService.saveAccession(a); - - Long accessionId = a.getId(); - Accession b = genesysService.getAccession(accessionId); - assertTrue(b.getStorage() != null); - assertThat("Storage value should be '1'", a.getStorage(), is("1")); - assertTrue(b.getStoRage() != null); - } - - @Test - public void twoStorage() { - Accession a = new Accession(); - a.setAccessionName("A-" + System.currentTimeMillis()); - List stoRage = new ArrayList(); - stoRage.add(1); - stoRage.add(2); - a.setStoRage(stoRage); - genesysService.saveAccession(a); - - Long accessionId = a.getId(); - Accession b = genesysService.getAccession(accessionId); - assertTrue(b.getStorage() != null); - assertThat("Storage value should be '1'", a.getStorage(), is("1;2")); - assertTrue(b.getStoRage() != null); - } - - @Test - public void clearStorage() { - Accession a = new Accession(); - a.setAccessionName("A-" + System.currentTimeMillis()); - List stoRage = new ArrayList(); - stoRage.add(1); - stoRage.add(2); - a.setStoRage(stoRage); - genesysService.saveAccession(a); - - Long accessionId = a.getId(); - assertNotNull("Accession#id must not be null", a.getId()); - Accession b = genesysService.getAccession(accessionId); - assertTrue(b.getStorage() != null); - assertThat("Storage value should be '1'", a.getStorage(), is("1;2")); - assertTrue(b.getStoRage() != null); - - b.getStoRage().clear(); - genesysService.saveAccession(b); - - Accession c = genesysService.getAccession(accessionId); - assertNotNull("Accession#stoRage must not be null", c.getStoRage()); - assertThat("Accession#stoRage size is not 0", c.getStoRage().size(), is(0)); - assertThat("Accession#storage is not null", c.getStorage(), is(nullValue())); - } - - @Test - public void updateStorage() { - Accession a = new Accession(); - a.setAccessionName("A-" + System.currentTimeMillis()); - List stoRage = new ArrayList(); - stoRage.add(1); - stoRage.add(2); - stoRage.add(3); - a.setStoRage(stoRage); - System.out.println("Saving 1"); - genesysService.saveAccession(a); - System.out.println("Saving 2"); - genesysService.saveAccession(a); - - Long accessionId = a.getId(); - assertNotNull("Accession#id must not be null", a.getId()); - Accession b = genesysService.getAccession(accessionId); - assertNotNull(b.getStorage()); - assertNotNull(b.getStoRage()); - assertThat("StoRage length is not 3", a.getStoRage().size(), is(3)); - assertThat("Storage value should be '1;2;3'", a.getStorage(), is("1;2;3")); - - b.getStoRage().remove(0); - genesysService.saveAccession(b); - - Accession c = genesysService.getAccession(accessionId); - assertNotNull("Accession#stoRage must not be null", c.getStoRage()); - assertThat("Accession#stoRage size is not 2", c.getStoRage().size(), is(2)); - assertThat("Accession#storage is not '2;3'", c.getStorage(), is("2;3")); - assertThat("Accession#stoRage does not generate MCPD style string'", c.getStorage(), is(MCPDUtil.toMcpdArray(c.getStoRage()))); - System.out.println("Saving 3"); - genesysService.saveAccession(c); - } - -} diff --git a/src/test/java/org/genesys2/server/service/impl/AccessionHistoryTest.java b/src/test/java/org/genesys2/server/service/impl/AccessionHistoryTest.java index 9cc484f6b6fd8fa48b567b3950cd80dc8e93a4fa..395806488477ef522d1c7654f2427a1df81a177e 100644 --- a/src/test/java/org/genesys2/server/service/impl/AccessionHistoryTest.java +++ b/src/test/java/org/genesys2/server/service/impl/AccessionHistoryTest.java @@ -83,20 +83,20 @@ public class AccessionHistoryTest extends GenesysServicesTest { @Test public void testDeleteAccession1() throws NonUniqueAccessionException { - accession.setAccessionName(ACCENUMB); + accession.setAccessionNumber(ACCENUMB); accession.setInstitute(faoInstitute); accession.setTaxonomy(taxonomy2); accession.setCountryOfOrigin(country); - accession.getStoRage().add(10); - accession.getStoRage().add(20); + accession.getAccessionId().getStorage().add(10); + accession.getAccessionId().getStorage().add(20); genesysService.saveAccessions(faoInstitute, Collections.singletonList(accession)); accession = genesysService.getAccession(INSTCODE, ACCENUMB); assertThat("INSTCODE must match", accession.getInstituteCode(), is(INSTCODE)); assertThat("Institute#code must match", accession.getInstitute().getCode(), is(INSTCODE)); - assertThat("ACCENUMB must match", accession.getAccessionName(), is(ACCENUMB)); - assertThat("stoRage must match", accession.getStoRage(), contains(10, 20)); + assertThat("ACCENUMB must match", accession.getAccessionNumber(), is(ACCENUMB)); + assertThat("stoRage must match", accession.getAccessionId().getStorage(), contains(10, 20)); UUID uuid = accession.getUuid(); // Delete accession @@ -108,8 +108,8 @@ public class AccessionHistoryTest extends GenesysServicesTest { assertThat(historic, not(nullValue())); assertThat("INSTCODE must match", historic.getInstituteCode(), is(INSTCODE)); assertThat("Institute#code must match", historic.getInstitute().getCode(), is(INSTCODE)); - assertThat("ACCENUMB must match", historic.getAccessionName(), is(ACCENUMB)); - assertThat("stoRage must match", historic.getStoRage(), contains(10, 20)); + assertThat("ACCENUMB must match", historic.getAccessionNumber(), is(ACCENUMB)); + assertThat("stoRage must match", historic.getAccessionId().getStorage(), contains(10, 20)); } } diff --git a/src/test/java/org/genesys2/server/service/impl/AccessionListReal.java b/src/test/java/org/genesys2/server/service/impl/AccessionListReal.java index d040935cff543eca5162edb4e4a746988edbcd78..7195f13fa7b29f145c21e218cde4a73ab8b666bf 100644 --- a/src/test/java/org/genesys2/server/service/impl/AccessionListReal.java +++ b/src/test/java/org/genesys2/server/service/impl/AccessionListReal.java @@ -24,7 +24,7 @@ import java.util.HashSet; import java.util.Set; import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.persistence.domain.TraitValueRepository; import org.genesys2.server.persistence.domain.TraitValueRepositoryImpl; import org.genesys2.server.service.AccessionListService; diff --git a/src/test/java/org/genesys2/server/service/impl/AccessionListTest.java b/src/test/java/org/genesys2/server/service/impl/AccessionListTest.java index b9fb34257ec1cb0bf00f145c2528f047a9105ccb..a8c549fec16914168ab61791230419cc52d78128 100644 --- a/src/test/java/org/genesys2/server/service/impl/AccessionListTest.java +++ b/src/test/java/org/genesys2/server/service/impl/AccessionListTest.java @@ -19,7 +19,7 @@ package org.genesys2.server.service.impl; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; -import org.genesys2.server.model.impl.AccessionList; +import org.genesys2.server.model.genesys.AccessionList; import org.genesys2.server.service.AccessionListService; import org.genesys2.server.test.JpaDataConfig; import org.genesys2.server.test.PropertyPlacholderInitializer; diff --git a/src/test/java/org/genesys2/server/service/worker/SGSVUpdateTest.java b/src/test/java/org/genesys2/server/service/worker/SGSVUpdateTest.java index 723f0b42711e4f34c7efed60360dd5e53f53667c..22e326ce150e8524ace1987be355091aca2a0af4 100644 --- a/src/test/java/org/genesys2/server/service/worker/SGSVUpdateTest.java +++ b/src/test/java/org/genesys2/server/service/worker/SGSVUpdateTest.java @@ -36,7 +36,6 @@ import org.genesys2.server.model.genesys.Accession; import org.genesys2.server.model.genesys.SvalbardDeposit; import org.genesys2.server.model.impl.FaoInstitute; import org.genesys2.server.persistence.domain.SvalbardRepository; -import org.genesys2.server.service.BatchRESTService; import org.genesys2.server.service.ContentService; import org.genesys2.server.service.GenesysService; import org.genesys2.server.service.GeoService; @@ -45,7 +44,6 @@ import org.genesys2.server.service.InstituteService; import org.genesys2.server.service.OrganizationService; import org.genesys2.server.service.TaxonomyService; import org.genesys2.server.service.UserService; -import org.genesys2.server.service.impl.BatchRESTServiceImpl; import org.genesys2.server.service.impl.ContentServiceImpl; import org.genesys2.server.service.impl.GenesysServiceImpl; import org.genesys2.server.service.impl.GeoServiceImpl; @@ -109,11 +107,6 @@ public class SGSVUpdateTest { return new TaxonomyServiceImpl(); } - @Bean - public BatchRESTService batchRESTService() { - return new BatchRESTServiceImpl(); - } - @Bean public GenesysService genesysService() { return new GenesysServiceImpl(); @@ -221,7 +214,7 @@ public class SGSVUpdateTest { final Accession a = new Accession(); a.setInstitute(institute); - a.setAccessionName(acceNumb); + a.setAccessionNumber(acceNumb); a.setTaxonomy(taxonomyManager.ensureTaxonomy2(genus, species, null, null, null)); accessions.add(a); diff --git a/src/test/java/org/genesys2/server/test/BatchRESTServiceTest.java b/src/test/java/org/genesys2/server/test/BatchRESTServiceTest.java deleted file mode 100644 index 72781f48ca8851e5c90b65b783e3fcd1107b0de7..0000000000000000000000000000000000000000 --- a/src/test/java/org/genesys2/server/test/BatchRESTServiceTest.java +++ /dev/null @@ -1,438 +0,0 @@ -/** - * Copyright 2014 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.genesys2.server.test; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.velocity.app.VelocityEngine; -import org.apache.velocity.exception.VelocityException; -import org.genesys.blocks.auditlog.service.ClassPKService; -import org.genesys.blocks.auditlog.service.impl.ClassPKServiceImpl; -import org.genesys.blocks.security.service.CustomAclService; -import org.genesys.blocks.security.service.impl.CustomAclServiceImpl; -import org.genesys2.server.aspect.AsAdminAspect; -import org.genesys2.server.model.genesys.Accession; -import org.genesys2.server.model.genesys.Taxonomy2; -import org.genesys2.server.model.impl.Country; -import org.genesys2.server.model.impl.FaoInstitute; -import org.genesys2.server.model.json.Api1Constants; -import org.genesys2.server.persistence.domain.CountryRepository; -import org.genesys2.server.service.BatchRESTService; -import org.genesys2.server.service.ContentService; -import org.genesys2.server.service.CropService; -import org.genesys2.server.service.GenesysService; -import org.genesys2.server.service.GeoService; -import org.genesys2.server.service.HtmlSanitizer; -import org.genesys2.server.service.InstituteService; -import org.genesys2.server.service.OrganizationService; -import org.genesys2.server.service.TaxonomyService; -import org.genesys2.server.service.UserService; -import org.genesys2.server.service.impl.BatchRESTServiceImpl; -import org.genesys2.server.service.impl.ContentServiceImpl; -import org.genesys2.server.service.impl.CropServiceImpl; -import org.genesys2.server.service.impl.GenesysServiceImpl; -import org.genesys2.server.service.impl.GeoServiceImpl; -import org.genesys2.server.service.impl.InstituteServiceImpl; -import org.genesys2.server.service.impl.NonUniqueAccessionException; -import org.genesys2.server.service.impl.OWASPSanitizer; -import org.genesys2.server.service.impl.OrganizationServiceImpl; -import org.genesys2.server.service.impl.RESTApiException; -import org.genesys2.server.service.impl.TaxonomyManager; -import org.genesys2.server.service.impl.TaxonomyServiceImpl; -import org.genesys2.server.service.impl.UserServiceImpl; -import org.genesys2.server.servlet.controller.rest.model.AccessionHeaderJson; -import org.genesys2.spring.config.HazelcastConfig; -import org.genesys2.spring.config.CacheConfig; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.core.task.TaskExecutor; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.ContextHierarchy; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.ui.velocity.VelocityEngineFactoryBean; - -@RunWith(SpringJUnit4ClassRunner.class) -@ActiveProfiles("dev") -@ContextHierarchy({ - @ContextConfiguration(name = "root", classes = { JpaDataConfig.class, HazelcastConfig.class, CacheConfig.class }, initializers = PropertyPlacholderInitializer.class), - @ContextConfiguration(classes = BatchRESTServiceTest.Config.class, initializers = PropertyPlacholderInitializer.class) -}) -@Ignore -public class BatchRESTServiceTest { - private final ObjectMapper mapper = new ObjectMapper(); - - public static class Config { - - @Bean - public AsAdminAspect asAdminAspect() { - return new AsAdminAspect(); - } - - @Bean - public UserService userService() { - return new UserServiceImpl(); - } - - @Bean - public CustomAclService aclService() { - return new CustomAclServiceImpl(); - } - - @Bean - public TaxonomyService taxonomyService() { - return new TaxonomyServiceImpl(); - } - - @Bean - public BatchRESTService batchRESTService() { - return new BatchRESTServiceImpl(); - } - - @Bean - public CropService cropService() { - return new CropServiceImpl(); - } - - @Bean - public GenesysService genesysService() { - return new GenesysServiceImpl(); - } - - @Bean - public HtmlSanitizer htmlSanitizer() { - return new OWASPSanitizer(); - } - - @Bean - public GeoService geoService() { - return new GeoServiceImpl(); - } - - @Bean - public ContentService contentService() { - return new ContentServiceImpl(); - } - - @Bean - public ClassPKService classPkService() { - return new ClassPKServiceImpl(); - } - - @Bean - public VelocityEngine velocityEngine() throws VelocityException, IOException { - final VelocityEngineFactoryBean vf = new VelocityEngineFactoryBean(); - return vf.createVelocityEngine(); - } - - @Bean - public OrganizationService organizationService() { - return new OrganizationServiceImpl(); - } - - @Bean - public InstituteService instituteService() { - return new InstituteServiceImpl(); - } - - @Bean - public TaskExecutor taskExecutor() { - return new ThreadPoolTaskExecutor(); - } - - @Bean - public TaxonomyManager taxonomyManager() { - return new TaxonomyManager(); - } - } - - @Autowired - private BatchRESTService batchRESTService; - - @Autowired - private GenesysService genesysService; - - @Autowired - private TaxonomyService taxonomyService; - - @Autowired - private InstituteService instituteService; - - @Autowired - private CountryRepository countryRepository; - - @Before - public void setup() { - System.err.println("Setting up"); - final Collection institutes = new ArrayList(); - for (final String instCode : new String[] { "INS002", "INS001" }) { - final FaoInstitute institute = new FaoInstitute(); - institute.setFullName(instCode + " institute"); - institute.setCode(instCode); - institute.setUniqueAcceNumbs(true); - institutes.add(institute); - } - instituteService.update(institutes); - - final Country country = new Country(); - country.setCode2("CT"); - country.setCode3("CTY"); - country.setName("Country"); - country.setCurrent(true); - countryRepository.save(country); - } - - @After - public void teardown() { - System.err.println("Tearing down"); - for (final String instCode : new String[] { "INS002", "INS001" }) { - final FaoInstitute institute = instituteService.getInstitute(instCode); - instituteService.delete(institute.getCode()); - } - - countryRepository.delete(countryRepository.findAll()); - } - - @Test - public void testTaxonomy() throws NonUniqueAccessionException { - final String instCode = "INS002"; - final FaoInstitute institute = instituteService.getInstitute(instCode); - assertTrue("institute is null", institute != null); - System.err.println(institute); - - final Map batch = new HashMap(); - - final AccessionHeaderJson dataJson = new AccessionHeaderJson(); - dataJson.acceNumb = "AC 1"; - dataJson.instCode = instCode; - - String genus="Triticum", sp="aestivum", spauthor="L." ,subtaxa="subsp. aestivum", subtauthor="(Desf.) Husn."; - - final ObjectNode json = mapper.createObjectNode(); - json.put(Api1Constants.Accession.GENUS, genus); - json.put(Api1Constants.Accession.SPECIES, sp); - json.put(Api1Constants.Accession.SPAUTHOR, spauthor); - json.put(Api1Constants.Accession.SUBTAXA, subtaxa); - json.put(Api1Constants.Accession.SUBTAUTHOR, subtauthor); - batch.put(dataJson, json); - - try { - batchRESTService.ensureTaxonomies(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - Taxonomy2 loaded = taxonomyService.find(genus, sp, spauthor, subtaxa, subtauthor); - assertThat("Taxonomy should be found!", loaded, notNullValue()); - assertThat("Genus doesn't match", loaded.getGenus(), is(genus)); - assertThat("Species doesn't match", loaded.getSpecies(), is(sp)); - assertThat("SpAuthor doesn't match", loaded.getSpAuthor(), is(spauthor)); - assertThat("SubTaxa doesn't match", loaded.getSubtaxa(), is(subtaxa)); - assertThat("SubtAuthor doesn't match", loaded.getSubtAuthor(), is(subtauthor)); - } - - @Test - public void testNewAccession() throws NonUniqueAccessionException { - final String instCode = "INS002"; - final FaoInstitute institute = instituteService.getInstitute(instCode); - assertTrue("institute is null", institute != null); - System.err.println(institute); - - final Map batch = new HashMap(); - - final AccessionHeaderJson dataJson = new AccessionHeaderJson(); - dataJson.acceNumb = "AC 1"; - dataJson.instCode = instCode; - - final ObjectNode json = mapper.createObjectNode(); - json.put(Api1Constants.Accession.GENUS, "Hordeum"); - batch.put(dataJson, json); - - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - - Accession accession = genesysService.getAccession(instCode, "AC 1"); - assertTrue(accession.getId() != null); - assertTrue(accession.getInstituteCode().equals(instCode)); - assertTrue(accession.getInstitute().getId().equals(institute.getId())); - assertTrue(accession.getTaxonomy() != null); - final Taxonomy2 tax = accession.getTaxonomy(); - System.err.println(tax); - System.err.println(accession.getTaxGenus()); - - // Modify taxonomy - json.put(Api1Constants.Accession.GENUS, "Hordeum"); - json.put(Api1Constants.Accession.SPECIES, "vulgare"); - json.put(Api1Constants.Accession.SPAUTHOR, "L."); - json.put(Api1Constants.Accession.SUBTAXA, "some subtaxa"); - json.put(Api1Constants.Accession.SUBTAUTHOR, "Subtauthor"); - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - // reload - accession = genesysService.getAccession(instCode, "AC 1"); - final Taxonomy2 tax2 = accession.getTaxonomy(); - System.err.println(tax2); - assertFalse(tax2.getId().equals(tax.getId())); - System.err.println(accession.getTaxGenus()); - - // test nothing - try { - System.err.println("NO UPDATE!"); - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - } - - @Test - public void testClearOrgCty() throws NonUniqueAccessionException { - final String instCode = "INS002"; - final FaoInstitute institute = instituteService.getInstitute(instCode); - assertTrue("institute is null", institute != null); - System.err.println(institute); - - final Map batch = new HashMap(); - - final AccessionHeaderJson dataJson = new AccessionHeaderJson(); - dataJson.acceNumb = "AC 100"; - dataJson.instCode = instCode; - - final ObjectNode json = mapper.createObjectNode(); - json.put(Api1Constants.Accession.GENUS, "Hordeum"); - json.put(Api1Constants.Accession.ORIGCTY, "CTY"); - batch.put(dataJson, json); - System.err.println(json); - - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - - Accession accession = genesysService.getAccession(instCode, "AC 100"); - assertTrue(accession.getId() != null); - assertTrue(accession.getInstituteCode().equals(instCode)); - assertTrue(accession.getInstitute().getId().equals(institute.getId())); - assertTrue(accession.getOrigin() != null); - assertTrue("CTY".equals(accession.getOrigin())); - assertTrue(accession.getCountryOfOrigin() != null); - assertTrue("Country".equals(accession.getCountryOfOrigin().getName())); - - // Modify taxonomy - json.putNull(Api1Constants.Accession.ORIGCTY); - System.err.println(json); - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - // reload - accession = genesysService.getAccession(instCode, "AC 100"); - assertTrue(accession.getOrigin() == null); - assertTrue(accession.getCountryOfOrigin() == null); - } - - @Test - public void testUpdateStorage() throws NonUniqueAccessionException { - final String instCode = "INS002"; - final FaoInstitute institute = instituteService.getInstitute(instCode); - assertTrue("institute is null", institute != null); - System.err.println(institute); - - final Map batch = new HashMap(); - - final AccessionHeaderJson dataJson = new AccessionHeaderJson(); - dataJson.acceNumb = "AC 100"; - dataJson.instCode = instCode; - - final ObjectNode json = mapper.createObjectNode(); - json.put(Api1Constants.Accession.GENUS, "Hordeum"); - json.put(Api1Constants.Accession.ORIGCTY, "CTY"); - json.put(Api1Constants.Accession.STORAGE, "10;30"); - batch.put(dataJson, json); - System.err.println(json); - - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - - Accession accession = genesysService.getAccession(instCode, "AC 100"); - assertTrue(accession.getId() != null); - assertTrue(accession.getInstituteCode().equals(instCode)); - assertTrue(accession.getInstitute().getId().equals(institute.getId())); - assertTrue(accession.getOrigin() != null); - assertTrue("CTY".equals(accession.getOrigin())); - assertTrue(accession.getCountryOfOrigin() != null); - assertTrue("Country".equals(accession.getCountryOfOrigin().getName())); - - assertNotNull("StoRage must be", accession.getStoRage()); - assertNotNull("Storage must be", accession.getStorage()); - assertThat("Storage must be 10;30", accession.getStorage(), is("10;30")); - - // Modify STORAGE - json.put(Api1Constants.Accession.STORAGE, "40"); - System.err.println(json); - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - // reload - accession = genesysService.getAccession(instCode, "AC 100"); - assertNotNull("storage should not be null", accession.getStorage()); - assertThat("stoRage should 40", accession.getStorage(), is("40")); - assertThat("stoRage should be 0-size", accession.getStoRage().size(), is(1)); - - // Clear STORAGE - json.putNull(Api1Constants.Accession.STORAGE); - System.err.println(json); - try { - batchRESTService.upsertAccessionData(institute, batch); - } catch (final RESTApiException e) { - fail(e.getMessage()); - } - // reload - accession = genesysService.getAccession(instCode, "AC 100"); - assertNull("storage should be null", accession.getStorage()); - assertNotNull("stoRage should be null", accession.getStoRage()); - assertThat("stoRage should be 0-size", accession.getStoRage().size(), is(0)); - } - -} diff --git a/src/test/java/org/genesys2/tests/resttests/AbstractRestTest.java b/src/test/java/org/genesys2/tests/resttests/AbstractRestTest.java index 8254854d75fbbf0e604dfc387c9bd907e76720a7..8bfaebffdc063c6b7a7cc1327c4469d7dccf6e37 100644 --- a/src/test/java/org/genesys2/tests/resttests/AbstractRestTest.java +++ b/src/test/java/org/genesys2/tests/resttests/AbstractRestTest.java @@ -75,7 +75,6 @@ import org.genesys2.server.persistence.domain.UserRepository; import org.genesys2.server.persistence.domain.kpi.KPIParameterRepository; import org.genesys2.server.persistence.domain.kpi.ObservationRepository; import org.genesys2.server.persistence.domain.mock.TraitServiceMock; -import org.genesys2.server.service.BatchRESTService; import org.genesys2.server.service.ContentService; import org.genesys2.server.service.CropService; import org.genesys2.server.service.DatasetService; @@ -101,7 +100,6 @@ import org.genesys2.server.service.TeamService; import org.genesys2.server.service.TokenVerificationService; import org.genesys2.server.service.TraitService; import org.genesys2.server.service.UserService; -import org.genesys2.server.service.impl.BatchRESTServiceImpl; import org.genesys2.server.service.impl.ContentServiceImpl; import org.genesys2.server.service.impl.CropServiceImpl; import org.genesys2.server.service.impl.EMailServiceImpl; @@ -127,6 +125,7 @@ import org.genesys2.server.service.impl.TaxonomyServiceImpl; import org.genesys2.server.service.impl.TeamServiceImpl; import org.genesys2.server.service.impl.TokenVerificationServiceImpl; import org.genesys2.server.service.impl.UserServiceImpl; +import org.genesys2.server.service.worker.AccessionUploader; import org.genesys2.server.service.worker.ElasticUpdater; import org.genesys2.server.service.worker.GeoRegionDataCLDR; import org.genesys2.server.servlet.controller.admin.OAuthManagementController; @@ -399,11 +398,6 @@ public abstract class AbstractRestTest extends BaseSpringTest { return new OrganizationController(); } - @Bean - public BatchRESTService batchRESTService() { - return new BatchRESTServiceImpl(); - } - @Bean public GenesysApi glisGenesysApi() { return new GenesysApi(); @@ -463,6 +457,11 @@ public abstract class AbstractRestTest extends BaseSpringTest { public GenesysFilterService genesysFilterService() { return new GenesysFilterServiceImpl(); } + + @Bean + public AccessionUploader uploader() { + return new AccessionUploader(); + } @Bean public AccessionController accessionController() { diff --git a/src/test/java/org/genesys2/tests/resttests/docs/ApiImagesDocsTest.java b/src/test/java/org/genesys2/tests/resttests/docs/ApiImagesDocsTest.java index 444afc155331c73051f60a240fb3d2e2288ea4f2..3bf2a66e606c3f46aa5befcd9b2dd7e5cffcefbe 100644 --- a/src/test/java/org/genesys2/tests/resttests/docs/ApiImagesDocsTest.java +++ b/src/test/java/org/genesys2/tests/resttests/docs/ApiImagesDocsTest.java @@ -45,6 +45,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import org.elasticsearch.common.collect.Lists; import org.genesys.filerepository.model.RepositoryImage; import org.genesys.filerepository.persistence.ImageGalleryPersistence; import org.genesys2.server.model.genesys.Accession; @@ -115,10 +116,11 @@ public class ApiImagesDocsTest extends AbstractRestTest { Accession acce = new Accession(); acce.setAccessionId(new AccessionId()); - acce.setAccessionName(ACCENUMB); + acce.setAccessionNumber(ACCENUMB); acce.setInstitute(institute); acce.setTaxonomy(taxonomy); - genesysService.saveAccession(acce); + + genesysService.saveAccessions(institute, Lists.newArrayList(acce)); assertThat(acce.getId(), greaterThan(0l)); }