From 6cf5c7836c6f4ecdc0ace125ab54a46e5063dac8 Mon Sep 17 00:00:00 2001 From: Andreas Marek Date: Tue, 25 Mar 2025 11:26:19 +1000 Subject: [PATCH] add jspecify --- build.gradle | 3 ++- src/main/java/org/dataloader/BatchLoader.java | 3 +++ .../BatchLoaderContextProvider.java | 4 ++- .../dataloader/BatchLoaderEnvironment.java | 5 +++- .../BatchLoaderEnvironmentProvider.java | 4 ++- .../dataloader/BatchLoaderWithContext.java | 2 ++ .../java/org/dataloader/BatchPublisher.java | 5 ++++ .../dataloader/BatchPublisherWithContext.java | 4 +++ src/main/java/org/dataloader/CacheKey.java | 5 ++++ src/main/java/org/dataloader/CacheMap.java | 5 +++- src/main/java/org/dataloader/DataLoader.java | 25 +++++++++++-------- .../org/dataloader/DataLoaderFactory.java | 3 ++- .../java/org/dataloader/DispatchResult.java | 2 ++ .../org/dataloader/MappedBatchLoader.java | 5 ++++ .../MappedBatchLoaderWithContext.java | 5 ++++ .../org/dataloader/MappedBatchPublisher.java | 4 +++ .../MappedBatchPublisherWithContext.java | 4 +++ src/main/java/org/dataloader/ValueCache.java | 4 ++- .../org/dataloader/ValueCacheOptions.java | 5 ++++ 19 files changed, 79 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 0a58559..9b943f3 100644 --- a/build.gradle +++ b/build.gradle @@ -66,6 +66,7 @@ jar { dependencies { api "org.reactivestreams:reactive-streams:$reactive_streams_version" + api "org.jspecify:jspecify:1.0.0" } task sourcesJar(type: Jar) { @@ -197,4 +198,4 @@ tasks.named("dependencyUpdates").configure { rejectVersionIf { isNonStable(it.candidate.version) } -} \ No newline at end of file +} diff --git a/src/main/java/org/dataloader/BatchLoader.java b/src/main/java/org/dataloader/BatchLoader.java index c1916e3..2b0c3c5 100644 --- a/src/main/java/org/dataloader/BatchLoader.java +++ b/src/main/java/org/dataloader/BatchLoader.java @@ -17,6 +17,8 @@ package org.dataloader; import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; import java.util.List; import java.util.concurrent.CompletionStage; @@ -74,6 +76,7 @@ */ @FunctionalInterface @PublicSpi +@NullMarked public interface BatchLoader { /** diff --git a/src/main/java/org/dataloader/BatchLoaderContextProvider.java b/src/main/java/org/dataloader/BatchLoaderContextProvider.java index d1eb1fe..702fd66 100644 --- a/src/main/java/org/dataloader/BatchLoaderContextProvider.java +++ b/src/main/java/org/dataloader/BatchLoaderContextProvider.java @@ -1,6 +1,7 @@ package org.dataloader; import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; /** * A BatchLoaderContextProvider is used by the {@link org.dataloader.DataLoader} code to @@ -8,9 +9,10 @@ * case is for propagating user security credentials or database connection parameters for example. */ @PublicSpi +@NullMarked public interface BatchLoaderContextProvider { /** * @return a context object that may be needed in batch load calls */ Object getContext(); -} \ No newline at end of file +} diff --git a/src/main/java/org/dataloader/BatchLoaderEnvironment.java b/src/main/java/org/dataloader/BatchLoaderEnvironment.java index 6039a4a..6b84e70 100644 --- a/src/main/java/org/dataloader/BatchLoaderEnvironment.java +++ b/src/main/java/org/dataloader/BatchLoaderEnvironment.java @@ -2,6 +2,8 @@ import org.dataloader.annotations.PublicApi; import org.dataloader.impl.Assertions; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -14,6 +16,7 @@ * of the calling users for example or database parameters that allow the data layer call to succeed. */ @PublicApi +@NullMarked public class BatchLoaderEnvironment { private final Object context; @@ -34,7 +37,7 @@ private BatchLoaderEnvironment(Object context, List keyContextsList, Map * @return a context object or null if there isn't one */ @SuppressWarnings("unchecked") - public T getContext() { + public @Nullable T getContext() { return (T) context; } diff --git a/src/main/java/org/dataloader/BatchLoaderEnvironmentProvider.java b/src/main/java/org/dataloader/BatchLoaderEnvironmentProvider.java index fd60a14..dae7c92 100644 --- a/src/main/java/org/dataloader/BatchLoaderEnvironmentProvider.java +++ b/src/main/java/org/dataloader/BatchLoaderEnvironmentProvider.java @@ -1,6 +1,7 @@ package org.dataloader; import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; /** * A BatchLoaderEnvironmentProvider is used by the {@link org.dataloader.DataLoader} code to @@ -9,9 +10,10 @@ * case is for propagating user security credentials or database connection parameters. */ @PublicSpi +@NullMarked public interface BatchLoaderEnvironmentProvider { /** * @return a {@link org.dataloader.BatchLoaderEnvironment} that may be needed in batch calls */ BatchLoaderEnvironment get(); -} \ No newline at end of file +} diff --git a/src/main/java/org/dataloader/BatchLoaderWithContext.java b/src/main/java/org/dataloader/BatchLoaderWithContext.java index fbe66b0..eba26e4 100644 --- a/src/main/java/org/dataloader/BatchLoaderWithContext.java +++ b/src/main/java/org/dataloader/BatchLoaderWithContext.java @@ -1,6 +1,7 @@ package org.dataloader; import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; import java.util.List; import java.util.concurrent.CompletionStage; @@ -14,6 +15,7 @@ * use this interface. */ @PublicSpi +@NullMarked public interface BatchLoaderWithContext { /** * Called to batch load the provided keys and return a promise to a list of values. This default diff --git a/src/main/java/org/dataloader/BatchPublisher.java b/src/main/java/org/dataloader/BatchPublisher.java index c499226..943becf 100644 --- a/src/main/java/org/dataloader/BatchPublisher.java +++ b/src/main/java/org/dataloader/BatchPublisher.java @@ -1,5 +1,8 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Subscriber; import java.util.List; @@ -18,6 +21,8 @@ * @param type parameter indicating the type of values returned * @see BatchLoader for the non-reactive version */ +@NullMarked +@PublicSpi public interface BatchPublisher { /** * Called to batch the provided keys into a stream of values. You must provide diff --git a/src/main/java/org/dataloader/BatchPublisherWithContext.java b/src/main/java/org/dataloader/BatchPublisherWithContext.java index 4eadfe9..9ee010b 100644 --- a/src/main/java/org/dataloader/BatchPublisherWithContext.java +++ b/src/main/java/org/dataloader/BatchPublisherWithContext.java @@ -1,5 +1,7 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; import org.reactivestreams.Subscriber; import java.util.List; @@ -12,6 +14,8 @@ * See {@link BatchPublisher} for more details on the design invariants that you must implement in order to * use this interface. */ +@NullMarked +@PublicSpi public interface BatchPublisherWithContext { /** * Called to batch the provided keys into a stream of values. You must provide diff --git a/src/main/java/org/dataloader/CacheKey.java b/src/main/java/org/dataloader/CacheKey.java index 88b5f97..c5641b1 100644 --- a/src/main/java/org/dataloader/CacheKey.java +++ b/src/main/java/org/dataloader/CacheKey.java @@ -16,6 +16,9 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; + /** * Function that is invoked on input keys of type {@code K} to derive keys that are required by the {@link CacheMap} * implementation. @@ -25,6 +28,8 @@ * @author Arnold Schrijver */ @FunctionalInterface +@NullMarked +@PublicSpi public interface CacheKey { /** diff --git a/src/main/java/org/dataloader/CacheMap.java b/src/main/java/org/dataloader/CacheMap.java index 1a4a455..54b1b49 100644 --- a/src/main/java/org/dataloader/CacheMap.java +++ b/src/main/java/org/dataloader/CacheMap.java @@ -18,6 +18,8 @@ import org.dataloader.annotations.PublicSpi; import org.dataloader.impl.DefaultCacheMap; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.util.Collection; import java.util.concurrent.CompletableFuture; @@ -39,6 +41,7 @@ * @author Brad Baker */ @PublicSpi +@NullMarked public interface CacheMap { /** @@ -71,7 +74,7 @@ static CacheMap simpleMap() { * * @return the cached value, or {@code null} if not found (depends on cache implementation) */ - CompletableFuture get(K key); + @Nullable CompletableFuture get(K key); /** * Gets a collection of CompletableFutures from the cache map. diff --git a/src/main/java/org/dataloader/DataLoader.java b/src/main/java/org/dataloader/DataLoader.java index 62e80de..fb15d44 100644 --- a/src/main/java/org/dataloader/DataLoader.java +++ b/src/main/java/org/dataloader/DataLoader.java @@ -21,6 +21,8 @@ import org.dataloader.impl.CompletableFutureKit; import org.dataloader.stats.Statistics; import org.dataloader.stats.StatisticsCollector; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import java.time.Clock; import java.time.Duration; @@ -64,6 +66,7 @@ * @author Brad Baker */ @PublicApi +@NullMarked public class DataLoader { private final DataLoaderHelper helper; @@ -99,7 +102,7 @@ public static DataLoader newDataLoader(BatchLoader batchLoadF * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newDataLoader(BatchLoader batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newDataLoader(BatchLoader batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -139,7 +142,7 @@ public static DataLoader newDataLoaderWithTry(BatchLoader * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newDataLoaderWithTry(BatchLoader> batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newDataLoaderWithTry(BatchLoader> batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -169,7 +172,7 @@ public static DataLoader newDataLoader(BatchLoaderWithContext * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newDataLoader(BatchLoaderWithContext batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newDataLoader(BatchLoaderWithContext batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -209,7 +212,7 @@ public static DataLoader newDataLoaderWithTry(BatchLoaderWithContex * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newDataLoaderWithTry(BatchLoaderWithContext> batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newDataLoaderWithTry(BatchLoaderWithContext> batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -239,7 +242,7 @@ public static DataLoader newMappedDataLoader(MappedBatchLoader DataLoader newMappedDataLoader(MappedBatchLoader batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newMappedDataLoader(MappedBatchLoader batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -280,7 +283,7 @@ public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoad * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoader> batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoader> batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -310,7 +313,7 @@ public static DataLoader newMappedDataLoader(MappedBatchLoaderWithC * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newMappedDataLoader(MappedBatchLoaderWithContext batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newMappedDataLoader(MappedBatchLoaderWithContext batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -350,7 +353,7 @@ public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoad * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoaderWithContext> batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newMappedDataLoaderWithTry(MappedBatchLoaderWithContext> batchLoadFunction, @Nullable DataLoaderOptions options) { return DataLoaderFactory.mkDataLoader(batchLoadFunction, options); } @@ -373,17 +376,17 @@ public DataLoader(BatchLoader batchLoadFunction) { * @deprecated use {@link DataLoaderFactory} instead */ @Deprecated - public DataLoader(BatchLoader batchLoadFunction, DataLoaderOptions options) { + public DataLoader(BatchLoader batchLoadFunction, @Nullable DataLoaderOptions options) { this((Object) batchLoadFunction, options); } @VisibleForTesting - DataLoader(Object batchLoadFunction, DataLoaderOptions options) { + DataLoader(Object batchLoadFunction, @Nullable DataLoaderOptions options) { this(batchLoadFunction, options, Clock.systemUTC()); } @VisibleForTesting - DataLoader(Object batchLoadFunction, DataLoaderOptions options, Clock clock) { + DataLoader(Object batchLoadFunction, @Nullable DataLoaderOptions options, Clock clock) { DataLoaderOptions loaderOptions = options == null ? new DataLoaderOptions() : options; this.futureCache = determineFutureCache(loaderOptions); this.valueCache = determineValueCache(loaderOptions); diff --git a/src/main/java/org/dataloader/DataLoaderFactory.java b/src/main/java/org/dataloader/DataLoaderFactory.java index a87e4eb..ef1a287 100644 --- a/src/main/java/org/dataloader/DataLoaderFactory.java +++ b/src/main/java/org/dataloader/DataLoaderFactory.java @@ -1,6 +1,7 @@ package org.dataloader; import org.dataloader.annotations.PublicApi; +import org.jspecify.annotations.Nullable; /** * A factory class to create {@link DataLoader}s @@ -155,7 +156,7 @@ public static DataLoader newMappedDataLoader(MappedBatchLoader the value type * @return a new DataLoader */ - public static DataLoader newMappedDataLoader(MappedBatchLoader batchLoadFunction, DataLoaderOptions options) { + public static DataLoader newMappedDataLoader(MappedBatchLoader batchLoadFunction, @Nullable DataLoaderOptions options) { return mkDataLoader(batchLoadFunction, options); } diff --git a/src/main/java/org/dataloader/DispatchResult.java b/src/main/java/org/dataloader/DispatchResult.java index 97711da..7305c78 100644 --- a/src/main/java/org/dataloader/DispatchResult.java +++ b/src/main/java/org/dataloader/DispatchResult.java @@ -1,6 +1,7 @@ package org.dataloader; import org.dataloader.annotations.PublicApi; +import org.jspecify.annotations.NullMarked; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -12,6 +13,7 @@ * @param for two */ @PublicApi +@NullMarked public class DispatchResult { private final CompletableFuture> futureList; private final int keysCount; diff --git a/src/main/java/org/dataloader/MappedBatchLoader.java b/src/main/java/org/dataloader/MappedBatchLoader.java index 5a7a1a6..1ad4c79 100644 --- a/src/main/java/org/dataloader/MappedBatchLoader.java +++ b/src/main/java/org/dataloader/MappedBatchLoader.java @@ -16,6 +16,9 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; + import java.util.Map; import java.util.Set; import java.util.concurrent.CompletionStage; @@ -54,6 +57,8 @@ * @param type parameter indicating the type of values returned * */ +@PublicSpi +@NullMarked public interface MappedBatchLoader { /** diff --git a/src/main/java/org/dataloader/MappedBatchLoaderWithContext.java b/src/main/java/org/dataloader/MappedBatchLoaderWithContext.java index 7438d20..9559260 100644 --- a/src/main/java/org/dataloader/MappedBatchLoaderWithContext.java +++ b/src/main/java/org/dataloader/MappedBatchLoaderWithContext.java @@ -16,6 +16,9 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; + import java.util.Map; import java.util.Set; import java.util.concurrent.CompletionStage; @@ -28,6 +31,8 @@ * See {@link MappedBatchLoader} for more details on the design invariants that you must implement in order to * use this interface. */ +@PublicSpi +@NullMarked public interface MappedBatchLoaderWithContext { /** * Called to batch load the provided keys and return a promise to a map of values. diff --git a/src/main/java/org/dataloader/MappedBatchPublisher.java b/src/main/java/org/dataloader/MappedBatchPublisher.java index 754ee52..493401f 100644 --- a/src/main/java/org/dataloader/MappedBatchPublisher.java +++ b/src/main/java/org/dataloader/MappedBatchPublisher.java @@ -1,5 +1,7 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; import org.reactivestreams.Subscriber; import java.util.Map; @@ -16,6 +18,8 @@ * @param type parameter indicating the type of values returned * @see MappedBatchLoader for the non-reactive version */ +@PublicSpi +@NullMarked public interface MappedBatchPublisher { /** * Called to batch the provided keys into a stream of map entries of keys and values. diff --git a/src/main/java/org/dataloader/MappedBatchPublisherWithContext.java b/src/main/java/org/dataloader/MappedBatchPublisherWithContext.java index 2e94152..7b862ca 100644 --- a/src/main/java/org/dataloader/MappedBatchPublisherWithContext.java +++ b/src/main/java/org/dataloader/MappedBatchPublisherWithContext.java @@ -1,5 +1,7 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; import org.reactivestreams.Subscriber; import java.util.List; @@ -13,6 +15,8 @@ * See {@link MappedBatchPublisher} for more details on the design invariants that you must implement in order to * use this interface. */ +@PublicSpi +@NullMarked public interface MappedBatchPublisherWithContext { /** diff --git a/src/main/java/org/dataloader/ValueCache.java b/src/main/java/org/dataloader/ValueCache.java index a8dabb1..80c8402 100644 --- a/src/main/java/org/dataloader/ValueCache.java +++ b/src/main/java/org/dataloader/ValueCache.java @@ -3,6 +3,7 @@ import org.dataloader.annotations.PublicSpi; import org.dataloader.impl.CompletableFutureKit; import org.dataloader.impl.NoOpValueCache; +import org.jspecify.annotations.NullMarked; import java.util.ArrayList; import java.util.List; @@ -38,6 +39,7 @@ * @author Brad Baker */ @PublicSpi +@NullMarked public interface ValueCache { /** @@ -158,4 +160,4 @@ public Throwable fillInStackTrace() { return this; } } -} \ No newline at end of file +} diff --git a/src/main/java/org/dataloader/ValueCacheOptions.java b/src/main/java/org/dataloader/ValueCacheOptions.java index 7e2f025..b681dda 100644 --- a/src/main/java/org/dataloader/ValueCacheOptions.java +++ b/src/main/java/org/dataloader/ValueCacheOptions.java @@ -1,10 +1,15 @@ package org.dataloader; +import org.dataloader.annotations.PublicSpi; +import org.jspecify.annotations.NullMarked; + /** * Options that control how the {@link ValueCache} is used by {@link DataLoader} * * @author Brad Baker */ +@PublicSpi +@NullMarked public class ValueCacheOptions { private final boolean completeValueAfterCacheSet;