# SliceResultWindower.java

    package org.codefilarete.stalactite.spring.repository.query.execution.reduce;

    import java.util.List;
    import java.util.function.Supplier;

    import org.codefilarete.stalactite.spring.repository.query.execution.StalactiteQueryMethodInvocationParameters;
    import org.codefilarete.stalactite.spring.repository.query.StalactiteRepositoryQuery;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.SliceImpl;

    /**
     * {@link QueryResultWindower} dedicated to {@link org.springframework.data.domain.Slice} result.
     * @param <C>
     * @param <R>
     * @param <P>
     * @author Guillaume Mary
     */
    public class SliceResultWindower<C, R, P> extends QueryResultWindower<C, R, P> {

    	public SliceResultWindower(StalactiteRepositoryQuery<C, ?> delegate,
    							   LimitHandler limitHandler,
    							   Supplier<List<P>> resultSupplier) {
    		super(delegate,
    				limitHandler,
    				(accessor, result) -> {
    					int pageSize = 0;
    					Pageable pageable = accessor.getPageable();
    					if (pageable.isPaged()) {
    						pageSize = pageable.getPageSize();
    					}
    					boolean hasNext = pageable.isPaged() && result.size() > pageSize;
    					return (R) new SliceImpl<>(hasNext ? result.subList(0, pageSize) : result, pageable, hasNext);
    				},
    				resultSupplier);
    	}

    	@Override
    	protected void adaptLimit(StalactiteQueryMethodInvocationParameters invocationParameters) {
    		Pageable pageable = invocationParameters.getPageable();
    		if (!pageable.isUnpaged()) {
    			if (pageable.getPageNumber() == 0) {
    				// The + 1 is a look-ahead tip to make the returned Slice eventually return true on hasNext()
    				limitHandler.limit(pageable.getPageSize() + 1);
    			} else {
    				// when the user asks for a page number (given Pageable is a Page instance or a Slice with page number) then we ask for the page number
    				limitHandler.limit(pageable.getPageSize(), (int) pageable.getOffset());
    			}
    		}
    		// else: not paging is expected, thus no limit is required
    	}
    }