Commit e8965443 authored by Matija Obreza's avatar Matija Obreza
Browse files

REST Insert accession data to the dataset

parent 48bad354
......@@ -143,7 +143,8 @@ public class Method extends BusinessModel implements AclAwareModel {
@Transient
public boolean isCoded() {
return this.fieldType == 0;
// TODO Check database!
return this.options != null;
}
// FIXME String?
......
......@@ -33,6 +33,8 @@ public interface AccessionTraitRepository extends JpaRepository<AccessionTrait,
List<AccessionTrait> findByMetadata(Metadata metadata);
List<AccessionTrait> findByMetadataAndAccession(Metadata metadata, Accession accession);
List<AccessionTrait> findByMethod(Method method);
@Query("select distinct at.metadata from AccessionTrait at where at.accession = ?1")
......@@ -46,4 +48,5 @@ public interface AccessionTraitRepository extends JpaRepository<AccessionTrait,
@Query("select distinct at.method from AccessionTrait at where at.metadata = ?1")
List<Method> listMetadataMethods(Metadata metadata);
}
......@@ -35,4 +35,6 @@ public interface TraitValueRepository {
Map<Long, Map<Long, Object>> getValues(Metadata metadata, List<Method> methods, List<Accession> accessions);
void insert(Metadata metadata, Accession accession, Method method, List<Object> accessionValues);
}
\ No newline at end of file
......@@ -16,6 +16,8 @@
package org.genesys2.server.persistence.domain;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
......@@ -31,6 +33,7 @@ import org.genesys2.server.model.genesys.ExperimentTrait;
import org.genesys2.server.model.genesys.Metadata;
import org.genesys2.server.model.genesys.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
......@@ -137,6 +140,7 @@ public class TraitValueRepositoryImpl implements TraitValueRepository {
long accessionId = (Long) row.get("accessionId");
Object value = row.get("traitvalue");
// TODO null values should not exist
if (value != null) {
Map<Long, Object> accessionValues = accessionMetadataValues.get(accessionId);
if (accessionValues != null)
......@@ -149,4 +153,25 @@ public class TraitValueRepositoryImpl implements TraitValueRepository {
return accessionMetadataValues;
}
@Override
@Transactional
public void insert(Metadata metadata, Accession accession, Method method, final List<Object> accessionValues) {
final long accessionId = accession.getId();
final long metadataId = metadata.getId();
this.jdbcTemplate.batchUpdate(String.format("INSERT INTO `%s` (Alis_Id, Meta_id, `%s`) VALUES (?, ?, ?)", method.getId(), method.getFieldName()),
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pst, int idx) throws SQLException {
pst.setLong(1, accessionId);
pst.setLong(2, metadataId);
pst.setObject(3, accessionValues.get(idx));
}
@Override
public int getBatchSize() {
return accessionValues.size();
}
});
}
}
......@@ -19,6 +19,7 @@ package org.genesys2.server.service;
import java.util.List;
import org.genesys2.server.model.genesys.Metadata;
import org.springframework.data.repository.query.Param;
import org.springframework.security.access.prepost.PreAuthorize;
public interface DatasetService {
......@@ -31,4 +32,6 @@ public interface DatasetService {
Metadata getDataset(long metadataId);
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#metadata, 'WRITE')")
void touch(@Param("metadata") Metadata metadata);
}
......@@ -38,7 +38,6 @@ import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.model.impl.Organization;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public interface GenesysService {
......@@ -66,16 +65,16 @@ public interface GenesysService {
AllAcqBreeding listAccessionBreeding(Accession accession);
AllEnvironment listAccessionEnvironment(Accession accession);
List<Metadata> listMetadata(Accession accession);
Page<Metadata> listMetadata(PageRequest pageRequest);
Page<Metadata> listMetadata(Pageable pageable);
Metadata getMetadata(long metadataId);
List<Method> listMethods(Metadata metadata);
Page<Accession> listMetadataAccessions(Metadata metadata, PageRequest pageRequest);
Page<Accession> listMetadataAccessions(Metadata metadata, Pageable pageable);
List<Method> listMethods(Accession accession);
......@@ -87,11 +86,13 @@ public interface GenesysService {
List<Accession> listAccessions(List<? extends AccessionIdentifier3> accns);
Accession getAccession(AccessionIdentifier3 aid3);
Page<Object[]> statisticsGenusByInstitute(FaoInstitute faoInstitute, Pageable pageable);
Page<Object[]> statisticsTaxonomyByInstitute(FaoInstitute faoInstitute, Pageable pageable);
Page<Object[]> statisticsCropByInstitute(FaoInstitute faoInstitute, Pageable pageable);
Page<Object[]> statisticsCropByInstitute(FaoInstitute faoInstitute, Pageable pageable);
Page<Accession> listAccessionsByInstituteAndTaxonomy(FaoInstitute institute, Taxonomy taxonomy, Pageable pageable);
......@@ -113,4 +114,13 @@ public interface GenesysService {
long countAvailable(Set<Long> accessionIds);
/**
*
* @param metadata
* @param accession
* @param methodValues
* Map of method ids with List of objects
*/
void upsertAccessionData(Metadata metadata, Accession accession, Map<Long, List<Object>> methodValues);
}
......@@ -26,6 +26,7 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionTrait;
import org.genesys2.server.model.genesys.AllAccnames;
import org.genesys2.server.model.genesys.AllAcqBreeding;
import org.genesys2.server.model.genesys.AllAcqCollect;
......@@ -68,8 +69,8 @@ import org.genesys2.server.service.TraitService;
import org.genesys2.spring.SecurityContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.stereotype.Service;
......@@ -181,6 +182,11 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return result;
}
@Override
public Accession getAccession(AccessionIdentifier3 aid3) {
return accessionRepository.findByInstituteCodeAndAccessionNameAndGenus(aid3.getHoldingInstitute(), aid3.getAccessionName(), aid3.getGenus());
}
@Override
public Accession getAccession(long accessionId) {
return accessionRepository.findOne(accessionId);
......@@ -227,8 +233,8 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
}
@Override
public Page<Metadata> listMetadata(PageRequest pageRequest) {
return metadataRepository.findAll(pageRequest);
public Page<Metadata> listMetadata(Pageable pageable) {
return metadataRepository.findAll(pageable);
}
@Override
......@@ -242,8 +248,8 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
}
@Override
public Page<Accession> listMetadataAccessions(Metadata metadata, PageRequest pageRequest) {
return accessionTraitRepository.listMetadataAccessions(metadata, pageRequest);
public Page<Accession> listMetadataAccessions(Metadata metadata, Pageable pageable) {
return accessionTraitRepository.listMetadataAccessions(metadata, pageable);
}
@Override
......@@ -411,6 +417,12 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return metadataRepository.findOne(id);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#metadata, 'WRITE')")
public void touch(@Param("metadata") Metadata metadata) {
}
@Override
@PreAuthorize("isAuthenticated()")
@Transactional(readOnly = false)
......@@ -464,4 +476,25 @@ public class GenesysServiceImpl implements GenesysService, TraitService, Dataset
return methodRepository.findByIds(oids);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#metadata, 'WRITE')")
@Transactional(readOnly = false)
public void upsertAccessionData(Metadata metadata, Accession accession, Map<Long, List<Object>> methodValues) {
// TODO Load all existing records for metadata+accession
List<AccessionTrait> existingEntries = accessionTraitRepository.findByMetadataAndAccession(metadata, accession);
// Remove entries missing from map
for (AccessionTrait accessionTrait : existingEntries) {
LOG.debug("Existing trait " + accessionTrait);
// TODO Remove
}
// TODO Add new entries from map
// just stick them to database
for (long methodId : methodValues.keySet()) {
Method method = methodRepository.findOne(methodId);
traitValueRepository.insert(metadata, accession, method, methodValues.get(methodId));
}
}
}
......@@ -16,7 +16,14 @@
package org.genesys2.server.servlet.controller.rest;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.ValidationException;
......@@ -28,7 +35,10 @@ import net.sf.oval.constraint.NotBlank;
import net.sf.oval.constraint.NotNull;
import org.genesys2.server.exception.AuthorizationException;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.Metadata;
import org.genesys2.server.model.genesys.Method;
import org.genesys2.server.model.impl.AccessionIdentifier3;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.DatasetService;
import org.genesys2.server.service.GenesysService;
......@@ -44,6 +54,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller("restDatasetController")
@PreAuthorize("isAuthenticated()")
@RequestMapping(value = { "/api/v0/datasets", "/json/v0/datasets" })
......@@ -125,6 +138,163 @@ public class DatasetController extends RestController {
return OAuth2Cleanup.clean(genesysService.listMethods(metadata));
}
/**
* Get metadata Methods /datasets/{shortName}/methods
*
* @return
* @throws AuthorizationException
* @throws IOException
*/
@RequestMapping(value = "/{metadataId:.+}/data", method = { RequestMethod.PUT, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody
Object upsertMetadataData(@PathVariable("metadataId") Long metadataId, @RequestBody String data) throws AuthorizationException, IOException {
final Metadata metadata = datasetService.getDataset(metadataId);
if (metadata == null) {
throw new ResourceNotFoundException();
}
// Check for 'WRITE' permission
datasetService.touch(metadata);
System.err.println(data);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode json = null;
try {
json = objectMapper.readTree(data);
System.err.println(json);
} catch (IOException e) {
LOG.error(e);
throw e;
}
if (json.isArray()) {
for (JsonNode jo : json) {
upsertEntry(metadata, jo);
}
} else {
upsertEntry(metadata, json);
}
return null;
}
private void upsertEntry(final Metadata metadata, JsonNode json) {
if (LOG.isDebugEnabled())
LOG.debug("Upserting " + json);
DataJson dataJson = readDataJson(json);
Accession accession = genesysService.getAccession(dataJson);
if (accession == null) {
throw new NullPointerException("No accession for " + dataJson);
}
LOG.info("Upserting data for accession " + accession);
genesysService.upsertAccessionData(metadata, accession, dataJson.methodValues);
}
private DataJson readDataJson(JsonNode json) {
DataJson dataJson = new DataJson();
for (Iterator<Entry<String, JsonNode>> fields = json.fields(); fields.hasNext();) {
Entry<String, JsonNode> field = fields.next();
String key = field.getKey();
JsonNode value = field.getValue();
if ("instCode".equals(key)) {
dataJson.instCode = value.asText();
} else if ("acceNumb".equals(key)) {
dataJson.acceNumb = value.asText();
} else if ("genus".equals(key)) {
dataJson.genus = value.asText();
} else if (key.startsWith("gm:")) {
// Handle Genesys Method!
long methodId = Long.parseLong(key.substring(3));
// Need to validate method
Method method = traitService.getMethod(methodId);
if (method == null) {
throw new NullPointerException("No method with id=" + methodId);
}
if (value.isArray()) {
for (JsonNode v : value) {
dataJson.addMethodValue(methodId, convert(method, v));
}
} else {
dataJson.addMethodValue(methodId, convert(method, value));
}
}
}
return dataJson;
}
private Object convert(Method method, JsonNode v) {
if (v == null) {
return null;
}
if (method.isCoded()) {
// TODO Handle coded descriptors
throw new UnsupportedOperationException("Handling coded descriptors is supported");
} else if (method.getFieldType() == 0) {
// String
return v.asText();
} else if (method.getFieldType() == 1) {
// Double
return v.isNumber() ? v.doubleValue() : null;
} else if (method.getFieldType() == 2) {
// Long
return v.isNumber() ? v.longValue() : null;
}
throw new UnsupportedOperationException("Unknown method#fieldType " + method.getFieldType());
}
public static class DataJson implements AccessionIdentifier3 {
public String instCode;
public String acceNumb;
public String genus;
private Map<Long, List<Object>> methodValues;
@Override
public String getHoldingInstitute() {
return instCode;
}
public void addMethodValue(long methodId, Object value) {
if (value == null) {
// skip nulls
return;
}
if (methodValues == null) {
methodValues = new HashMap<Long, List<Object>>();
}
List<Object> values = methodValues.get(methodId);
if (values == null) {
methodValues.put(methodId, values = new ArrayList<Object>(5));
}
values.add(value);
}
@Override
public String getAccessionName() {
return acceNumb;
}
@Override
public String getGenus() {
return genus;
}
@Override
public String toString() {
return MessageFormat.format("AID3 instCode={0} acceNumb={1} genus={2}", instCode, acceNumb, genus);
}
}
public static class MetadataJson {
@NotBlank
@NotNull
......
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