001
002package com.commercetools.api.models;
003
004import java.util.List;
005import java.util.Optional;
006
007public interface ResourcePagedQueryResponse<T> {
008    public Long getLimit();
009
010    public Long getCount();
011
012    public Long getTotal();
013
014    public Long getOffset();
015
016    List<T> getResults();
017
018    /**
019     * Tries to access the first element of the result list.
020     * Use case: query by slug which should contain zero or one element in the result list.
021     *
022     * @return the first value or absent
023     */
024    default Optional<T> head() {
025        final List<T> results = getResults();
026        return results.isEmpty() ? Optional.empty() : Optional.of(results.get(0));
027    }
028
029    /**
030     * Calculates the page number of the result, the pages are indexed staring 0, which means that {@code getPageIndex()}
031     * returns a value in [0,n) , given 'n' is the total number of pages
032     *
033     * @return the page number of the result
034     */
035    default Long getPageIndex() {
036        if (getTotal() == null || getLimit() == null || getLimit() == 0) {
037            throw new UnsupportedOperationException(
038                "Can only be used if the limit & total are known and limit is non-zero.");
039        }
040        return (long) Math.floor(getOffset() / getLimit().doubleValue());
041    }
042
043    /**
044     * Calculates the total number of pages matching the request.
045     *
046     * @return the total number of pages
047     */
048    default Long getTotalPages() {
049        if (getTotal() == null || getLimit() == null || getLimit() == 0) {
050            throw new UnsupportedOperationException(
051                "Can only be used if the limit & total are known and limit is non-zero.");
052        }
053        return (long) Math.ceil(getTotal() / getLimit().doubleValue());
054    }
055
056    /**
057     * Checks if this is the first page of a result.
058     *
059     * @return true if offset is 0 otherwise false
060     */
061    default boolean isFirst() {
062        if (getOffset() == null) {
063            throw new UnsupportedOperationException("Can only be used if the offset is known.");
064        }
065        return getOffset() == 0;
066    }
067
068    /**
069     * Checks if it is the last possible page.
070     *
071     * @return true if doing a request with an incremented offset parameter would cause an empty result otherwise false.
072     */
073    default boolean isLast() {
074        if (getOffset() == null || getTotal() == null) {
075            throw new UnsupportedOperationException("Can only be used if the offset & total are known.");
076        }
077        //currently counting the total amount is performed in a second database call, so it is possible
078        //that the left side can be greater than total
079        return getOffset() + getCount() >= getTotal();
080    }
081}