Java tutorial
/** * Copyright 2008 Autentia Real Business Solutions S.L. * * This file is part of autentia-util. * * autentia-util is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * autentia-util is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with autentia-util. If not, see <http://www.gnu.org/licenses/>. */ package com.autentia.common.util; import java.util.AbstractList; import java.util.Collection; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Esta clase representa una lista paginada, esto es, no tiene en memoria todos los posibles elementos de la lista, * sino slo la pgina que se est usando en cada momento. Si se pide un elemetno que no est en la pgina actual, se * descarta la informacin actual y se carga la pgina correspondiente. La carga de esta informacin se hace mediante la * interfaz {@link PagedListDataProvider}. * <p> * Mientras se pida informacin dentro de la pgina que est actualmente cargada en memoria, siempre se devuelve la * misma informacin. Es decir, no se vuelve a consultar la interfaz {@link PagedListDataProvider}. Para forzar que se * vuelva a leer la pgina actual se puede usar el mtodo {@link PagedList#clear()}. Esto puede ser til, por ejemplo si * estamos en una pantalla de listado/detalle, tenemos en la lista los elementos A y C y aadimos un nuevo elemento B. * Al volver al listado, si no invalidamos la lista, el nuevo elemento B no lo veramos. * <p> * <b>Atencin !!!</b> Esta lista no est preparada para ser manipulada directamente, es decir no se pueden aadir * elementos, ... el contenido de esta lista slo puede cambiarse a traves del {@link PagedListDataProvider}. * * @param <T> Tipo de los objetos que se guardan en esta lista. */ public class PagedList<T> extends AbstractList<T> { private static final Log log = LogFactory.getLog(PagedList.class); public static final int DEFAULT_PAGE_SIZE = 10; /** Lista con los elementos de la pgina actualmente cargada. */ protected List<T> loadedElements; /** Tamao de la pgina. */ private int pageSize; /** Total de filas. */ protected int rowsCount = -1; /** ?ndice del primer elemento de la pgina actualmente cargada. */ protected int firstRow = 0; /** ?ndice del ltimo elemento de la pgina actualmente cargada. */ private int lastRow; /** Referencia a la interfaz que devolver los datos cuando sea necesario cambiar de pgina. */ private final PagedListDataProvider<T> dataProvider; /** * Crea una nueva instancia de la clase con un tamao de pgina de 10 elementos. * * @param dataProvider referencia a una clase que implemente la interfaz {@link PagedListDataProvider}. */ public PagedList(PagedListDataProvider<T> dataProvider) { this(dataProvider, DEFAULT_PAGE_SIZE); } /** * Crea una nueva instancia de la clase con el tamao de pgina indicado. * * @param dataProvider referencia a una clase que implemente la interfaz {@link PagedListDataProvider}. * @param pageSize tamao de la pgina. */ public PagedList(PagedListDataProvider<T> dataProvider, int pageSize) { this.dataProvider = dataProvider; this.pageSize = pageSize; } @Override public boolean add(T e) { throw new UnsupportedOperationException(); } @Override public void add(int index, T element) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection<? extends T> c) { throw new UnsupportedOperationException(); } @Override public boolean addAll(int index, Collection<? extends T> c) { throw new UnsupportedOperationException(); } /** * Invalida el contenido actual de la liasta, de forma que se fuerza a volver a cargar la informacin del proveedor * de datos. */ @Override public void clear() { loadedElements = null; } /** * En funcin del ndice que nos pasan como parmetro, se comprueba si es necesario cargar una nueva pgina. * * @param index ndice del registro que se quiere recuperar. */ void checkLoadPage(int index) { if (loadedElements == null || index < firstRow || index > lastRow) { loadPage(index); } } protected void loadPage(int index) { final int pagesBefore = index / pageSize; firstRow = pagesBefore * pageSize; if (log.isDebugEnabled()) { log.debug("Loading new page: index=" + index + ", firstRow=" + firstRow + ", pageSize=" + pageSize); } final Pair<List<T>, Long> pair = dataProvider.getPage(firstRow, pageSize); loadedElements = pair.getLeft(); rowsCount = pair.getRight().intValue(); lastRow = firstRow + loadedElements.size() - 1; } @Override public T get(int index) { checkLoadPage(index); return loadedElements.get(index - firstRow); } @Override public boolean remove(Object o) { throw new UnsupportedOperationException(); } @Override public T remove(int index) { throw new UnsupportedOperationException(); } @Override public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public T set(int index, T element) { throw new UnsupportedOperationException(); } @Override public int size() { if (loadedElements == null) { checkLoadPage(firstRow); } return rowsCount; } public int getPageSize() { return pageSize; } /** * Elementos cargados por pagina * @return */ public List<T> getLoadedElements() { return loadedElements; } /** * Fija el nuevo tamao de pgina e invalida el contenido actual para forzar la recarga de la pgina. * * @param pageSize el nuevo tamao de pgina. */ public void setPageSize(int pageSize) { this.pageSize = pageSize; clear(); } }