001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.html.list;
018
019import java.util.List;
020
021import org.apache.wicket.markup.html.navigation.paging.IPageableItems;
022import org.apache.wicket.model.IModel;
023
024
025/**
026 * PageableListView is similar to ListView but provides in addition pageable views. A
027 * PageableListView holds pageable rows of information. The rows can be re-ordered and deleted,
028 * either one at a time or many at a time.
029 * 
030 * @author Jonathan Locke
031 * @param <T>
032 *            type of elements contained in the model's list
033 */
034public abstract class PageableListView<T> extends ListView<T> implements IPageableItems
035{
036        private static final long serialVersionUID = 1L;
037
038        /** The page to show. */
039        private long currentPage;
040
041        /** Number of rows per page of the list view. */
042        private long itemsPerPage;
043
044        /**
045         * Constructor
046         * 
047         * @param id
048         *            See Component
049         * @param model
050         *            See Component
051         * @param itemsPerPage
052         *            Number of rows to show on a page
053         */
054        public PageableListView(final String id, final IModel<? extends List<T>> model,
055                long itemsPerPage)
056        {
057                super(id, model);
058                this.itemsPerPage = itemsPerPage;
059        }
060
061        /**
062         * Creates a pageable list view having the given number of rows per page that uses the provided
063         * object as a simple model.
064         * 
065         * @param id
066         *            See Component
067         * @param list
068         *            See Component
069         * @param itemsPerPage
070         *            Number of rows to show on a page
071         * @see ListView#ListView(String, List)
072         */
073        public PageableListView(final String id, final List<T> list, final long itemsPerPage)
074        {
075                super(id, list);
076                this.itemsPerPage = itemsPerPage;
077        }
078
079        /**
080         * Gets the index of the current page being displayed by this list view.
081         * 
082         * @return Returns the currentPage.
083         */
084        @Override
085        public final long getCurrentPage()
086        {
087                // If first cell is out of range, bring page back into range
088                while ((currentPage > 0) && ((currentPage * itemsPerPage) >= getItemCount()))
089                {
090                        currentPage--;
091                }
092
093                return currentPage;
094        }
095
096        /**
097         * Gets the number of pages in this list view.
098         * 
099         * @return The number of pages in this list view
100         */
101        @Override
102        public final long getPageCount()
103        {
104                return ((getItemCount() + itemsPerPage) - 1) / itemsPerPage;
105        }
106
107        /**
108         * Gets the maximum number of rows on each page.
109         * 
110         * @return the maximum number of rows on each page.
111         */
112        @Override
113        public final long getItemsPerPage()
114        {
115                return itemsPerPage;
116        }
117
118        /**
119         * Sets the maximum number of rows on each page.
120         * 
121         * @param itemsPerPage
122         *            the maximum number of rows on each page.
123         */
124        @Override
125        public final void setItemsPerPage(long itemsPerPage)
126        {
127                if (itemsPerPage < 0)
128                {
129                        itemsPerPage = 0;
130                }
131
132                addStateChange();
133                this.itemsPerPage = itemsPerPage;
134        }
135
136        /**
137         * @return offset of first item
138         */
139        public long getFirstItemOffset()
140        {
141                return getCurrentPage() * getItemsPerPage();
142        }
143
144        /**
145         * @see org.apache.wicket.markup.html.navigation.paging.IPageableItems#getItemCount()
146         */
147        @Override
148        public long getItemCount()
149        {
150                return getList().size();
151        }
152
153        /**
154         * @see org.apache.wicket.markup.html.list.ListView#getViewSize()
155         */
156        @Override
157        public int getViewSize()
158        {
159                if (getDefaultModelObject() != null)
160                {
161                        super.setStartIndex((int)getFirstItemOffset());
162                        super.setViewSize((int)getItemsPerPage());
163                }
164
165                return super.getViewSize();
166        }
167
168        /**
169         * Sets the current page that this list view should show.
170         * 
171         * @param currentPage
172         *            The currentPage to set.
173         */
174        @Override
175        public final void setCurrentPage(long currentPage)
176        {
177                if (currentPage < 0)
178                {
179                        currentPage = 0;
180                }
181
182                long pageCount = getPageCount();
183                if ((currentPage > 0) && (currentPage >= pageCount))
184                {
185                        currentPage = pageCount - 1;
186                }
187
188                addStateChange();
189                this.currentPage = currentPage;
190        }
191
192
193        /**
194         * Prevent users from accidentally using it.
195         * 
196         * @see org.apache.wicket.markup.html.list.ListView#setStartIndex(int)
197         * @throws UnsupportedOperationException
198         *             always
199         */
200        @Override
201        public ListView<T> setStartIndex(int startIndex) throws UnsupportedOperationException
202        {
203                throw new UnsupportedOperationException(
204                        "You must not use setStartIndex() with PageableListView");
205        }
206
207        /**
208         * Prevent users from accidentally using it.
209         * 
210         * @param size
211         *            the view size
212         * @return This
213         * @throws UnsupportedOperationException
214         *             always
215         * @see org.apache.wicket.markup.html.list.ListView#setStartIndex(int)
216         */
217        @Override
218        public ListView<T> setViewSize(int size) throws UnsupportedOperationException
219        {
220                throw new UnsupportedOperationException(
221                        "You must not use setViewSize() with PageableListView");
222        }
223
224}