Commit 2d051270 authored by Matija Obreza's avatar Matija Obreza

Updates to Crops API v1

parent 3bb78f5b
......@@ -16,10 +16,10 @@
package org.genesys2.server.api.v1;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.Api;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
import java.util.List;
import javax.xml.bind.ValidationException;
import org.genesys.blocks.model.JsonViews;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys2.server.api.ApiBaseController;
......@@ -39,13 +39,19 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.xml.bind.ValidationException;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.Api;
import net.sf.oval.ConstraintViolation;
import net.sf.oval.Validator;
@RestController("cropApi1")
@RequestMapping(value = { CropsController.CONTROLLER_URL, "/json/v1/crops" })
......@@ -71,10 +77,9 @@ public class CropsController extends ApiBaseController {
* @throws AuthorizationException
*/
@RequestMapping(value = "", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public List<Crop> listCrops() {
public List<CropService.CropDetails> listCrops() {
LOG.info("Listing crops");
final List<Crop> crops = cropService.list(LocaleContextHolder.getLocale());
return crops;
return cropService.listDetails(LocaleContextHolder.getLocale());
}
/**
......@@ -126,10 +131,10 @@ public class CropsController extends ApiBaseController {
* @throws AuthorizationException
*/
@JsonView(JsonViews.Public.class)
@RequestMapping(value = "/{shortName}/details/{lang}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public CropService.CropDetails getCropDetails(@PathVariable("shortName") String shortName, @PathVariable("lang") String lang) throws InvalidRepositoryPathException {
@RequestMapping(value = "/{shortName}/details", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public CropService.CropDetails getCropDetails(@PathVariable("shortName") String shortName) throws InvalidRepositoryPathException {
LOG.info("Getting crop details {}", shortName);
return cropService.getDetails(shortName, lang);
return cropService.getDetails(shortName, LocaleContextHolder.getLocale());
}
/**
......
......@@ -16,10 +16,12 @@
package org.genesys2.server.service;
import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.genesys.blocks.model.JsonViews;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.model.genesys.Taxonomy2;
......@@ -30,11 +32,16 @@ import org.genesys2.server.model.impl.CropTaxonomy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonView;
public interface CropService {
Crop getCrop(String shortName);
CropDetails getDetails(String shortName, String lang) throws InvalidRepositoryPathException;
CropDetails getDetails(String shortName, Locale locale) throws InvalidRepositoryPathException;
List<CropDetails> listDetails(Locale locale);
List<Crop> listCrops();
......@@ -64,6 +71,7 @@ public interface CropService {
Crop addCrop(String shortName, String name, String description, String i18n);
Crop addCrop(Crop crop);
/**
* Updates a crop record
*
......@@ -118,16 +126,20 @@ public interface CropService {
*/
Crop updateAliases(Crop crop, List<String> otherNames);
public static class CropDetails implements Serializable {
private static final long serialVersionUID = 1622015024393351713L;
class CropDetails {
@JsonUnwrapped
public Crop crop;
@JsonView({ JsonViews.Public.class })
public Article blurb;
public long accessionCount;
public List<RepositoryImage> covers;
@JsonView({ JsonViews.Public.class })
public Map<String, ElasticsearchService.TermResult> overview;
public static CropDetails from(Crop crop, Article blurb, long accessionCount, List<RepositoryImage> covers, Map<String, ElasticsearchService.TermResult> overview){
public static CropDetails from(Crop crop, Article blurb, long accessionCount, List<RepositoryImage> covers, Map<String, ElasticsearchService.TermResult> overview) {
CropDetails cropDetails = new CropDetails();
cropDetails.crop = crop;
cropDetails.blurb = blurb;
......
......@@ -150,7 +150,7 @@ public class AccessionServiceImpl implements AccessionService {
}
@Override
@Cacheable(value = "accessionCount")
@Cacheable(value = "accessionCount", keyGenerator = "shortFilterKeyGenerator")
public long countAccessions(AccessionFilter filter) {
long total = elasticsearchService.count(Accession.class, filter);
......
......@@ -17,7 +17,14 @@
package org.genesys2.server.service.impl;
import java.nio.file.Paths;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
......@@ -37,7 +44,12 @@ import org.genesys2.server.persistence.CropRepository;
import org.genesys2.server.persistence.CropRuleRepository;
import org.genesys2.server.persistence.CropTaxonomyRepository;
import org.genesys2.server.persistence.Taxonomy2Repository;
import org.genesys2.server.service.*;
import org.genesys2.server.service.AccessionService;
import org.genesys2.server.service.CRMException;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.ElasticsearchService;
import org.genesys2.server.service.HtmlSanitizer;
import org.genesys2.server.service.filter.AccessionFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -46,9 +58,7 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.common.exceptions.UnauthorizedUserException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -111,19 +121,16 @@ public class CropServiceImpl implements CropService {
}
@Override
@Transactional(readOnly = true, noRollbackFor = AccessDeniedException.class)
public CropDetails getDetails(String shortName, String lang) throws AccessDeniedException, InvalidRepositoryPathException {
Locale locale = lang == null ? Locale.getDefault() : Locale.forLanguageTag(lang);
@Transactional
public CropDetails getDetails(String shortName, Locale locale) throws InvalidRepositoryPathException {
Crop crop = getCrop(shortName);
Article article = contentService.getArticle(crop, "blurp", locale);
AccessionFilter byCrop = new AccessionFilter();
byCrop.cropName = crop.getName();
byCrop.cropName = crop.getShortName();
long accessionCount = accessionService.countAccessions(byCrop);
ImageGallery imageGallery = imageGalleryService.loadImageGallery(Paths.get("/crop/"+ crop.getShortName() +"/cover"));
ImageGallery imageGallery = imageGalleryService.loadImageGallery(Paths.get("/crop", crop.getShortName(), "covers"));
List<RepositoryImage> covers = imageGallery == null ? Collections.emptyList() : imageGallery.getImages();
Map<String, ElasticsearchService.TermResult> overview = getOverviewData(byCrop);
......@@ -159,9 +166,9 @@ public class CropServiceImpl implements CropService {
return cropRepository.save(crop);
}
@Override
@Cacheable(value = CACHE_CROPS, key = "'findAll'")
@Cacheable(value = CACHE_CROPS, key = "'listCrops'")
public List<Crop> listCrops() {
List<Crop> crops = cropRepository.findAll();
// Fetch otherNames list
......@@ -172,6 +179,31 @@ public class CropServiceImpl implements CropService {
return crops;
}
@Override
@Cacheable(value = CACHE_CROPS, key = "'findAll-' + #locale.language")
public List<CropDetails> listDetails(Locale locale) {
List<Crop> crops = cropRepository.findAll();
// Fetch details
return crops.stream().map(c -> {
if (c.getOtherNames() != null)
c.getOtherNames().size();
AccessionFilter byCrop = new AccessionFilter();
byCrop.cropName = c.getShortName();
long accessionCount = accessionService.countAccessions(byCrop);
List<RepositoryImage> covers = null;
try {
ImageGallery imageGallery = imageGalleryService.loadImageGallery(Paths.get("/crop", c.getShortName(), "covers"));
covers = imageGallery == null ? Collections.emptyList() : imageGallery.getImages();
} catch (InvalidRepositoryPathException e) {
}
return CropDetails.from(c, null, accessionCount, covers, null);
}).collect(Collectors.toList());
}
@Override
public Page<Crop> listCrops(Pageable pageable) {
return cropRepository.findAll(pageable);
......
......@@ -266,12 +266,11 @@ public class CropsControllerTest extends AbstractApiTest {
setupBlurb();
/*@formatter:off*/
mockMvc.perform(get("/api/v1/crops/{shortName}/details/en", crop.getShortName())
mockMvc.perform(get("/api/v1/crops/{shortName}/details", crop.getShortName())
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.crop", is(notNullValue())))
.andExpect(jsonPath("$.crop.shortName", is("maize")))
.andExpect(jsonPath("$.shortName", is("maize")))
.andExpect(jsonPath("$.blurb", is(notNullValue())))
.andExpect(jsonPath("$.covers", is(notNullValue())))
.andExpect(jsonPath("$.overview", is(notNullValue())))
......
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