net.jrouter.paging.component.PageImpl Maven / Gradle / Ivy
/*
* Copyright (C) 2010-2111 [email protected]
*
* 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 net.jrouter.paging.component;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 分页模型。
*
* @param Generic type 分页结果类型。
*/
public class PageImpl extends ArrayList implements Serializable, Cloneable, Page, PageSupplier { //NOPMD ShortClassName
/** 当前页码号 */
@lombok.Getter
@lombok.Setter
private int pageNumber = 1;
/** 分页尺寸 */
@lombok.Getter
@lombok.Setter
private int pageSize = -1;
/** 记录总数,为查询前初始值为 -1 */
private long totalElements = -1;
/** 探测模式 - 设置偏移量查询offset数据以省去count查询 */
@lombok.Getter
private int forwardElementOffset = 0;
/** 分页总数 */
@lombok.Getter
private int totalPages = -1;
/**
* 是否自动执行count以计算{@code totalPages},默认false。
*/
@lombok.Getter
@lombok.Setter
private boolean autoCount = false;
/** 实际获取的数据数目 - 每页数据数目 (正负数0 均有可能) */
private int _elementsOffset = 0;//NOPMD for FieldNamingConventions & SUPPRESS CHECKSTYLE MemberName
/** 偏移数据转换成偏移页数 */
private int _elementsOffsetPage = 0;//NOPMD for FieldNamingConventions & SUPPRESS CHECKSTYLE MemberName
/**
* Empty Constructor for serialization.
*/
public PageImpl() {
super();
}
/**
* 根据 页码号 和 分页尺寸 构造分页对象。
*
* @param pageNumber 页码号。
* @param pageSize 分页尺寸。
*/
public PageImpl(int pageNumber, int pageSize) {
super();
this.pageNumber = pageNumber;
this.pageSize = pageSize;
}
/*
* 数据校验。
*/
private void check() {
if (pageSize < 1) {
throw new IllegalArgumentException("PageImpl size can't be zero or negative.");
}
if (pageNumber < 1) {
pageNumber = 1;
}
if (totalElements <= 0) {
totalPages = 0;
pageNumber = 1;
} else {
//计算分页总数
totalPages = ((int) totalElements - 1) / pageSize + 1;
//判断pageNum是否过界,负值赋值为末页
if (pageNumber > totalPages) {
pageNumber = totalPages;
}
}
}
/**
* 设置偏移量查询offset数据;默认为0无偏移量。
*
* @param forwardElementOffset 数据偏移量,必须为非负整数。
*/
public void setForwardElementOffset(int forwardElementOffset) {
if (forwardElementOffset < 0) {
throw new IllegalArgumentException("ForwardElementOffset can't be negative.");
}
this.forwardElementOffset = forwardElementOffset;
}
/**
* Set total elements size and check.
*
* @param totalElements 设置数据总数目以计算分页各参数。
*
* @see #check()
*/
@Override
public void countTotalElements(long totalElements) {
this.totalElements = totalElements;
check();
}
/**
* Get max elements size really need to get.
*
* @return Amount of elements really need to get.
*/
@Override
public int getMaxResults() {
return (int) Math.min(Integer.MAX_VALUE, (0l + getPageSize() + getForwardElementOffset()));
}
/**
* 设置实际查询的单页数据(包含偏移量)列表,并计算偏移量。
*
* @param content 实际查询的数据量。
*
* @see #getMaxResults()
*/
@Override
public void setContent(List content) {
if (content != null && !content.equals(this)) {
if (forwardElementOffset > 0) {
this._elementsOffset = content.size() - pageSize;
this._elementsOffsetPage = _elementsOffset > 0 ? (_elementsOffset - 1) / pageSize + 1 : 0;
//probe at the last page
if (content.size() < getMaxResults()) {
this.totalPages = this.pageNumber + _elementsOffsetPage;
}
//this.content = _elementsOffset > 0 ? content.subList(0, pageSize) : content;
clear();
addAll(_elementsOffset > 0 ? content.subList(0, pageSize) : content);
} else {
clear();
addAll(content);
}
}
}
@Override
public List getContent() {
return this;
}
@Override
public String toString() {
return "PageImpl{" + "pageNumber=" + pageNumber + ", pageSize=" + pageSize + ", totalElements=" + totalElements + ", forwardElementOffset=" + forwardElementOffset + ", totalPages=" + totalPages + ", autoCount=" + autoCount + ", _elementsOffset=" + _elementsOffset + ", _elementsOffsetPage=" + _elementsOffsetPage + '}';
}
/**
* 返回{@code int}类型记录总数。
*
* @return {@code int}类型记录总数。。
*/
@Override
public Long getTotalElements() {
return totalElements < 0 ? null : totalElements;
}
/**
* 判断是否第一页。默认{@code pageNumber}默认第一页,返回 true。
*
* @return 是否第一页。默认第一页,返回 true。
*/
public boolean isFirstPage() {
return pageNumber == 1;
}
/**
* 判断是否最后一页。
* 通过计算{@code totalPages}或者{@code elementsOffsetSize}返回,否则默认返回 false。
*
* @return 判断是否最后一页;默认返回 false。
*
* @see #getMaxResults()
* @see #setContent(java.util.List)
*/
public boolean isLastPage() {
//count totalPages or offset content, otherwise return false
return (pageNumber == totalPages) || (forwardElementOffset > 0 && _elementsOffset <= 0);
}
/**
* 返回最大下一页标签。
* 通过计算{@code elementsOffsetSize}或者{@code totalPages}返回;
* 如无计算,{@code totalPages}为0,默认返回-pageNumber。
*
* @return 最大下一页标签;可能为负值。
*
* @see #getMaxResults()
* @see #setContent(java.util.List)
*/
@Override
public int getMaxNextPageNumber() {
//firstly offset then totalPages
if (forwardElementOffset > 0) {
return pageNumber + _elementsOffsetPage;
} else {
return totalPages;
}
}
/**
* 判断 是否计算过总页数。默认false。
*
* @return 计算过总页数返回true,否则false.
*/
public boolean hasTotalPages() {
return totalPages != -1;
}
@Override
public PageImpl clone() {
return (PageImpl) super.clone();
}
@Override
public PageImpl get() {
return this;
}
}