diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 112e32b3..180ef9e3 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "6.0.0"
+ ".": "7.0.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index d004027c..9cbd6b8d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 45
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-f09e5f2c555d7ee764478b7bc73e92cd21f403d6ec189be14574c8367bc131ce.yml
-openapi_spec_hash: bd0a8e001f14132c105992d40149909a
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-5b00a0bc705b1d5bfcb5ea79c7af544766d51ec12ccc4721825664ab397789d8.yml
+openapi_spec_hash: 34891659cff31395ba7683a8153b1db5
config_hash: 53778a0b839c4f6ad34fbba051f5e8a6
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 38ebf293..a9ad4b1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
# Changelog
+## 7.0.0 (2025-05-16)
+
+Full Changelog: [v6.0.0...v7.0.0](https://github.com/Finch-API/finch-api-java/compare/v6.0.0...v7.0.0)
+
+### ⚠ BREAKING CHANGES
+
+* **client:** extract auto pagination to shared classes
+* **client:** **Migration:** - If you were referencing the `AutoPager` class on a specific `*Page` or `*PageAsync` type, then you should instead reference the shared `AutoPager` and `AutoPagerAsync` types, under the `core` package
+ - `AutoPagerAsync` now has different usage. You can call `.subscribe(...)` on the returned object instead to get called back each page item. You can also call `onCompleteFuture()` to get a future that completes when all items have been processed. Finally, you can call `.close()` on the returned object to stop auto-paginating early
+ - If you were referencing `getNextPage` or `getNextPageParams`:
+ - Swap to `nextPage()` and `nextPageParams()`
+ - Note that these both now return non-optional types (use `hasNextPage()` before calling these, since they will throw if it's impossible to get another page)
+
+### Features
+
+* **api:** api update ([f226da9](https://github.com/Finch-API/finch-api-java/commit/f226da9c89911bb4f3f39f3657c2f725d0773e7a))
+* **api:** api update ([7932861](https://github.com/Finch-API/finch-api-java/commit/79328615d98546e904f7cf99c222f7645ecd9131))
+* **api:** api update ([17bd5c1](https://github.com/Finch-API/finch-api-java/commit/17bd5c172f3ef94e68846f5b18670b42560e1fce))
+* **client:** allow providing some params positionally ([ec6fa40](https://github.com/Finch-API/finch-api-java/commit/ec6fa40e9be337318708f336e853b3f9e551dd47))
+* **client:** extract auto pagination to shared classes ([c4a8874](https://github.com/Finch-API/finch-api-java/commit/c4a8874a3f7799b0d689beaafd00cf1a3727f0ea))
+
## 6.0.0 (2025-05-08)
Full Changelog: [v5.5.0...v6.0.0](https://github.com/Finch-API/finch-api-java/compare/v5.5.0...v6.0.0)
diff --git a/README.md b/README.md
index fe0a5e8d..4ac5dff0 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.tryfinch.api/finch-java/6.0.0)
-[](https://javadoc.io/doc/com.tryfinch.api/finch-java/6.0.0)
+[](https://central.sonatype.com/artifact/com.tryfinch.api/finch-java/7.0.0)
+[](https://javadoc.io/doc/com.tryfinch.api/finch-java/7.0.0)
@@ -15,7 +15,7 @@ It is generated with [Stainless](https://www.stainless.com/).
-The REST API documentation can be found on [developer.tryfinch.com](https://developer.tryfinch.com/). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.tryfinch.api/finch-java/6.0.0).
+The REST API documentation can be found on [developer.tryfinch.com](https://developer.tryfinch.com/). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.tryfinch.api/finch-java/7.0.0).
@@ -26,7 +26,7 @@ The REST API documentation can be found on [developer.tryfinch.com](https://deve
### Gradle
```kotlin
-implementation("com.tryfinch.api:finch-java:6.0.0")
+implementation("com.tryfinch.api:finch-java:7.0.0")
```
### Maven
@@ -35,7 +35,7 @@ implementation("com.tryfinch.api:finch-java:6.0.0")
com.tryfinch.api
finch-java
- 6.0.0
+ 7.0.0
```
@@ -219,53 +219,101 @@ The SDK throws custom unchecked exception types:
## Pagination
-For methods that return a paginated list of results, this library provides convenient ways access the results either one page at a time, or item-by-item across all pages.
+The SDK defines methods that return a paginated lists of results. It provides convenient ways to access the results either one page at a time or item-by-item across all pages.
### Auto-pagination
-To iterate through all results across all pages, you can use `autoPager`, which automatically handles fetching more pages for you:
+To iterate through all results across all pages, use the `autoPager()` method, which automatically fetches more pages as needed.
-### Synchronous
+When using the synchronous client, the method returns an [`Iterable`](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html)
```java
import com.tryfinch.api.models.HrisDirectoryListPage;
import com.tryfinch.api.models.IndividualInDirectory;
-// As an Iterable:
-HrisDirectoryListPage page = client.hris().directory().list(params);
+HrisDirectoryListPage page = client.hris().directory().list();
+
+// Process as an Iterable
for (IndividualInDirectory directory : page.autoPager()) {
System.out.println(directory);
-};
+}
-// As a Stream:
-client.hris().directory().list(params).autoPager().stream()
+// Process as a Stream
+page.autoPager()
+ .stream()
.limit(50)
.forEach(directory -> System.out.println(directory));
```
-### Asynchronous
+When using the asynchronous client, the method returns an [`AsyncStreamResponse`](finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/AsyncStreamResponse.kt):
```java
-// Using forEach, which returns CompletableFuture:
-asyncClient.hris().directory().list(params).autoPager()
- .forEach(directory -> System.out.println(directory), executor);
+import com.tryfinch.api.core.http.AsyncStreamResponse;
+import com.tryfinch.api.models.HrisDirectoryListPageAsync;
+import com.tryfinch.api.models.IndividualInDirectory;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+
+CompletableFuture pageFuture = client.async().hris().directory().list();
+
+pageFuture.thenRun(page -> page.autoPager().subscribe(directory -> {
+ System.out.println(directory);
+}));
+
+// If you need to handle errors or completion of the stream
+pageFuture.thenRun(page -> page.autoPager().subscribe(new AsyncStreamResponse.Handler<>() {
+ @Override
+ public void onNext(IndividualInDirectory directory) {
+ System.out.println(directory);
+ }
+
+ @Override
+ public void onComplete(Optional error) {
+ if (error.isPresent()) {
+ System.out.println("Something went wrong!");
+ throw new RuntimeException(error.get());
+ } else {
+ System.out.println("No more!");
+ }
+ }
+}));
+
+// Or use futures
+pageFuture.thenRun(page -> page.autoPager()
+ .subscribe(directory -> {
+ System.out.println(directory);
+ })
+ .onCompleteFuture()
+ .whenComplete((unused, error) -> {
+ if (error != null) {
+ System.out.println("Something went wrong!");
+ throw new RuntimeException(error);
+ } else {
+ System.out.println("No more!");
+ }
+ }));
```
### Manual pagination
-If none of the above helpers meet your needs, you can also manually request pages one-by-one. A page of results has a `data()` method to fetch the list of objects, as well as top-level `response` and other methods to fetch top-level data about the page. It also has methods `hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination.
+To access individual page items and manually request the next page, use the `items()`,
+`hasNextPage()`, and `nextPage()` methods:
```java
import com.tryfinch.api.models.HrisDirectoryListPage;
import com.tryfinch.api.models.IndividualInDirectory;
-HrisDirectoryListPage page = client.hris().directory().list(params);
-while (page != null) {
- for (IndividualInDirectory directory : page.individuals()) {
+HrisDirectoryListPage page = client.hris().directory().list();
+while (true) {
+ for (IndividualInDirectory directory : page.items()) {
System.out.println(directory);
}
- page = page.getNextPage().orElse(null);
+ if (!page.hasNextPage()) {
+ break;
+ }
+
+ page = page.nextPage();
}
```
@@ -343,7 +391,6 @@ To set a custom timeout, configure the method call using the `timeout` method:
```java
import com.tryfinch.api.models.HrisDirectoryListPage;
-import com.tryfinch.api.models.HrisDirectoryListParams;
HrisDirectoryListPage page = client.hris().directory().list(RequestOptions.builder().timeout(Duration.ofSeconds(30)).build());
```
@@ -573,7 +620,6 @@ Or configure the method call to validate the response using the `responseValidat
```java
import com.tryfinch.api.models.HrisDirectoryListPage;
-import com.tryfinch.api.models.HrisDirectoryListParams;
HrisDirectoryListPage page = client.hris().directory().list(RequestOptions.builder().responseValidation(true).build());
```
diff --git a/build.gradle.kts b/build.gradle.kts
index dcfcd84d..7d01d9e2 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.tryfinch.api"
- version = "6.0.0" // x-release-please-version
+ version = "7.0.0" // x-release-please-version
}
subprojects {
diff --git a/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt b/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt
index 625e6cac..21e1d896 100644
--- a/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt
+++ b/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt
@@ -13,6 +13,7 @@ import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
+import java.util.concurrent.Executor
import kotlin.jvm.optionals.getOrNull
class FinchOkHttpClient private constructor() {
@@ -47,6 +48,10 @@ class FinchOkHttpClient private constructor() {
fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ clientOptions.streamHandlerExecutor(streamHandlerExecutor)
+ }
+
fun clock(clock: Clock) = apply { clientOptions.clock(clock) }
fun headers(headers: Headers) = apply { clientOptions.headers(headers) }
diff --git a/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt b/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt
index b8aac548..ecfb663d 100644
--- a/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt
+++ b/finch-java-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt
@@ -13,6 +13,7 @@ import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
+import java.util.concurrent.Executor
import kotlin.jvm.optionals.getOrNull
class FinchOkHttpClientAsync private constructor() {
@@ -47,6 +48,10 @@ class FinchOkHttpClientAsync private constructor() {
fun jsonMapper(jsonMapper: JsonMapper) = apply { clientOptions.jsonMapper(jsonMapper) }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ clientOptions.streamHandlerExecutor(streamHandlerExecutor)
+ }
+
fun clock(clock: Clock) = apply { clientOptions.clock(clock) }
fun headers(headers: Headers) = apply { clientOptions.headers(headers) }
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPager.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPager.kt
new file mode 100644
index 00000000..4ec6210a
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPager.kt
@@ -0,0 +1,21 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.tryfinch.api.core
+
+import java.util.stream.Stream
+import java.util.stream.StreamSupport
+
+class AutoPager private constructor(private val firstPage: Page) : Iterable {
+
+ companion object {
+
+ fun from(firstPage: Page): AutoPager = AutoPager(firstPage)
+ }
+
+ override fun iterator(): Iterator =
+ generateSequence(firstPage) { if (it.hasNextPage()) it.nextPage() else null }
+ .flatMap { it.items() }
+ .iterator()
+
+ fun stream(): Stream = StreamSupport.stream(spliterator(), false)
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPagerAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPagerAsync.kt
new file mode 100644
index 00000000..a2b37a0b
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/AutoPagerAsync.kt
@@ -0,0 +1,88 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.tryfinch.api.core
+
+import com.tryfinch.api.core.http.AsyncStreamResponse
+import java.util.Optional
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.CompletionException
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicReference
+
+class AutoPagerAsync
+private constructor(private val firstPage: PageAsync, private val defaultExecutor: Executor) :
+ AsyncStreamResponse {
+
+ companion object {
+
+ fun from(firstPage: PageAsync, defaultExecutor: Executor): AutoPagerAsync =
+ AutoPagerAsync(firstPage, defaultExecutor)
+ }
+
+ private val onCompleteFuture = CompletableFuture()
+ private val state = AtomicReference(State.NEW)
+
+ override fun subscribe(handler: AsyncStreamResponse.Handler): AsyncStreamResponse =
+ subscribe(handler, defaultExecutor)
+
+ override fun subscribe(
+ handler: AsyncStreamResponse.Handler,
+ executor: Executor,
+ ): AsyncStreamResponse = apply {
+ // TODO(JDK): Use `compareAndExchange` once targeting JDK 9.
+ check(state.compareAndSet(State.NEW, State.SUBSCRIBED)) {
+ if (state.get() == State.SUBSCRIBED) "Cannot subscribe more than once"
+ else "Cannot subscribe after the response is closed"
+ }
+
+ fun PageAsync.handle(): CompletableFuture {
+ if (state.get() == State.CLOSED) {
+ return CompletableFuture.completedFuture(null)
+ }
+
+ items().forEach { handler.onNext(it) }
+ return if (hasNextPage()) nextPage().thenCompose { it.handle() }
+ else CompletableFuture.completedFuture(null)
+ }
+
+ executor.execute {
+ firstPage.handle().whenComplete { _, error ->
+ val actualError =
+ if (error is CompletionException && error.cause != null) error.cause else error
+ try {
+ handler.onComplete(Optional.ofNullable(actualError))
+ } finally {
+ try {
+ if (actualError == null) {
+ onCompleteFuture.complete(null)
+ } else {
+ onCompleteFuture.completeExceptionally(actualError)
+ }
+ } finally {
+ close()
+ }
+ }
+ }
+ }
+ }
+
+ override fun onCompleteFuture(): CompletableFuture = onCompleteFuture
+
+ override fun close() {
+ val previousState = state.getAndSet(State.CLOSED)
+ if (previousState == State.CLOSED) {
+ return
+ }
+
+ // When the stream is closed, we should always consider it closed. If it closed due
+ // to an error, then we will have already completed the future earlier, and this
+ // will be a no-op.
+ onCompleteFuture.complete(null)
+ }
+}
+
+private enum class State {
+ NEW,
+ SUBSCRIBED,
+ CLOSED,
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Check.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Check.kt
index b228e69d..817890bb 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Check.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Check.kt
@@ -5,6 +5,9 @@ package com.tryfinch.api.core
import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.core.util.VersionUtil
+fun checkRequired(name: String, condition: Boolean) =
+ check(condition) { "`$name` is required, but was not set" }
+
fun checkRequired(name: String, value: T?): T =
checkNotNull(value) { "`$name` is required, but was not set" }
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/ClientOptions.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/ClientOptions.kt
index 8a9abd9c..cfdb5e56 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/ClientOptions.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/ClientOptions.kt
@@ -11,6 +11,10 @@ import com.tryfinch.api.core.http.RetryingHttpClient
import java.time.Clock
import java.util.Base64
import java.util.Optional
+import java.util.concurrent.Executor
+import java.util.concurrent.Executors
+import java.util.concurrent.ThreadFactory
+import java.util.concurrent.atomic.AtomicLong
import kotlin.jvm.optionals.getOrNull
class ClientOptions
@@ -19,6 +23,7 @@ private constructor(
@get:JvmName("httpClient") val httpClient: HttpClient,
@get:JvmName("checkJacksonVersionCompatibility") val checkJacksonVersionCompatibility: Boolean,
@get:JvmName("jsonMapper") val jsonMapper: JsonMapper,
+ @get:JvmName("streamHandlerExecutor") val streamHandlerExecutor: Executor,
@get:JvmName("clock") val clock: Clock,
@get:JvmName("baseUrl") val baseUrl: String,
@get:JvmName("headers") val headers: Headers,
@@ -71,6 +76,7 @@ private constructor(
private var httpClient: HttpClient? = null
private var checkJacksonVersionCompatibility: Boolean = true
private var jsonMapper: JsonMapper = jsonMapper()
+ private var streamHandlerExecutor: Executor? = null
private var clock: Clock = Clock.systemUTC()
private var baseUrl: String = PRODUCTION_URL
private var headers: Headers.Builder = Headers.builder()
@@ -88,6 +94,7 @@ private constructor(
httpClient = clientOptions.originalHttpClient
checkJacksonVersionCompatibility = clientOptions.checkJacksonVersionCompatibility
jsonMapper = clientOptions.jsonMapper
+ streamHandlerExecutor = clientOptions.streamHandlerExecutor
clock = clientOptions.clock
baseUrl = clientOptions.baseUrl
headers = clientOptions.headers.toBuilder()
@@ -109,6 +116,10 @@ private constructor(
fun jsonMapper(jsonMapper: JsonMapper) = apply { this.jsonMapper = jsonMapper }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
fun clock(clock: Clock) = apply { this.clock = clock }
fun baseUrl(baseUrl: String) = apply { this.baseUrl = baseUrl }
@@ -285,6 +296,21 @@ private constructor(
),
checkJacksonVersionCompatibility,
jsonMapper,
+ streamHandlerExecutor
+ ?: Executors.newCachedThreadPool(
+ object : ThreadFactory {
+
+ private val threadFactory: ThreadFactory =
+ Executors.defaultThreadFactory()
+ private val count = AtomicLong(0)
+
+ override fun newThread(runnable: Runnable): Thread =
+ threadFactory.newThread(runnable).also {
+ it.name =
+ "finch-stream-handler-thread-${count.getAndIncrement()}"
+ }
+ }
+ ),
clock,
baseUrl,
headers.build(),
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Page.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Page.kt
new file mode 100644
index 00000000..456d2b6f
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/Page.kt
@@ -0,0 +1,33 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.tryfinch.api.core
+
+/**
+ * An interface representing a single page, with items of type [T], from a paginated endpoint
+ * response.
+ *
+ * Implementations of this interface are expected to request additional pages synchronously. For
+ * asynchronous pagination, see the [PageAsync] interface.
+ */
+interface Page {
+
+ /**
+ * Returns whether there's another page after this one.
+ *
+ * The method generally doesn't make requests so the result depends entirely on the data in this
+ * page. If a significant amount of time has passed between requesting this page and calling
+ * this method, then the result could be stale.
+ */
+ fun hasNextPage(): Boolean
+
+ /**
+ * Returns the page after this one by making another request.
+ *
+ * @throws IllegalStateException if it's impossible to get the next page. This exception is
+ * avoidable by calling [hasNextPage] first.
+ */
+ fun nextPage(): Page
+
+ /** Returns the items in this page. */
+ fun items(): List
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/PageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/PageAsync.kt
new file mode 100644
index 00000000..366bfede
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/PageAsync.kt
@@ -0,0 +1,35 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.tryfinch.api.core
+
+import java.util.concurrent.CompletableFuture
+
+/**
+ * An interface representing a single page, with items of type [T], from a paginated endpoint
+ * response.
+ *
+ * Implementations of this interface are expected to request additional pages asynchronously. For
+ * synchronous pagination, see the [Page] interface.
+ */
+interface PageAsync {
+
+ /**
+ * Returns whether there's another page after this one.
+ *
+ * The method generally doesn't make requests so the result depends entirely on the data in this
+ * page. If a significant amount of time has passed between requesting this page and calling
+ * this method, then the result could be stale.
+ */
+ fun hasNextPage(): Boolean
+
+ /**
+ * Returns the page after this one by making another request.
+ *
+ * @throws IllegalStateException if it's impossible to get the next page. This exception is
+ * avoidable by calling [hasNextPage] first.
+ */
+ fun nextPage(): CompletableFuture>
+
+ /** Returns the items in this page. */
+ fun items(): List
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/AsyncStreamResponse.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/AsyncStreamResponse.kt
new file mode 100644
index 00000000..a86ddffd
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/AsyncStreamResponse.kt
@@ -0,0 +1,157 @@
+package com.tryfinch.api.core.http
+
+import com.tryfinch.api.core.http.AsyncStreamResponse.Handler
+import java.util.Optional
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.Executor
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * A class providing access to an API response as an asynchronous stream of chunks of type [T],
+ * where each chunk can be individually processed as soon as it arrives instead of waiting on the
+ * full response.
+ */
+interface AsyncStreamResponse {
+
+ /**
+ * Registers [handler] to be called for events of this stream.
+ *
+ * [handler]'s methods will be called in the client's configured or default thread pool.
+ *
+ * @throws IllegalStateException if [subscribe] has already been called.
+ */
+ fun subscribe(handler: Handler): AsyncStreamResponse
+
+ /**
+ * Registers [handler] to be called for events of this stream.
+ *
+ * [handler]'s methods will be called in the given [executor].
+ *
+ * @throws IllegalStateException if [subscribe] has already been called.
+ */
+ fun subscribe(handler: Handler, executor: Executor): AsyncStreamResponse
+
+ /**
+ * Returns a future that completes when a stream is fully consumed, errors, or gets closed
+ * early.
+ */
+ fun onCompleteFuture(): CompletableFuture
+
+ /**
+ * Closes this resource, relinquishing any underlying resources.
+ *
+ * This is purposefully not inherited from [AutoCloseable] because this response should not be
+ * synchronously closed via try-with-resources.
+ */
+ fun close()
+
+ /** A class for handling streaming events. */
+ fun interface Handler {
+
+ /** Called whenever a chunk is received. */
+ fun onNext(value: T)
+
+ /**
+ * Called when a stream is fully consumed, errors, or gets closed early.
+ *
+ * [onNext] will not be called once this method is called.
+ *
+ * @param error Non-empty if the stream completed due to an error.
+ */
+ fun onComplete(error: Optional) {}
+ }
+}
+
+@JvmSynthetic
+internal fun CompletableFuture>.toAsync(streamHandlerExecutor: Executor) =
+ PhantomReachableClosingAsyncStreamResponse(
+ object : AsyncStreamResponse {
+
+ private val onCompleteFuture = CompletableFuture()
+ private val state = AtomicReference(State.NEW)
+
+ init {
+ this@toAsync.whenComplete { _, error ->
+ // If an error occurs from the original future, then we should resolve the
+ // `onCompleteFuture` even if `subscribe` has not been called.
+ error?.let(onCompleteFuture::completeExceptionally)
+ }
+ }
+
+ override fun subscribe(handler: Handler): AsyncStreamResponse =
+ subscribe(handler, streamHandlerExecutor)
+
+ override fun subscribe(
+ handler: Handler,
+ executor: Executor,
+ ): AsyncStreamResponse = apply {
+ // TODO(JDK): Use `compareAndExchange` once targeting JDK 9.
+ check(state.compareAndSet(State.NEW, State.SUBSCRIBED)) {
+ if (state.get() == State.SUBSCRIBED) "Cannot subscribe more than once"
+ else "Cannot subscribe after the response is closed"
+ }
+
+ this@toAsync.whenCompleteAsync(
+ { streamResponse, futureError ->
+ if (state.get() == State.CLOSED) {
+ // Avoid doing any work if `close` was called before the future
+ // completed.
+ return@whenCompleteAsync
+ }
+
+ if (futureError != null) {
+ // An error occurred before we started passing chunks to the handler.
+ handler.onComplete(Optional.of(futureError))
+ return@whenCompleteAsync
+ }
+
+ var streamError: Throwable? = null
+ try {
+ streamResponse.stream().forEach(handler::onNext)
+ } catch (e: Throwable) {
+ streamError = e
+ }
+
+ try {
+ handler.onComplete(Optional.ofNullable(streamError))
+ } finally {
+ try {
+ // Notify completion via the `onCompleteFuture` as well. This is in
+ // a separate `try-finally` block so that we still complete the
+ // future if `handler.onComplete` throws.
+ if (streamError == null) {
+ onCompleteFuture.complete(null)
+ } else {
+ onCompleteFuture.completeExceptionally(streamError)
+ }
+ } finally {
+ close()
+ }
+ }
+ },
+ executor,
+ )
+ }
+
+ override fun onCompleteFuture(): CompletableFuture = onCompleteFuture
+
+ override fun close() {
+ val previousState = state.getAndSet(State.CLOSED)
+ if (previousState == State.CLOSED) {
+ return
+ }
+
+ this@toAsync.whenComplete { streamResponse, error -> streamResponse?.close() }
+ // When the stream is closed, we should always consider it closed. If it closed due
+ // to an error, then we will have already completed the future earlier, and this
+ // will be a no-op.
+ onCompleteFuture.complete(null)
+ }
+ }
+ )
+
+private enum class State {
+ NEW,
+ SUBSCRIBED,
+ CLOSED,
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt
new file mode 100644
index 00000000..deca7d02
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingAsyncStreamResponse.kt
@@ -0,0 +1,56 @@
+package com.tryfinch.api.core.http
+
+import com.tryfinch.api.core.closeWhenPhantomReachable
+import com.tryfinch.api.core.http.AsyncStreamResponse.Handler
+import java.util.Optional
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.Executor
+
+/**
+ * A delegating wrapper around an `AsyncStreamResponse` that closes it once it's only phantom
+ * reachable.
+ *
+ * This class ensures the `AsyncStreamResponse` is closed even if the user forgets to close it.
+ */
+internal class PhantomReachableClosingAsyncStreamResponse(
+ private val asyncStreamResponse: AsyncStreamResponse
+) : AsyncStreamResponse {
+
+ /**
+ * An object used for keeping `asyncStreamResponse` open while the object is still reachable.
+ */
+ private val reachabilityTracker = Object()
+
+ init {
+ closeWhenPhantomReachable(reachabilityTracker, asyncStreamResponse::close)
+ }
+
+ override fun subscribe(handler: Handler): AsyncStreamResponse = apply {
+ asyncStreamResponse.subscribe(TrackedHandler(handler, reachabilityTracker))
+ }
+
+ override fun subscribe(handler: Handler, executor: Executor): AsyncStreamResponse =
+ apply {
+ asyncStreamResponse.subscribe(TrackedHandler(handler, reachabilityTracker), executor)
+ }
+
+ override fun onCompleteFuture(): CompletableFuture =
+ asyncStreamResponse.onCompleteFuture()
+
+ override fun close() = asyncStreamResponse.close()
+}
+
+/**
+ * A wrapper around a `Handler` that also references a `reachabilityTracker` object.
+ *
+ * Referencing the `reachabilityTracker` object prevents it from getting reclaimed while the handler
+ * is still reachable.
+ */
+private class TrackedHandler(
+ private val handler: Handler,
+ private val reachabilityTracker: Any,
+) : Handler {
+ override fun onNext(value: T) = handler.onNext(value)
+
+ override fun onComplete(error: Optional) = handler.onComplete(error)
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingStreamResponse.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingStreamResponse.kt
new file mode 100644
index 00000000..f23638aa
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/PhantomReachableClosingStreamResponse.kt
@@ -0,0 +1,21 @@
+package com.tryfinch.api.core.http
+
+import com.tryfinch.api.core.closeWhenPhantomReachable
+import java.util.stream.Stream
+
+/**
+ * A delegating wrapper around a `StreamResponse` that closes it once it's only phantom reachable.
+ *
+ * This class ensures the `StreamResponse` is closed even if the user forgets to close it.
+ */
+internal class PhantomReachableClosingStreamResponse(
+ private val streamResponse: StreamResponse
+) : StreamResponse {
+ init {
+ closeWhenPhantomReachable(this, streamResponse)
+ }
+
+ override fun stream(): Stream = streamResponse.stream()
+
+ override fun close() = streamResponse.close()
+}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/StreamResponse.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/StreamResponse.kt
new file mode 100644
index 00000000..89acf0ef
--- /dev/null
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/core/http/StreamResponse.kt
@@ -0,0 +1,19 @@
+package com.tryfinch.api.core.http
+
+import java.util.stream.Stream
+
+interface StreamResponse : AutoCloseable {
+
+ fun stream(): Stream
+
+ /** Overridden from [AutoCloseable] to not have a checked exception in its signature. */
+ override fun close()
+}
+
+@JvmSynthetic
+internal fun StreamResponse.map(transform: (T) -> R): StreamResponse =
+ object : StreamResponse {
+ override fun stream(): Stream = this@map.stream().map(transform)
+
+ override fun close() = this@map.close()
+ }
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualEnrolledIdsParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualEnrolledIdsParams.kt
index ed8fb88a..bdd47916 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualEnrolledIdsParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualEnrolledIdsParams.kt
@@ -3,20 +3,21 @@
package com.tryfinch.api.models
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/** Lists individuals currently enrolled in a given deduction. */
class HrisBenefitIndividualEnrolledIdsParams
private constructor(
- private val benefitId: String,
+ private val benefitId: String?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun benefitId(): String = benefitId
+ fun benefitId(): Optional = Optional.ofNullable(benefitId)
fun _additionalHeaders(): Headers = additionalHeaders
@@ -26,14 +27,11 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisBenefitIndividualEnrolledIdsParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of
* [HrisBenefitIndividualEnrolledIdsParams].
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -55,7 +53,10 @@ private constructor(
hrisBenefitIndividualEnrolledIdsParams.additionalQueryParams.toBuilder()
}
- fun benefitId(benefitId: String) = apply { this.benefitId = benefitId }
+ fun benefitId(benefitId: String?) = apply { this.benefitId = benefitId }
+
+ /** Alias for calling [Builder.benefitId] with `benefitId.orElse(null)`. */
+ fun benefitId(benefitId: Optional) = benefitId(benefitId.getOrNull())
fun additionalHeaders(additionalHeaders: Headers) = apply {
this.additionalHeaders.clear()
@@ -159,17 +160,10 @@ private constructor(
* Returns an immutable instance of [HrisBenefitIndividualEnrolledIdsParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisBenefitIndividualEnrolledIdsParams =
HrisBenefitIndividualEnrolledIdsParams(
- checkRequired("benefitId", benefitId),
+ benefitId,
additionalHeaders.build(),
additionalQueryParams.build(),
)
@@ -177,7 +171,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> benefitId
+ 0 -> benefitId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPage.kt
index b5773d4e..dfc47dd0 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPage.kt
@@ -2,13 +2,11 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.benefits.IndividualService
import java.util.Objects
-import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
-import kotlin.jvm.optionals.getOrNull
/** @see [IndividualService.retrieveManyBenefits] */
class HrisBenefitIndividualRetrieveManyBenefitsPage
@@ -16,23 +14,23 @@ private constructor(
private val service: IndividualService,
private val params: HrisBenefitIndividualRetrieveManyBenefitsParams,
private val items: List,
-) {
+) : Page {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional =
- Optional.empty()
+ fun nextPageParams(): HrisBenefitIndividualRetrieveManyBenefitsParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage(): Optional =
- getNextPageParams().map { service.retrieveManyBenefits(it) }
+ override fun nextPage(): HrisBenefitIndividualRetrieveManyBenefitsPage =
+ service.retrieveManyBenefits(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitIndividualRetrieveManyBenefitsParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -101,26 +99,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisBenefitIndividualRetrieveManyBenefitsPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.items().size) {
- yield(page.items()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPageAsync.kt
index 1d164078..85f9ba74 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsPageAsync.kt
@@ -2,40 +2,39 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.benefits.IndividualServiceAsync
import java.util.Objects
-import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
/** @see [IndividualServiceAsync.retrieveManyBenefits] */
class HrisBenefitIndividualRetrieveManyBenefitsPageAsync
private constructor(
private val service: IndividualServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisBenefitIndividualRetrieveManyBenefitsParams,
private val items: List,
-) {
+) : PageAsync {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional =
- Optional.empty()
+ fun nextPageParams(): HrisBenefitIndividualRetrieveManyBenefitsParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage():
- CompletableFuture> =
- getNextPageParams()
- .map { service.retrieveManyBenefits(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ override fun nextPage(): CompletableFuture =
+ service.retrieveManyBenefits(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitIndividualRetrieveManyBenefitsParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -48,6 +47,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -59,6 +59,7 @@ private constructor(
class Builder internal constructor() {
private var service: IndividualServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisBenefitIndividualRetrieveManyBenefitsParams? = null
private var items: List? = null
@@ -68,12 +69,18 @@ private constructor(
HrisBenefitIndividualRetrieveManyBenefitsPageAsync
) = apply {
service = hrisBenefitIndividualRetrieveManyBenefitsPageAsync.service
+ streamHandlerExecutor =
+ hrisBenefitIndividualRetrieveManyBenefitsPageAsync.streamHandlerExecutor
params = hrisBenefitIndividualRetrieveManyBenefitsPageAsync.params
items = hrisBenefitIndividualRetrieveManyBenefitsPageAsync.items
}
fun service(service: IndividualServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisBenefitIndividualRetrieveManyBenefitsParams) = apply {
this.params = params
@@ -90,6 +97,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -99,51 +107,22 @@ private constructor(
fun build(): HrisBenefitIndividualRetrieveManyBenefitsPageAsync =
HrisBenefitIndividualRetrieveManyBenefitsPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("items", items),
)
}
- class AutoPager(private val firstPage: HrisBenefitIndividualRetrieveManyBenefitsPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>
- .forEach(
- action: (IndividualBenefit) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.items().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisBenefitIndividualRetrieveManyBenefitsPageAsync && service == other.service && params == other.params && items == other.items /* spotless:on */
+ return /* spotless:off */ other is HrisBenefitIndividualRetrieveManyBenefitsPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && items == other.items /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, items) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, items) /* spotless:on */
override fun toString() =
- "HrisBenefitIndividualRetrieveManyBenefitsPageAsync{service=$service, params=$params, items=$items}"
+ "HrisBenefitIndividualRetrieveManyBenefitsPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, items=$items}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsParams.kt
index dd2e70a8..7c6e196e 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualRetrieveManyBenefitsParams.kt
@@ -3,7 +3,6 @@
package com.tryfinch.api.models
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import java.util.Objects
@@ -13,13 +12,13 @@ import kotlin.jvm.optionals.getOrNull
/** Get enrollment information for the given individuals. */
class HrisBenefitIndividualRetrieveManyBenefitsParams
private constructor(
- private val benefitId: String,
+ private val benefitId: String?,
private val individualIds: String?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun benefitId(): String = benefitId
+ fun benefitId(): Optional = Optional.ofNullable(benefitId)
/**
* comma-delimited list of stable Finch uuids for each individual. If empty, defaults to all
@@ -35,14 +34,11 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisBenefitIndividualRetrieveManyBenefitsParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of
* [HrisBenefitIndividualRetrieveManyBenefitsParams].
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -68,7 +64,10 @@ private constructor(
hrisBenefitIndividualRetrieveManyBenefitsParams.additionalQueryParams.toBuilder()
}
- fun benefitId(benefitId: String) = apply { this.benefitId = benefitId }
+ fun benefitId(benefitId: String?) = apply { this.benefitId = benefitId }
+
+ /** Alias for calling [Builder.benefitId] with `benefitId.orElse(null)`. */
+ fun benefitId(benefitId: Optional) = benefitId(benefitId.getOrNull())
/**
* comma-delimited list of stable Finch uuids for each individual. If empty, defaults to all
@@ -182,17 +181,10 @@ private constructor(
* Returns an immutable instance of [HrisBenefitIndividualRetrieveManyBenefitsParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisBenefitIndividualRetrieveManyBenefitsParams =
HrisBenefitIndividualRetrieveManyBenefitsParams(
- checkRequired("benefitId", benefitId),
+ benefitId,
individualIds,
additionalHeaders.build(),
additionalQueryParams.build(),
@@ -201,7 +193,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> benefitId
+ 0 -> benefitId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualUnenrollManyParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualUnenrollManyParams.kt
index da3f66cd..45431317 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualUnenrollManyParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitIndividualUnenrollManyParams.kt
@@ -12,7 +12,6 @@ import com.tryfinch.api.core.JsonMissing
import com.tryfinch.api.core.JsonValue
import com.tryfinch.api.core.Params
import com.tryfinch.api.core.checkKnown
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import com.tryfinch.api.core.toImmutable
@@ -25,13 +24,13 @@ import kotlin.jvm.optionals.getOrNull
/** Unenroll individuals from a deduction or contribution */
class HrisBenefitIndividualUnenrollManyParams
private constructor(
- private val benefitId: String,
+ private val benefitId: String?,
private val body: Body,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun benefitId(): String = benefitId
+ fun benefitId(): Optional = Optional.ofNullable(benefitId)
/**
* Array of individual_ids to unenroll.
@@ -58,14 +57,11 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisBenefitIndividualUnenrollManyParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of
* [HrisBenefitIndividualUnenrollManyParams].
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -90,7 +86,10 @@ private constructor(
hrisBenefitIndividualUnenrollManyParams.additionalQueryParams.toBuilder()
}
- fun benefitId(benefitId: String) = apply { this.benefitId = benefitId }
+ fun benefitId(benefitId: String?) = apply { this.benefitId = benefitId }
+
+ /** Alias for calling [Builder.benefitId] with `benefitId.orElse(null)`. */
+ fun benefitId(benefitId: Optional) = benefitId(benefitId.getOrNull())
/**
* Sets the entire request body.
@@ -243,17 +242,10 @@ private constructor(
* Returns an immutable instance of [HrisBenefitIndividualUnenrollManyParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisBenefitIndividualUnenrollManyParams =
HrisBenefitIndividualUnenrollManyParams(
- checkRequired("benefitId", benefitId),
+ benefitId,
body.build(),
additionalHeaders.build(),
additionalQueryParams.build(),
@@ -264,7 +256,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> benefitId
+ 0 -> benefitId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPage.kt
index 7b00ce90..fbcf2ff6 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPage.kt
@@ -2,13 +2,11 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.BenefitService
import java.util.Objects
-import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
-import kotlin.jvm.optionals.getOrNull
/** @see [BenefitService.list] */
class HrisBenefitListPage
@@ -16,21 +14,22 @@ private constructor(
private val service: BenefitService,
private val params: HrisBenefitListParams,
private val items: List,
-) {
+) : Page {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional = Optional.empty()
+ fun nextPageParams(): HrisBenefitListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage(): Optional = getNextPageParams().map { service.list(it) }
+ override fun nextPage(): HrisBenefitListPage = service.list(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitListParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -93,25 +92,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisBenefitListPage) : Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.items().size) {
- yield(page.items()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPageAsync.kt
index f49f49a4..9cd78291 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListPageAsync.kt
@@ -2,38 +2,39 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.BenefitServiceAsync
import java.util.Objects
-import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
/** @see [BenefitServiceAsync.list] */
class HrisBenefitListPageAsync
private constructor(
private val service: BenefitServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisBenefitListParams,
private val items: List,
-) {
+) : PageAsync {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional = Optional.empty()
+ fun nextPageParams(): HrisBenefitListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.list(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ override fun nextPage(): CompletableFuture =
+ service.list(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitListParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -45,6 +46,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -56,18 +58,24 @@ private constructor(
class Builder internal constructor() {
private var service: BenefitServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisBenefitListParams? = null
private var items: List? = null
@JvmSynthetic
internal fun from(hrisBenefitListPageAsync: HrisBenefitListPageAsync) = apply {
service = hrisBenefitListPageAsync.service
+ streamHandlerExecutor = hrisBenefitListPageAsync.streamHandlerExecutor
params = hrisBenefitListPageAsync.params
items = hrisBenefitListPageAsync.items
}
fun service(service: BenefitServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisBenefitListParams) = apply { this.params = params }
@@ -82,6 +90,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -91,50 +100,22 @@ private constructor(
fun build(): HrisBenefitListPageAsync =
HrisBenefitListPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("items", items),
)
}
- class AutoPager(private val firstPage: HrisBenefitListPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (CompanyBenefit) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.items().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisBenefitListPageAsync && service == other.service && params == other.params && items == other.items /* spotless:on */
+ return /* spotless:off */ other is HrisBenefitListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && items == other.items /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, items) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, items) /* spotless:on */
override fun toString() =
- "HrisBenefitListPageAsync{service=$service, params=$params, items=$items}"
+ "HrisBenefitListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, items=$items}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPage.kt
index 147d1698..3409c4b3 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPage.kt
@@ -2,12 +2,12 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.BenefitService
import java.util.Objects
import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrNull
/** @see [BenefitService.listSupportedBenefits] */
@@ -16,22 +16,23 @@ private constructor(
private val service: BenefitService,
private val params: HrisBenefitListSupportedBenefitsParams,
private val items: List,
-) {
+) : Page {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional = Optional.empty()
+ fun nextPageParams(): HrisBenefitListSupportedBenefitsParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage(): Optional =
- getNextPageParams().map { service.listSupportedBenefits(it) }
+ override fun nextPage(): HrisBenefitListSupportedBenefitsPage =
+ service.listSupportedBenefits(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitListSupportedBenefitsParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -99,26 +100,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisBenefitListSupportedBenefitsPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.items().size) {
- yield(page.items()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPageAsync.kt
index 859239d8..3f3abf51 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitListSupportedBenefitsPageAsync.kt
@@ -2,39 +2,41 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.BenefitServiceAsync
import java.util.Objects
import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
import kotlin.jvm.optionals.getOrNull
/** @see [BenefitServiceAsync.listSupportedBenefits] */
class HrisBenefitListSupportedBenefitsPageAsync
private constructor(
private val service: BenefitServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisBenefitListSupportedBenefitsParams,
private val items: List,
-) {
+) : PageAsync {
- fun hasNextPage(): Boolean = items.isNotEmpty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPageParams(): Optional = Optional.empty()
+ fun nextPageParams(): HrisBenefitListSupportedBenefitsParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.listSupportedBenefits(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ override fun nextPage(): CompletableFuture =
+ service.listSupportedBenefits(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisBenefitListSupportedBenefitsParams = params
/** The response that this page was parsed from. */
- fun items(): List = items
+ override fun items(): List = items
fun toBuilder() = Builder().from(this)
@@ -47,6 +49,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -58,6 +61,7 @@ private constructor(
class Builder internal constructor() {
private var service: BenefitServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisBenefitListSupportedBenefitsParams? = null
private var items: Optional>? = null
@@ -66,12 +70,17 @@ private constructor(
hrisBenefitListSupportedBenefitsPageAsync: HrisBenefitListSupportedBenefitsPageAsync
) = apply {
service = hrisBenefitListSupportedBenefitsPageAsync.service
+ streamHandlerExecutor = hrisBenefitListSupportedBenefitsPageAsync.streamHandlerExecutor
params = hrisBenefitListSupportedBenefitsPageAsync.params
items = Optional.of(hrisBenefitListSupportedBenefitsPageAsync.items)
}
fun service(service: BenefitServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisBenefitListSupportedBenefitsParams) = apply { this.params = params }
@@ -88,6 +97,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .items()
* ```
@@ -97,52 +107,22 @@ private constructor(
fun build(): HrisBenefitListSupportedBenefitsPageAsync =
HrisBenefitListSupportedBenefitsPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("items", items).getOrNull() ?: emptyList(),
)
}
- class AutoPager(private val firstPage: HrisBenefitListSupportedBenefitsPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (BenefitListSupportedBenefitsResponse) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.items().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(
- executor: Executor
- ): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisBenefitListSupportedBenefitsPageAsync && service == other.service && params == other.params && items == other.items /* spotless:on */
+ return /* spotless:off */ other is HrisBenefitListSupportedBenefitsPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && items == other.items /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, items) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, items) /* spotless:on */
override fun toString() =
- "HrisBenefitListSupportedBenefitsPageAsync{service=$service, params=$params, items=$items}"
+ "HrisBenefitListSupportedBenefitsPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, items=$items}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitRetrieveParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitRetrieveParams.kt
index 0167113d..c6fa8c33 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitRetrieveParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitRetrieveParams.kt
@@ -3,20 +3,21 @@
package com.tryfinch.api.models
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/** Lists deductions and contributions information for a given item */
class HrisBenefitRetrieveParams
private constructor(
- private val benefitId: String,
+ private val benefitId: String?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun benefitId(): String = benefitId
+ fun benefitId(): Optional = Optional.ofNullable(benefitId)
fun _additionalHeaders(): Headers = additionalHeaders
@@ -26,13 +27,10 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisBenefitRetrieveParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of [HrisBenefitRetrieveParams].
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -51,7 +49,10 @@ private constructor(
additionalQueryParams = hrisBenefitRetrieveParams.additionalQueryParams.toBuilder()
}
- fun benefitId(benefitId: String) = apply { this.benefitId = benefitId }
+ fun benefitId(benefitId: String?) = apply { this.benefitId = benefitId }
+
+ /** Alias for calling [Builder.benefitId] with `benefitId.orElse(null)`. */
+ fun benefitId(benefitId: Optional) = benefitId(benefitId.getOrNull())
fun additionalHeaders(additionalHeaders: Headers) = apply {
this.additionalHeaders.clear()
@@ -155,17 +156,10 @@ private constructor(
* Returns an immutable instance of [HrisBenefitRetrieveParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisBenefitRetrieveParams =
HrisBenefitRetrieveParams(
- checkRequired("benefitId", benefitId),
+ benefitId,
additionalHeaders.build(),
additionalQueryParams.build(),
)
@@ -173,7 +167,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> benefitId
+ 0 -> benefitId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitUpdateParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitUpdateParams.kt
index 91bc5f13..90b691f3 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitUpdateParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisBenefitUpdateParams.kt
@@ -11,24 +11,24 @@ import com.tryfinch.api.core.JsonField
import com.tryfinch.api.core.JsonMissing
import com.tryfinch.api.core.JsonValue
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import com.tryfinch.api.errors.FinchInvalidDataException
import java.util.Collections
import java.util.Objects
import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/** Updates an existing company-wide deduction or contribution */
class HrisBenefitUpdateParams
private constructor(
- private val benefitId: String,
+ private val benefitId: String?,
private val body: Body,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun benefitId(): String = benefitId
+ fun benefitId(): Optional = Optional.ofNullable(benefitId)
/**
* Updated name or description.
@@ -55,14 +55,9 @@ private constructor(
companion object {
- /**
- * Returns a mutable builder for constructing an instance of [HrisBenefitUpdateParams].
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- */
+ @JvmStatic fun none(): HrisBenefitUpdateParams = builder().build()
+
+ /** Returns a mutable builder for constructing an instance of [HrisBenefitUpdateParams]. */
@JvmStatic fun builder() = Builder()
}
@@ -82,7 +77,10 @@ private constructor(
additionalQueryParams = hrisBenefitUpdateParams.additionalQueryParams.toBuilder()
}
- fun benefitId(benefitId: String) = apply { this.benefitId = benefitId }
+ fun benefitId(benefitId: String?) = apply { this.benefitId = benefitId }
+
+ /** Alias for calling [Builder.benefitId] with `benefitId.orElse(null)`. */
+ fun benefitId(benefitId: Optional) = benefitId(benefitId.getOrNull())
/**
* Sets the entire request body.
@@ -226,17 +224,10 @@ private constructor(
* Returns an immutable instance of [HrisBenefitUpdateParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .benefitId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisBenefitUpdateParams =
HrisBenefitUpdateParams(
- checkRequired("benefitId", benefitId),
+ benefitId,
body.build(),
additionalHeaders.build(),
additionalQueryParams.build(),
@@ -247,7 +238,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> benefitId
+ 0 -> benefitId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPage.kt
index 00bcd8fa..823bce21 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPage.kt
@@ -2,12 +2,11 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.company.PayStatementItemService
import java.util.Objects
-import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrNull
/** @see [PayStatementItemService.list] */
@@ -16,7 +15,7 @@ private constructor(
private val service: PayStatementItemService,
private val params: HrisCompanyPayStatementItemListParams,
private val response: HrisCompanyPayStatementItemListPageResponse,
-) {
+) : Page {
/**
* Delegates to [HrisCompanyPayStatementItemListPageResponse], but gracefully handles missing
@@ -27,14 +26,16 @@ private constructor(
fun responses(): List =
response._responses().getOptional("responses").getOrNull() ?: emptyList()
- fun hasNextPage(): Boolean = responses().isNotEmpty()
+ override fun items(): List = responses()
- fun getNextPageParams(): Optional = Optional.empty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPage(): Optional =
- getNextPageParams().map { service.list(it) }
+ fun nextPageParams(): HrisCompanyPayStatementItemListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun autoPager(): AutoPager = AutoPager(this)
+ override fun nextPage(): HrisCompanyPayStatementItemListPage = service.list(nextPageParams())
+
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisCompanyPayStatementItemListParams = params
@@ -108,26 +109,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisCompanyPayStatementItemListPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.responses().size) {
- yield(page.responses()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPageAsync.kt
index 8a50507b..a39ed6ef 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemListPageAsync.kt
@@ -2,22 +2,23 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.company.PayStatementItemServiceAsync
import java.util.Objects
-import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
import kotlin.jvm.optionals.getOrNull
/** @see [PayStatementItemServiceAsync.list] */
class HrisCompanyPayStatementItemListPageAsync
private constructor(
private val service: PayStatementItemServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisCompanyPayStatementItemListParams,
private val response: HrisCompanyPayStatementItemListPageResponse,
-) {
+) : PageAsync {
/**
* Delegates to [HrisCompanyPayStatementItemListPageResponse], but gracefully handles missing
@@ -28,16 +29,18 @@ private constructor(
fun responses(): List =
response._responses().getOptional("responses").getOrNull() ?: emptyList()
- fun hasNextPage(): Boolean = responses().isNotEmpty()
+ override fun items(): List = responses()
- fun getNextPageParams(): Optional = Optional.empty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.list(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ fun nextPageParams(): HrisCompanyPayStatementItemListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun autoPager(): AutoPager = AutoPager(this)
+ override fun nextPage(): CompletableFuture =
+ service.list(nextPageParams())
+
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisCompanyPayStatementItemListParams = params
@@ -56,6 +59,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -67,6 +71,7 @@ private constructor(
class Builder internal constructor() {
private var service: PayStatementItemServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisCompanyPayStatementItemListParams? = null
private var response: HrisCompanyPayStatementItemListPageResponse? = null
@@ -75,12 +80,17 @@ private constructor(
hrisCompanyPayStatementItemListPageAsync: HrisCompanyPayStatementItemListPageAsync
) = apply {
service = hrisCompanyPayStatementItemListPageAsync.service
+ streamHandlerExecutor = hrisCompanyPayStatementItemListPageAsync.streamHandlerExecutor
params = hrisCompanyPayStatementItemListPageAsync.params
response = hrisCompanyPayStatementItemListPageAsync.response
}
fun service(service: PayStatementItemServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisCompanyPayStatementItemListParams) = apply { this.params = params }
@@ -97,6 +107,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -106,50 +117,22 @@ private constructor(
fun build(): HrisCompanyPayStatementItemListPageAsync =
HrisCompanyPayStatementItemListPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("response", response),
)
}
- class AutoPager(private val firstPage: HrisCompanyPayStatementItemListPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (PayStatementItemListResponse) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.responses().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisCompanyPayStatementItemListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */
+ return /* spotless:off */ other is HrisCompanyPayStatementItemListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */
override fun toString() =
- "HrisCompanyPayStatementItemListPageAsync{service=$service, params=$params, response=$response}"
+ "HrisCompanyPayStatementItemListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleDeleteParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleDeleteParams.kt
index a9f7f64d..1f47cbe2 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleDeleteParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleDeleteParams.kt
@@ -4,12 +4,12 @@ package com.tryfinch.api.models
import com.tryfinch.api.core.JsonValue
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import com.tryfinch.api.core.toImmutable
import java.util.Objects
import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/**
* **Beta:** this endpoint currently serves employers onboarded after March 4th and historical
@@ -17,13 +17,13 @@ import java.util.Optional
*/
class HrisCompanyPayStatementItemRuleDeleteParams
private constructor(
- private val ruleId: String,
+ private val ruleId: String?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
private val additionalBodyProperties: Map,
) : Params {
- fun ruleId(): String = ruleId
+ fun ruleId(): Optional = Optional.ofNullable(ruleId)
fun _additionalBodyProperties(): Map = additionalBodyProperties
@@ -35,14 +35,11 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisCompanyPayStatementItemRuleDeleteParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of
* [HrisCompanyPayStatementItemRuleDeleteParams].
- *
- * The following fields are required:
- * ```java
- * .ruleId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -68,7 +65,10 @@ private constructor(
hrisCompanyPayStatementItemRuleDeleteParams.additionalBodyProperties.toMutableMap()
}
- fun ruleId(ruleId: String) = apply { this.ruleId = ruleId }
+ fun ruleId(ruleId: String?) = apply { this.ruleId = ruleId }
+
+ /** Alias for calling [Builder.ruleId] with `ruleId.orElse(null)`. */
+ fun ruleId(ruleId: Optional) = ruleId(ruleId.getOrNull())
fun additionalHeaders(additionalHeaders: Headers) = apply {
this.additionalHeaders.clear()
@@ -194,17 +194,10 @@ private constructor(
* Returns an immutable instance of [HrisCompanyPayStatementItemRuleDeleteParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .ruleId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisCompanyPayStatementItemRuleDeleteParams =
HrisCompanyPayStatementItemRuleDeleteParams(
- checkRequired("ruleId", ruleId),
+ ruleId,
additionalHeaders.build(),
additionalQueryParams.build(),
additionalBodyProperties.toImmutable(),
@@ -216,7 +209,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> ruleId
+ 0 -> ruleId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPage.kt
index cb2c5147..580d9169 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPage.kt
@@ -2,12 +2,11 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.company.payStatementItem.RuleService
import java.util.Objects
-import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrNull
/** @see [RuleService.list] */
@@ -16,7 +15,7 @@ private constructor(
private val service: RuleService,
private val params: HrisCompanyPayStatementItemRuleListParams,
private val response: HrisCompanyPayStatementItemRuleListPageResponse,
-) {
+) : Page {
/**
* Delegates to [HrisCompanyPayStatementItemRuleListPageResponse], but gracefully handles
@@ -27,14 +26,17 @@ private constructor(
fun responses(): List =
response._responses().getOptional("responses").getOrNull() ?: emptyList()
- fun hasNextPage(): Boolean = responses().isNotEmpty()
+ override fun items(): List = responses()
- fun getNextPageParams(): Optional = Optional.empty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPage(): Optional =
- getNextPageParams().map { service.list(it) }
+ fun nextPageParams(): HrisCompanyPayStatementItemRuleListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun autoPager(): AutoPager = AutoPager(this)
+ override fun nextPage(): HrisCompanyPayStatementItemRuleListPage =
+ service.list(nextPageParams())
+
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisCompanyPayStatementItemRuleListParams = params
@@ -110,26 +112,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisCompanyPayStatementItemRuleListPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.responses().size) {
- yield(page.responses()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPageAsync.kt
index 269318ac..1a083316 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleListPageAsync.kt
@@ -2,22 +2,23 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.company.payStatementItem.RuleServiceAsync
import java.util.Objects
-import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
import kotlin.jvm.optionals.getOrNull
/** @see [RuleServiceAsync.list] */
class HrisCompanyPayStatementItemRuleListPageAsync
private constructor(
private val service: RuleServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisCompanyPayStatementItemRuleListParams,
private val response: HrisCompanyPayStatementItemRuleListPageResponse,
-) {
+) : PageAsync {
/**
* Delegates to [HrisCompanyPayStatementItemRuleListPageResponse], but gracefully handles
@@ -28,16 +29,18 @@ private constructor(
fun responses(): List =
response._responses().getOptional("responses").getOrNull() ?: emptyList()
- fun hasNextPage(): Boolean = responses().isNotEmpty()
+ override fun items(): List = responses()
- fun getNextPageParams(): Optional = Optional.empty()
+ override fun hasNextPage(): Boolean = items().isNotEmpty()
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.list(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ fun nextPageParams(): HrisCompanyPayStatementItemRuleListParams =
+ throw IllegalStateException("Cannot construct next page params")
- fun autoPager(): AutoPager = AutoPager(this)
+ override fun nextPage(): CompletableFuture =
+ service.list(nextPageParams())
+
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisCompanyPayStatementItemRuleListParams = params
@@ -56,6 +59,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -67,6 +71,7 @@ private constructor(
class Builder internal constructor() {
private var service: RuleServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisCompanyPayStatementItemRuleListParams? = null
private var response: HrisCompanyPayStatementItemRuleListPageResponse? = null
@@ -76,12 +81,18 @@ private constructor(
HrisCompanyPayStatementItemRuleListPageAsync
) = apply {
service = hrisCompanyPayStatementItemRuleListPageAsync.service
+ streamHandlerExecutor =
+ hrisCompanyPayStatementItemRuleListPageAsync.streamHandlerExecutor
params = hrisCompanyPayStatementItemRuleListPageAsync.params
response = hrisCompanyPayStatementItemRuleListPageAsync.response
}
fun service(service: RuleServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisCompanyPayStatementItemRuleListParams) = apply {
this.params = params
@@ -100,6 +111,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -109,50 +121,22 @@ private constructor(
fun build(): HrisCompanyPayStatementItemRuleListPageAsync =
HrisCompanyPayStatementItemRuleListPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("response", response),
)
}
- class AutoPager(private val firstPage: HrisCompanyPayStatementItemRuleListPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (RuleListResponse) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.responses().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisCompanyPayStatementItemRuleListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */
+ return /* spotless:off */ other is HrisCompanyPayStatementItemRuleListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */
override fun toString() =
- "HrisCompanyPayStatementItemRuleListPageAsync{service=$service, params=$params, response=$response}"
+ "HrisCompanyPayStatementItemRuleListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleUpdateParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleUpdateParams.kt
index 0ec80b82..e509e8bf 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleUpdateParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisCompanyPayStatementItemRuleUpdateParams.kt
@@ -10,12 +10,13 @@ import com.tryfinch.api.core.ExcludeMissing
import com.tryfinch.api.core.JsonMissing
import com.tryfinch.api.core.JsonValue
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import com.tryfinch.api.errors.FinchInvalidDataException
import java.util.Collections
import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/**
* **Beta:** this endpoint currently serves employers onboarded after March 4th and historical
@@ -23,13 +24,13 @@ import java.util.Objects
*/
class HrisCompanyPayStatementItemRuleUpdateParams
private constructor(
- private val ruleId: String,
+ private val ruleId: String?,
private val body: UpdateRuleRequest,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun ruleId(): String = ruleId
+ fun ruleId(): Optional = Optional.ofNullable(ruleId)
fun _optionalProperty(): JsonValue = body._optionalProperty()
@@ -43,14 +44,11 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisCompanyPayStatementItemRuleUpdateParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of
* [HrisCompanyPayStatementItemRuleUpdateParams].
- *
- * The following fields are required:
- * ```java
- * .ruleId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -75,7 +73,10 @@ private constructor(
hrisCompanyPayStatementItemRuleUpdateParams.additionalQueryParams.toBuilder()
}
- fun ruleId(ruleId: String) = apply { this.ruleId = ruleId }
+ fun ruleId(ruleId: String?) = apply { this.ruleId = ruleId }
+
+ /** Alias for calling [Builder.ruleId] with `ruleId.orElse(null)`. */
+ fun ruleId(ruleId: Optional) = ruleId(ruleId.getOrNull())
/**
* Sets the entire request body.
@@ -211,17 +212,10 @@ private constructor(
* Returns an immutable instance of [HrisCompanyPayStatementItemRuleUpdateParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .ruleId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisCompanyPayStatementItemRuleUpdateParams =
HrisCompanyPayStatementItemRuleUpdateParams(
- checkRequired("ruleId", ruleId),
+ ruleId,
body.build(),
additionalHeaders.build(),
additionalQueryParams.build(),
@@ -232,7 +226,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> ruleId
+ 0 -> ruleId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPage.kt
index eeafc093..8f3c042a 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPage.kt
@@ -2,12 +2,12 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.DirectoryService
import java.util.Objects
import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrDefault
import kotlin.jvm.optionals.getOrNull
@@ -18,7 +18,7 @@ private constructor(
private val service: DirectoryService,
private val params: HrisDirectoryListIndividualsParams,
private val response: HrisDirectoryListIndividualsPageResponse,
-) {
+) : Page {
/**
* Delegates to [HrisDirectoryListIndividualsPageResponse], but gracefully handles missing data.
@@ -35,30 +35,28 @@ private constructor(
*/
fun paging(): Optional = response._paging().getOptional("paging")
- fun hasNextPage(): Boolean {
- if (individuals().isEmpty()) {
+ override fun items(): List = individuals()
+
+ override fun hasNextPage(): Boolean {
+ if (items().isEmpty()) {
return false
}
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
val totalCount =
paging().flatMap { it._count().getOptional("count") }.getOrDefault(Long.MAX_VALUE)
- return offset + individuals().size < totalCount
+ return offset + items().size < totalCount
}
- fun getNextPageParams(): Optional {
- if (!hasNextPage()) {
- return Optional.empty()
- }
-
+ fun nextPageParams(): HrisDirectoryListIndividualsParams {
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
- return Optional.of(params.toBuilder().offset(offset + individuals().size).build())
+ return params.toBuilder().offset(offset + items().size).build()
}
- fun getNextPage(): Optional =
- getNextPageParams().map { service.listIndividuals(it) }
+ override fun nextPage(): HrisDirectoryListIndividualsPage =
+ service.listIndividuals(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisDirectoryListIndividualsParams = params
@@ -131,26 +129,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisDirectoryListIndividualsPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.individuals().size) {
- yield(page.individuals()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPageAsync.kt
index e7480379..1a20863f 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListIndividualsPageAsync.kt
@@ -2,13 +2,14 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.DirectoryServiceAsync
import java.util.Objects
import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
import kotlin.jvm.optionals.getOrDefault
import kotlin.jvm.optionals.getOrNull
@@ -17,9 +18,10 @@ import kotlin.jvm.optionals.getOrNull
class HrisDirectoryListIndividualsPageAsync
private constructor(
private val service: DirectoryServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisDirectoryListIndividualsParams,
private val response: HrisDirectoryListIndividualsPageResponse,
-) {
+) : PageAsync {
/**
* Delegates to [HrisDirectoryListIndividualsPageResponse], but gracefully handles missing data.
@@ -36,32 +38,29 @@ private constructor(
*/
fun paging(): Optional = response._paging().getOptional("paging")
- fun hasNextPage(): Boolean {
- if (individuals().isEmpty()) {
+ override fun items(): List = individuals()
+
+ override fun hasNextPage(): Boolean {
+ if (items().isEmpty()) {
return false
}
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
val totalCount =
paging().flatMap { it._count().getOptional("count") }.getOrDefault(Long.MAX_VALUE)
- return offset + individuals().size < totalCount
+ return offset + items().size < totalCount
}
- fun getNextPageParams(): Optional {
- if (!hasNextPage()) {
- return Optional.empty()
- }
-
+ fun nextPageParams(): HrisDirectoryListIndividualsParams {
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
- return Optional.of(params.toBuilder().offset(offset + individuals().size).build())
+ return params.toBuilder().offset(offset + items().size).build()
}
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.listIndividuals(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ override fun nextPage(): CompletableFuture =
+ service.listIndividuals(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisDirectoryListIndividualsParams = params
@@ -80,6 +79,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -91,6 +91,7 @@ private constructor(
class Builder internal constructor() {
private var service: DirectoryServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisDirectoryListIndividualsParams? = null
private var response: HrisDirectoryListIndividualsPageResponse? = null
@@ -99,12 +100,17 @@ private constructor(
hrisDirectoryListIndividualsPageAsync: HrisDirectoryListIndividualsPageAsync
) = apply {
service = hrisDirectoryListIndividualsPageAsync.service
+ streamHandlerExecutor = hrisDirectoryListIndividualsPageAsync.streamHandlerExecutor
params = hrisDirectoryListIndividualsPageAsync.params
response = hrisDirectoryListIndividualsPageAsync.response
}
fun service(service: DirectoryServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisDirectoryListIndividualsParams) = apply { this.params = params }
@@ -121,6 +127,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -130,50 +137,22 @@ private constructor(
fun build(): HrisDirectoryListIndividualsPageAsync =
HrisDirectoryListIndividualsPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("response", response),
)
}
- class AutoPager(private val firstPage: HrisDirectoryListIndividualsPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (IndividualInDirectory) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.individuals().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisDirectoryListIndividualsPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */
+ return /* spotless:off */ other is HrisDirectoryListIndividualsPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */
override fun toString() =
- "HrisDirectoryListIndividualsPageAsync{service=$service, params=$params, response=$response}"
+ "HrisDirectoryListIndividualsPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPage.kt
index 36eff6a0..f30e6e3c 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPage.kt
@@ -2,12 +2,12 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.DirectoryService
import java.util.Objects
import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrDefault
import kotlin.jvm.optionals.getOrNull
@@ -17,7 +17,7 @@ private constructor(
private val service: DirectoryService,
private val params: HrisDirectoryListParams,
private val response: HrisDirectoryListPageResponse,
-) {
+) : Page {
/**
* Delegates to [HrisDirectoryListPageResponse], but gracefully handles missing data.
@@ -34,30 +34,27 @@ private constructor(
*/
fun paging(): Optional = response._paging().getOptional("paging")
- fun hasNextPage(): Boolean {
- if (individuals().isEmpty()) {
+ override fun items(): List = individuals()
+
+ override fun hasNextPage(): Boolean {
+ if (items().isEmpty()) {
return false
}
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
val totalCount =
paging().flatMap { it._count().getOptional("count") }.getOrDefault(Long.MAX_VALUE)
- return offset + individuals().size < totalCount
+ return offset + items().size < totalCount
}
- fun getNextPageParams(): Optional {
- if (!hasNextPage()) {
- return Optional.empty()
- }
-
+ fun nextPageParams(): HrisDirectoryListParams {
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
- return Optional.of(params.toBuilder().offset(offset + individuals().size).build())
+ return params.toBuilder().offset(offset + items().size).build()
}
- fun getNextPage(): Optional =
- getNextPageParams().map { service.list(it) }
+ override fun nextPage(): HrisDirectoryListPage = service.list(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPager = AutoPager.from(this)
/** The parameters that were used to request this page. */
fun params(): HrisDirectoryListParams = params
@@ -126,26 +123,6 @@ private constructor(
)
}
- class AutoPager(private val firstPage: HrisDirectoryListPage) :
- Iterable {
-
- override fun iterator(): Iterator = iterator {
- var page = firstPage
- var index = 0
- while (true) {
- while (index < page.individuals().size) {
- yield(page.individuals()[index++])
- }
- page = page.getNextPage().getOrNull() ?: break
- index = 0
- }
- }
-
- fun stream(): Stream {
- return StreamSupport.stream(spliterator(), false)
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPageAsync.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPageAsync.kt
index bc8d9645..06b6ee3a 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPageAsync.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDirectoryListPageAsync.kt
@@ -2,13 +2,14 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPagerAsync
+import com.tryfinch.api.core.PageAsync
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.async.hris.DirectoryServiceAsync
import java.util.Objects
import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
-import java.util.function.Predicate
import kotlin.jvm.optionals.getOrDefault
import kotlin.jvm.optionals.getOrNull
@@ -16,9 +17,10 @@ import kotlin.jvm.optionals.getOrNull
class HrisDirectoryListPageAsync
private constructor(
private val service: DirectoryServiceAsync,
+ private val streamHandlerExecutor: Executor,
private val params: HrisDirectoryListParams,
private val response: HrisDirectoryListPageResponse,
-) {
+) : PageAsync {
/**
* Delegates to [HrisDirectoryListPageResponse], but gracefully handles missing data.
@@ -35,32 +37,29 @@ private constructor(
*/
fun paging(): Optional = response._paging().getOptional("paging")
- fun hasNextPage(): Boolean {
- if (individuals().isEmpty()) {
+ override fun items(): List = individuals()
+
+ override fun hasNextPage(): Boolean {
+ if (items().isEmpty()) {
return false
}
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
val totalCount =
paging().flatMap { it._count().getOptional("count") }.getOrDefault(Long.MAX_VALUE)
- return offset + individuals().size < totalCount
+ return offset + items().size < totalCount
}
- fun getNextPageParams(): Optional {
- if (!hasNextPage()) {
- return Optional.empty()
- }
-
+ fun nextPageParams(): HrisDirectoryListParams {
val offset = paging().flatMap { it._offset().getOptional("offset") }.getOrDefault(0)
- return Optional.of(params.toBuilder().offset(offset + individuals().size).build())
+ return params.toBuilder().offset(offset + items().size).build()
}
- fun getNextPage(): CompletableFuture> =
- getNextPageParams()
- .map { service.list(it).thenApply { Optional.of(it) } }
- .orElseGet { CompletableFuture.completedFuture(Optional.empty()) }
+ override fun nextPage(): CompletableFuture =
+ service.list(nextPageParams())
- fun autoPager(): AutoPager = AutoPager(this)
+ fun autoPager(): AutoPagerAsync =
+ AutoPagerAsync.from(this, streamHandlerExecutor)
/** The parameters that were used to request this page. */
fun params(): HrisDirectoryListParams = params
@@ -78,6 +77,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -89,18 +89,24 @@ private constructor(
class Builder internal constructor() {
private var service: DirectoryServiceAsync? = null
+ private var streamHandlerExecutor: Executor? = null
private var params: HrisDirectoryListParams? = null
private var response: HrisDirectoryListPageResponse? = null
@JvmSynthetic
internal fun from(hrisDirectoryListPageAsync: HrisDirectoryListPageAsync) = apply {
service = hrisDirectoryListPageAsync.service
+ streamHandlerExecutor = hrisDirectoryListPageAsync.streamHandlerExecutor
params = hrisDirectoryListPageAsync.params
response = hrisDirectoryListPageAsync.response
}
fun service(service: DirectoryServiceAsync) = apply { this.service = service }
+ fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply {
+ this.streamHandlerExecutor = streamHandlerExecutor
+ }
+
/** The parameters that were used to request this page. */
fun params(params: HrisDirectoryListParams) = apply { this.params = params }
@@ -115,6 +121,7 @@ private constructor(
* The following fields are required:
* ```java
* .service()
+ * .streamHandlerExecutor()
* .params()
* .response()
* ```
@@ -124,50 +131,22 @@ private constructor(
fun build(): HrisDirectoryListPageAsync =
HrisDirectoryListPageAsync(
checkRequired("service", service),
+ checkRequired("streamHandlerExecutor", streamHandlerExecutor),
checkRequired("params", params),
checkRequired("response", response),
)
}
- class AutoPager(private val firstPage: HrisDirectoryListPageAsync) {
-
- fun forEach(
- action: Predicate,
- executor: Executor,
- ): CompletableFuture {
- fun CompletableFuture>.forEach(
- action: (IndividualInDirectory) -> Boolean,
- executor: Executor,
- ): CompletableFuture =
- thenComposeAsync(
- { page ->
- page
- .filter { it.individuals().all(action) }
- .map { it.getNextPage().forEach(action, executor) }
- .orElseGet { CompletableFuture.completedFuture(null) }
- },
- executor,
- )
- return CompletableFuture.completedFuture(Optional.of(firstPage))
- .forEach(action::test, executor)
- }
-
- fun toList(executor: Executor): CompletableFuture> {
- val values = mutableListOf()
- return forEach(values::add, executor).thenApply { values }
- }
- }
-
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
- return /* spotless:off */ other is HrisDirectoryListPageAsync && service == other.service && params == other.params && response == other.response /* spotless:on */
+ return /* spotless:off */ other is HrisDirectoryListPageAsync && service == other.service && streamHandlerExecutor == other.streamHandlerExecutor && params == other.params && response == other.response /* spotless:on */
}
- override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, params, response) /* spotless:on */
+ override fun hashCode(): Int = /* spotless:off */ Objects.hash(service, streamHandlerExecutor, params, response) /* spotless:on */
override fun toString() =
- "HrisDirectoryListPageAsync{service=$service, params=$params, response=$response}"
+ "HrisDirectoryListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}"
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDocumentRetreiveParams.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDocumentRetreiveParams.kt
index 5de75843..c0d046d1 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDocumentRetreiveParams.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisDocumentRetreiveParams.kt
@@ -3,10 +3,11 @@
package com.tryfinch.api.models
import com.tryfinch.api.core.Params
-import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.core.http.Headers
import com.tryfinch.api.core.http.QueryParams
import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
/**
* **Beta:** This endpoint is in beta and may change. Retrieve details of a specific document by its
@@ -14,12 +15,12 @@ import java.util.Objects
*/
class HrisDocumentRetreiveParams
private constructor(
- private val documentId: String,
+ private val documentId: String?,
private val additionalHeaders: Headers,
private val additionalQueryParams: QueryParams,
) : Params {
- fun documentId(): String = documentId
+ fun documentId(): Optional = Optional.ofNullable(documentId)
fun _additionalHeaders(): Headers = additionalHeaders
@@ -29,13 +30,10 @@ private constructor(
companion object {
+ @JvmStatic fun none(): HrisDocumentRetreiveParams = builder().build()
+
/**
* Returns a mutable builder for constructing an instance of [HrisDocumentRetreiveParams].
- *
- * The following fields are required:
- * ```java
- * .documentId()
- * ```
*/
@JvmStatic fun builder() = Builder()
}
@@ -54,7 +52,10 @@ private constructor(
additionalQueryParams = hrisDocumentRetreiveParams.additionalQueryParams.toBuilder()
}
- fun documentId(documentId: String) = apply { this.documentId = documentId }
+ fun documentId(documentId: String?) = apply { this.documentId = documentId }
+
+ /** Alias for calling [Builder.documentId] with `documentId.orElse(null)`. */
+ fun documentId(documentId: Optional) = documentId(documentId.getOrNull())
fun additionalHeaders(additionalHeaders: Headers) = apply {
this.additionalHeaders.clear()
@@ -158,17 +159,10 @@ private constructor(
* Returns an immutable instance of [HrisDocumentRetreiveParams].
*
* Further updates to this [Builder] will not mutate the returned instance.
- *
- * The following fields are required:
- * ```java
- * .documentId()
- * ```
- *
- * @throws IllegalStateException if any required field is unset.
*/
fun build(): HrisDocumentRetreiveParams =
HrisDocumentRetreiveParams(
- checkRequired("documentId", documentId),
+ documentId,
additionalHeaders.build(),
additionalQueryParams.build(),
)
@@ -176,7 +170,7 @@ private constructor(
fun _pathParam(index: Int): String =
when (index) {
- 0 -> documentId
+ 0 -> documentId ?: ""
else -> ""
}
diff --git a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisEmploymentRetrieveManyPage.kt b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisEmploymentRetrieveManyPage.kt
index 9987671a..a4fb48cd 100644
--- a/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisEmploymentRetrieveManyPage.kt
+++ b/finch-java-core/src/main/kotlin/com/tryfinch/api/models/HrisEmploymentRetrieveManyPage.kt
@@ -2,12 +2,11 @@
package com.tryfinch.api.models
+import com.tryfinch.api.core.AutoPager
+import com.tryfinch.api.core.Page
import com.tryfinch.api.core.checkRequired
import com.tryfinch.api.services.blocking.hris.EmploymentService
import java.util.Objects
-import java.util.Optional
-import java.util.stream.Stream
-import java.util.stream.StreamSupport
import kotlin.jvm.optionals.getOrNull
/** @see [EmploymentService.retrieveMany] */
@@ -16,7 +15,7 @@ private constructor(
private val service: EmploymentService,
private val params: HrisEmploymentRetrieveManyParams,
private val response: HrisEmploymentRetrieveManyPageResponse,
-) {
+) : Page {
/**
* Delegates to [HrisEmploymentRetrieveManyPageResponse], but gracefully handles missing data.
@@ -26,14 +25,16 @@ private constructor(
fun responses(): List