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

org.apache.wicket.markup.repeater.AbstractPageableView Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.wicket.markup.repeater;

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

import org.apache.wicket.markup.html.navigation.paging.IPageable;
import org.apache.wicket.model.IModel;
import org.apache.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 org.apache.wicket.markup.repeater.RefreshingView * @see org.apache.wicket.markup.html.navigation.paging.IPageable * * @author Igor Vaynberg (ivaynberg) * * @param * Model object type */ public abstract class AbstractPageableView extends RefreshingView implements IPageable { /** */ private static final long serialVersionUID = 1L; /** * 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 transient int cachedItemCount; /** * Constructor * * @param id * @param model * @see org.apache.wicket.Component#Component(String, IModel) */ public AbstractPageableView(String id, IModel> model) { super(id, model); clearCachedItemCount(); } /** @see org.apache.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 */ @Override protected Iterator> getItemModels() { int offset = getViewOffset(); int size = getViewSize(); Iterator> models = getItemModels(offset, size); models = new CappedIteratorAdapter(models, size); return models; } /** * @see org.apache.wicket.markup.repeater.AbstractRepeater#onBeforeRender() */ @Override protected void onBeforeRender() { clearCachedItemCount(); super.onBeforeRender(); } /** * 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 shown 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 than 1"); } if (itemsPerPage != items) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; final int old = itemsPerPage; @Override public void undo() { itemsPerPage = old; } @Override 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(); /** * Get the row count. * * @see #getItemCount() * * @return total item count, but 0 if not visible in the hierarchy */ public final int getRowCount() { if (!isVisibleInHierarchy()) { return 0; } return getItemCount(); } /** * Get the item count. Since dataprovider.size() could potentially be * expensive, the item count is cached. * * @see #getRowCount() * * @return the item count */ public final int getItemCount() { if (isItemCountCached()) { return getCachedItemCount(); } int count = internalGetItemCount(); setCachedItemCount(count); return count; } /** * @see org.apache.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 > 0 && page >= getPageCount()) { page = Math.max(getPageCount() - 1, 0); currentPage = page; return page; } return page; } /** * @see org.apache.wicket.markup.html.navigation.paging.IPageable#setCurrentPage(int) */ public final void setCurrentPage(int page) { if (currentPage != page) { if (isVersioned()) { addStateChange(new Change() { private static final long serialVersionUID = 1L; private final int old = currentPage; @Override public void undo() { currentPage = old; } @Override public String toString() { return "CurrentPageChange[component: " + getPath() + ", currentPage: " + old + "]"; } }); } } currentPage = page; } /** * @see org.apache.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. * * @param * Model object type */ private static class CappedIteratorAdapter implements Iterator> { private final int max; private int index; private final 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 IModel next() { if (index >= max) { throw new NoSuchElementException(); } index++; return delegate.next(); } }; /** * @see org.apache.wicket.Component#onDetach() */ @Override protected void onDetach() { clearCachedItemCount(); super.onDetach(); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in all fields s.defaultReadObject(); clearCachedItemCount(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy