package gov.nysenate.openleg.dao.base; import org.apache.commons.lang3.builder.ToStringBuilder; import java.util.ArrayList; import java.util.List; /** * The LimitOffset class is intended to be used for limiting the number of results * returned by query methods. */ public class LimitOffset { /** Use this reference when no limit is desired. */ public static final LimitOffset ALL = new LimitOffset(0,0); /** Some references for convenience. */ public static final LimitOffset ONE = new LimitOffset(1); public static final LimitOffset TEN = new LimitOffset(10); public static final LimitOffset TWENTY_FIVE = new LimitOffset(25); public static final LimitOffset FIFTY = new LimitOffset(50); public static final LimitOffset HUNDRED = new LimitOffset(100); public static final LimitOffset THOUSAND = new LimitOffset(1000); /** Number of elements to limit the result set to. */ private final int limit; /** The offset position used in conjunction with the limit. The offset starts from 1 * which is the same as not offsetting the results. */ private final int offset; /** --- Constructors --- */ public LimitOffset(int limit) { this(limit, 1); } public LimitOffset(int limit, int offset) { this.limit = limit; this.offset = (offset > 1) ? offset : 1; } /** --- Methods --- */ /** * If the 'limitOffset' is valid, return a new sub-list according to the given 'limitOffset'. * * @param list List<T> - The original list. * @param limOff LimitOffset - The limit/offset to trim the list to. * @return List<T> - The trimmed list. */ public static <T> List<T> limitList(List<T> list, LimitOffset limOff) { if (limOff != null && limOff.hasLimit()) { int start = limOff.getOffsetStart() - 1; int end = start + limOff.getLimit(); end = (end > list.size()) ? list.size() : end; return new ArrayList<>(list.subList(start, end)); } return list; } /** * Using the given LimitOffset object, return a new instance that has it's offset value set as * directly after the end of given LimitOffset. This method can be used for pagination such that * the offset does not have to be manually incremented by the limit each time. * * @return LimitOffset */ public LimitOffset next() { int nextOffset = this.getOffsetEnd(); nextOffset = (nextOffset == Integer.MAX_VALUE) ? Integer.MAX_VALUE : nextOffset + 1; return new LimitOffset(this.getLimit(), nextOffset); } /** --- Functional Getters/Setters --- */ public boolean hasLimit() { return (this.limit > 0); } public boolean hasOffset() { return (this.offset > 1); } public int getOffsetEnd() { if (!hasLimit()) return Integer.MAX_VALUE; return this.limit + this.offset - 1; } /** --- Overrides --- */ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof LimitOffset)) return false; LimitOffset that = (LimitOffset) o; if (limit != that.limit) return false; if (offset != that.offset) return false; return true; } @Override public int hashCode() { int result = limit; result = 31 * result + offset; return result; } @Override public String toString() { return new ToStringBuilder(this) .append("limit", limit) .append("offset", offset) .toString(); } /** --- Basic Getters/Setters --- */ public int getLimit() { return limit; } public int getOffsetStart() { return offset; } }