001package com.box.sdk;
002
003/**
004 * Abstraction on how SDK is doing pagination. Can be used to start offset or marker based
005 * pagination.
006 */
007public final class PagingParameters {
008  /** Default limit value. */
009  public static final long DEFAULT_LIMIT = 1000;
010
011  private static final int MAXIMUM_ALLOWED_OFFSET = 300_000;
012  private final long limit;
013  private final boolean useMarker;
014  private final Long offset;
015  private final String marker;
016
017  private PagingParameters(long limit, boolean useMarker, Long offset, String marker) {
018    this.limit = limit;
019    this.useMarker = useMarker;
020    this.offset = offset;
021    this.marker = marker;
022  }
023
024  /**
025   * Starts marker based pagination.
026   *
027   * @param limit how many elements per request should be fetched.
028   * @return PagingParameters setup to start marker based pagination.
029   */
030  public static PagingParameters marker(long limit) {
031    return new PagingParameters(limit, true, null, null);
032  }
033
034  /**
035   * Starts offset based pagination.
036   *
037   * @param offset where offset pagination should start. Offset cannot be larger than 300000.
038   * @param limit how many elements per request should be fetched.
039   * @return PagingParameters setup to start offset based pagination.
040   */
041  public static PagingParameters offset(long offset, long limit) {
042    if (offset > MAXIMUM_ALLOWED_OFFSET) {
043      throw new IllegalArgumentException(
044          "The maximum offset for offset-based pagination is 300000."
045              + " Marker-based pagination is recommended when a higher offset is needed.");
046    }
047    return new PagingParameters(limit, false, offset, null);
048  }
049
050  QueryStringBuilder asQueryStringBuilder() {
051    QueryStringBuilder result = new QueryStringBuilder().appendParam("limit", limit);
052    if (useMarker) {
053      result.appendParam("usemarker", "true");
054      if (marker != null) {
055        result.appendParam("marker", marker);
056      }
057    } else {
058      result.appendParam("offset", offset);
059    }
060    return result;
061  }
062
063  boolean isMarkerBasedPaging() {
064    return useMarker;
065  }
066
067  PagingParameters nextMarker(String nextMarker) {
068    if (!useMarker) {
069      throw new IllegalArgumentException(
070          "Cannot change offset paging to marker based paging. Use PagingParameters#nextOffset(long).");
071    }
072    return new PagingParameters(limit, true, null, nextMarker);
073  }
074
075  PagingParameters nextOffset(long nextOffset) {
076    if (useMarker) {
077      throw new IllegalArgumentException(
078          "Cannot change marker paging to offset based paging. Use PagingParameters#nextMarker(String).");
079    }
080    return PagingParameters.offset(nextOffset + limit, limit);
081  }
082
083  long getLimit() {
084    return limit;
085  }
086}