org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper.java

Source

/*******************************************************************************
 * Copyright (C) 2011 Angelo Zerr <angelo.zerr@gmail.com>, Pascal Leclercq <pascal.leclercq@gmail.com>
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Angelo ZERR - initial API and implementation
 *     Pascal Leclercq - initial API and implementation
 *******************************************************************************/
package org.eclipse.nebula.widgets.pagination;

import java.awt.print.Pageable;
import java.util.List;

import org.eclipse.jface.viewers.AbstractListViewer;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.nebula.widgets.pagination.collections.PageResult;
import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TreeItem;

/**
 * This class help you to configure a {@link PageableController} to manage
 * paginated list data in a {@link Viewer}. This helper manages the 2 following
 * strategies for pagination :
 * 
 * <ul>
 * <li>
 * load the paginated list and <strong>replace data</strong> from the viewer
 * with the new list. See
 * {@link PageLoaderStrategyHelper#loadPageAndReplaceItems(PageableController, Viewer, IPageLoader)}
 * </li>
 * <li>
 * load the paginated list and <strong>add to the data</strong> of the viewer
 * the new list. See
 * {@link PageLoaderStrategyHelper#loadPageAndAddItems(PageableController, TableViewer, IPageLoader)}
 * </li>
 * </ul>
 * 
 */
public class PageLoaderStrategyHelper {

    // ---------------- Replace strategy

    /**
     * This method loads the paginated list by using the given page loader
     * {@link IPageLoader} and information about pagination from the given
     * controller {@link PageableController}. After loading paginated list
     * returned in a pagination structure {@link PageResult}, this method :
     * 
     * <ul>
     * <li>update the total elements of the given controller
     * {@link PageableController}</li>
     * <li>refresh the given {@link Viewer} by replacing data with the new
     * paginated list.</li>
     * </ul>
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     */
    public static void loadPageAndReplaceItems(final PageableController controller, final Viewer viewer,
            final IPageLoader<?> pageLoader, final IPageContentProvider pageContentProvider,
            final IPageLoaderHandler<PageableController> handler) {
        Object page = loadPageAndUpdateTotalElements(controller, pageLoader, pageContentProvider, handler);
        if (page != null) {
            List<?> content = pageContentProvider.getPaginatedList(page);
            if (content != null) {
                // Refresh the viewer with the paginated list.
                viewer.setInput(content);
            }
        }
    }

    /**
     * Create {@link IPageChangedListener} with pagination "replace" strategy.
     * See
     * {@link PageLoaderStrategyHelper#loadPageAndReplaceItems(PageableController, Viewer, IPageLoader)}
     * for more information.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * @return
     */
    public static IPageChangedListener createLoadPageAndReplaceItemsListener(final PageableController controller,
            final StructuredViewer viewer, final IPageLoader<?> pageLoader,
            final IPageContentProvider pageContentProvider, final IPageLoaderHandler<PageableController> handler) {
        return new PageChangedAdapter() {
            @Override
            public void pageIndexChanged(int oldPageIndex, int newPageIndex, PageableController controller) {
                PageLoaderStrategyHelper.loadPageAndReplaceItems(controller, viewer, pageLoader,
                        pageContentProvider, handler);
            }

            @Override
            public void pageSizeChanged(int oldPageSize, int newPageSize, PageableController paginationController) {
                controller.reset();
            }

            @Override
            public void sortChanged(String oldPopertyName, String propertyName, int oldSortDirection,
                    int sortDirection, PageableController controller) {
                controller.reset();
            }
        };
    }

    // ---------------- Add strategy

    // ---------------- For table

    /**
     * This method loads the paginated list by using the given page loader
     * {@link IPageLoader} and information about pagination from the given
     * controller {@link PageableController}. After loading paginated list
     * returned in a pagination structure {@link PageResult}, this method :
     * 
     * <ul>
     * <li>update the total elements of the given controller
     * {@link PageableController}</li>
     * <li>refresh the given {@link Viewer} by replacing data with the new
     * paginated list.</li>
     * </ul>
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     */
    public static void loadPageAndAddItems(final PageableController controller, final TableViewer viewer,
            final IPageLoader<?> pageLoader, final IPageContentProvider pageContentProvider,
            final IPageLoaderHandler<PageableController> handler) {
        Object page = loadPageAndUpdateTotalElements(controller, pageLoader, pageContentProvider, handler);
        if (page != null) {
            List<?> content = pageContentProvider.getPaginatedList(page);
            if (content != null && !content.isEmpty()) {
                viewer.add(content.toArray());
                int count = viewer.getTable().getItemCount();
                if (count > 0) {
                    TableItem item = viewer.getTable().getItem(count - 1);
                    item.setData(LazyItemsSelectionListener.LAST_ITEM_LOADED, true);
                }
            }
        }
    }

