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

org.nuiton.topia.persistence.pager.PaginationParameter Maven / Gradle / Ivy

The newest version!
package org.nuiton.topia.persistence.pager;

/*-
 * #%L
 * ToPIA Extension :: API
 * %%
 * Copyright (C) 2018 - 2022 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * This class represents the necessary information to do pagination (page number, size, ...).
 *
 * @author Arnaud Thimel (Code Lutin)
 * @since 3.0
 */
public class PaginationParameter implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * All results.
     */
    protected static final int ALL_PAGE_SIZE = -1;

    /**
     * An instance that represents a page of ALL elements
     */
    public static final PaginationParameter ALL = PaginationParameter.of(0, ALL_PAGE_SIZE);

    /**
     * 0-based page number
     */
    protected int pageNumber;

    /**
     * The size of each page. Value can be -1 (for infinite pageSize) or greater than 0
     */
    protected int pageSize;

    /**
     * The list of order clauses. This instance is unmodifiable and never null.
     */
    protected List orderClauses;

    protected PaginationParameter(int pageNumber, int pageSize) {
        this(pageNumber, pageSize, new LinkedList<>());
    }

    protected PaginationParameter(int pageNumber, int pageSize, List orderClauses) {
        Preconditions.checkArgument(pageNumber >= 0, "pageNumber cannot be lower than 0");
        Preconditions.checkArgument(pageSize == -1 || pageSize > 0, "pageSize can only be -1 or greater than 0");
        Preconditions.checkArgument(pageSize != -1 || pageNumber == 0, "This is non-sense to have pageNumber>1 if pageSize==-1");
        this.pageNumber = pageNumber;
        this.pageSize = pageSize;
        this.orderClauses = Collections.unmodifiableList(orderClauses);
    }

    /**
     * Method to create a PaginationParameter only based on pageNumber and pageSize (no order clauses).
     *
     * @param pageNumber the index (0-based) of the page
     * @param pageSize   the size of each page. Value can be -1 (for infinite pageSize) or greater than 0
     * @return an immutable PaginationParameter instance
     */
    public static PaginationParameter of(int pageNumber, int pageSize) {
        return new PaginationParameter(pageNumber, pageSize);
    }

    /**
     * Method to create a PaginationParameter based on pageNumber, pageSize and a single order clause.
     * 

* If you have an unknown number of order clauses, you should use the {@link #builder(int, int)} * method together with {@link PaginationParameterBuilder#addOrder(String, boolean)} and * {@link PaginationParameterBuilder#build()} methods. * * @param pageNumber the index (0-based) of the page * @param pageSize the size of each page. Value can be -1 (for infinite pageSize) or greater than 0 * @param orderClause1 an order clause attribute name. It comes together with {code}orderDesc1{/code} * @param orderDesc1 the asc/desc property associated with {code}orderClause1{/code} * @return an immutable PaginationParameter instance * @see PaginationOrder * @see PaginationParameterBuilder */ public static PaginationParameter of(int pageNumber, int pageSize, String orderClause1, boolean orderDesc1) { return builder(pageNumber, pageSize) .addOrder(orderClause1, orderDesc1) .build(); } /** * Method to create a PaginationParameter based on pageNumber, pageSize and two order clauses. *

* If you have an unknown number of order clauses, you should use the {@link #builder(int, int)} * method together with {@link PaginationParameterBuilder#addOrder(String, boolean)} and * {@link PaginationParameterBuilder#build()} methods. * * @param pageNumber the index (0-based) of the page * @param pageSize the size of each page. Value can be -1 (for infinite pageSize) or greater than 0 * @param orderClause1 an order clause attribute name. It comes together with {code}orderDesc1{/code} * @param orderDesc1 the asc/desc property associated with {code}orderClause1{/code} * @param orderClause2 an order clause attribute name. It comes together with {code}orderDesc2{/code} * @param orderDesc2 the asc/desc property associated with {code}orderClause2{/code} * @return an immutable PaginationParameter instance * @see PaginationOrder * @see PaginationParameterBuilder */ public static PaginationParameter of(int pageNumber, int pageSize, String orderClause1, boolean orderDesc1, String orderClause2, boolean orderDesc2) { return builder(pageNumber, pageSize) .addOrder(orderClause1, orderDesc1) .addOrder(orderClause2, orderDesc2) .build(); } /** * Method to create a PaginationParameter based on pageNumber, pageSize and three order clauses. *

* If you have more order clauses, or an unknown number of clauses, you should use the {@link #builder(int, int)} * method together with {@link PaginationParameterBuilder#addOrder(String, boolean)} and * {@link PaginationParameterBuilder#build()} methods. * * @param pageNumber the index (0-based) of the page * @param pageSize the size of each page. Value can be -1 (for infinite pageSize) or greater than 0 * @param orderClause1 an order clause attribute name. It comes together with {code}orderDesc1{/code} * @param orderDesc1 the asc/desc property associated with {code}orderClause1{/code} * @param orderClause2 an order clause attribute name. It comes together with {code}orderDesc2{/code} * @param orderDesc2 the asc/desc property associated with {code}orderClause2{/code} * @param orderClause3 an order clause attribute name. It comes together with {code}orderDesc3{/code} * @param orderDesc3 the asc/desc property associated with {code}orderClause3{/code} * @return an immutable PaginationParameter instance * @see PaginationOrder * @see PaginationParameterBuilder */ public static PaginationParameter of(int pageNumber, int pageSize, String orderClause1, boolean orderDesc1, String orderClause2, boolean orderDesc2, String orderClause3, boolean orderDesc3) { return builder(pageNumber, pageSize) .addOrder(orderClause1, orderDesc1) .addOrder(orderClause2, orderDesc2) .addOrder(orderClause3, orderDesc3) .build(); } /** * Method to create a PaginationParameter using the {@link PaginationParameterBuilder}. * * @param pageNumber the index (0-based) of the page * @param pageSize the size of each page. Value can be -1 (for infinite pageSize) or greater than 0 * @return an immutable PaginationParameter.Builder instance */ public static PaginationParameterBuilder builder(int pageNumber, int pageSize) { return new PaginationParameterBuilder(pageNumber, pageSize); } public int getPageNumber() { return pageNumber; } public int getPageSize() { return pageSize; } public List getOrderClauses() { return orderClauses; } /** * Method that computes the start index of a page according to {@link #pageNumber} and {@link #pageSize}. * * @return the computed start index */ public int getStartIndex() { if (pageNumber != 0) { Preconditions.checkState(pageSize != -1, "This is non-sense to have pageNumber>1 if pageSize==-1"); } return pageNumber * pageSize; } /** * Method that computes the end index of a page according to {@link #pageNumber} and {@link #pageSize}. If the * pageSize is -1, the end index will be {@link Integer#MAX_VALUE}. * * @return the computed end index */ public int getEndIndex() { int endIndex = Integer.MAX_VALUE; if (pageSize != -1) { endIndex = getStartIndex() + pageSize - 1; } return endIndex; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } PaginationParameter that = (PaginationParameter) o; if (pageNumber != that.pageNumber) { return false; } if (pageSize != that.pageSize) { return false; } return orderClauses.equals(that.orderClauses); } @Override public int hashCode() { int result = pageNumber; result = 31 * result + pageSize; result = 31 * result + orderClauses.hashCode(); return result; } /** * Test if pagination parameter is about all results range. * * @return {@code true} if pagination parameter is about all results range */ public boolean isAll() { return pageSize == ALL_PAGE_SIZE; } /** * Class used to build an instance of PaginationParameter. Use the {@link #build()} method to create the * {@link PaginationParameter}. * * @author Arnaud Thimel (Code Lutin) * @since 3.0 */ public static class PaginationParameterBuilder { protected int pageNumber; protected int pageSize; protected List orderClauses; /** * Creates a Builder instance * * @param pageNumber the index (0-based) of the page * @param pageSize the size of each page. Value can be -1 (for infinite pageSize) or greater than 0 */ public PaginationParameterBuilder(int pageNumber, int pageSize) { this.pageNumber = pageNumber; this.pageSize = pageSize; } /** * Adds an order clause * * @param clause an order clause attribute name. It comes together with {code}desc{/code} * @param desc the asc/desc property associated with {code}clause{/code} * @return the current Builder for a Fluent usage */ public PaginationParameterBuilder addOrder(String clause, boolean desc) { if (orderClauses == null) { orderClauses = Lists.newLinkedList(); } PaginationOrder paginationOrder = new PaginationOrder(clause, desc); orderClauses.add(paginationOrder); return this; } /** * Adds an ASC order clause * * @param clause an order clause attribute name * @return the current Builder for a Fluent usage */ public PaginationParameterBuilder addAscOrder(String clause) { return addOrder(clause, false); } /** * Adds an DESC order clause * * @param clause an order clause attribute name * @return the current Builder for a Fluent usage */ public PaginationParameterBuilder addDescOrder(String clause) { return addOrder(clause, true); } /** * Adds an order clause. The asc/desc value is guessed from the given {code}clause{/code}. The expected format * is "column asc" or "column desc" * * @param clause an order clause attribute name. It comes together with {code}desc{/code} * @return the current Builder for a Fluent usage */ public PaginationParameterBuilder addOrder(String clause) { boolean desc = false; String cleanedClause = clause; int spaceIndex = clause.indexOf(' '); if (spaceIndex != -1) { cleanedClause = clause.substring(0, spaceIndex).trim(); desc = "desc".equalsIgnoreCase(clause.substring(spaceIndex + 1).trim()); } return addOrder(cleanedClause, desc); } /** * Adds an the given order clauses * * @param clauses an list of order clauses * @return the current Builder for a Fluent usage */ public PaginationParameterBuilder addOrderClauses(Iterable clauses) { if (orderClauses == null) { orderClauses = Lists.newLinkedList(); } if (clauses != null) { Iterables.addAll(orderClauses, clauses); } return this; } /** * Final method that instantiates the immutable PaginationParameter * * @return the immutable PaginationParameter built */ public PaginationParameter build() { return new PaginationParameter(pageNumber, pageSize, orderClauses); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy