I’m working on a pagination system for my java project, and I’d like to make it generic for my various JPA Models.
The problem (as far as I know) is that if I use generics, I will have to somehow cast the returned final value to work on it. How can I avoid that ?
Here’s my code so far (absolutely not generic!) :
public interface Paginator {
public void setLimit(Integer limit);
public Page page(Integer page);
}
public class PicturesPaginator implements Paginator {
private Integer limit = 10;
private JPAQuery query;
private Long quantity;
public PicturesPaginator(String query, Object... params) {
this.query = Picture.find(query, params);
this.quantity = Picture.count(query, params);
}
@Override
public void setLimit(Integer limit) {
this.limit = limit;
}
@Override
public PicturesPage page(Integer page) {
if (page == null)
page = 1;
List<Picture> pictures = query.fetch(page, limit);
return new PicturesPage(pictures, quantity, page, limit);
}
}
public abstract class Page {
protected List<Picture> pictures;
protected Long quantity;
protected Integer page;
protected Integer limit;
public List<Picture> list() {
return pictures;
}
public Long count() {
return quantity;
}
public boolean hasNext() {
return (page * limit > quantity);
}
public boolean hasPrevious() {
return (page != 1);
}
public boolean hasOtherPages() {
return (hasNext() || hasPrevious());
}
public Integer nextPageNumber() {
if (!hasNext())
return null;
return (page + 1);
}
public Integer previousPageNumber() {
if (!hasPrevious())
return null;
return (page - 1);
}
public Integer currentPageNumber() {
return page;
}
}
public class PicturesPage extends Page {
public PicturesPage(List<Picture> pictures, Long quantity, Integer page, Integer limit) {
this.pictures = pictures;
this.quantity = quantity;
this.page = page;
this.limit = limit;
}
}
I would like to get rid of those PicturesPaginator and PicturesPage and make it generic, but the list() method from the abstract class Page would return a generic List (List<T> or List<GenericModel> since I use Play here).
What I would expect is this list() method to return the correct List, aka List<Picture> in my case. Is this possible ?
Note: I now there is a module for pagination in Play! Framework, my question is mainly for understanding more about java too 🙂
Thank you very much for your help, I really appreciate!
You can view my Play–Pagination module’s source code to see how I handle this type of thing. I put my source on github.
What you want to do is make Page generic as well, and probably non-abstract:
And instead of PicturesPage you could just do:
The Paginator interface would also need to be generified:
Generifying PicturesPaginator would be harder since you invoke methods on the Picture class. Java’s generics implementation erases types at runtime, so you’ll have to deal with type tokens and reflection.