    /**
     * Create {@link IPageChangedListener} with pagination "add" strategy. See
     * {@link PageLoaderStrategyHelper#loadPageAndAddItems(PageableController, TableViewer, IPageLoader)}
     * for more information.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * 
     * @return
     */
    public static IPageChangedListener createLoadPageAndAddItemsListener(final PageableController controller,
            final TableViewer viewer, final IPageLoader<?> pageLoader,
            final IPageLoaderHandler<PageableController> handler) {
        return createLoadPageAndAddItemsListener(controller, viewer, pageLoader,
                PageResultContentProvider.getInstance(), handler);
    }

    /**
     * Create {@link IPageChangedListener} with pagination "add" strategy. See
     * {@link PageLoaderStrategyHelper#loadPageAndAddItems(PageableController, TableViewer, IPageLoader)}
     * for more information.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * 
     * @return
     */
    public static IPageChangedListener createLoadPageAndAddItemsListener(final PageableController controller,
            final TableViewer viewer, final IPageLoader<?> pageLoader,
            final IPageContentProvider pageContentProvider, final IPageLoaderHandler<PageableController> handler) {
        return new PageChangedAdapter() {
            @Override
            public void pageIndexChanged(int oldPageIndex, int newPageIndex, PageableController controller) {
                PageLoaderStrategyHelper.loadPageAndAddItems(controller, viewer, pageLoader, pageContentProvider,
                        handler);
            }

            @Override
            public void pageSizeChanged(int oldPageSize, int newPageSize, PageableController paginationController) {
                controller.reset();
            }

            @Override
            public void sortChanged(String oldPopertyName, String propertyName, int oldSortDirection,
                    int sortDirection, PageableController controller) {
                controller.reset();
            }
        };
    }

    // ---------------- For tree

    /**
     * This method loads the paginated list by using the given page loader
     * {@link IPageLoader} and information about pagination from the given
     * controller {@link PageableController}. After loading paginated list
     * returned in a pagination structure {@link PageResult}, this method :
     * 
     * <ul>
     * <li>update the total elements of the given controller
     * {@link PageableController}</li>
     * <li>refresh the given {@link Viewer} by replacing data with the new
     * paginated list.</li>
     * </ul>
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     */
    public static void loadPageAndAddItems(final PageableController controller,
            final Object parentElementOrTreePath, final TreeViewer viewer, final IPageLoader<?> pageLoader,
            final IPageContentProvider pageContentProvider, final IPageLoaderHandler<PageableController> handler) {
        Object page = loadPageAndUpdateTotalElements(controller, pageLoader, pageContentProvider, handler);
        if (page != null) {
            List<?> content = pageContentProvider.getPaginatedList(page);
            if (content != null && !content.isEmpty()) {
                viewer.add(parentElementOrTreePath, content.toArray());
                int count = viewer.getTree().getItemCount();
                if (count > 0) {
                    TreeItem item = viewer.getTree().getItem(count - 1);
                    item.setData(LazyItemsSelectionListener.LAST_ITEM_LOADED, true);
                }
            }
        }
    }

    /**
     * Create {@link IPageChangedListener} with pagination "add" strategy. See
     * {@link PageLoaderStrategyHelper#loadPageAndAddItems(PageableController, TableViewer, IPageLoader)}
     * for more information.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * 
     * @return
     */
    public static IPageChangedListener createLoadPageAndAddItemsListener(final PageableController controller,
            final Object parentElementOrTreePath, final TreeViewer viewer, final IPageLoader<?> pageLoader,
            final IPageContentProvider pageContentProvider, final IPageLoaderHandler<PageableController> handler) {
        return new PageChangedAdapter() {
            @Override
            public void pageIndexChanged(int oldPageIndex, int newPageIndex, PageableController controller) {
                PageLoaderStrategyHelper.loadPageAndAddItems(controller, parentElementOrTreePath, viewer,
                        pageLoader, pageContentProvider, handler);
            }

            @Override
            public void pageSizeChanged(int oldPageSize, int newPageSize, PageableController paginationController) {
                controller.reset();
            }

            @Override
            public void sortChanged(String oldPopertyName, String propertyName, int oldSortDirection,
                    int sortDirection, PageableController controller) {
                controller.reset();
            }
        };
    }

