diff --git a/src/main/java/org/springframework/data/domain/Page.java b/src/main/java/org/springframework/data/domain/Page.java index a0637ef91..393913b2a 100644 --- a/src/main/java/org/springframework/data/domain/Page.java +++ b/src/main/java/org/springframework/data/domain/Page.java @@ -90,6 +90,24 @@ public interface Page extends Iterable { */ boolean isLastPage(); + /** + * Returns the {@link Pageable} to request the next {@link Page}. Can be {@literal null} in case the current + * {@link Page} is already the last one. Clients should check {@link #hasNextPage()} before calling this method to + * make sure they receive a non-{@literal null} value. + * + * @return + */ + Pageable nextPageable(); + + /** + * Returns the {@link Pageable} to request the previous page. Can be {@literal null} in case the current {@link Page} + * is already the first one. Clients should check {@link #hasPreviousPage()} before calling this method make sure + * receive a non-{@literal null} value. + * + * @return + */ + Pageable previousPageable(); + /* * (non-Javadoc) * @see java.lang.Iterable#iterator() diff --git a/src/main/java/org/springframework/data/domain/PageImpl.java b/src/main/java/org/springframework/data/domain/PageImpl.java index ba17bfc5d..0851795b1 100644 --- a/src/main/java/org/springframework/data/domain/PageImpl.java +++ b/src/main/java/org/springframework/data/domain/PageImpl.java @@ -135,6 +135,27 @@ public class PageImpl implements Page, Serializable { return !hasNextPage(); } + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Page#nextPageable() + */ + public Pageable nextPageable() { + return hasNextPage() ? pageable.next() : null; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Page#previousOrFirstPageable() + */ + public Pageable previousPageable() { + + if (hasPreviousPage()) { + return pageable.previousOrFirst(); + } + + return null; + } + /* * (non-Javadoc) * @see org.springframework.data.domain.Page#iterator() diff --git a/src/main/java/org/springframework/data/domain/PageRequest.java b/src/main/java/org/springframework/data/domain/PageRequest.java index 621937e88..32e506bea 100644 --- a/src/main/java/org/springframework/data/domain/PageRequest.java +++ b/src/main/java/org/springframework/data/domain/PageRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 the original author or authors. + * Copyright 2008-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,6 @@ public class PageRequest implements Pageable, Serializable { * @param page */ public PageRequest(int page, int size) { - this(page, size, null); } @@ -53,7 +52,6 @@ public class PageRequest implements Pageable, Serializable { * @param properties */ public PageRequest(int page, int size, Direction direction, String... properties) { - this(page, size, new Sort(direction, properties)); } @@ -62,16 +60,16 @@ public class PageRequest implements Pageable, Serializable { * * @param page * @param size - * @param sort + * @param sort can be {@literal null}. */ public PageRequest(int page, int size, Sort sort) { - if (0 > page) { + if (page < 0) { throw new IllegalArgumentException("Page index must not be less than zero!"); } - if (0 >= size) { - throw new IllegalArgumentException("Page size must not be less than or equal to zero!"); + if (size < 0) { + throw new IllegalArgumentException("Page size must not be less than zero!"); } this.page = page; @@ -80,50 +78,74 @@ public class PageRequest implements Pageable, Serializable { } /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Pageable#getPageSize() - */ + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#getPageSize() + */ public int getPageSize() { return size; } /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Pageable#getPageNumber() - */ + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#getPageNumber() + */ public int getPageNumber() { - return page; } /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Pageable#getFirstItem() - */ + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#getOffset() + */ public int getOffset() { - return page * size; } /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Pageable#getSort() - */ + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#getSort() + */ public Sort getSort() { - return sort; } + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#hasPrevious() + */ + public boolean hasPrevious() { + return page > 0; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#next() + */ + public Pageable next() { + return new PageRequest(page + 1, size, sort); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#previousOrFirst() + */ + public Pageable previousOrFirst() { + return hasPrevious() ? new PageRequest(page - 1, size, sort) : this; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.domain.Pageable#first() + */ + public Pageable first() { + return new PageRequest(0, size, sort); + } + /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ @Override public boolean equals(final Object obj) { @@ -146,10 +168,9 @@ public class PageRequest implements Pageable, Serializable { } /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ @Override public int hashCode() { @@ -161,4 +182,14 @@ public class PageRequest implements Pageable, Serializable { return result; } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String.format("Page request [number: %d, size %d, sort: %s]", page, size, + sort == null ? null : sort.toString()); + } } diff --git a/src/main/java/org/springframework/data/domain/Pageable.java b/src/main/java/org/springframework/data/domain/Pageable.java index ed0511702..acdd1e40c 100644 --- a/src/main/java/org/springframework/data/domain/Pageable.java +++ b/src/main/java/org/springframework/data/domain/Pageable.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,4 +49,33 @@ public interface Pageable { * @return */ Sort getSort(); + + /** + * Returns the {@link Pageable} requesting the next {@link Page}. + * + * @return + */ + Pageable next(); + + /** + * Returns the previous {@link Pageable} or the first {@link Pageable} if the current one already is the first one. + * + * @return + */ + Pageable previousOrFirst(); + + /** + * Returns the {@link Pageable} requesting the first page. + * + * @return + */ + Pageable first(); + + /** + * Returns whether there's a previous {@link Pageable} we can access from the current one. Will return + * {@literal false} in case the current {@link Pageable} already refers to the first page. + * + * @return + */ + boolean hasPrevious(); } diff --git a/src/main/java/org/springframework/data/domain/Sort.java b/src/main/java/org/springframework/data/domain/Sort.java index b734f5aaa..668cf7287 100644 --- a/src/main/java/org/springframework/data/domain/Sort.java +++ b/src/main/java/org/springframework/data/domain/Sort.java @@ -199,6 +199,7 @@ public class Sort implements Iterable page = new PageImpl(content, pageable, 100); assertEqualsAndHashcode(page, page); - assertEqualsAndHashcode(page, new PageImpl(content, pageable, 100)); - assertNotEqualsAndHashcode(page, new PageImpl(content, pageable, 90)); - assertNotEqualsAndHashcode(page, new PageImpl(content, new PageRequest(1, 10), 100)); - assertNotEqualsAndHashcode(page, new PageImpl(content, new PageRequest(0, 15), 100)); } @Test(expected = IllegalArgumentException.class) public void preventsNullContentForSimpleSetup() throws Exception { - new PageImpl(null); } @Test(expected = IllegalArgumentException.class) public void preventsNullContentForAdvancedSetup() throws Exception { - new PageImpl(null, null, 0); } + @Test + public void returnsNextPageable() { + + Page page = new PageImpl(Arrays.asList(new Object()), new PageRequest(0, 1), 10); + + assertThat(page.isFirstPage(), is(true)); + assertThat(page.hasPreviousPage(), is(false)); + assertThat(page.previousPageable(), is(nullValue())); + + assertThat(page.isLastPage(), is(false)); + assertThat(page.hasNextPage(), is(true)); + assertThat(page.nextPageable(), is((Pageable) new PageRequest(1, 1))); + } + + @Test + public void returnsPreviousPageable() { + + Page page = new PageImpl(Arrays.asList(new Object()), new PageRequest(1, 1), 2); + + assertThat(page.isFirstPage(), is(false)); + assertThat(page.hasPreviousPage(), is(true)); + assertThat(page.previousPageable(), is((Pageable) new PageRequest(0, 1))); + + assertThat(page.isLastPage(), is(true)); + assertThat(page.hasNextPage(), is(false)); + assertThat(page.nextPageable(), is(nullValue())); + } + @Test public void createsPageForEmptyContentCorrectly() { + List list = Collections.emptyList(); Page page = new PageImpl(list); + assertThat(page.getContent(), is(list)); assertThat(page.getNumber(), is(0)); assertThat(page.getNumberOfElements(), is(0)); diff --git a/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java b/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java index 6a6e3e85e..f851fc2e8 100644 --- a/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java +++ b/src/test/java/org/springframework/data/domain/PageRequestUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2013 the original author or authors. * * 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 @@ -13,9 +13,10 @@ * License for the specific language governing permissions and limitations under * the License. */ - package org.springframework.data.domain; +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; import static org.springframework.data.domain.UnitTestUtils.*; import org.junit.Test; @@ -30,20 +31,28 @@ public class PageRequestUnitTests { @Test(expected = IllegalArgumentException.class) public void preventsNegativePage() { - new PageRequest(-1, 10); } @Test(expected = IllegalArgumentException.class) public void preventsNegativeSize() { - new PageRequest(0, -1); } - @Test(expected = IllegalArgumentException.class) - public void preventsZeroSize() { + @Test + public void navigatesPageablesCorrectly() { - new PageRequest(0, 0); + Pageable request = new PageRequest(1, 10); + + assertThat(request.hasPrevious(), is(true)); + assertThat(request.next(), is((Pageable) new PageRequest(2, 10))); + + Pageable first = request.previousOrFirst(); + + assertThat(first.hasPrevious(), is(false)); + assertThat(first, is((Pageable) new PageRequest(0, 10))); + assertThat(first, is(request.first())); + assertThat(first.previousOrFirst(), is(first)); } @Test