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

sirius.kernel.commons.Limit Maven / Gradle / Ivy

Go to download

Provides common core classes and the microkernel powering all Sirius applications

There is a newer version: 12.9.1
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.kernel.commons;

import java.util.function.Predicate;

/**
 * Helper class to handle result windowing (start+limit) of arbitrary data sets.
 * 

* A Limit is used to process a stream of data while limiting the results to a given window. This * window is described by setting the number of items to skip and the maximal number of items to pass on. If the * maximal number of items to pass on is null, no limiting will be performed. *

* This class can be used to "page" through result lists. Having a page size of 25 and showing the 2nd page, * would lead to: *

 * {@code
 *         Limit limit = new Limit(25,25); // Skip the 25 items of the first page, and show up to 25 items.
 *         List result = new ArrayList();
 *         for(Object o : someList) {
 *             if (limit.nextRow()) {
 *                 result.add(o);
 *             }
 *             // If we already fetched enough items, we can also stop processing further.
 *             if (!limit.shouldContinue()) {
 *                 return;
 *             }
 *         }
 * }
 * 
*/ public class Limit { private int itemsToSkip; private int maxItems; private Integer itemsToOutput; /** * Represents a limit which has no upper limit and does not skip any items. *

* Although a limit is modified internally, we can use a constant here because a unlimited limit has * not internal state. */ public static final Limit UNLIMITED = new Limit(0, null); /** * Creates a new {@code Limit} based on the given parameters. * * @param itemsToSkip denotes the number of items to skip. * @param maxItems determines the max number of items. Can be null or 0 to indicate that no limiting * is active. */ public Limit(int itemsToSkip, Integer maxItems) { this.itemsToSkip = itemsToSkip > 0 ? itemsToSkip : 0; if (maxItems != null && maxItems > 0) { this.itemsToOutput = maxItems; this.maxItems = maxItems; } } /** * Represents a limit which only accepts the first item. * * @return a new limit which will only accept the first item */ public static Limit singleItem() { return new Limit(0, 1); } /** * Notifies the limit, that the next item is being processed and determines if this is part of the result. * * @return true if this item should be output, false otherwise. */ public boolean nextRow() { if (itemsToSkip > 0) { itemsToSkip--; return false; } if (itemsToOutput != null) { if (itemsToOutput > 0) { itemsToOutput--; return true; } else { return false; } } return true; } /** * Determines if already enough items have been processed or if processing should continue. * * @return true if more items can be used as output, false otherwise */ public boolean shouldContinue() { return itemsToOutput == null || itemsToOutput > 0; } /** * Converts the limit into a predicate. *

* Note that the limit is stateful and therefore asPredicate should only be called once. * * @param type used by the stream using this predicate. Ignored as we do not operate on the * items itself * @return a predicate implementing the limit */ public Predicate asPredicate() { return object -> nextRow(); } /** * Returns the max number of items or 0 to indicate that there is no upper limit. * * @return the max. number of items to accept or 0 if there is no upper limit */ public int getMaxItems() { return maxItems; } /** * Returns the total number of items to be processed. This is the number of items to be skipped plus the * number of items to be accepted. Returns 0 to indicate that there is no upper limit. * * @return the total number of items to be processed or 0 if there is no upper limit */ public int getTotalItems() { return maxItems == 0 ? 0 : itemsToSkip + maxItems; } /** * Returns the remaining number of items to be processed. This is the number of items to be skipped plus the * number of items to be accepted minus the number of items already processed. * Returns null to indicate that there is no upper limit. * * @return the remaining number of items to be processed or null if there is no upper limit */ public Integer getRemainingItems() { return itemsToOutput == null ? null : itemsToSkip + itemsToOutput; } @Override public String toString() { StringBuilder sb = new StringBuilder("Limit: "); if (maxItems == 0) { sb.append(" unlimited"); return sb.toString(); } if (itemsToSkip > 0) { sb.append("skip: ").append(itemsToSkip); } if (itemsToOutput == null) { sb.append(" output: all"); } else { if (itemsToOutput > 0) { sb.append(" output: ").append(itemsToOutput); } else { sb.append(" output: none"); } } sb.append(" (total: ").append(maxItems).append(")"); return sb.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy