/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license 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 jlibs.jdbc.paging; import jlibs.core.lang.ImpossibleException; import jlibs.core.lang.StringUtil; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author Santhosh Kumar T */ public class Page<T>{ public final Paging<T> paging; public final int pageSize; public Page(Paging<T> paging, int pageSize){ this.paging = paging; this.pageSize = pageSize; } /*-------------------------------------------------[ TotalRowCount ]---------------------------------------------------*/ private int totalRowCount = -1; public int getTotalRowCount(){ if(totalRowCount==-1) totalRowCount = paging.getTotalRowCount(); return totalRowCount; } public void setTotalRowCount(int count){ totalRowCount = count; } /*-------------------------------------------------[ Index ]---------------------------------------------------*/ private int index = -1; public int getIndex(){ return index; } public void setIndex(int index){ this.index = index; } /*-------------------------------------------------[ FirstRow ]---------------------------------------------------*/ private T firstRow; public T getFirstRow(){ return firstRow; } public void setFirstRow(T firstRow){ this.firstRow = firstRow; } /*-------------------------------------------------[ LastRow ]---------------------------------------------------*/ private T lastRow; public T getLastRow(){ return lastRow; } public void setLastRow(T lastRow){ this.lastRow = lastRow; } /*-------------------------------------------------[ Helpers ]---------------------------------------------------*/ public int getTotalPageCount(){ return (int)Math.ceil(getTotalRowCount()*1.0/pageSize); } /*-------------------------------------------------[ Navigation ]---------------------------------------------------*/ private List<T> records(int index, List<T> records, boolean reverse){ this.index = index; if(reverse) Collections.reverse(records); firstRow = records.get(0); lastRow = records.get(records.size()-1); return records; } public List<T> first(){ if(getTotalRowCount()==0) return Collections.emptyList(); int page = 0; String orderBy = paging.orderBy(false); String condition = StringUtil.isEmpty(paging.condition) ? orderBy : paging.condition+' '+orderBy; return records(page, paging.dao.top(pageSize, condition, paging.args), false); } public List<T> last(){ if(getTotalRowCount()==0) return Collections.emptyList(); String orderBy = paging.orderBy(true); int page = getTotalPageCount()-1; String condition = StringUtil.isEmpty(paging.condition) ? orderBy : paging.condition+' '+orderBy; int max = getTotalRowCount() - page*pageSize; return records(page, paging.dao.top(max, condition, paging.args), true); } private List<T> move(boolean previous){ if(getTotalRowCount()==0) return Collections.emptyList(); int page = index + (previous ? -1 : +1); String condition = StringUtil.isEmpty(paging.condition) ? "WHERE " : paging.condition+" AND "; condition = condition + paging.where(previous); String orderBy = paging.orderBy(previous); condition = condition+' '+orderBy; Object args[] = Arrays.copyOf(paging.args, paging.args.length+paging.orderBy.size()); int i = paging.args.length; for(PagingColumn col: paging.orderBy) args[i] = paging.dao.getColumnValue(col.index, previous?firstRow:lastRow); return records(page, paging.dao.top(pageSize, condition, args), previous); } public List<T> next(){ return move(false); } public List<T> previous(){ return move(true); } /*-------------------------------------------------[ Actions ]---------------------------------------------------*/ public enum Action{ FIRST, PREVIOUS, NEXT, LAST } public boolean canNavigate(Action action){ if(getTotalRowCount()==0) return false; int totalPageCount = getTotalPageCount(); switch(action){ case FIRST: return getIndex()!=0; case LAST: return getIndex()!=totalPageCount-1; case PREVIOUS: return getIndex()>0; case NEXT: return getIndex()>-1 && getIndex()<totalPageCount-1; default: throw new ImpossibleException(); } } public List<T> navigate(Action action){ if(!canNavigate(action)) throw new IllegalArgumentException("Invalid Action: "+action); switch(action){ case FIRST: return first(); case LAST: return last(); case PREVIOUS: return previous(); case NEXT: return next(); default: throw new ImpossibleException(); } } }