Commit 7ff46eb0 authored by Matija Obreza's avatar Matija Obreza
Browse files

Renamed Accession#dublInst to #duplSite, allow JSON [] where multiple

values are allowed in MCPD, use AccessionAlias as back-end for names
parent 6f7328f8
...@@ -69,8 +69,8 @@ public class Accession extends VersionedAuditedModel { ...@@ -69,8 +69,8 @@ public class Accession extends VersionedAuditedModel {
@JoinColumn(name = "orgCtyId", nullable = true) @JoinColumn(name = "orgCtyId", nullable = true)
private Country countryOfOrigin; private Country countryOfOrigin;
@Column(name = "dublInst", length = 8) @Column(name = "duplSite", length = 32)
private String dublInst; private String duplSite;
@Column(name = "sampStat", length = 3) @Column(name = "sampStat", length = 3)
private Integer sampleStatus; private Integer sampleStatus;
...@@ -168,12 +168,12 @@ public class Accession extends VersionedAuditedModel { ...@@ -168,12 +168,12 @@ public class Accession extends VersionedAuditedModel {
this.countryOfOrigin = countryOfOrigin; this.countryOfOrigin = countryOfOrigin;
} }
public String getDublInst() { public String getDuplSite() {
return this.dublInst; return this.duplSite;
} }
public void setDublInst(final String dublInst) { public void setDuplSite(final String duplSite) {
this.dublInst = dublInst; this.duplSite = duplSite;
} }
public Integer getSampleStatus() { public Integer getSampleStatus() {
......
...@@ -34,7 +34,7 @@ import org.genesys2.server.model.BusinessModel; ...@@ -34,7 +34,7 @@ import org.genesys2.server.model.BusinessModel;
public class AccessionAlias extends BusinessModel { public class AccessionAlias extends BusinessModel {
public static enum AliasType { public static enum AliasType {
GENERIC(0), DONORNAME(1), BREEDERNAME(2), DATABASEID(3), LOCALNAME(4); ACCENAME(0), DONORNUMB(1), BREEDERNAME(2), DATABASEID(3), LOCALNAME(4), OTHERNUMB(5), COLLNUMB(6);
private int id; private int id;
...@@ -75,7 +75,7 @@ public class AccessionAlias extends BusinessModel { ...@@ -75,7 +75,7 @@ public class AccessionAlias extends BusinessModel {
private String instCode; private String instCode;
@Column @Column
private int aliasType = AliasType.GENERIC.id; private int aliasType = AliasType.ACCENAME.id;
@Column(length = 2) @Column(length = 2)
private String lang; private String lang;
......
...@@ -19,6 +19,7 @@ package org.genesys2.server.service.impl; ...@@ -19,6 +19,7 @@ package org.genesys2.server.service.impl;
import static org.genesys2.util.NumberUtils.areEqual; import static org.genesys2.util.NumberUtils.areEqual;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
...@@ -53,6 +54,7 @@ import org.springframework.stereotype.Service; ...@@ -53,6 +54,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@Service @Service
...@@ -87,6 +89,11 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -87,6 +89,11 @@ public class BatchRESTServiceImpl implements BatchRESTService {
List<AccessionBreeding> toSaveBreed = new ArrayList<AccessionBreeding>(); List<AccessionBreeding> toSaveBreed = new ArrayList<AccessionBreeding>();
List<AccessionExchange> toSaveExch = new ArrayList<AccessionExchange>(); List<AccessionExchange> toSaveExch = new ArrayList<AccessionExchange>();
Map<Accession, ArrayNode> acceNames = new HashMap<Accession, ArrayNode>();
Map<Accession, ArrayNode> otherNumbs = new HashMap<Accession, ArrayNode>();
Map<Accession, ArrayNode> donorNumbs = new HashMap<Accession, ArrayNode>();
Map<Accession, ArrayNode> collNumbs = new HashMap<Accession, ArrayNode>();
for (AccessionJson dataJson : batch.keySet()) { for (AccessionJson dataJson : batch.keySet()) {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Loading accession " + dataJson); LOG.debug("Loading accession " + dataJson);
...@@ -203,20 +210,33 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -203,20 +210,33 @@ public class BatchRESTServiceImpl implements BatchRESTService {
if (value != null) { if (value != null) {
Boolean availability = value.isNull() ? null : value.asBoolean(); Boolean availability = value.isNull() ? null : value.asBoolean();
if (!areEqual(availability, accession.getMlsStatus())) { if (!areEqual(availability, accession.getAvailability())) {
accession.setAvailability(availability); accession.setAvailability(availability);
updated = true; updated = true;
} }
} }
value = accnJson.get("storage"); value = accnJson.get("storage");
// MUST BE ARRAY
if (value != null) { if (value != null) {
if (!StringUtils.equals(value.textValue(), accession.getStorage())) { String storage = arrayToString(toMcpdArray(accnJson, "storage"));
accession.setStorage(StringUtils.defaultIfBlank(value.textValue(), null));
if (!StringUtils.equals(storage, accession.getStorage())) {
accession.setStorage(storage);
updated = true; updated = true;
} }
} }
value = accnJson.get("acceName");
if (value != null) {
acceNames.put(accession, toMcpdArray(accnJson, "acceName"));
}
value = accnJson.get("otherNumb");
if (value != null) {
otherNumbs.put(accession, toMcpdArray(accnJson, "otherNumb"));
}
value = accnJson.get("sampStat"); value = accnJson.get("sampStat");
if (value != null) { if (value != null) {
Integer sampStat = value.isNull() || !value.isNumber() ? null : value.asInt(); Integer sampStat = value.isNull() || !value.isNumber() ? null : value.asInt();
...@@ -226,11 +246,11 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -226,11 +246,11 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
} }
value = accnJson.get("dublInst"); value = accnJson.get("duplSite");
if (value != null) { if (value != null) {
String dublInst = value.isNull() ? null : value.textValue(); String duplSite = arrayToString(toMcpdArray(accnJson, "duplSite"));
if (!StringUtils.equals(dublInst, accession.getDublInst())) { if (!StringUtils.equals(duplSite, accession.getDuplSite())) {
accession.setDublInst(StringUtils.defaultIfBlank(dublInst, null)); accession.setDuplSite(StringUtils.defaultIfBlank(duplSite, null));
updated = true; updated = true;
} }
} }
...@@ -249,6 +269,7 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -249,6 +269,7 @@ public class BatchRESTServiceImpl implements BatchRESTService {
value = collecting.get("collNumb"); value = collecting.get("collNumb");
if (value != null) { if (value != null) {
accnColl.setCollNumb(StringUtils.defaultIfBlank(value.textValue(), null)); accnColl.setCollNumb(StringUtils.defaultIfBlank(value.textValue(), null));
collNumbs.put(accession, toMcpdArray(collecting, "collNumb"));
} }
value = collecting.get("collSrc"); value = collecting.get("collSrc");
if (value != null) { if (value != null) {
...@@ -256,15 +277,15 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -256,15 +277,15 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
value = collecting.get("collCode"); value = collecting.get("collCode");
if (value != null) { if (value != null) {
accnColl.setCollCode(StringUtils.defaultIfBlank(value.textValue(), null)); accnColl.setCollCode(arrayToString(toMcpdArray(collecting, "collCode")));
} }
value = collecting.get("collName"); value = collecting.get("collName");
if (value != null) { if (value != null) {
accnColl.setCollName(StringUtils.defaultIfBlank(value.textValue(), null)); accnColl.setCollName(arrayToString(toMcpdArray(collecting, "collName")));
} }
value = collecting.get("collInstAddress"); value = collecting.get("collInstAddress");
if (value != null) { if (value != null) {
accnColl.setCollInstAddress(StringUtils.defaultIfBlank(value.textValue(), null)); accnColl.setCollInstAddress(arrayToString(toMcpdArray(collecting, "collInstAddress")));
} }
value = collecting.get("collSite"); value = collecting.get("collSite");
if (value != null) { if (value != null) {
...@@ -320,7 +341,7 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -320,7 +341,7 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
value = accnJson.get("bredCode"); value = accnJson.get("bredCode");
if (value != null) { if (value != null) {
accnBred.setBreederCode(value.isTextual() ? value.asText() : null); accnBred.setBreederCode(arrayToString(toMcpdArray(accnJson, "bredCode")));
} }
value = accnJson.get("ancest"); value = accnJson.get("ancest");
if (value != null) { if (value != null) {
...@@ -341,13 +362,25 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -341,13 +362,25 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
value = accnJson.get("donorNumb"); value = accnJson.get("donorNumb");
if (value != null) { if (value != null) {
accnExch.setAccNumbDonor(value.isTextual() ? value.asText() : null); accnExch.setAccNumbDonor(StringUtils.defaultIfBlank(value.textValue(), null));
} }
value = accnJson.get("donorName"); value = accnJson.get("donorName");
if (value != null) { if (value != null) {
accnExch.setDonorName(value.isTextual() ? value.asText() : null); accnExch.setDonorName(value.isTextual() ? value.asText() : null);
} }
toSaveExch.add(accnExch);
ArrayNode donorNumb = accnJson.arrayNode();
String donorNumbStr = "";
if (accnExch.getDonorInstitute() != null)
donorNumbStr = accnExch.getDonorInstitute();
if (accnExch.getAccNumbDonor() != null) {
donorNumb.add(donorNumbStr + ":" + accnExch.getAccNumbDonor());
donorNumbs.put(accession, donorNumb);
toSaveExch.add(accnExch);
} else {
donorNumbs.put(accession, null);
}
} }
if (updated) { if (updated) {
...@@ -377,9 +410,101 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -377,9 +410,101 @@ public class BatchRESTServiceImpl implements BatchRESTService {
genesysService.saveExchange(toSaveExch); genesysService.saveExchange(toSaveExch);
} }
updateAccessionAliases(acceNames, AliasType.ACCENAME);
updateAccessionAliases(otherNumbs, AliasType.OTHERNUMB);
updateAccessionAliases(donorNumbs, AliasType.DONORNUMB);
updateAccessionAliases(collNumbs, AliasType.COLLNUMB);
return toSave.size() > 0 || toSaveColl.size() > 0 || toSaveGeo.size() > 0 || toSaveBreed.size() > 0 || toSaveExch.size() > 0; return toSave.size() > 0 || toSaveColl.size() > 0 || toSaveGeo.size() > 0 || toSaveBreed.size() > 0 || toSaveExch.size() > 0;
} }
private String arrayToString(ArrayNode arr) {
if (arr == null || arr.isNull())
return null;
StringBuffer storageArr = new StringBuffer(20);
for (JsonNode st : arr) {
if (st != null && !st.isNull()) {
if (storageArr.length() > 0)
storageArr.append(";");
storageArr.append(st.asText());
}
}
return StringUtils.defaultIfBlank(storageArr.toString(), null);
}
/**
* Converts textValue to JSON array node if required.
*
* @param accnJson
* @param key
* @return
*/
private ArrayNode toMcpdArray(ObjectNode accnJson, String key) {
JsonNode value = accnJson.get(key);
if (value == null || value.isNull()) {
return null;
} else if (value.isArray()) {
return (ArrayNode) value;
} else if (value.isTextual()) {
ArrayNode arr = accnJson.arrayNode();
for (String s : value.textValue().split("[,;]")) {
if (StringUtils.isBlank(s))
continue;
arr.add(s.trim());
}
return arr;
}
return null;
}
/**
* Convert to {@link AccessionAlias}
*
* @param acceNames
*/
private void updateAccessionAliases(Map<Accession, ArrayNode> acceNames, AliasType aliasType) {
List<AccessionAlias> toSave = new ArrayList<AccessionAlias>();
List<AccessionAlias> toRemove = new ArrayList<AccessionAlias>();
for (Accession accession : acceNames.keySet()) {
ArrayNode acceName = acceNames.get(accession);
List<AccessionAliasJson> aliases = new ArrayList<AccessionAliasJson>();
if (acceName != null) {
for (JsonNode item : acceName) {
if (item.isTextual() && StringUtils.isNotBlank(item.textValue())) {
AccessionAliasJson alias = new AccessionAliasJson();
String val = item.textValue();
if (val.contains(":")) {
String[] s = val.split(":", 2);
alias.instCode = s[0].trim();
alias.name = s[1].trim();
} else {
alias.name = item.textValue().trim();
}
alias.type = aliasType.getId();
aliases.add(alias);
}
}
}
upsertAccessionAliases(accession, aliases, aliasType, toRemove, toSave);
}
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 @Override
@Transactional @Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')")
...@@ -397,38 +522,8 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -397,38 +522,8 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
// LOG.info("Updating " + dataJson + " with=" + dataJson.aliases); // LOG.info("Updating " + dataJson + " with=" + dataJson.aliases);
List<AccessionAlias> existingAliases = genesysService.listAccessionAliases(accession); List<AccessionAliasJson> aliases = dataJson.aliases;
// Find aliases to remove upsertAccessionAliases(accession, aliases, null, toRemove, toSave);
for (final AccessionAlias aa : existingAliases) {
if (null == CollectionUtils.find(dataJson.aliases, new Predicate<AccessionAliasJson>() {
@Override
public boolean evaluate(AccessionAliasJson alias) {
return StringUtils.equals(alias.name, aa.getName());
}
})) {
toRemove.add(aa);
}
}
// Add or update
for (final AccessionAliasJson aa : dataJson.aliases) {
AccessionAlias accessionAlias = CollectionUtils.find(existingAliases, new Predicate<AccessionAlias>() {
@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(aa.instCode);
accessionAlias.setAliasType(AliasType.getType(aa.type));
toSave.add(accessionAlias);
}
} }
if (toSave.size() > 0) { if (toSave.size() > 0) {
...@@ -441,4 +536,52 @@ public class BatchRESTServiceImpl implements BatchRESTService { ...@@ -441,4 +536,52 @@ public class BatchRESTServiceImpl implements BatchRESTService {
} }
} }
private void upsertAccessionAliases(Accession accession, List<AccessionAliasJson> aliases, final AliasType aliasType, List<AccessionAlias> toRemove,
List<AccessionAlias> toSave) {
List<AccessionAlias> existingAliases = genesysService.listAccessionAliases(accession);
// Allows us to focus only on a particular alias type
if (aliasType != null) {
LOG.debug("Filtering accession aliases by " + aliasType);
CollectionUtils.filter(existingAliases, new Predicate<AccessionAlias>() {
@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<AccessionAliasJson>() {
@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<AccessionAlias>() {
@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(aa.instCode);
accessionAlias.setAliasType(aliasType != null ? aliasType : AliasType.getType(aa.type));
toSave.add(accessionAlias);
}
}
} }
...@@ -167,6 +167,7 @@ accession.crop=Crop ...@@ -167,6 +167,7 @@ accession.crop=Crop
accession.otherNames=Also known as accession.otherNames=Also known as
accession.inTrust=In Trust accession.inTrust=In Trust
accession.mlsStatus=MLS Status accession.mlsStatus=MLS Status
accession.duplSite=Safety duplication
accession.inSvalbard=Svalbardized accession.inSvalbard=Svalbardized
accession.inTrust.true=This accession is under Article 15 of the International Treaty on Plant Genetic Resources for Food and Agriculture. accession.inTrust.true=This accession is under Article 15 of the International Treaty on Plant Genetic Resources for Food and Agriculture.
accession.mlsStatus.true=This accession is in the Multilateral System of the ITPGRFA. accession.mlsStatus.true=This accession is in the Multilateral System of the ITPGRFA.
...@@ -177,6 +178,7 @@ accession.elevation=Elevation ...@@ -177,6 +178,7 @@ accession.elevation=Elevation
accession.geolocation=Geolocation (lat, long) accession.geolocation=Geolocation (lat, long)
accession.storage=Germplasm storage accession.storage=Germplasm storage
accession.storage.=
accession.storage.10=Seed collection accession.storage.10=Seed collection
accession.storage.11=Short term accession.storage.11=Short term
accession.storage.12=Medium term accession.storage.12=Medium term
...@@ -198,6 +200,7 @@ accession.collecting.date=Collecting date ...@@ -198,6 +200,7 @@ accession.collecting.date=Collecting date
accession.collecting.mission=Collecting mission ID accession.collecting.mission=Collecting mission ID
accession.collecting.source=Collecting source accession.collecting.source=Collecting source
accession.collectingSource.=
accession.collectingSource.10=Wild habitat accession.collectingSource.10=Wild habitat
accession.collectingSource.11=Forest or woodland accession.collectingSource.11=Forest or woodland
accession.collectingSource.12=Shrubland accession.collectingSource.12=Shrubland
...@@ -253,9 +256,11 @@ accession.sampleStatus.600=GMO ...@@ -253,9 +256,11 @@ accession.sampleStatus.600=GMO
accession.sampleStatus.999=Other accession.sampleStatus.999=Other
accession.availability=Availability accession.availability=Availability
accession.aliasType.GENERIC= accession.aliasType.ACCENAME=Accession name
accession.aliasType.DONORNAME=(Donor accession name) accession.aliasType.DONORNUMB=Donor accession identifier
accession.aliasType.BREEDERNAME=(Used by breeders) accession.aliasType.BREEDERNAME=Breeder name
accession.aliasType.COLLNUMB=Collecting number
accession.aliasType.OTHERNUMB=Other names
accession.aliasType.DATABASEID=(Database ID) accession.aliasType.DATABASEID=(Database ID)
accession.aliasType.LOCALNAME=(Local name) accession.aliasType.LOCALNAME=(Local name)
......
...@@ -141,6 +141,13 @@ ...@@ -141,6 +141,13 @@
</td> </td>
</tr> </tr>
<tr>
<td><spring:message code="accession.duplSite" /></td>
<td><c:forEach items="${accession.duplSite.split('[;,]')}" var="duplSite">
<div><spring:message code="${duplSite}" /></div>
</c:forEach></td>
</tr>
<c:if test="${accessionExchange ne null}"> <c:if test="${accessionExchange ne null}">
<tr> <tr>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment