But the implementation to make paging stateless is not presented.
I wrote the following simple implementation.
public class BookmarkableNavigator extends PagingNavigator {
private static final long serialVersionUID = 1117219289688557460L;
private static final String DEFAULT_KEYNAME = "page";
private final String keyName;
public BookmarkableNavigator(String id, IPageable pageable) {
this(id, pageable, DEFAULT_KEYNAME);
}
public BookmarkableNavigator(String id, IPageable pageable, String keyName) {
super(id, pageable);
this.keyName = keyName;
}
@Override
protected void onInitialize() {
super.onInitialize();
int currentPage;
try {
currentPage = getPage().getPageParameters().get(keyName).toInt();
}catch (StringValueConversionException e) {
currentPage = 0;
}
getPageable().setCurrentPage(currentPage);
}
private PageParameters getParams(int page) {
PageParameters params = new PageParameters(getPage().getPageParameters()); // copy
params.set(keyName, page);
return params;
}
@Override
protected AbstractLink newPagingNavigationIncrementLink(String id, final IPageable pageable, final int increment) {
int idx = pageable.getCurrentPage() + increment;
int page = Math.max(0, Math.min(pageable.getPageCount() - 1, idx));
return new BookmarkablePageLink<void>(id, getPage().getClass(), getParams(page)) {
private static final long serialVersionUID = 4583210927959068500L;
private boolean isFirst() {
return pageable.getCurrentPage() <= 0;
}
public boolean isLast() {
return pageable.getCurrentPage() >= (pageable.getPageCount() - 1);
}
@Override
public boolean linksTo(final Page page)
{
pageable.getCurrentPage();
return ((increment < 0) && isFirst()) || ((increment > 0) && isLast());
}
}.setAutoEnable(true);
}
// copy from PagingNavigationLink#cullPageNumber
private int cullPageNumber(int pageNumber)
{
int idx = pageNumber;
IPageable pageable = getPageable();
if (idx < 0)
idx = pageable.getPageCount() + idx;
if (idx > (pageable.getPageCount() - 1))
idx = pageable.getPageCount() - 1;
if (idx < 0)
idx = 0;
return idx;
}
private class BookmarkableNavigationLink extends BookmarkablePageLink<void< {
private static final long serialVersionUID = 7905210383154082192L;
private final int pageNumber;
private final IPageable pageable;
public <c extends page> BookmarkableNavigationLink(
String id, Class<c> pageClass, IPageable pageable, int pageNumber) {
super(id, pageClass, getParams(pageNumber));
this.pageNumber = pageNumber;
this.pageable = pageable;
setAutoEnable(true);
}
@Override
public final boolean linksTo(final Page page) {
return cullPageNumber(pageNumber) == pageable.getCurrentPage();
}
}
@Override
protected AbstractLink newPagingNavigationLink(String id, final IPageable pageable, final int pageNumber) {
return new BookmarkableNavigationLink(id, getPage().getClass(), pageable, cullPageNumber(pageNumber));
}
@Override
protected PagingNavigation newNavigation(String id, IPageable pageable, IPagingLabelProvider labelProvider) {
return new PagingNavigation(id, pageable, labelProvider) {
private static final long serialVersionUID = -4044262294210880251L;
@Override
protected AbstractLink newPagingNavigationLink(String id, IPageable pageable, int pageIndex) {
return new BookmarkableNavigationLink(id, getPage().getClass(), pageable, pageIndex);
}
};
}
}