Commit 9a710b85 authored by Matija Obreza's avatar Matija Obreza

Scrolling with Slice<T>

parent 876802bd
......@@ -16,52 +16,39 @@
package org.genesys2.server.api;
import java.io.Serializable;
import java.util.List;
import java.util.Iterator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.genesys.blocks.model.filters.EmptyModelFilter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
/**
* The Class FilteredSlice.
*
* @param <T> the generic type
*/
public class FilteredSlice<T> implements Serializable {
public class FilteredSlice<T> implements Serializable, Iterable<T> {
private static final long serialVersionUID = 6965069448240229428L;
/** The data is serialized on the base JSON level. */
public List<T> content;
@JsonUnwrapped
public Slice<T> slice;
/** The filter. */
public EmptyModelFilter<?, ?> filter;
/** The filter code. */
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public String filterCode;
public Sort sort;
public long totalElements;
public long offset;
/**
* Instantiates a new filtered page.
*
* @param filter the filter
* @param data the data
*/
public FilteredSlice(final EmptyModelFilter<?, ?> filter, final Page<T> data, final Long offset) {
public FilteredSlice(final EmptyModelFilter<?, ?> filter, final Slice<T> data) {
this.filter = filter;
this.content = data.getContent();
this.sort = data.getSort();
this.totalElements = data.getTotalElements();
this.offset = offset == null ? 0 : offset;
this.slice = data;
}
/**
......@@ -71,18 +58,14 @@ public class FilteredSlice<T> implements Serializable {
* @param filter the filter
* @param data the data
*/
public FilteredSlice(final String filterCode, final EmptyModelFilter<?, ?> filter, final Page<T> data, final Long offset) {
public FilteredSlice(final String filterCode, final EmptyModelFilter<?, ?> filter, final Slice<T> data) {
this.filterCode = filterCode;
this.filter = filter;
this.content = data.getContent();
this.sort = data.getSort();
this.totalElements = data.getTotalElements();
this.offset = offset == null ? 0 : offset;
this.slice = data;
}
@JsonProperty
public int getSliceSize() {
return this.content == null ? 0 : this.content.size();
@Override
public Iterator<T> iterator() {
return slice.iterator();
}
}
/*
* Copyright 2020 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.api;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.springframework.data.domain.Sort;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* The data Slice.
*
* @param <T> the generic type
*/
public class Slice<T> implements Serializable, Iterable<T> {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 6965069448240229428L;
/** The data is serialized on the base JSON level. */
public List<T> content;
/** The sort. */
public Sort sort;
/** The total elements. */
public long totalElements;
/** The offset. */
public long offset;
/**
* Instantiates a new filtered page.
*
* @param data the data
* @param offset the offset
* @param totalElements the total elements
* @param sort the sort
*/
public Slice(final List<T> data, final long offset, final long totalElements, Sort sort) {
this.content = data;
this.sort = sort;
this.totalElements = totalElements;
this.offset = offset;
}
/**
* Gets the slice size.
*
* @return the slice size
*/
@JsonProperty
public int getSliceSize() {
return this.content == null ? 0 : this.content.size();
}
/**
* Iterator.
*
* @return the iterator
*/
@Override
public Iterator<T> iterator() {
return content.iterator();
}
}
......@@ -39,7 +39,6 @@ import org.genesys.catalog.service.ShortFilterService.FilterInfo;
import org.genesys2.server.api.ApiBaseController;
import org.genesys2.server.api.FilteredPage;
import org.genesys2.server.api.FilteredSlice;
import org.genesys2.server.api.OffsetRequest;
import org.genesys2.server.api.Pagination;
import org.genesys2.server.api.ScrollPagination;
import org.genesys2.server.api.model.AccessionHeaderJson;
......@@ -252,7 +251,7 @@ public class AccessionController {
FilterInfo<AccessionFilter> filterInfo = shortFilterService.processFilter(filterCode, filter, AccessionFilter.class);
FilteredSlice<AccessionService.AccessionDetails> pageRes = new FilteredSlice<>(filterInfo.filterCode, filterInfo.filter, accessionService.withImages(filterInfo.filter, page.toPageRequest(20, Sort.Direction.ASC, "seqNo")), page.getO());
FilteredSlice<AccessionService.AccessionDetails> pageRes = new FilteredSlice<>(filterInfo.filterCode, filterInfo.filter, accessionService.withImagesSlice(filterInfo.filter, page.toPageRequest(20, Sort.Direction.ASC, "seqNo")));
filterInfo.filter.images = true;
Map<String, TermResult> suggestionRes = accessionService.getSuggestions(filterInfo.filter);
......
......@@ -29,6 +29,7 @@ import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys2.server.api.FilteredPage;
import org.genesys2.server.api.FilteredSlice;
import org.genesys2.server.api.Slice;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.PDCI;
import org.genesys2.server.model.genesys.Taxonomy2;
......@@ -111,6 +112,15 @@ public interface AccessionService {
*/
Page<AccessionDetails> withImages(AccessionFilter filter, Pageable page) throws SearchException;
/**
* List accessions with images by filter
*
* @param filter the filter
* @param page the page
* @return the page
*/
Slice<AccessionDetails> withImagesSlice(AccessionFilter filter, Pageable page) throws SearchException;
/**
* Filtering autocompleter with suggestions
*
......
......@@ -37,6 +37,7 @@ import org.genesys.catalog.service.DatasetService;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys2.server.api.Slice;
import org.genesys2.server.component.aspect.DatasetAndSubsetCountAspect;
import org.genesys2.server.exception.NotFoundElement;
import org.genesys2.server.model.PublishState;
......@@ -427,6 +428,38 @@ public class AccessionServiceImpl implements AccessionService {
return new PageImpl<>(contentWithImages, page, paged .getTotalElements());
}
@Override
public Slice<AccessionDetails> withImagesSlice(AccessionFilter filter, Pageable page) throws SearchException {
filter.images = true;
Page<Accession> paged = findAll(filter, page);
paged.forEach(accession -> accession.getTaxonomy().getId());
List<AccessionDetails> contentWithImages = new ArrayList<>(paged .getNumberOfElements());
int imageCount = 0;
for (Accession accession : paged ) {
AccessionDetails details = new AccessionDetails();
details.details = accession;
RepositoryFolder folder = accession.getAccessionId().getRepositoryFolder();
ImageGallery imageGallery = imageGalleryService.getImageGallery(folder);
if (imageGallery != null) {
if (imageGallery.getImages() != null) {
imageGallery.getImages().size();
imageCount += imageGallery.getImages().size();
}
details.imageGallery = imageGallery;
}
contentWithImages.add(details);
if (imageCount > page.getPageSize()) {
break;
}
}
return new Slice<>(contentWithImages, page.getOffset(), paged.getTotalElements(), paged.getSort());
}
// Utility method that uses ES as required
private Page<Accession> findAll(AccessionFilter filter, Pageable page) throws SearchException {
if (filter.isFulltextQuery()) {
......
......@@ -1504,9 +1504,8 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
AccessionFilter af = new AccessionFilter();
/*@formatter:off*/
mockMvc
.perform(post(AccessionController.CONTROLLER_URL + "/images?l=1")
.perform(post(AccessionController.CONTROLLER_URL + "/images?o=0&l=1")
.contentType(MediaType.APPLICATION_JSON)
.param("o", "")
.content(objectMapper.writeValueAsString(af))
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
......@@ -1535,11 +1534,41 @@ public class AccessionControllerTest extends AbstractAccessionControllerTest {
.andExpect(jsonPath("$.totalPages").doesNotHaveJsonPath())
;
mockMvc
.perform(post(AccessionController.CONTROLLER_URL + "/images?o=0&l=15")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(af))
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.content").isArray())
.andExpect(jsonPath("$.content", hasSize(2)))
.andExpect(jsonPath("$.content[0].details").isMap())
.andExpect(jsonPath("$.content[0].imageGallery").isMap())
.andExpect(jsonPath("$.content[0].imageGallery.images").isArray())
.andExpect(jsonPath("$.content[0].imageGallery.images", hasSize(10)))
.andExpect(jsonPath("$.suggestions").isMap())
.andExpect(jsonPath("$.filter").exists())
.andExpect(jsonPath("$.filterCode").exists())
// pageable
.andExpect(jsonPath("$.sort").isArray())
.andExpect(jsonPath("$.totalElements", is(3)))
.andExpect(jsonPath("$.offset", is(0))) // must be 0 by default
.andExpect(jsonPath("$.sliceSize", is(2)))
.andExpect(jsonPath("$.size").doesNotHaveJsonPath())
.andExpect(jsonPath("$.numberOfElements").doesNotHaveJsonPath())
.andExpect(jsonPath("$.number").doesNotHaveJsonPath())
.andExpect(jsonPath("$.first").doesNotHaveJsonPath())
.andExpect(jsonPath("$.last").doesNotHaveJsonPath())
.andExpect(jsonPath("$.totalPages").doesNotHaveJsonPath())
;
mockMvc
.perform(post(AccessionController.CONTROLLER_URL + "/images?o=1&l=1")
.contentType(MediaType.APPLICATION_JSON)
.param("o", "")
.content(objectMapper.writeValueAsString(af))
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
......
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