Repository: jakartaee/data (java)

Issue:
Does make sense rename Limit to Range?
To make the intention of the ```Limit``` class more explicit, what do you think if we rename it to ```Range``` instead?


## Quarkus
E.g.: 

https://quarkus.io/guides/hibernate-orm-panache#using-a-range-instead-of-pages

```java
Range range = Range.of(2);

Range range = Range.of(2, 10);
```

Pull request:
new name for method that creates range limits
Fixes #35

Renames to the following: `Limit.range(101, 200)`

Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>

Patch:
diff --git a/api/src/main/java/jakarta/data/repository/Limit.java b/api/src/main/java/jakarta/data/repository/Limit.java
index c8748d50..73da4581 100644
--- a/api/src/main/java/jakarta/data/repository/Limit.java
+++ b/api/src/main/java/jakarta/data/repository/Limit.java
@@ -18,8 +18,9 @@
 package jakarta.data.repository;
 
 /**
- * <p>Caps the number of results that can be returned by a single invocation
- * of a repository find method.</p>
+ * <p>Limits the number of results of a single invocation of a
+ * repository find method to a maximum amount or to within a
+ * positional range.</p>
  *
  * <p><code>Limit</code> is optionally specified as a parameter to a
  * repository method in one of the parameter positions after the
@@ -27,10 +28,12 @@ package jakarta.data.repository;
  *
  * <pre>
  * &#64;Query("SELECT o FROM Products o WHERE o.weight &lt;= ?1 AND o.width * o.length * o.height &lt;= ?2 ORDER BY o.price DESC")
- * Product[] freeShippingEligible(float maxWeight, float maxVolume, Limit maxResults);
+ * Product[] freeShippingEligible(float maxWeight, float maxVolume, Limit limit);
  * 
  * ...
- * found = products.freeShippingEligible(6.0f, 360.0f, Limit.of(50));
+ * mostExpensive50 = products.freeShippingEligible(6.0f, 360.0f, Limit.of(50));
+ * ...
+ * secondMostExpensive50 = products.freeShippingEligible(6.0f, 360.0f, Limit.range(51, 100));
  * </pre>
  *
  * <p>A repository method will raise {@link IllegalArgumentException} if</p>
@@ -49,9 +52,6 @@ public class Limit {
     private final long startAt;
 
     private Limit(long maxResults, long startAt) {
-        if (maxResults < 1)
-            throw new IllegalArgumentException("maxResults: " + maxResults);
-
         this.maxResults = maxResults;
         this.startAt = startAt;
     }
@@ -86,24 +86,33 @@ public class Limit {
      * @throws IllegalArgumentException if maxResults is less than 1.
      */
     public static Limit of(long maxResults) {
+        if (maxResults < 1)
+            throw new IllegalArgumentException("maxResults: " + maxResults);
+
         return new Limit(maxResults, DEFAULT_START_AT);
     }
 
     /**
-     * <p>Create a limit that caps the number of results at the
-     * specified maximum, starting from the specified position.</p>
+     * <p>Create a limit that restricts the results to a range,
+     * beginning with the <code>startAt</code> position and
+     * ending after the <code>endAt</code> position or the
+     * position of the final result, whichever comes first.</p>
      *
-     * @param maxResults maximum number of results.
-     * @param startAt    position at which to start returning results.
+     * @param startAt position at which to start including results.
+     *                The first query result is position 1.
+     * @param endAt   position after which to cease including results.
      * @return limit that can be supplied to a <code>find...By</code>
      *         or <code>&#64;Query</code> method.
-     * @throws IllegalArgumentException if maxResults or startAt is
-     *         less than 1.
+     * @throws IllegalArgumentException if <code>startAt</code> is less than 1
+     *         or <code>endAt</code> is less than <code>startAt</code>.
      */
-    public static Limit of(long maxResults, long startAt) {
+    public static Limit range(long startAt, long endAt) {
         if (startAt < 1)
             throw new IllegalArgumentException("startAt: " + startAt);
 
-        return new Limit(maxResults, startAt);
+        if (endAt < startAt)
+            throw new IllegalArgumentException("startAt: " + startAt + ", endAt: " + endAt);
+
+        return new Limit(endAt - startAt + 1, startAt);
     }
 }
diff --git a/api/src/main/java/jakarta/data/repository/Repository.java b/api/src/main/java/jakarta/data/repository/Repository.java
index 60c8d34a..d5def7ef 100644
--- a/api/src/main/java/jakarta/data/repository/Repository.java
+++ b/api/src/main/java/jakarta/data/repository/Repository.java
@@ -328,14 +328,16 @@ import java.lang.annotation.Target;
  *
  * <p>You can cap the number of results that can be returned by a single
  * invocation of a repository find method by adding a {@link Limit} parameter.
- * For example,</p>
+ * You can also limit the results to a positional range. For example,</p>
  *
  * <pre>
  * &#64;Query("SELECT o FROM Products o WHERE (o.fullPrice - o.salePrice) / o.fullPrice &gt;= ?1 ORDER BY o.salePrice DESC")
- * Product[] highlyDiscounted(float minPercentOff, Limit maxResults);
+ * Product[] highlyDiscounted(float minPercentOff, Limit limit);
  *
  * ...
- * found = products.highlyDiscounted(0.30, Limit.of(50));
+ * first50 = products.highlyDiscounted(0.30, Limit.of(50));
+ * ...
+ * second50 = products.highlyDiscounted(0.30, Limit.range(51, 100));
  * </pre>
  *
  * <h3>Pagination</h3>


Test patch:
diff --git a/api/src/test/java/jakarta/data/repository/LimitTest.java b/api/src/test/java/jakarta/data/repository/LimitTest.java
index 13f8e4f0..40043e10 100644
--- a/api/src/test/java/jakarta/data/repository/LimitTest.java
+++ b/api/src/test/java/jakarta/data/repository/LimitTest.java
@@ -22,6 +22,11 @@ import org.junit.jupiter.api.Test;
 
 class LimitTest {
 
+    @Test
+    public void shouldRaiseErrorWhenEndAtIsLessThanStartAt() {
+        Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.range(10, 1));
+    }
+
     @Test
     public void shouldReturnErrorWhenMaxResultsIsNegative() {
         Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.of(-1));
@@ -34,12 +39,12 @@ class LimitTest {
 
     @Test
     public void shouldReturnErrorWhenStartAtIsNegative(){
-        Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.of(1, -1));
+        Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.range(-1, 10));
     }
 
     @Test
     public void shouldReturnErrorWhenStartAtIsZero(){
-        Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.of(1, 0));
+        Assertions.assertThrows(IllegalArgumentException.class, () -> Limit.range(0, 100));
     }
     @Test
     public void shouldCreateLimitWithDefaultStartAt() {
@@ -50,8 +55,8 @@ class LimitTest {
     }
 
     @Test
-    public void shouldCreateLimit() {
-        Limit limit = Limit.of(10, 2);
+    public void shouldCreateLimitWithRange() {
+        Limit limit = Limit.range(2, 11);
         Assertions.assertNotNull(limit);
         Assertions.assertEquals(10L, limit.maxResults());
         Assertions.assertEquals(2L, limit.startAt());