    // ---------------- For list view

    /**
     * This method loads the paginated list by using the given page loader
     * {@link IPageLoader} and information about pagination from the given
     * controller {@link PageableController}. After loading paginated list
     * returned in a pagination structure {@link PageResult}, this method :
     * 
     * <ul>
     * <li>update the total elements of the given controller
     * {@link PageableController}</li>
     * <li>refresh the given {@link Viewer} by replacing data with the new
     * paginated list.</li>
     * </ul>
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     */
    public static void loadPageAndAddItems(final PageableController controller, final AbstractListViewer viewer,
            final IPageLoader<?> pageLoader, final IPageContentProvider pageContentProvider,
            final IPageLoaderHandler<PageableController> handler) {
        Object page = loadPageAndUpdateTotalElements(controller, pageLoader, pageContentProvider, handler);
        List<?> content = pageContentProvider.getPaginatedList(page);
        if (content != null && !content.isEmpty()) {
            viewer.add(content.toArray());
        }
    }

    /**
     * Create {@link IPageChangedListener} with pagination "add" strategy. See
     * {@link PageLoaderStrategyHelper#loadPageAndAddItems(PageableController, TableViewer, IPageLoader)}
     * for more information.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param viewer
     *            the viewer to refresh with new paginated list.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * @return
     */
    public static IPageChangedListener createLoadPageAndAddItemsListener(final PageableController controller,
            final AbstractListViewer viewer, final IPageLoader<?> pageLoader,
            final IPageContentProvider pageContentProvider, final IPageLoaderHandler<PageableController> handler) {
        return new PageChangedAdapter() {
            @Override
            public void pageIndexChanged(int oldPageIndex, int newPageIndex, PageableController controller) {
                PageLoaderStrategyHelper.loadPageAndAddItems(controller, viewer, pageLoader, pageContentProvider,
                        handler);
            }

            @Override
            public void pageSizeChanged(int oldPageSize, int newPageSize, PageableController paginationController) {
                controller.reset();
            }

            @Override
            public void sortChanged(String oldPopertyName, String propertyName, int oldSortDirection,
                    int sortDirection, PageableController controller) {
                controller.reset();
            }
        };
    }

    // ---------------- Utilities methods

    /**
     * Load the paginated list and update the total element of the given
     * controller.
     * 
     * @param controller
     *            the controller to use to load paginated list and update the
     *            total elements.
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @pageContentProvider the page content provider to retrieves total
     *                      elements+paginated list from the page result
     *                      structure returned by the pageLoader.
     * @param handler
     *            the page loader handler to observe before/after page loading
     *            process. If null no observation is done.
     * 
     * @return the pagination {@link PageResult}.
     */
    public static Object loadPageAndUpdateTotalElements(final PageableController controller,
            final IPageLoader<?> pageLoader, final IPageContentProvider pageContentProvider,
            final IPageLoaderHandler<PageableController> handler) {
        // Load the paginated list.
        Object page = null;
        if (handler == null) {
            page = loadPage(pageLoader, controller);
        } else {
            handler.onBeforePageLoad(controller);
            try {
                page = loadPage(pageLoader, controller);
                handler.onAfterPageLoad(controller, null);
            } catch (Throwable e) {
                boolean stop = handler.onAfterPageLoad(controller, e);
                if (stop) {
                    return null;
                }
                if (e instanceof RuntimeException) {
                    throw (RuntimeException) e;
                }
                throw new RuntimeException(e);
            }
        }
        // Update the total elements of the controller.
        controller.setTotalElements(pageContentProvider.getTotalElements(page));
        return page;
    }

    /**
     * Load the paginated list.
     * 
     * @param pageLoader
     *            the page loader used to load paginated list.
     * @param pageable
     *            the pagination {@link Pageable}.
     * @return the pagination {@link PageResult}.
     */
    public static Object loadPage(IPageLoader<?> pageLoader, PageableController controller) {
        if (pageLoader == null) {
            throw new NullPointerException("PageLoader cannot be null!");
        }
        return pageLoader.loadPage(controller);
    }
}