001/*
002 * SonarQube
003 * Copyright (C) 2009-2016 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.utils;
021
022/**
023 * @since 3.6
024 */
025public class Paging {
026
027  private final int pageSize;
028  private final int pageIndex;
029  private final int total;
030
031  private Paging(int pageSize, int pageIndex, int total) {
032    if (pageSize < 1) {
033      throw new IllegalArgumentException("Page size must be strictly positive. Got " + pageSize);
034    }
035    if (pageIndex < 1) {
036      throw new IllegalArgumentException("Page index must be strictly positive. Got " + pageIndex);
037    }
038    if (total < 0) {
039      throw new IllegalArgumentException("Total items must be positive. Got " + total);
040    }
041
042    this.pageSize = pageSize;
043    this.pageIndex = pageIndex;
044    this.total = total;
045  }
046
047  /**
048   * @deprecated since 5.2 please use the forPageIndex(...) builder method
049   */
050  @Deprecated
051  public static Paging create(int pageSize, int pageIndex, int totalItems) {
052    return new Paging(pageSize, pageIndex, totalItems);
053  }
054
055  public static Builder forPageIndex(int pageIndex) {
056    return new Builder(pageIndex);
057  }
058
059  /**
060   * Page index, starting with 1.
061   */
062  public int pageIndex() {
063    return pageIndex;
064  }
065
066  /**
067   * Maximum number of items per page. It is greater than 0.
068   */
069  public int pageSize() {
070    return pageSize;
071  }
072
073  /**
074   * Total number of items. It is greater than or equal 0.
075   */
076  public int total() {
077    return total;
078  }
079
080  public int offset() {
081    return (pageIndex - 1) * pageSize;
082  }
083
084  public static int offset(int pageIndex, int pageSize) {
085    return (pageIndex - 1) * pageSize;
086  }
087
088  /**
089   * Number of pages. It is greater than or equal 0.
090   */
091  public int pages() {
092    int p = total / pageSize;
093    if (total % pageSize > 0) {
094      p++;
095    }
096    return p;
097  }
098
099  /**
100   *
101   * @since 4.1
102   */
103  public boolean hasNextPage() {
104    return pageIndex() < pages();
105  }
106
107  public static class Builder {
108    private int pageSize;
109    private int pageIndex;
110
111    private Builder(int pageIndex) {
112      this.pageIndex = pageIndex;
113    }
114
115    public Builder withPageSize(int pageSize) {
116      this.pageSize = pageSize;
117      return this;
118    }
119
120    public Paging andTotal(int total) {
121      return new Paging(pageSize, pageIndex, total);
122    }
123  }
124}