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

org.nuiton.util.pagination.PaginationParameter Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
package org.nuiton.util.pagination;

/*
 * #%L
 * Nuiton Utils
 * %%
 * Copyright (C) 2004 - 2014 CodeLutin
 * %%
 * This program 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, 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser 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;

    /**
     * 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) {
        PaginationParameter result = new PaginationParameter(pageNumber, pageSize);
        return result;
    }

    /**
     * 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) {
        PaginationParameterBuilder result = new PaginationParameterBuilder(pageNumber, pageSize);
        return result;
    }

    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");
        }
        int startIndex = pageNumber * pageSize;
        return startIndex;
    }

    /**
     * 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;
    }

    /**
     * Class used to build an instance of PaginationParameter. Use the {@link #build()} method to create the
     * {@link org.nuiton.util.pagination.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() {
            PaginationParameter result = new PaginationParameter(pageNumber, pageSize, orderClauses);
            return result;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy