package productcatalog.pages; import common.pages.SelectableLinkData; import io.sphere.sdk.models.Base; import io.sphere.sdk.queries.PagedResult; import play.mvc.Http; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.IntStream; import static common.utils.UrlUtils.buildUrl; import static java.util.stream.Collectors.toList; public class PaginationDataFactory extends Base { private final Http.Request request; private final PagedResult<?> searchResult; private final int currentPage; private final int totalPages; private final int productsCount; private final int totalProducts; private final int displayedPages; private int pageThresholdLeft; private int pageThresholdRight; public PaginationDataFactory(final Http.Request request, final PagedResult<?> searchResult, final int currentPage, final int pageSize, final int displayedPages) { this.request = request; this.searchResult = searchResult; this.currentPage = currentPage; this.totalPages = getTotalPages(searchResult, pageSize); this.productsCount = searchResult.getOffset() + searchResult.size(); this.totalProducts = searchResult.getTotal(); this.displayedPages = displayedPages; this.pageThresholdLeft = displayedPages - 1; this.pageThresholdRight = totalPages - displayedPages + 2; } public PaginationData create() { final PaginationData paginationData = new PaginationData(productsCount, totalProducts); final List<SelectableLinkData> pages; if (totalPages <= displayedPages) { pages = getPages(1, totalPages); } else if (currentPage < pageThresholdLeft) { pages = getPages(1, pageThresholdLeft); paginationData.setLastPage(getLinkData(totalPages)); } else if (currentPage > pageThresholdRight) { pages = getPages(pageThresholdRight, totalPages); paginationData.setFirstPage(getLinkData(1)); } else { pages = getPages(currentPage - 1, currentPage + 1); paginationData.setFirstPage(getLinkData(1)); paginationData.setLastPage(getLinkData(totalPages)); } paginationData.setPages(pages); if (!searchResult.isFirst()) { paginationData.setPrevPage(getLinkData(currentPage - 1)); } if (!searchResult.isLast()) { paginationData.setNextPage(getLinkData(currentPage + 1)); } return paginationData; } private List<SelectableLinkData> getPages(final int startPage, final int endPage) { return IntStream.rangeClosed(startPage, endPage) .mapToObj(this::getLinkData) .collect(toList()); } private SelectableLinkData getLinkData(final int page) { return new SelectableLinkData(String.valueOf(page), buildRequestUrlWithPage(page), page == currentPage); } private String buildRequestUrlWithPage(final int page) { final Map<String, String[]> queryString = new HashMap<>(request.queryString()); queryString.put("page", new String[]{String.valueOf(page)}); return buildUrl(request.path(), queryString); } private static int getTotalPages(final PagedResult<?> searchResult, final int pageSize) { final Double totalPages = Math.ceil((float) searchResult.getTotal() / pageSize); return totalPages.intValue(); } }