All Downloads are FREE. Search and download functionalities are using the official Maven repository.

wicket.extensions.markup.html.repeater.pageable.AbstractPageableView Maven / Gradle / Ivy

There is a newer version: 1.2.7
Show newest version
/*
 * $Id: AbstractPageableView.java 5715 2006-05-10 15:16:14Z ivaynberg $
 * $Revision: 5715 $
 * $Date: 2006-05-10 17:16:14 +0200 (Wed, 10 May 2006) $
 *
 * ====================================================================
 * 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 the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wicket.extensions.markup.html.repeater.pageable;

import java.util.Iterator;
import java.util.NoSuchElementException;

import wicket.extensions.markup.html.repeater.refreshing.RefreshingView;
import wicket.markup.html.navigation.paging.IPageable;
import wicket.model.IModel;
import wicket.version.undo.Change;

/**
 * An abstract repeater view that provides paging functionality to its
 * subclasses.
 * 

* The view is populated by overriding the * getItemModels(int offset, int count) method and providing an * iterator that returns models for items in the current page. The * AbstractPageableView builds the items that will be rendered by looping over * the models and calling the * newItem(String id, int index, IModel model) to generate the * child item container followed by populateItem(Component item) * to let the user populate the newly created item container with with custom * components. *

* * @see wicket.extensions.markup.html.repeater.refreshing.RefreshingView * @see wicket.markup.html.navigation.paging.IPageable * * @author Igor Vaynberg (ivaynberg) * */ public abstract class AbstractPageableView extends RefreshingView implements IPageable { /** * Keeps track of the number of items we show per page. The default is * Integer.MAX_VALUE which effectively disables paging. */ private int itemsPerPage = Integer.MAX_VALUE; /** * Keeps track of the current page number. */ private int currentPage; /** * cachedItemCount is used to cache the call to * internalGetItemCount() for the duration of the request * because that call can potentially be expensive ( a select count query ) * and so we do not want to execute it multiple times. */ private int cachedItemCount; /** @see wicket.Component#Component(String, IModel) */ public AbstractPageableView(String id, IModel model) { super(id, model); clearCachedItemCount(); } /** @see wicket.Component#Component(String) */ public AbstractPageableView(String id) { super(id); clearCachedItemCount(); } /** * This method retrieves the subset of models for items in the current page * and allows RefreshingView to generate items. * * @return iterator over models for items in the current page */ protected Iterator getItemModels() { int offset = getViewOffset(); int size = getViewSize(); Iterator models = getItemModels(offset, size); models = new CappedIteratorAdapter(models, size); return models; } protected void internalOnDetach() { super.internalOnDetach(); clearCachedItemCount(); } /** * Returns an iterator over models for items in the current page * * @param offset * index of first item in this page * @param size * number of items that will be showin in the current page * @return an iterator over models for items in the current page */ protected abstract Iterator getItemModels(int offset, int size); // ///////////////////////////////////////////////////////////////////////// // ITEM COUNT CACHE // ///////////////////////////////////////////////////////////////////////// private void clearCachedItemCount() { cachedItemCount = -1; } private void setCachedItemCount(int itemCount) { cachedItemCount = itemCount; } private int getCachedItemCount() { if (cachedItemCount < 0) { throw new IllegalStateException("getItemCountCache() called when cache was not set"); } return cachedItemCount; } private boolean isItemCountCached() { return cachedItemCount >= 0; } // ///////////////////////////////////////////////////////////////////////// // PAGING // ///////////////////////////////////////////////////////////////////////// /** * @return maximum number of items that will be shown per page */ protected final int internalGetRowsPerPage() { return itemsPerPage; } /** * Sets the maximum number of items to show per page. The current page will * also be set to zero * * @param items */ protected final void internalSetRowsPerPage(int items) { if (items < 1) { throw new IllegalArgumentException("Argument [itemsPerPage] cannot be less then 1"); } if (itemsPerPage != items) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; final int old = itemsPerPage; public void undo() { itemsPerPage = old; } public String toString() { return "ItemsPerPageChange[component: " + getPath() + ", itemsPerPage: " + old + "]"; } }); } } itemsPerPage = items; // because items per page can effect the total number of pages we always // reset the current page back to zero setCurrentPage(0); } /** * @return total item count */ protected abstract int internalGetItemCount(); /** * @return total item count */ public final int getRowCount() { if (!isVisibleInHierarchy()) { return 0; } if (isItemCountCached()) { return getCachedItemCount(); } int count = internalGetItemCount(); setCachedItemCount(count); return count; } /** * @see wicket.markup.html.navigation.paging.IPageable#getCurrentPage() */ public final int getCurrentPage() { int page = currentPage; /* * trim current page if its out of bounds this can happen if items are * added/deleted between requests */ if (page >= getPageCount()) { page = Math.max(getPageCount() - 1, 0); setCurrentPage(page); return page; } return page; } /** * @see wicket.markup.html.navigation.paging.IPageable#setCurrentPage(int) */ public final void setCurrentPage(int page) { if (page < 0 || (page >= getPageCount() && getPageCount() > 0)) { throw new IndexOutOfBoundsException("argument [page]=" + page + ", must be 0<=page<" + getPageCount()); } if (currentPage != page) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; private final int old = currentPage; public void undo() { currentPage = old; } public String toString() { return "CurrentPageChange[component: " + getPath() + ", currentPage: " + old + "]"; } }); } } currentPage = page; } /** * @see wicket.markup.html.navigation.paging.IPageable#getPageCount() */ public final int getPageCount() { int total = getRowCount(); int page = internalGetRowsPerPage(); int count = total / page; if (page * count < total) { count++; } return count; } /** * @return the index of the first visible item */ protected int getViewOffset() { return getCurrentPage() * internalGetRowsPerPage(); } /** * @return the number of items visible */ protected int getViewSize() { return Math.min(internalGetRowsPerPage(), getRowCount() - getViewOffset()); } // ///////////////////////////////////////////////////////////////////////// // HELPER CLASSES // ///////////////////////////////////////////////////////////////////////// /** * Iterator adapter that makes sure only the specified max number of items * can be accessed from its delegate. */ private static class CappedIteratorAdapter implements Iterator { private int max; private int index; private Iterator delegate; /** * Constructor * * @param delegate * delegate iterator * @param max * maximum number of items that can be accessed. */ public CappedIteratorAdapter(Iterator delegate, int max) { this.delegate = delegate; this.max = max; } /** * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return (index < max) && delegate.hasNext(); } /** * @see java.util.Iterator#next() */ public Object next() { if (index >= max) { throw new NoSuchElementException(); } index++; return delegate.next(); } }; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy