Thursday, December 29, 2011

Bookmarkable PagingNavigator

The code for SEO is written in https://cwiki.apache.org/WICKET/seo-search-engine-optimization.html.

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);
            }
        };
    }
}

No comments:

Post a Comment