diff --git a/pom.xml b/pom.xml index b780d1e99c..c2f383da90 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-redis - 4.0.0-SNAPSHOT + 4.0.0-GH-3290-SNAPSHOT Spring Data Redis Spring Data module for Redis diff --git a/src/main/java/org/springframework/data/redis/ClusterRedirectException.java b/src/main/java/org/springframework/data/redis/ClusterRedirectException.java index 562347e86a..2c50c5ca57 100644 --- a/src/main/java/org/springframework/data/redis/ClusterRedirectException.java +++ b/src/main/java/org/springframework/data/redis/ClusterRedirectException.java @@ -17,6 +17,7 @@ import java.io.Serial; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataRetrievalFailureException; /** @@ -44,7 +45,7 @@ public class ClusterRedirectException extends DataRetrievalFailureException { * @param targetPort the port on the host. * @param e the root cause from the data access API in use. */ - public ClusterRedirectException(int slot, String targetHost, int targetPort, Throwable e) { + public ClusterRedirectException(int slot, String targetHost, int targetPort, @Nullable Throwable e) { super("Redirect: slot %s to %s:%s.".formatted(slot, targetHost, targetPort), e); diff --git a/src/main/java/org/springframework/data/redis/ClusterStateFailureException.java b/src/main/java/org/springframework/data/redis/ClusterStateFailureException.java index 29543870d6..8b354161aa 100644 --- a/src/main/java/org/springframework/data/redis/ClusterStateFailureException.java +++ b/src/main/java/org/springframework/data/redis/ClusterStateFailureException.java @@ -17,6 +17,7 @@ import java.io.Serial; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessResourceFailureException; /** @@ -38,7 +39,7 @@ public class ClusterStateFailureException extends DataAccessResourceFailureExcep * * @param msg the detail message. */ - public ClusterStateFailureException(String msg) { + public ClusterStateFailureException(@Nullable String msg) { super(msg); } @@ -48,7 +49,7 @@ public ClusterStateFailureException(String msg) { * @param msg the detail message. * @param cause the nested exception. */ - public ClusterStateFailureException(String msg, Throwable cause) { + public ClusterStateFailureException(@Nullable String msg, @Nullable Throwable cause) { super(msg, cause); } diff --git a/src/main/java/org/springframework/data/redis/ExceptionTranslationStrategy.java b/src/main/java/org/springframework/data/redis/ExceptionTranslationStrategy.java index a389a4c814..c255c30392 100644 --- a/src/main/java/org/springframework/data/redis/ExceptionTranslationStrategy.java +++ b/src/main/java/org/springframework/data/redis/ExceptionTranslationStrategy.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; /** * Potentially translates an {@link Exception} into appropriate {@link DataAccessException}. diff --git a/src/main/java/org/springframework/data/redis/PassThroughExceptionTranslationStrategy.java b/src/main/java/org/springframework/data/redis/PassThroughExceptionTranslationStrategy.java index 55da37766b..f8649f6e69 100644 --- a/src/main/java/org/springframework/data/redis/PassThroughExceptionTranslationStrategy.java +++ b/src/main/java/org/springframework/data/redis/PassThroughExceptionTranslationStrategy.java @@ -15,9 +15,9 @@ */ package org.springframework.data.redis; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; /** * {@link PassThroughExceptionTranslationStrategy} returns {@literal null} for unknown {@link Exception}s. @@ -34,9 +34,8 @@ public PassThroughExceptionTranslationStrategy(Converter doGet(connection, name, key, ttl)); } - @Nullable - private byte[] doGet(RedisConnection connection, String name, byte[] key, @Nullable Duration ttl) { + + @SuppressWarnings("NullAway") + private byte @Nullable[] doGet(RedisConnection connection, String name, byte[] key, @Nullable Duration ttl) { byte[] result = shouldExpireWithin(ttl) ? connection.stringCommands().getEx(key, Expiration.from(ttl)) : connection.stringCommands().get(key); @@ -241,6 +242,7 @@ public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) { } + @SuppressWarnings("NullAway") private void doPut(RedisConnection connection, String name, byte[] key, byte[] value, @Nullable Duration ttl) { if (shouldExpireWithin(ttl)) { @@ -265,6 +267,7 @@ public CompletableFuture store(String name, byte[] key, byte[] value, @Nul } @Override + @SuppressWarnings("NullAway") public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) { Assert.notNull(name, "Name must not be null"); @@ -538,6 +541,7 @@ public boolean isSupported() { } @Override + @SuppressWarnings("NullAway") public CompletableFuture retrieve(String name, byte[] key, @Nullable Duration ttl) { return doWithConnection(connection -> { @@ -572,6 +576,7 @@ private Mono doStoreWithLocking(String name, byte[] key, byte[] value, unused -> doUnlock(name, connection)); } + @SuppressWarnings("NullAway") private Mono doStore(byte[] cacheKey, byte[] value, @Nullable Duration ttl, ReactiveRedisConnection connection) { diff --git a/src/main/java/org/springframework/data/redis/cache/FixedDurationTtlFunction.java b/src/main/java/org/springframework/data/redis/cache/FixedDurationTtlFunction.java index 6c456de4c8..d20c4a419d 100644 --- a/src/main/java/org/springframework/data/redis/cache/FixedDurationTtlFunction.java +++ b/src/main/java/org/springframework/data/redis/cache/FixedDurationTtlFunction.java @@ -17,8 +17,8 @@ import java.time.Duration; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.cache.RedisCacheWriter.TtlFunction; -import org.springframework.lang.Nullable; /** * {@link TtlFunction} implementation returning the given, predetermined {@link Duration} used for per cache entry diff --git a/src/main/java/org/springframework/data/redis/cache/NoOpCacheStatisticsCollector.java b/src/main/java/org/springframework/data/redis/cache/NoOpCacheStatisticsCollector.java index 4180ce875d..b76be1cc15 100644 --- a/src/main/java/org/springframework/data/redis/cache/NoOpCacheStatisticsCollector.java +++ b/src/main/java/org/springframework/data/redis/cache/NoOpCacheStatisticsCollector.java @@ -18,7 +18,7 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCache.java b/src/main/java/org/springframework/data/redis/cache/RedisCache.java index 8bf70e0853..5f3e5e7f86 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCache.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCache.java @@ -27,6 +27,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.cache.Cache; import org.springframework.cache.support.AbstractValueAdaptingCache; import org.springframework.cache.support.NullValue; @@ -37,7 +38,6 @@ import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -57,6 +57,7 @@ @SuppressWarnings("unused") public class RedisCache extends AbstractValueAdaptingCache { + @SuppressWarnings("NullAway") static final byte[] BINARY_NULL_VALUE = RedisSerializer.java().serialize(NullValue.INSTANCE); static final String CACHE_RETRIEVAL_UNSUPPORTED_OPERATION_EXCEPTION_MESSAGE = "The Redis driver configured with RedisCache through RedisCacheWriter does not support CompletableFuture-based retrieval"; @@ -146,7 +147,7 @@ public CacheStatistics getStatistics() { @Override @SuppressWarnings("unchecked") - public T get(Object key, Callable valueLoader) { + public @Nullable T get(Object key, Callable valueLoader) { byte[] binaryKey = createAndConvertCacheKey(key); byte[] binaryValue = getCacheWriter().get(getName(), binaryKey, @@ -176,7 +177,7 @@ protected T loadCacheValue(Object key, Callable valueLoader) { } @Override - protected Object lookup(Object key) { + protected @Nullable Object lookup(Object key) { byte[] binaryKey = createAndConvertCacheKey(key); @@ -196,6 +197,7 @@ private Duration getTimeToLive(Object key, @Nullable Object value) { } @Override + @SuppressWarnings("NullAway") public void put(Object key, @Nullable Object value) { Object cacheValue = processAndCheckValue(value); @@ -209,7 +211,8 @@ public void put(Object key, @Nullable Object value) { } @Override - public ValueWrapper putIfAbsent(Object key, @Nullable Object value) { + @SuppressWarnings("NullAway") + public @Nullable ValueWrapper putIfAbsent(Object key, @Nullable Object value) { Object cacheValue = preProcessCacheValue(value); @@ -268,7 +271,7 @@ public CompletableFuture retrieve(Object key) { } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "NullAway"}) public CompletableFuture retrieve(Object key, Supplier> valueLoader) { return retrieve(key).thenCompose(wrapper -> { @@ -291,7 +294,7 @@ public CompletableFuture retrieve(Object key, Supplier retrieveValue(Object key) { .thenApply(this::toValueWrapper); } - @Nullable - private Object nullSafeDeserializedStoreValue(@Nullable byte[] value) { + private @Nullable Object nullSafeDeserializedStoreValue(byte @Nullable[] value) { return value != null ? fromStoreValue(deserializeCacheValue(value)) : null; } diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCacheConfiguration.java b/src/main/java/org/springframework/data/redis/cache/RedisCacheConfiguration.java index b74ebf2d75..bb774e4fd3 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCacheConfiguration.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCacheConfiguration.java @@ -19,6 +19,7 @@ import java.time.Duration; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.springframework.cache.Cache; import org.springframework.cache.interceptor.SimpleKey; import org.springframework.core.convert.ConversionService; @@ -28,7 +29,6 @@ import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java b/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java index 3c9e3c5415..4e65c67b1c 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCacheManager.java @@ -23,11 +23,11 @@ import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -374,7 +374,7 @@ protected RedisCacheWriter getCacheWriter() { } @Override - protected RedisCache getMissingCache(String name) { + protected @Nullable RedisCache getMissingCache(String name) { return isAllowRuntimeCacheCreation() ? createRedisCache(name, getDefaultCacheConfiguration()) : null; } diff --git a/src/main/java/org/springframework/data/redis/cache/RedisCacheWriter.java b/src/main/java/org/springframework/data/redis/cache/RedisCacheWriter.java index e5e3d16b2b..25ec4f0388 100644 --- a/src/main/java/org/springframework/data/redis/cache/RedisCacheWriter.java +++ b/src/main/java/org/springframework/data/redis/cache/RedisCacheWriter.java @@ -19,8 +19,8 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -119,8 +119,8 @@ static RedisCacheWriter lockingRedisCacheWriter(RedisConnectionFactory connectio * @return {@literal null} if key does not exist. * @see #get(String, byte[], Duration) */ - @Nullable - byte[] get(String name, byte[] key); + byte @Nullable[] get(String name, byte[] key); + /** * Get the binary value representation from Redis stored for the given key and set the given {@link Duration TTL @@ -131,8 +131,7 @@ static RedisCacheWriter lockingRedisCacheWriter(RedisConnectionFactory connectio * @param ttl {@link Duration} specifying the {@literal expiration timeout} for the cache entry. * @return {@literal null} if key does not exist or has {@literal expired}. */ - @Nullable - default byte[] get(String name, byte[] key, @Nullable Duration ttl) { + default byte @Nullable[] get(String name, byte[] key, @Nullable Duration ttl) { return get(name, key); } @@ -242,8 +241,7 @@ default CompletableFuture retrieve(String name, byte[] key) { * @param ttl optional expiration time. Can be {@literal null}. * @return {@literal null} if the value has been written, the value stored for the key if it already exists. */ - @Nullable - byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl); + byte @Nullable[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl); /** * Remove the given key from Redis. diff --git a/src/main/java/org/springframework/data/redis/cache/package-info.java b/src/main/java/org/springframework/data/redis/cache/package-info.java index 3b4695da6c..00516a9bb2 100644 --- a/src/main/java/org/springframework/data/redis/cache/package-info.java +++ b/src/main/java/org/springframework/data/redis/cache/package-info.java @@ -3,6 +3,5 @@ * cache * abstraction. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.cache; diff --git a/src/main/java/org/springframework/data/redis/config/package-info.java b/src/main/java/org/springframework/data/redis/config/package-info.java index 41ea5708bd..37bcac4eac 100644 --- a/src/main/java/org/springframework/data/redis/config/package-info.java +++ b/src/main/java/org/springframework/data/redis/config/package-info.java @@ -1,6 +1,5 @@ /** * Namespace and configuration. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.config; diff --git a/src/main/java/org/springframework/data/redis/connection/AbstractRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/AbstractRedisConnection.java index 46a7a12ded..421e356678 100644 --- a/src/main/java/org/springframework/data/redis/connection/AbstractRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/AbstractRedisConnection.java @@ -21,11 +21,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -64,6 +63,7 @@ public boolean hasRedisSentinelConfigured() { return this.sentinelConfiguration != null; } + @SuppressWarnings("NullAway") private RedisNode selectActiveSentinel() { Assert.state(hasRedisSentinelConfigured(), "Sentinel configuration missing"); diff --git a/src/main/java/org/springframework/data/redis/connection/BitFieldSubCommands.java b/src/main/java/org/springframework/data/redis/connection/BitFieldSubCommands.java index b90121f90b..3be6e6cddb 100644 --- a/src/main/java/org/springframework/data/redis/connection/BitFieldSubCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/BitFieldSubCommands.java @@ -21,8 +21,9 @@ import java.util.Iterator; import java.util.List; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldSubCommand; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -573,10 +574,11 @@ public String toString() { /** * @author Christoph Strobl */ + @NullUnmarked public static abstract class AbstractBitFieldSubCommand implements BitFieldSubCommand { - BitFieldType type; - Offset offset; + BitFieldType type; + Offset offset; @Override public BitFieldType getType() { @@ -809,8 +811,7 @@ public long getValue() { * * @return can be {@literal null}. */ - @Nullable - public Overflow getOverflow() { + public @Nullable Overflow getOverflow() { return overflow; } diff --git a/src/main/java/org/springframework/data/redis/connection/ClusterCommandExecutor.java b/src/main/java/org/springframework/data/redis/connection/ClusterCommandExecutor.java index b0d9c1a720..944177d28c 100644 --- a/src/main/java/org/springframework/data/redis/connection/ClusterCommandExecutor.java +++ b/src/main/java/org/springframework/data/redis/connection/ClusterCommandExecutor.java @@ -15,7 +15,19 @@ */ package org.springframework.data.redis.connection; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.TreeMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -24,6 +36,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; @@ -34,7 +47,7 @@ import org.springframework.data.redis.TooManyClusterRedirectionsException; import org.springframework.data.redis.connection.util.ByteArraySet; import org.springframework.data.redis.connection.util.ByteArrayWrapper; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -226,6 +239,7 @@ public MultiNodeResult executeCommandAsyncOnNodes(ClusterCommandCallba return collectResults(futures); } + @SuppressWarnings("NullAway") MultiNodeResult collectResults(Map>> futures) { MultiNodeResult result = new MultiNodeResult<>(); @@ -254,8 +268,7 @@ MultiNodeResult collectResults(Map>> } catch (ExecutionException ex) { entryIterator.remove(); exceptionCollector.addException(nodeExecution, ex.getCause()); - } catch (TimeoutException ignore) { - } catch (InterruptedException ex) { + } catch (TimeoutException ignore) {} catch (InterruptedException ex) { Thread.currentThread().interrupt(); exceptionCollector.addException(nodeExecution, ex); break OUT; @@ -332,8 +345,7 @@ private ClusterTopology getClusterTopology() { return this.topologyProvider.getTopology(); } - @Nullable - private DataAccessException convertToDataAccessException(Exception cause) { + private @Nullable DataAccessException convertToDataAccessException(Exception cause) { return this.exceptionTranslationStrategy.translate(cause); } @@ -413,6 +425,7 @@ RedisClusterNode getNode() { * * @since 2.0.3 */ + @Nullable PositionalKey getPositionalKey() { return this.positionalKey; } @@ -484,8 +497,20 @@ public byte[] getKey() { * * @return can be {@literal null}. */ - @Nullable - public T getValue() { + public @Nullable T getValue() { + return this.value; + } + + /** + * Get the actual value of the command execution or raise an error if {@literal null}. + * + * @return can be {@literal null}. + * @throws IllegalArgumentException in case the value is {@literal null}. + * @since 4.0 + */ + public T getRequiredValue() { + + Assert.notNull(this.value, "Expected non null value, but was null"); return this.value; } @@ -497,8 +522,7 @@ public T getValue() { * @return the mapped value. * @since 2.1 */ - @Nullable - public U mapValue(Function mapper) { + public @Nullable U mapValue(Function mapper) { Assert.notNull(mapper, "Mapper function must not be null"); @@ -601,8 +625,8 @@ public List resultsAsListSortBy(byte[]... keys) { * @param returnValue can be {@literal null}. * @return can be {@literal null}. */ - @Nullable - public T getFirstNonNullNotEmptyOrDefault(@Nullable T returnValue) { + @Contract("!null -> !null") + public @Nullable T getFirstNonNullNotEmptyOrDefault(@Nullable T returnValue) { for (NodeResult nodeResult : nodeResults) { if (nodeResult.getValue() != null) { @@ -805,7 +829,7 @@ public Iterator iterator() { */ private class NodeExceptionCollector { - private final Map exceptions = new HashMap<>(); + private final Map exceptions = new HashMap<>(); /** * @return {@code true} if the collector contains at least one exception. @@ -814,7 +838,7 @@ public boolean hasExceptions() { return !exceptions.isEmpty(); } - public void addException(NodeExecution execution, Throwable throwable) { + public void addException(NodeExecution execution, @Nullable Throwable throwable) { Throwable translated = throwable instanceof Exception e ? convertToDataAccessException(e) : throwable; Throwable resolvedException = translated != null ? translated : throwable; @@ -825,7 +849,7 @@ public void addException(NodeExecution execution, Throwable throwable) { /** * @return the collected exceptions. */ - public List getExceptions() { + public List getExceptions() { return new ArrayList<>(exceptions.values()); } } diff --git a/src/main/java/org/springframework/data/redis/connection/ClusterInfo.java b/src/main/java/org/springframework/data/redis/connection/ClusterInfo.java index 8d6179811c..d5b1fe2679 100644 --- a/src/main/java/org/springframework/data/redis/connection/ClusterInfo.java +++ b/src/main/java/org/springframework/data/redis/connection/ClusterInfo.java @@ -17,8 +17,8 @@ import java.util.Properties; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.types.RedisClientInfo.INFO; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -60,8 +60,7 @@ public ClusterInfo(Properties clusterProperties) { * @see Info#STATE * @return {@literal null} if no entry found for requested {@link Info#STATE}. */ - @Nullable - public String getState() { + public @Nullable String getState() { return get(Info.STATE); } @@ -69,8 +68,7 @@ public String getState() { * @see Info#SLOTS_ASSIGNED * @return {@literal null} if no entry found for requested {@link Info#SLOTS_ASSIGNED}. */ - @Nullable - public Long getSlotsAssigned() { + public @Nullable Long getSlotsAssigned() { return getLongValueOf(Info.SLOTS_ASSIGNED); } @@ -78,8 +76,7 @@ public Long getSlotsAssigned() { * @see Info#SLOTS_OK * @return {@literal null} if no entry found for requested {@link Info#SLOTS_OK}. */ - @Nullable - public Long getSlotsOk() { + public @Nullable Long getSlotsOk() { return getLongValueOf(Info.SLOTS_OK); } @@ -87,8 +84,7 @@ public Long getSlotsOk() { * @see Info#SLOTS_PFAIL * @return {@literal null} if no entry found for requested {@link Info#SLOTS_PFAIL}. */ - @Nullable - public Long getSlotsPfail() { + public @Nullable Long getSlotsPfail() { return getLongValueOf(Info.SLOTS_PFAIL); } @@ -96,8 +92,7 @@ public Long getSlotsPfail() { * @see Info#SLOTS_FAIL * @return {@literal null} if no entry found for requested {@link Info#SLOTS_FAIL}. */ - @Nullable - public Long getSlotsFail() { + public @Nullable Long getSlotsFail() { return getLongValueOf(Info.SLOTS_FAIL); } @@ -105,8 +100,7 @@ public Long getSlotsFail() { * @see Info#KNOWN_NODES * @return {@literal null} if no entry found for requested {@link Info#KNOWN_NODES}. */ - @Nullable - public Long getKnownNodes() { + public @Nullable Long getKnownNodes() { return getLongValueOf(Info.KNOWN_NODES); } @@ -114,8 +108,7 @@ public Long getKnownNodes() { * @see Info#SIZE * @return {@literal null} if no entry found for requested {@link Info#SIZE}. */ - @Nullable - public Long getClusterSize() { + public @Nullable Long getClusterSize() { return getLongValueOf(Info.SIZE); } @@ -123,8 +116,7 @@ public Long getClusterSize() { * @see Info#CURRENT_EPOCH * @return {@literal null} if no entry found for requested {@link Info#CURRENT_EPOCH}. */ - @Nullable - public Long getCurrentEpoch() { + public @Nullable Long getCurrentEpoch() { return getLongValueOf(Info.CURRENT_EPOCH); } @@ -132,8 +124,7 @@ public Long getCurrentEpoch() { * @see Info#MESSAGES_SENT * @return {@literal null} if no entry found for requested {@link Info#MESSAGES_SENT}. */ - @Nullable - public Long getMessagesSent() { + public @Nullable Long getMessagesSent() { return getLongValueOf(Info.MESSAGES_SENT); } @@ -141,8 +132,7 @@ public Long getMessagesSent() { * @see Info#MESSAGES_RECEIVED * @return {@literal null} if no entry found for requested {@link Info#MESSAGES_RECEIVED}. */ - @Nullable - public Long getMessagesReceived() { + public @Nullable Long getMessagesReceived() { return getLongValueOf(Info.MESSAGES_RECEIVED); } @@ -150,8 +140,7 @@ public Long getMessagesReceived() { * @param info must not be null * @return {@literal null} if no entry found for requested {@link INFO}. */ - @Nullable - public String get(Info info) { + public @Nullable String get(Info info) { Assert.notNull(info, "Cannot retrieve cluster information for 'null'"); return get(info.key); @@ -161,15 +150,13 @@ public String get(Info info) { * @param key must not be {@literal null} or {@literal empty}. * @return {@literal null} if no entry found for requested {@code key}. */ - @Nullable - public String get(String key) { + public @Nullable String get(String key) { Assert.hasText(key, "Cannot get cluster information for 'empty' / 'null' key."); return this.clusterProperties.getProperty(key); } - @Nullable - private Long getLongValueOf(Info info) { + private @Nullable Long getLongValueOf(Info info) { String value = get(info); return value == null ? null : Long.valueOf(value); diff --git a/src/main/java/org/springframework/data/redis/connection/ClusterTopology.java b/src/main/java/org/springframework/data/redis/connection/ClusterTopology.java index 42436431f4..d519b93b28 100644 --- a/src/main/java/org/springframework/data/redis/connection/ClusterTopology.java +++ b/src/main/java/org/springframework/data/redis/connection/ClusterTopology.java @@ -20,8 +20,8 @@ import java.util.LinkedHashSet; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.ClusterStateFailureException; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -193,6 +193,7 @@ public RedisClusterNode lookup(String nodeId) { * @return never {@literal null}. * @throws ClusterStateFailureException */ + @SuppressWarnings("NullAway") public RedisClusterNode lookup(RedisClusterNode node) { Assert.notNull(node, "RedisClusterNode must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultMessage.java b/src/main/java/org/springframework/data/redis/connection/DefaultMessage.java index b96a0895f3..51a632f482 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultMessage.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultMessage.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultSortParameters.java b/src/main/java/org/springframework/data/redis/connection/DefaultSortParameters.java index bd50f34ba6..d8a58448cc 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultSortParameters.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultSortParameters.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Default implementation for {@link SortParameters}. @@ -28,7 +28,7 @@ */ public class DefaultSortParameters implements SortParameters { - private @Nullable byte[] byPattern; + private byte @Nullable[] byPattern; private @Nullable Range limit; private final List getPattern = new ArrayList<>(4); private @Nullable Order order; @@ -61,7 +61,7 @@ public DefaultSortParameters(@Nullable Range limit, @Nullable Order order, @Null * @param order * @param alphabetic */ - public DefaultSortParameters(@Nullable byte[] byPattern, @Nullable Range limit, @Nullable byte[][] getPattern, + public DefaultSortParameters(byte @Nullable[] byPattern, @Nullable Range limit, byte @Nullable[][] getPattern, @Nullable Order order, @Nullable Boolean alphabetic) { super(); this.byPattern = byPattern; @@ -71,8 +71,8 @@ public DefaultSortParameters(@Nullable byte[] byPattern, @Nullable Range limit, setGetPattern(getPattern); } - @Nullable - public byte[] getByPattern() { + + public byte @Nullable[] getByPattern() { return byPattern; } @@ -80,7 +80,7 @@ public void setByPattern(byte[] byPattern) { this.byPattern = byPattern; } - public Range getLimit() { + public @Nullable Range getLimit() { return limit; } @@ -92,12 +92,11 @@ public byte[][] getGetPattern() { return getPattern.toArray(new byte[getPattern.size()][]); } - @Nullable - public void addGetPattern(byte[] gPattern) { + public void addGetPattern(byte @Nullable[] gPattern) { getPattern.add(gPattern); } - public void setGetPattern(@Nullable byte[][] gPattern) { + public void setGetPattern(byte @Nullable[][] gPattern) { getPattern.clear(); if (gPattern == null) { @@ -107,8 +106,7 @@ public void setGetPattern(@Nullable byte[][] gPattern) { Collections.addAll(getPattern, gPattern); } - @Nullable - public Order getOrder() { + public @Nullable Order getOrder() { return order; } @@ -116,8 +114,7 @@ public void setOrder(Order order) { this.order = order; } - @Nullable - public Boolean isAlphabetic() { + public @Nullable Boolean isAlphabetic() { return alphabetic; } diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java index c2ea198d8b..50dfab46b9 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java @@ -23,7 +23,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -62,7 +63,6 @@ import org.springframework.data.redis.domain.geo.GeoShape; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -82,6 +82,7 @@ * @author Dennis Neufeld * @author Shyngys Sapraliyev */ +@NullUnmarked @SuppressWarnings({ "ConstantConditions", "deprecation" }) public class DefaultStringRedisConnection implements StringRedisConnection, DecoratedRedisConnection { @@ -103,9 +104,8 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco private Converter>, GeoResults>> byteGeoResultsToStringGeoResults; private Converter byteMapRecordToStringMapRecordConverter = new Converter() { - @Nullable @Override - public StringRecord convert(ByteRecord source) { + public @Nullable StringRecord convert(ByteRecord source) { return StringRecord.of(source.deserialize(serializer)); } }; @@ -129,9 +129,8 @@ public String convert(byte[] source) { private class SerializingConverter implements Converter { - @Nullable @Override - public byte[] convert(String source) { + public byte @Nullable[] convert(String source) { return serializer.serialize(source); } } @@ -392,27 +391,25 @@ public byte[] get(byte[] key) { return convertAndReturn(delegate.get(key), Converters.identityConverter()); } - @Nullable + @Override - public byte[] getDel(byte[] key) { + public byte @Nullable[] getDel(byte[] key) { return convertAndReturn(delegate.getDel(key), Converters.identityConverter()); } - @Nullable @Override - public String getDel(String key) { + public @Nullable String getDel(String key) { return convertAndReturn(delegate.getDel(serialize(key)), bytesToString); } - @Nullable + @Override - public byte[] getEx(byte[] key, Expiration expiration) { + public byte @Nullable[] getEx(byte[] key, Expiration expiration) { return convertAndReturn(delegate.getEx(key, expiration), Converters.identityConverter()); } - @Nullable @Override - public String getEx(String key, Expiration expiration) { + public @Nullable String getEx(String key, Expiration expiration) { return convertAndReturn(delegate.getEx(serialize(key), expiration), bytesToString); } @@ -925,9 +922,8 @@ public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { return convertAndReturn(delegate.bitOp(op, destination, keys), Converters.identityConverter()); } - @Nullable @Override - public Long bitPos(byte[] key, boolean bit, org.springframework.data.domain.Range range) { + public @Nullable Long bitPos(byte[] key, boolean bit, org.springframework.data.domain.Range range) { return convertAndReturn(delegate.bitPos(key, bit, range), Converters.identityConverter()); } @@ -1006,82 +1002,69 @@ public Double zIncrBy(byte[] key, double increment, byte[] value) { return convertAndReturn(delegate.zIncrBy(key, increment, value), Converters.identityConverter()); } - @Nullable @Override - public Set zDiff(byte[]... sets) { + public @Nullable Set zDiff(byte[]... sets) { return convertAndReturn(delegate.zDiff(sets), Converters.identityConverter()); } - @Nullable @Override - public Set zDiffWithScores(byte[]... sets) { + public @Nullable Set zDiffWithScores(byte[]... sets) { return convertAndReturn(delegate.zDiffWithScores(sets), Converters.identityConverter()); } - @Nullable @Override - public Long zDiffStore(byte[] destKey, byte[]... sets) { + public @Nullable Long zDiffStore(byte[] destKey, byte[]... sets) { return convertAndReturn(delegate.zDiffStore(destKey, sets), Converters.identityConverter()); } - @Nullable @Override - public Set zDiff(String... sets) { + public @Nullable Set zDiff(String... sets) { return convertAndReturn(delegate.zDiff(serializeMulti(sets)), byteSetToStringSet); } - @Nullable @Override - public Set zDiffWithScores(String... sets) { + public @Nullable Set zDiffWithScores(String... sets) { return convertAndReturn(delegate.zDiffWithScores(serializeMulti(sets)), tupleToStringTuple); } - @Nullable @Override - public Long zDiffStore(String destKey, String... sets) { + public @Nullable Long zDiffStore(String destKey, String... sets) { return convertAndReturn(delegate.zDiffStore(serialize(destKey), serializeMulti(sets)), Converters.identityConverter()); } - @Nullable @Override - public Set zInter(byte[]... sets) { + public @Nullable Set zInter(byte[]... sets) { return convertAndReturn(delegate.zInter(sets), Converters.identityConverter()); } - @Nullable @Override - public Set zInterWithScores(byte[]... sets) { + public @Nullable Set zInterWithScores(byte[]... sets) { return convertAndReturn(delegate.zInterWithScores(sets), Converters.identityConverter()); } - @Nullable @Override - public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public @Nullable Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { return convertAndReturn(delegate.zInterWithScores(aggregate, weights, sets), Converters.identityConverter()); } - @Nullable @Override - public Set zInter(String... sets) { + public @Nullable Set zInter(String... sets) { return convertAndReturn(delegate.zInter(serializeMulti(sets)), byteSetToStringSet); } - @Nullable @Override - public Set zInterWithScores(String... sets) { + public @Nullable Set zInterWithScores(String... sets) { return convertAndReturn(delegate.zInterWithScores(serializeMulti(sets)), tupleToStringTuple); } - @Nullable @Override - public Set zInterWithScores(Aggregate aggregate, Weights weights, String... sets) { + public @Nullable Set zInterWithScores(Aggregate aggregate, Weights weights, String... sets) { return convertAndReturn(delegate.zInterWithScores(aggregate, weights, serializeMulti(sets)), tupleToStringTuple); } - @Nullable @Override - public Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + public @Nullable Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { return convertAndReturn(delegate.zInterStore(destKey, aggregate, Weights.of(weights), sets), Converters.identityConverter()); } @@ -1249,39 +1232,33 @@ public List zMScore(byte[] key, byte[]... values) { return convertAndReturn(delegate.zMScore(key, values), Converters.identityConverter()); } - @Nullable @Override - public Set zUnion(byte[]... sets) { + public @Nullable Set zUnion(byte[]... sets) { return convertAndReturn(delegate.zUnion(sets), Converters.identityConverter()); } - @Nullable @Override - public Set zUnionWithScores(byte[]... sets) { + public @Nullable Set zUnionWithScores(byte[]... sets) { return convertAndReturn(delegate.zUnionWithScores(sets), Converters.identityConverter()); } - @Nullable @Override - public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public @Nullable Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { return convertAndReturn(delegate.zUnionWithScores(aggregate, weights, sets), Converters.identityConverter()); } - @Nullable @Override - public Set zUnion(String... sets) { + public @Nullable Set zUnion(String... sets) { return convertAndReturn(delegate.zUnion(serializeMulti(sets)), byteSetToStringSet); } - @Nullable @Override - public Set zUnionWithScores(String... sets) { + public @Nullable Set zUnionWithScores(String... sets) { return convertAndReturn(delegate.zUnionWithScores(serializeMulti(sets)), tupleToStringTuple); } - @Nullable @Override - public Set zUnionWithScores(Aggregate aggregate, Weights weights, String... sets) { + public @Nullable Set zUnionWithScores(Aggregate aggregate, Weights weights, String... sets) { return convertAndReturn(delegate.zUnionWithScores(aggregate, weights, serializeMulti(sets)), tupleToStringTuple); } @@ -1290,9 +1267,8 @@ public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, by return convertAndReturn(delegate.zUnionStore(destKey, aggregate, weights, sets), Converters.identityConverter()); } - @Nullable @Override - public Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + public @Nullable Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { return convertAndReturn(delegate.zUnionStore(destKey, aggregate, Weights.of(weights), sets), Converters.identityConverter()); } @@ -1555,52 +1531,45 @@ public Double hIncrBy(String key, String field, double delta) { return hIncrBy(serialize(key), serialize(field), delta); } - @Nullable + @Override - public byte[] hRandField(byte[] key) { + public byte @Nullable[] hRandField(byte[] key) { return convertAndReturn(delegate.hRandField(key), Converters.identityConverter()); } - @Nullable @Override - public Entry hRandFieldWithValues(byte[] key) { + public @Nullable Entry hRandFieldWithValues(byte[] key) { return convertAndReturn(delegate.hRandFieldWithValues(key), Converters.identityConverter()); } - @Nullable @Override - public List hRandField(byte[] key, long count) { + public @Nullable List hRandField(byte[] key, long count) { return convertAndReturn(delegate.hRandField(key, count), Converters.identityConverter()); } - @Nullable @Override - public List> hRandFieldWithValues(byte[] key, long count) { + public @Nullable List> hRandFieldWithValues(byte[] key, long count) { return convertAndReturn(delegate.hRandFieldWithValues(key, count), Converters.identityConverter()); } - @Nullable @Override - public String hRandField(String key) { + public @Nullable String hRandField(String key) { return convertAndReturn(delegate.hRandField(serialize(key)), bytesToString); } - @Nullable @Override - public Entry hRandFieldWithValues(String key) { + public @Nullable Entry hRandFieldWithValues(String key) { return convertAndReturn(delegate.hRandFieldWithValues(serialize(key)), (Converter, Entry>) this::convertEntry); } - @Nullable @Override - public List hRandField(String key, long count) { + public @Nullable List hRandField(String key, long count) { return convertAndReturn(delegate.hRandField(serialize(key), count), byteListToStringList); } - @Nullable @Override - public List> hRandFieldWithValues(String key, long count) { + public @Nullable List> hRandFieldWithValues(String key, long count) { return convertAndReturn(delegate.hRandFieldWithValues(serialize(key), count), new ListConverter<>(this::convertEntry)); } @@ -1945,9 +1914,8 @@ public Long bitOp(BitOperation op, String destination, String... keys) { return bitOp(op, serialize(destination), serializeMulti(keys)); } - @Nullable @Override - public Long bitPos(String key, boolean bit, org.springframework.data.domain.Range range) { + public @Nullable Long bitPos(String key, boolean bit, org.springframework.data.domain.Range range) { return bitPos(serialize(key), bit, range); } @@ -1981,9 +1949,8 @@ public DataType type(String key) { return type(serialize(key)); } - @Nullable @Override - public Long touch(String... keys) { + public @Nullable Long touch(String... keys) { return touch(serializeMulti(keys)); } @@ -2022,75 +1989,63 @@ public Long zLexCount(byte[] key, org.springframework.data.domain.Range return delegate.zLexCount(key, range); } - @Nullable @Override - public Tuple zPopMin(byte[] key) { + public @Nullable Tuple zPopMin(byte[] key) { return delegate.zPopMin(key); } - @Nullable @Override - public StringTuple zPopMin(String key) { + public @Nullable StringTuple zPopMin(String key) { return convertAndReturn(delegate.zPopMin(serialize(key)), tupleConverter); } - @Nullable @Override - public Set zPopMin(byte[] key, long count) { + public @Nullable Set zPopMin(byte[] key, long count) { return delegate.zPopMin(key, count); } - @Nullable @Override - public Set zPopMin(String key, long count) { + public @Nullable Set zPopMin(String key, long count) { return convertAndReturn(delegate.zPopMin(serialize(key), count), tupleToStringTuple); } - @Nullable @Override - public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { + public @Nullable Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { return delegate.bZPopMin(key, timeout, unit); } - @Nullable @Override - public StringTuple bZPopMin(String key, long timeout, TimeUnit unit) { + public @Nullable StringTuple bZPopMin(String key, long timeout, TimeUnit unit) { return convertAndReturn(delegate.bZPopMin(serialize(key), timeout, unit), tupleConverter); } - @Nullable @Override - public Tuple zPopMax(byte[] key) { + public @Nullable Tuple zPopMax(byte[] key) { return delegate.zPopMax(key); } - @Nullable @Override - public StringTuple zPopMax(String key) { + public @Nullable StringTuple zPopMax(String key) { return convertAndReturn(delegate.zPopMax(serialize(key)), tupleConverter); } - @Nullable @Override - public Set zPopMax(byte[] key, long count) { + public @Nullable Set zPopMax(byte[] key, long count) { return delegate.zPopMax(key, count); } - @Nullable @Override - public Set zPopMax(String key, long count) { + public @Nullable Set zPopMax(String key, long count) { return convertAndReturn(delegate.zPopMax(serialize(key), count), tupleToStringTuple); } - @Nullable @Override - public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { + public @Nullable Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { return delegate.bZPopMax(key, timeout, unit); } - @Nullable @Override - public StringTuple bZPopMax(String key, long timeout, TimeUnit unit) { + public @Nullable StringTuple bZPopMax(String key, long timeout, TimeUnit unit) { return convertAndReturn(delegate.bZPopMax(serialize(key), timeout, unit), tupleConverter); } @@ -3135,8 +3090,7 @@ public void setDeserializePipelineAndTxResults(boolean deserializePipelineAndTxR } @SuppressWarnings("unchecked") - @Nullable - private T convertAndReturn(@Nullable Object value, Converter converter) { + private @Nullable T convertAndReturn(@Nullable Object value, Converter converter) { if (isFutureConversion()) { diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringTuple.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringTuple.java index b35522c642..b73a22aa6e 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultStringTuple.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringTuple.java @@ -17,10 +17,10 @@ import java.nio.charset.StandardCharsets; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.StringRedisConnection.StringTuple; import org.springframework.data.redis.connection.zset.DefaultTuple; import org.springframework.data.redis.connection.zset.Tuple; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java index f3be7ab276..b5976bc082 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java @@ -23,6 +23,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; @@ -49,7 +51,6 @@ import org.springframework.data.redis.core.types.RedisClientInfo; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; /** * {@link DefaultedRedisConnection} provides method delegates to {@code Redis*Command} interfaces accessible via @@ -69,6 +70,7 @@ * @since 2.0 */ @Deprecated +@NullUnmarked public interface DefaultedRedisConnection extends RedisCommands, RedisCommandsProvider { // KEY COMMANDS diff --git a/src/main/java/org/springframework/data/redis/connection/FutureResult.java b/src/main/java/org/springframework/data/redis/connection/FutureResult.java index 58da880234..d9b847bbc1 100644 --- a/src/main/java/org/springframework/data/redis/connection/FutureResult.java +++ b/src/main/java/org/springframework/data/redis/connection/FutureResult.java @@ -17,8 +17,8 @@ import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; -import org.springframework.lang.Nullable; /** * The result of an asynchronous operation @@ -95,8 +95,7 @@ public T getResultHolder() { * @return The converted result or {@literal null}. */ @SuppressWarnings("unchecked") - @Nullable - public Object convert(@Nullable Object result) { + public @Nullable Object convert(@Nullable Object result) { if (result == null) { return computeDefaultResult(null); @@ -105,8 +104,7 @@ public Object convert(@Nullable Object result) { return computeDefaultResult(converter.convert(result)); } - @Nullable - private Object computeDefaultResult(@Nullable Object source) { + private @Nullable Object computeDefaultResult(@Nullable Object source) { return source != null ? source : defaultConversionResult.get(); } @@ -134,8 +132,7 @@ public void setStatus(boolean status) { /** * @return The result of the operation. Can be {@literal null}. */ - @Nullable - public abstract Object get(); + public abstract @Nullable Object get(); /** * Indicate whether or not the actual result needs to be {@link #convert(Object) converted} before handing over. diff --git a/src/main/java/org/springframework/data/redis/connection/MessageListener.java b/src/main/java/org/springframework/data/redis/connection/MessageListener.java index 4857b45c6d..73fd726e89 100644 --- a/src/main/java/org/springframework/data/redis/connection/MessageListener.java +++ b/src/main/java/org/springframework/data/redis/connection/MessageListener.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Listener of messages published in Redis. A MessageListener can implement {@link SubscriptionListener} to receive @@ -34,5 +34,5 @@ public interface MessageListener { * @param message message must not be {@literal null}. * @param pattern pattern matching the channel (if specified) - can be {@literal null}. */ - void onMessage(Message message, @Nullable byte[] pattern); + void onMessage(Message message, byte @Nullable[] pattern); } diff --git a/src/main/java/org/springframework/data/redis/connection/NamedNode.java b/src/main/java/org/springframework/data/redis/connection/NamedNode.java index 5ccf100762..65f51ad9de 100644 --- a/src/main/java/org/springframework/data/redis/connection/NamedNode.java +++ b/src/main/java/org/springframework/data/redis/connection/NamedNode.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Christoph Strobl diff --git a/src/main/java/org/springframework/data/redis/connection/PoolException.java b/src/main/java/org/springframework/data/redis/connection/PoolException.java index 1dc6b89cbb..0c6ecb10ae 100644 --- a/src/main/java/org/springframework/data/redis/connection/PoolException.java +++ b/src/main/java/org/springframework/data/redis/connection/PoolException.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.connection; +import org.jspecify.annotations.Nullable; import org.springframework.core.NestedRuntimeException; -import org.springframework.lang.Nullable; /** * Exception thrown when there are issues with a resource pool diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveGeoCommands.java index 80c9fde257..9206f91efc 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveGeoCommands.java @@ -28,6 +28,7 @@ import java.util.Optional; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.domain.Sort.Direction; @@ -43,7 +44,6 @@ import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.Flag; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -183,8 +183,8 @@ default Mono geoAdd(ByteBuffer key, Collection> lo */ class GeoDistCommand extends KeyCommand { - private final ByteBuffer from; - private final ByteBuffer to; + private final @Nullable ByteBuffer from; + private final @Nullable ByteBuffer to; private final Metric metric; private GeoDistCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer from, @Nullable ByteBuffer to, @@ -280,16 +280,14 @@ public GeoDistCommand forKey(ByteBuffer key) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getFrom() { + public @Nullable ByteBuffer getFrom() { return from; } /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getTo() { + public @Nullable ByteBuffer getTo() { return to; } @@ -828,8 +826,7 @@ public Optional getLimit() { /** * @return can be {@literal null}. */ - @Nullable - public Point getPoint() { + public @Nullable Point getPoint() { return point; } @@ -1161,8 +1158,7 @@ public Optional getLimit() { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getMember() { + public @Nullable ByteBuffer getMember() { return member; } @@ -1319,13 +1315,11 @@ public Optional getArgs() { return Optional.ofNullable(args); } - @Nullable - public GeoReference getReference() { + public @Nullable GeoReference getReference() { return reference; } - @Nullable - public GeoShape getShape() { + public @Nullable GeoShape getShape() { return shape; } } @@ -1419,8 +1413,7 @@ public GeoSearchStoreCommand with(GeoSearchStoreCommandArgs args) { return new GeoSearchStoreCommand(getKey(), getDestKey(), getReference(), getShape(), args); } - @Nullable - public ByteBuffer getDestKey() { + public @Nullable ByteBuffer getDestKey() { return destKey; } @@ -1428,13 +1421,11 @@ public Optional getArgs() { return Optional.ofNullable(args); } - @Nullable - public GeoReference getReference() { + public @Nullable GeoReference getReference() { return reference; } - @Nullable - public GeoShape getShape() { + public @Nullable GeoShape getShape() { return shape; } } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java index 385b652f2b..44ca7e8429 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveHashCommands.java @@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse; @@ -40,7 +41,6 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveHyperLogLogCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveHyperLogLogCommands.java index cba1cc8fac..eddf4c29ac 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveHyperLogLogCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveHyperLogLogCommands.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.connection; +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -50,7 +51,7 @@ class PfAddCommand extends KeyCommand { private final List values; - private PfAddCommand(ByteBuffer key, List values) { + private PfAddCommand(@Nullable ByteBuffer key, List values) { super(key); this.values = values; @@ -193,7 +194,7 @@ public List getKeys() { } @Override - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } } @@ -245,7 +246,7 @@ class PfMergeCommand extends KeyCommand { private final List sourceKeys; - private PfMergeCommand(ByteBuffer key, List sourceKeys) { + private PfMergeCommand(@Nullable ByteBuffer key, List sourceKeys) { super(key); this.sourceKeys = sourceKeys; diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveKeyCommands.java index 3354cf9af1..69427921d0 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveKeyCommands.java @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.List; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse; @@ -34,7 +35,6 @@ import org.springframework.data.redis.core.KeyScanOptions; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -59,7 +59,7 @@ class CopyCommand extends KeyCommand { private final boolean replace; private final @Nullable Integer database; - public CopyCommand(ByteBuffer key, @Nullable ByteBuffer target, boolean replace, @Nullable Integer database) { + public CopyCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer target, boolean replace, @Nullable Integer database) { super(key); this.target = target; this.replace = replace; @@ -117,8 +117,7 @@ public CopyCommand database(int database) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getTarget() { + public @Nullable ByteBuffer getTarget() { return target; } @@ -129,8 +128,7 @@ public boolean isReplace() { /** * @return can be {@literal null}. */ - @Nullable - public Integer getDatabase() { + public @Nullable Integer getDatabase() { return database; } @@ -326,7 +324,7 @@ class RenameCommand extends KeyCommand { private @Nullable ByteBuffer newKey; - private RenameCommand(ByteBuffer key, @Nullable ByteBuffer newKey) { + private RenameCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer newKey) { super(key); @@ -363,8 +361,7 @@ public RenameCommand to(ByteBuffer newKey) { * @return can be {@literal null}. * @since 2.5.7 */ - @Nullable - public ByteBuffer getNewKey() { + public @Nullable ByteBuffer getNewKey() { return newKey; } } @@ -600,8 +597,7 @@ public ExpireCommand expire(Duration timeout) { /** * @return can be {@literal null}. */ - @Nullable - public Duration getTimeout() { + public @Nullable Duration getTimeout() { if (expiration.isUnixTimestamp() || expiration.isPersistent()) { return null; @@ -714,11 +710,11 @@ class ExpireAtCommand extends KeyCommand { private @Nullable Instant expireAt; private final ExpirationOptions options; - private ExpireAtCommand(ByteBuffer key, Instant expireAt) { + private ExpireAtCommand(@Nullable ByteBuffer key, @Nullable Instant expireAt) { this(key, expireAt, ExpirationOptions.none()); } - private ExpireAtCommand(@Nullable ByteBuffer key, Instant expireAt, ExpirationOptions options) { + private ExpireAtCommand(@Nullable ByteBuffer key, @Nullable Instant expireAt, ExpirationOptions options) { super(key); @@ -764,8 +760,7 @@ public ExpireAtCommand withOptions(ExpirationOptions options) { /** * @return can be {@literal null}. */ - @Nullable - public Instant getExpireAt() { + public @Nullable Instant getExpireAt() { return expireAt; } @@ -906,7 +901,7 @@ class MoveCommand extends KeyCommand { private @Nullable Integer database; - private MoveCommand(ByteBuffer key, @Nullable Integer database) { + private MoveCommand(@Nullable ByteBuffer key, @Nullable Integer database) { super(key); @@ -940,8 +935,7 @@ public MoveCommand timeout(int database) { /** * @return can be {@literal null}. */ - @Nullable - public Integer getDatabase() { + public @Nullable Integer getDatabase() { return database; } } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveListCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveListCommands.java index d92a99a270..5cf150840d 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveListCommands.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse; import org.springframework.data.redis.connection.ReactiveRedisConnection.ByteBufferResponse; @@ -33,7 +34,6 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse; import org.springframework.data.redis.connection.ReactiveRedisConnection.RangeCommand; import org.springframework.data.redis.connection.RedisListCommands.Position; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -399,18 +399,15 @@ public LPosCommand rank(Integer rank) { return new LPosCommand(getKey(), element, count, rank); } - @Nullable - public Integer getCount() { + public @Nullable Integer getCount() { return count; } - @Nullable - public Integer getRank() { + public @Nullable Integer getRank() { return rank; } - @Nullable - public ByteBuffer getElement() { + public @Nullable ByteBuffer getElement() { return element; } } @@ -608,16 +605,14 @@ public ByteBuffer getValue() { /** * @return can be {@literal null}. */ - @Nullable - public Position getPosition() { + public @Nullable Position getPosition() { return position; } /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getPivot() { + public @Nullable ByteBuffer getPivot() { return pivot; } } @@ -723,18 +718,15 @@ public BLMoveCommand timeout(Duration timeout) { return new BLMoveCommand(getKey(), destinationKey, from, to, timeout); } - @Nullable - public ByteBuffer getDestinationKey() { + public @Nullable ByteBuffer getDestinationKey() { return destinationKey; } - @Nullable - public Direction getFrom() { + public @Nullable Direction getFrom() { return from; } - @Nullable - public Direction getTo() { + public @Nullable Direction getTo() { return to; } } @@ -756,8 +748,7 @@ private BLMoveCommand(@Nullable ByteBuffer sourceKey, @Nullable ByteBuffer desti this.timeout = timeout; } - @Nullable - public Duration getTimeout() { + public @Nullable Duration getTimeout() { return timeout; } } @@ -897,8 +888,7 @@ public LSetCommand forKey(ByteBuffer key) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return value; } @@ -1020,8 +1010,7 @@ public Long getCount() { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return value; } } @@ -1288,7 +1277,7 @@ public BPopCommand blockingFor(Duration timeout) { } @Override - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -1327,11 +1316,11 @@ public PopResult(List result) { this.result = result; } - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return ObjectUtils.isEmpty(result) ? null : result.get(0); } - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return ObjectUtils.isEmpty(result) ? null : result.get(1); } @@ -1407,7 +1396,7 @@ class RPopLPushCommand extends KeyCommand { private final @Nullable ByteBuffer destination; - private RPopLPushCommand(ByteBuffer key, @Nullable ByteBuffer destination) { + private RPopLPushCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer destination) { super(key); this.destination = destination; @@ -1443,8 +1432,7 @@ public RPopLPushCommand to(ByteBuffer destinationKey) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getDestination() { + public @Nullable ByteBuffer getDestination() { return destination; } } @@ -1488,7 +1476,7 @@ class BRPopLPushCommand extends KeyCommand { private final @Nullable ByteBuffer destination; private final Duration timeout; - private BRPopLPushCommand(ByteBuffer key, @Nullable ByteBuffer destination, Duration timeout) { + private BRPopLPushCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer destination, Duration timeout) { super(key); @@ -1539,8 +1527,7 @@ public BRPopLPushCommand blockingFor(Duration timeout) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getDestination() { + public @Nullable ByteBuffer getDestination() { return destination; } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java index 31f80cc460..170ac80745 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveNumberCommands.java @@ -20,10 +20,10 @@ import java.nio.ByteBuffer; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand; import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -68,7 +68,7 @@ class IncrByCommand extends KeyCommand { private @Nullable T value; - private IncrByCommand(ByteBuffer key, @Nullable T value) { + private IncrByCommand(@Nullable ByteBuffer key, @Nullable T value) { super(key); this.value = value; @@ -104,8 +104,7 @@ public IncrByCommand by(T value) { /** * @return can be {@literal null}. */ - @Nullable - public T getValue() { + public @Nullable T getValue() { return value; } } @@ -148,7 +147,7 @@ class DecrByCommand extends KeyCommand { private @Nullable T value; - private DecrByCommand(ByteBuffer key, @Nullable T value) { + private DecrByCommand(@Nullable ByteBuffer key, @Nullable T value) { super(key); this.value = value; } @@ -183,8 +182,7 @@ public DecrByCommand by(T value) { /** * @return can be {@literal null}. */ - @Nullable - public T getValue() { + public @Nullable T getValue() { return value; } } @@ -298,8 +296,7 @@ public HIncrByCommand forKey(ByteBuffer key) { /** * @return can be {@literal null}. */ - @Nullable - public T getValue() { + public @Nullable T getValue() { return value; } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnection.java index 5dfb6d9db8..f5cb48452e 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveRedisConnection.java @@ -21,10 +21,10 @@ import java.nio.ByteBuffer; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.domain.Range.Bound; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -205,7 +205,7 @@ public KeyCommand(@Nullable ByteBuffer key) { } @Override - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return key; } } @@ -273,7 +273,7 @@ class RangeCommand extends KeyCommand { * @param key must not be {@literal null}. * @param range must not be {@literal null}. */ - private RangeCommand(ByteBuffer key, Range range) { + private RangeCommand(@Nullable ByteBuffer key, Range range) { super(key); this.range = range; @@ -360,8 +360,7 @@ public I getInput() { return this.input; } - @Nullable - public O getOutput() { + public @Nullable O getOutput() { return this.output; } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java index 76911fd441..9fe40b8eee 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveSetCommands.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse; import org.springframework.data.redis.connection.ReactiveRedisConnection.ByteBufferResponse; @@ -35,7 +36,6 @@ import org.springframework.data.redis.connection.ReactiveRedisConnection.MultiValueResponse; import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -415,8 +415,7 @@ public SMoveCommand to(ByteBuffer destination) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getDestination() { + public @Nullable ByteBuffer getDestination() { return destination; } @@ -663,8 +662,7 @@ public static SInterCommand keys(Collection keys) { } @Override - @Nullable - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -805,8 +803,7 @@ public static SUnionCommand keys(Collection keys) { } @Override - @Nullable - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -947,8 +944,7 @@ public static SDiffCommand keys(Collection keys) { } @Override - @Nullable - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveStreamCommands.java index 2860dc691c..2af6cb326a 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveStreamCommands.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse; @@ -47,7 +48,6 @@ import org.springframework.data.redis.connection.stream.StreamOffset; import org.springframework.data.redis.connection.stream.StreamReadOptions; import org.springframework.data.redis.connection.stream.StreamRecords; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -137,8 +137,7 @@ public AcknowledgeCommand inGroup(String group) { return new AcknowledgeCommand(getKey(), group, getRecordIds()); } - @Nullable - public String getGroup() { + public @Nullable String getGroup() { return group; } @@ -327,8 +326,7 @@ public boolean isNoMkStream() { * @return can be {@literal null}. * @since 2.3 */ - @Nullable - public Long getMaxlen() { + public @Nullable Long getMaxlen() { return maxlen; } @@ -352,8 +350,7 @@ public boolean isApproximateTrimming() { * @return the minimum record Id to retain during trimming. * @since 2.7 */ - @Nullable - public RecordId getMinId() { + public @Nullable RecordId getMinId() { return minId; } @@ -405,6 +402,7 @@ default Mono xAdd(ByteBufferRecord record) { * @see Redis Documentation: XADD * @since 3.4 */ + @SuppressWarnings("NullAway") default Mono xAdd(ByteBufferRecord record, XAddOptions xAddOptions) { Assert.notNull(record, "Record must not be null"); @@ -709,7 +707,6 @@ Flux> xPendingSum * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable default Mono xPending(ByteBuffer key, Consumer consumer) { return xPending(key, consumer.getGroup(), consumer.getName()); } @@ -724,7 +721,6 @@ default Mono xPending(ByteBuffer key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable default Mono xPending(ByteBuffer key, String groupName, String consumerName) { return xPending(Mono.just(PendingRecordsCommand.pending(key, groupName).consumer(consumerName))).next() .map(CommandResponse::getOutput); @@ -807,7 +803,7 @@ class PendingRecordsCommand extends KeyCommand { private final Range range; private final @Nullable Long count; - private PendingRecordsCommand(ByteBuffer key, String groupName, @Nullable String consumerName, Range range, + private PendingRecordsCommand(@Nullable ByteBuffer key, String groupName, @Nullable String consumerName, Range range, @Nullable Long count) { super(key); @@ -861,8 +857,7 @@ public String getGroupName() { /** * @return can be {@literal null}. */ - @Nullable - public String getConsumerName() { + public @Nullable String getConsumerName() { return consumerName; } @@ -876,8 +871,7 @@ public Range getRange() { /** * @return can be {@literal null}. */ - @Nullable - public Long getCount() { + public @Nullable Long getCount() { return count; } @@ -914,7 +908,7 @@ class RangeCommand extends KeyCommand { * @param range must not be {@literal null}. * @param limit must not be {@literal null}. */ - private RangeCommand(ByteBuffer key, Range range, Limit limit) { + private RangeCommand(@Nullable ByteBuffer key, Range range, Limit limit) { super(key); this.range = range; @@ -1104,13 +1098,11 @@ public List> getStreamOffsets() { return streamOffsets; } - @Nullable - public StreamReadOptions getReadOptions() { + public @Nullable StreamReadOptions getReadOptions() { return readOptions; } - @Nullable - public Consumer getConsumer() { + public @Nullable Consumer getConsumer() { return consumer; } } @@ -1161,7 +1153,7 @@ class XInfoCommand extends KeyCommand { private final @Nullable String groupName; - private XInfoCommand(ByteBuffer key, @Nullable String groupName) { + private XInfoCommand(@Nullable ByteBuffer key, @Nullable String groupName) { super(key); this.groupName = groupName; @@ -1178,8 +1170,7 @@ public XInfoCommand consumersIn(String groupName) { return new XInfoCommand(getKey(), groupName); } - @Nullable - public String getGroupName() { + public @Nullable String getGroupName() { return groupName; } } @@ -1308,18 +1299,15 @@ public boolean isMkStream() { return this.mkStream; } - @Nullable - public ReadOffset getReadOffset() { + public @Nullable ReadOffset getReadOffset() { return this.offset; } - @Nullable - public String getGroupName() { + public @Nullable String getGroupName() { return groupName; } - @Nullable - public String getConsumerName() { + public @Nullable String getConsumerName() { return consumerName; } @@ -1369,7 +1357,6 @@ default Mono xGroupCreate(ByteBuffer key, String groupName, ReadOffset r * @param consumerName the name of the consumer to remove from the group. * @return the {@link Mono} emitting {@literal ok} if successful. */ - @Nullable default Mono xGroupDelConsumer(ByteBuffer key, String groupName, String consumerName) { return xGroupDelConsumer(key, Consumer.from(groupName, consumerName)); } @@ -1392,7 +1379,6 @@ default Mono xGroupDelConsumer(ByteBuffer key, Consumer consumer) { * @param groupName name of the consumer group. * @return the {@link Mono} emitting {@literal ok} if successful. */ - @Nullable default Mono xGroupDestroy(ByteBuffer key, String groupName) { return xGroup(GroupCommand.destroyGroup(groupName).forStream(key)); } @@ -1497,7 +1483,7 @@ class TrimCommand extends KeyCommand { private @Nullable Long count; private boolean approximateTrimming; - private TrimCommand(ByteBuffer key, @Nullable Long count, boolean approximateTrimming) { + private TrimCommand(@Nullable ByteBuffer key, @Nullable Long count, boolean approximateTrimming) { super(key); this.count = count; this.approximateTrimming = approximateTrimming; @@ -1551,8 +1537,7 @@ public TrimCommand approximate(boolean approximateTrimming) { /** * @return can be {@literal null}. */ - @Nullable - public Long getCount() { + public @Nullable Long getCount() { return count; } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveStringCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveStringCommands.java index 3c1bfc8eea..19e512126a 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveStringCommands.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.ReactiveRedisConnection.BooleanResponse; @@ -39,7 +40,6 @@ import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.data.redis.connection.RedisStringCommands.SetOption; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -61,10 +61,10 @@ public interface ReactiveStringCommands { class SetCommand extends KeyCommand { private @Nullable ByteBuffer value; - private Expiration expiration; - private SetOption option; + private @Nullable Expiration expiration; + private @Nullable SetOption option; - private SetCommand(ByteBuffer key, @Nullable ByteBuffer value, @Nullable Expiration expiration, + private SetCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer value, @Nullable Expiration expiration, @Nullable SetOption option) { super(key); @@ -129,8 +129,7 @@ public SetCommand withSetOption(SetOption option) { /** * @return */ - @Nullable - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return value; } @@ -208,7 +207,6 @@ default Mono set(ByteBuffer key, ByteBuffer value, Expiration expiratio * @see Redis Documentation: SET * @since 3.5 */ - @Nullable default Mono setGet(ByteBuffer key, ByteBuffer value, Expiration expiration, SetOption option) { Assert.notNull(key, "Key must not be null"); @@ -505,8 +503,7 @@ private MSetCommand(Map keyValuePairs) { } @Override - @Nullable - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -589,7 +586,7 @@ class AppendCommand extends KeyCommand { private @Nullable ByteBuffer value; - private AppendCommand(ByteBuffer key, @Nullable ByteBuffer value) { + private AppendCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer value) { super(key); this.value = value; @@ -625,8 +622,7 @@ public AppendCommand append(ByteBuffer value) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return value; } } @@ -694,7 +690,7 @@ class SetRangeCommand extends KeyCommand { private @Nullable ByteBuffer value; private @Nullable Long offset; - private SetRangeCommand(ByteBuffer key, @Nullable ByteBuffer value, @Nullable Long offset) { + private SetRangeCommand(@Nullable ByteBuffer key, @Nullable ByteBuffer value, @Nullable Long offset) { super(key); this.value = value; @@ -740,16 +736,14 @@ public SetRangeCommand atPosition(long index) { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getValue() { + public @Nullable ByteBuffer getValue() { return value; } /** * @return can be {@literal null}. */ - @Nullable - public Long getOffset() { + public @Nullable Long getOffset() { return offset; } } @@ -792,7 +786,7 @@ class GetBitCommand extends KeyCommand { private @Nullable Long offset; - private GetBitCommand(ByteBuffer key, @Nullable Long offset) { + private GetBitCommand(@Nullable ByteBuffer key, @Nullable Long offset) { super(key); @@ -825,8 +819,7 @@ public GetBitCommand atOffset(long offset) { /** * @return can be {@literal null}. */ - @Nullable - public Long getOffset() { + public @Nullable Long getOffset() { return offset; } } @@ -866,7 +859,7 @@ class SetBitCommand extends KeyCommand { private @Nullable Long offset; private boolean value; - private SetBitCommand(ByteBuffer key, Long offset, boolean value) { + private SetBitCommand(@Nullable ByteBuffer key, @Nullable Long offset, boolean value) { super(key); @@ -910,8 +903,7 @@ public SetBitCommand to(boolean bit) { /** * @return can be {@literal null}. */ - @Nullable - public Long getOffset() { + public @Nullable Long getOffset() { return offset; } @@ -957,7 +949,7 @@ class BitCountCommand extends KeyCommand { private Range range; - private BitCountCommand(ByteBuffer key, Range range) { + private BitCountCommand(@Nullable ByteBuffer key, Range range) { super(key); @@ -1052,7 +1044,7 @@ class BitFieldCommand extends KeyCommand { private @Nullable BitFieldSubCommands subcommands; - private BitFieldCommand(ByteBuffer key, @Nullable BitFieldSubCommands subcommands) { + private BitFieldCommand(@Nullable ByteBuffer key, @Nullable BitFieldSubCommands subcommands) { super(key); @@ -1086,7 +1078,7 @@ public BitFieldCommand commands(BitFieldSubCommands commands) { return new BitFieldCommand(getKey(), commands); } - public BitFieldSubCommands getSubCommands() { + public @Nullable BitFieldSubCommands getSubCommands() { return subcommands; } } @@ -1198,8 +1190,7 @@ public List getKeys() { /** * @return can be {@literal null}. */ - @Nullable - public ByteBuffer getDestinationKey() { + public @Nullable ByteBuffer getDestinationKey() { return destinationKey; } } diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveSubscription.java b/src/main/java/org/springframework/data/redis/connection/ReactiveSubscription.java index 153d139e8f..9d2b37f024 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveSubscription.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveSubscription.java @@ -15,13 +15,13 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/ReactiveZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/ReactiveZSetCommands.java index c4037e2c55..d96b283314 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReactiveZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/ReactiveZSetCommands.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.domain.Range; import org.springframework.data.domain.Sort.Direction; @@ -42,7 +43,6 @@ import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -264,6 +264,7 @@ public boolean isReturnTotalChanged() { * @return * @see Redis Documentation: ZADD */ + @SuppressWarnings("NullAway") default Mono zAdd(ByteBuffer key, Double score, ByteBuffer value) { Assert.notNull(key, "Key must not be null"); @@ -282,6 +283,7 @@ default Mono zAdd(ByteBuffer key, Double score, ByteBuffer value) { * @return * @see Redis Documentation: ZADD */ + @SuppressWarnings("NullAway") default Mono zAdd(ByteBuffer key, Collection tuples) { Assert.notNull(key, "Key must not be null"); @@ -473,8 +475,7 @@ public ByteBuffer getValue() { /** * @return can be {@literal null}. */ - @Nullable - public Number getIncrement() { + public @Nullable Number getIncrement() { return increment; } } @@ -942,7 +943,7 @@ default Flux zRevRangeWithScores(ByteBuffer key, Range range) { */ class ZRangeStoreCommand extends KeyCommand { - private final ByteBuffer destKey; + private final @Nullable ByteBuffer destKey; private final RangeMode rangeMode; private final Range range; private final Direction direction; @@ -1054,7 +1055,7 @@ public ZRangeStoreCommand limit(Limit limit) { return new ZRangeStoreCommand(getKey(), getDestKey(), rangeMode, range, direction, limit); } - public ByteBuffer getDestKey() { + public @Nullable ByteBuffer getDestKey() { return destKey; } @@ -1832,13 +1833,11 @@ public PopDirection getDirection() { return direction; } - @Nullable - public Long getTimeout() { + public @Nullable Long getTimeout() { return timeout; } - @Nullable - public TimeUnit getTimeUnit() { + public @Nullable TimeUnit getTimeUnit() { return timeUnit; } @@ -2161,7 +2160,7 @@ class ZRemRangeByRankCommand extends KeyCommand { private final Range range; - private ZRemRangeByRankCommand(ByteBuffer key, Range range) { + private ZRemRangeByRankCommand(@Nullable ByteBuffer key, Range range) { super(key); this.range = range; } @@ -2404,8 +2403,7 @@ public static ZDiffCommand sets(Collection keys) { } @Override - @Nullable - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -2610,9 +2608,8 @@ public ZAggregateCommand aggregateUsing(@Nullable Aggregate aggregateFunction) { return new ZAggregateCommand(sourceKeys, weights, aggregateFunction); } - @Nullable @Override - public ByteBuffer getKey() { + public @Nullable ByteBuffer getKey() { return null; } @@ -2865,7 +2862,7 @@ Flux>> zInterWithScores( */ class ZInterStoreCommand extends ZAggregateStoreCommand { - private ZInterStoreCommand(ByteBuffer key, List sourceKeys, List weights, + private ZInterStoreCommand(@Nullable ByteBuffer key, List sourceKeys, List weights, @Nullable Aggregate aggregate) { super(key, sourceKeys, weights, aggregate); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterCommands.java index 018a78b6cb..24c2ddab03 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterCommands.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; /** @@ -30,6 +32,7 @@ * @author Mark Paluch * @since 1.7 */ +@NullUnmarked public interface RedisClusterCommands { /** @@ -38,7 +41,7 @@ public interface RedisClusterCommands { * @return never {@literal null}. * @see Redis Documentation: CLUSTER NODES */ - Iterable clusterGetNodes(); + Iterable<@NonNull RedisClusterNode> clusterGetNodes(); /** * Retrieve information about connected replicas for given master node. @@ -47,7 +50,7 @@ public interface RedisClusterCommands { * @return never {@literal null}. * @see Redis Documentation: CLUSTER REPLICAS */ - Collection clusterGetReplicas(RedisClusterNode master); + Collection<@NonNull RedisClusterNode> clusterGetReplicas(@NonNull RedisClusterNode master); /** * Retrieve information about masters and their connected replicas. @@ -55,7 +58,7 @@ public interface RedisClusterCommands { * @return never {@literal null}. * @see Redis Documentation: CLUSTER REPLICAS */ - Map> clusterGetMasterReplicaMap(); + Map<@NonNull RedisClusterNode, @NonNull Collection<@NonNull RedisClusterNode>> clusterGetMasterReplicaMap(); /** * Find the slot for a given {@code key}. @@ -64,7 +67,7 @@ public interface RedisClusterCommands { * @return * @see Redis Documentation: CLUSTER KEYSLOT */ - Integer clusterGetSlotForKey(byte[] key); + Integer clusterGetSlotForKey(byte @NonNull [] key); /** * Find the {@link RedisClusterNode} serving given {@literal slot}. @@ -80,7 +83,7 @@ public interface RedisClusterCommands { * @param key must not be {@literal null}. * @return */ - RedisClusterNode clusterGetNodeForKey(byte[] key); + RedisClusterNode clusterGetNodeForKey(byte @NonNull [] key); /** * Get cluster information. @@ -97,7 +100,7 @@ public interface RedisClusterCommands { * @param slots * @see Redis Documentation: CLUSTER ADDSLOTS */ - void clusterAddSlots(RedisClusterNode node, int... slots); + void clusterAddSlots(@NonNull RedisClusterNode node, int @NonNull... slots); /** * Assign {@link SlotRange#getSlotsArray()} to given {@link RedisClusterNode}. @@ -106,7 +109,7 @@ public interface RedisClusterCommands { * @param range must not be {@literal null}. * @see Redis Documentation: CLUSTER ADDSLOTS */ - void clusterAddSlots(RedisClusterNode node, SlotRange range); + void clusterAddSlots(@NonNull RedisClusterNode node, @NonNull SlotRange range); /** * Count the number of keys assigned to one {@literal slot}. @@ -124,7 +127,7 @@ public interface RedisClusterCommands { * @param slots * @see Redis Documentation: CLUSTER DELSLOTS */ - void clusterDeleteSlots(RedisClusterNode node, int... slots); + void clusterDeleteSlots( @NonNull RedisClusterNode node, int @NonNull ... slots); /** * Removes {@link SlotRange#getSlotsArray()} from given {@link RedisClusterNode}. @@ -133,7 +136,7 @@ public interface RedisClusterCommands { * @param range must not be {@literal null}. * @see Redis Documentation: CLUSTER DELSLOTS */ - void clusterDeleteSlotsInRange(RedisClusterNode node, SlotRange range); + void clusterDeleteSlotsInRange(@NonNull RedisClusterNode node, @NonNull SlotRange range); /** * Remove given {@literal node} from cluster. @@ -141,7 +144,7 @@ public interface RedisClusterCommands { * @param node must not be {@literal null}. * @see Redis Documentation: CLUSTER FORGET */ - void clusterForget(RedisClusterNode node); + void clusterForget(@NonNull RedisClusterNode node); /** * Add given {@literal node} to cluster. @@ -150,7 +153,7 @@ public interface RedisClusterCommands { * not be {@literal null}. * @see Redis Documentation: CLUSTER MEET */ - void clusterMeet(RedisClusterNode node); + void clusterMeet(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -158,7 +161,7 @@ public interface RedisClusterCommands { * @param mode must not be{@literal null}. * @see Redis Documentation: CLUSTER SETSLOT */ - void clusterSetSlot(RedisClusterNode node, int slot, AddSlots mode); + void clusterSetSlot(@NonNull RedisClusterNode node, int slot, @NonNull AddSlots mode); /** * Get {@literal keys} served by slot. @@ -168,7 +171,7 @@ public interface RedisClusterCommands { * @return * @see Redis Documentation: CLUSTER GETKEYSINSLOT */ - List clusterGetKeysInSlot(int slot, Integer count); + List clusterGetKeysInSlot(int slot, @NonNull Integer count); /** * Assign a {@literal replica} to given {@literal master}. @@ -177,7 +180,7 @@ public interface RedisClusterCommands { * @param replica must not be {@literal null}. * @see Redis Documentation: CLUSTER REPLICATE */ - void clusterReplicate(RedisClusterNode master, RedisClusterNode replica); + void clusterReplicate(@NonNull RedisClusterNode master, @NonNull RedisClusterNode replica); enum AddSlots { MIGRATING, IMPORTING, STABLE, NODE diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterConfiguration.java index 8960d32ae1..a0554a0e6e 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterConfiguration.java @@ -22,10 +22,10 @@ import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.data.redis.connection.RedisConfiguration.ClusterConfiguration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; @@ -194,7 +194,7 @@ public void setMaxRedirects(int maxRedirects) { } @Override - public Integer getMaxRedirects() { + public @Nullable Integer getMaxRedirects() { return maxRedirects != null && maxRedirects > Integer.MIN_VALUE ? maxRedirects : null; } @@ -203,9 +203,8 @@ public void setUsername(@Nullable String username) { this.username = username; } - @Nullable @Override - public String getUsername() { + public @Nullable String getUsername() { return this.username; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterConnection.java index 585780ecb1..09db27c9d7 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterConnection.java @@ -18,9 +18,10 @@ import java.util.Collection; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -36,6 +37,7 @@ * @author Mark Paluch * @since 1.7 */ +@NullUnmarked public interface RedisClusterConnection extends RedisConnection, DefaultedRedisClusterConnection, RedisClusterCommandsProvider { @@ -44,8 +46,7 @@ public interface RedisClusterConnection * @return {@literal null} when used in pipeline / transaction. * @see RedisConnectionCommands#ping() */ - @Nullable - String ping(RedisClusterNode node); + String ping(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -53,8 +54,7 @@ public interface RedisClusterConnection * @return {@literal null} when used in pipeline / transaction. * @see RedisKeyCommands#keys(byte[]) */ - @Nullable - Set keys(RedisClusterNode node, byte[] pattern); + Set keys(@NonNull RedisClusterNode node, byte @NonNull [] pattern); /** * Use a {@link Cursor} to iterate over keys. @@ -65,15 +65,14 @@ public interface RedisClusterConnection * @since 2.1 * @see Redis Documentation: SCAN */ - Cursor scan(RedisClusterNode node, ScanOptions options); + Cursor scan(@NonNull RedisClusterNode node, @NonNull ScanOptions options); /** * @param node must not be {@literal null}. * @return {@literal null} when no keys stored at node or when used in pipeline / transaction. * @see RedisKeyCommands#randomKey() */ - @Nullable - byte[] randomKey(RedisClusterNode node); + byte[] randomKey(@NonNull RedisClusterNode node); /** * Execute the given command for the {@code key} provided potentially appending args.
@@ -93,8 +92,7 @@ public interface RedisClusterConnection * @return command result as delivered by the underlying Redis driver. Can be {@literal null}. * @since 2.1 */ - @Nullable - default T execute(String command, byte[] key, Collection args) { + default T execute(@NonNull String command, byte @NonNull [] key, @NonNull Collection args) { Assert.notNull(command, "Command must not be null"); Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java index 7a6443d484..1ea2f6a02b 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java @@ -22,7 +22,7 @@ import java.util.LinkedHashSet; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -132,8 +132,7 @@ public boolean servesSlot(int slot) { /** * @return can be {@literal null} */ - @Nullable - public LinkState getLinkState() { + public @Nullable LinkState getLinkState() { return this.linkState; } @@ -216,8 +215,8 @@ public SlotRange(BitSet range) { } /** - * Determines whether this {@link SlotRange} contains the given {@link Integer slot}, which implies - * this cluster nodes manages the slot holding data stored in Redis. + * Determines whether this {@link SlotRange} contains the given {@link Integer slot}, which implies this cluster + * nodes manages the slot holding data stored in Redis. * * @param slot {@link Integer slot} to evaluate. * @return true when slot is part of the range. @@ -286,14 +285,8 @@ public enum LinkState { */ public enum Flag { - MYSELF("myself"), - MASTER("master"), - REPLICA("slave"), - FAIL("fail"), - PFAIL("fail?"), - HANDSHAKE("handshake"), - NOADDR("noaddr"), - NOFLAGS("noflags"); + MYSELF("myself"), MASTER("master"), REPLICA("slave"), FAIL("fail"), PFAIL("fail?"), HANDSHAKE("handshake"), NOADDR( + "noaddr"), NOFLAGS("noflags"); private String raw; @@ -388,12 +381,13 @@ public RedisClusterNodeBuilder linkState(LinkState linkState) { } @Override + @SuppressWarnings("NullAway") public RedisClusterNode build() { RedisNode base = super.build(); RedisClusterNode node; - if (base.host != null) { + if (base.getHost() != null) { node = new RedisClusterNode(base.getHost(), base.getPort(), slotRange); } else { node = new RedisClusterNode(slotRange); @@ -402,7 +396,7 @@ public RedisClusterNode build() { node.type = base.type; node.masterId = base.masterId; node.name = base.name; - node.flags = flags; + node.flags = flags != null ? flags : Collections.emptySet(); node.linkState = linkState; return node; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterServerCommands.java index 1bcac4c1f7..8b09e8eeee 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterServerCommands.java @@ -19,6 +19,8 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.core.types.RedisClientInfo; /** @@ -26,45 +28,46 @@ * @author Dennis Neufeld * @since 2.0 */ +@NullUnmarked public interface RedisClusterServerCommands extends RedisServerCommands { /** * @param node must not be {@literal null}. * @see RedisServerCommands#bgReWriteAof() */ - void bgReWriteAof(RedisClusterNode node); + void bgReWriteAof(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @see RedisServerCommands#bgSave() */ - void bgSave(RedisClusterNode node); + void bgSave(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @return * @see RedisServerCommands#lastSave() */ - Long lastSave(RedisClusterNode node); + Long lastSave(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @see RedisServerCommands#save() */ - void save(RedisClusterNode node); + void save(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @return * @see RedisServerCommands#dbSize() */ - Long dbSize(RedisClusterNode node); + Long dbSize(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @see RedisServerCommands#flushDb() */ - void flushDb(RedisClusterNode node); + void flushDb(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -72,13 +75,13 @@ public interface RedisClusterServerCommands extends RedisServerCommands { * @see RedisServerCommands#flushDb(FlushOption) * @since 2.7 */ - void flushDb(RedisClusterNode node, FlushOption option); + void flushDb(@NonNull RedisClusterNode node, @NonNull FlushOption option); /** * @param node must not be {@literal null}. * @see RedisServerCommands#flushAll() */ - void flushAll(RedisClusterNode node); + void flushAll(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -86,14 +89,14 @@ public interface RedisClusterServerCommands extends RedisServerCommands { * @see RedisServerCommands#flushAll(FlushOption) * @since 2.7 */ - void flushAll(RedisClusterNode node, FlushOption option); + void flushAll(@NonNull RedisClusterNode node, @NonNull FlushOption option); /** * @param node must not be {@literal null}. * @return * @see RedisServerCommands#info() */ - Properties info(RedisClusterNode node); + Properties info(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -101,13 +104,13 @@ public interface RedisClusterServerCommands extends RedisServerCommands { * @return * @see RedisServerCommands#info(String) */ - Properties info(RedisClusterNode node, String section); + Properties info(@NonNull RedisClusterNode node, @NonNull String section); /** * @param node must not be {@literal null}. * @see RedisServerCommands#shutdown() */ - void shutdown(RedisClusterNode node); + void shutdown(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. @@ -115,7 +118,7 @@ public interface RedisClusterServerCommands extends RedisServerCommands { * @return * @see RedisServerCommands#getConfig(String) */ - Properties getConfig(RedisClusterNode node, String pattern); + Properties getConfig(@NonNull RedisClusterNode node, @NonNull String pattern); /** * @param node must not be {@literal null}. @@ -123,27 +126,27 @@ public interface RedisClusterServerCommands extends RedisServerCommands { * @param value * @see RedisServerCommands#setConfig(String, String) */ - void setConfig(RedisClusterNode node, String param, String value); + void setConfig(@NonNull RedisClusterNode node, @NonNull String param, @NonNull String value); /** * @param node must not be {@literal null}. * @see RedisServerCommands#resetConfigStats() */ - void resetConfigStats(RedisClusterNode node); + void resetConfigStats(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @see RedisServerCommands#rewriteConfig() * @since 2.5 */ - void rewriteConfig(RedisClusterNode node); + void rewriteConfig(@NonNull RedisClusterNode node); /** * @param node must not be {@literal null}. * @return * @see RedisServerCommands#time() */ - default Long time(RedisClusterNode node) { + default Long time(@NonNull RedisClusterNode node) { return time(node, TimeUnit.MILLISECONDS); } @@ -154,12 +157,12 @@ default Long time(RedisClusterNode node) { * @since 2.5 * @see RedisServerCommands#time(TimeUnit) */ - Long time(RedisClusterNode node, TimeUnit timeUnit); + Long time(@NonNull RedisClusterNode node, @NonNull TimeUnit timeUnit); /** * @param node must not be {@literal null}. * @return * @see RedisServerCommands#getClientList() */ - List getClientList(RedisClusterNode node); + List<@NonNull RedisClientInfo> getClientList(@NonNull RedisClusterNode node); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisCommands.java index 1ebb48b83f..0f76f567dc 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisCommands.java @@ -15,7 +15,8 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; /** * Interface defining the commands supported by Redis. @@ -24,6 +25,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked public interface RedisCommands extends RedisKeyCommands, RedisStringCommands, RedisListCommands, RedisSetCommands, RedisZSetCommands, RedisHashCommands, RedisTxCommands, RedisPubSubCommands, RedisConnectionCommands, RedisServerCommands, RedisStreamCommands, RedisScriptingCommands, RedisGeoCommands, RedisHyperLogLogCommands { diff --git a/src/main/java/org/springframework/data/redis/connection/RedisConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisConfiguration.java index 053ce917de..2dfd8118ad 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisConfiguration.java @@ -21,7 +21,8 @@ import java.util.function.IntSupplier; import java.util.function.Supplier; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -68,6 +69,7 @@ default RedisPassword getPasswordOrElse(Supplier other) { * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link WithPassword}. */ + @Contract("null -> false") static boolean isAuthenticationAware(@Nullable RedisConfiguration configuration) { return configuration instanceof WithAuthentication; } @@ -76,6 +78,7 @@ static boolean isAuthenticationAware(@Nullable RedisConfiguration configuration) * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link WithDatabaseIndex}. */ + @Contract("null -> false") static boolean isDatabaseIndexAware(@Nullable RedisConfiguration configuration) { return configuration instanceof WithDatabaseIndex; } @@ -84,6 +87,7 @@ static boolean isDatabaseIndexAware(@Nullable RedisConfiguration configuration) * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link SentinelConfiguration}. */ + @Contract("null -> false") static boolean isSentinelConfiguration(@Nullable RedisConfiguration configuration) { return configuration instanceof SentinelConfiguration; } @@ -93,6 +97,7 @@ static boolean isSentinelConfiguration(@Nullable RedisConfiguration configuratio * @return {@code true} if given {@link RedisConfiguration} is instance of {@link WithHostAndPort}. * @since 2.1.6 */ + @Contract("null -> false") static boolean isHostAndPortAware(@Nullable RedisConfiguration configuration) { return configuration instanceof WithHostAndPort; } @@ -101,6 +106,7 @@ static boolean isHostAndPortAware(@Nullable RedisConfiguration configuration) { * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link ClusterConfiguration}. */ + @Contract("null -> false") static boolean isClusterConfiguration(@Nullable RedisConfiguration configuration) { return configuration instanceof ClusterConfiguration; } @@ -109,6 +115,7 @@ static boolean isClusterConfiguration(@Nullable RedisConfiguration configuration * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link StaticMasterReplicaConfiguration}. */ + @Contract("null -> false") static boolean isStaticMasterReplicaConfiguration(@Nullable RedisConfiguration configuration) { return configuration instanceof StaticMasterReplicaConfiguration; } @@ -117,6 +124,7 @@ static boolean isStaticMasterReplicaConfiguration(@Nullable RedisConfiguration c * @param configuration can be {@literal null}. * @return {@code true} if given {@link RedisConfiguration} is instance of {@link DomainSocketConfiguration}. */ + @Contract("null -> false") static boolean isDomainSocketConfiguration(@Nullable RedisConfiguration configuration) { return configuration instanceof DomainSocketConfiguration; } @@ -141,8 +149,7 @@ static Integer getDatabaseOrElse(@Nullable RedisConfiguration configuration, Sup * @return can be {@literal null}. * @throws IllegalArgumentException if {@code other} is {@literal null}. */ - @Nullable - static String getUsernameOrElse(@Nullable RedisConfiguration configuration, Supplier other) { + static @Nullable String getUsernameOrElse(@Nullable RedisConfiguration configuration, Supplier other) { Assert.notNull(other, "Other must not be null"); return isAuthenticationAware(configuration) ? ((WithAuthentication) configuration).getUsername() : other.get(); @@ -227,7 +234,7 @@ default void setPassword(@Nullable String password) { * * @param password can be {@literal null}. */ - default void setPassword(@Nullable char[] password) { + default void setPassword(char @Nullable[] password) { setPassword(RedisPassword.of(password)); } @@ -418,8 +425,7 @@ default void setMaster(String name) { * @return can be {@literal null} if not set. * @since 2.4 */ - @Nullable - default String getDataNodeUsername() { + default @Nullable String getDataNodeUsername() { return getUsername(); } @@ -468,7 +474,7 @@ default void setSentinelPassword(@Nullable String password) { * @param password can be {@literal null}. * @since 2.2.2 */ - default void setSentinelPassword(@Nullable char[] password) { + default void setSentinelPassword(char @Nullable[] password) { setSentinelPassword(RedisPassword.of(password)); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisConnection.java b/src/main/java/org/springframework/data/redis/connection/RedisConnection.java index 69917d5391..0320d17a89 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisConnection.java @@ -17,6 +17,8 @@ import java.util.List; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; /** @@ -37,6 +39,7 @@ * @author James Howe * @author John Blum */ +@NullUnmarked public interface RedisConnection extends RedisCommandsProvider, DefaultedRedisConnection, AutoCloseable { /** @@ -102,7 +105,7 @@ public interface RedisConnection extends RedisCommandsProvider, DefaultedRedisCo * @throws RedisPipelineException if the pipeline contains any incorrect/invalid statements * @return the result of the executed commands. */ - List closePipeline() throws RedisPipelineException; + List<@Nullable Object> closePipeline() throws RedisPipelineException; /** * @return the {@link RedisSentinelConnection} when using Redis Sentinel. diff --git a/src/main/java/org/springframework/data/redis/connection/RedisConnectionCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisConnectionCommands.java index 74875a4bb2..9edfd63f9c 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisConnectionCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisConnectionCommands.java @@ -15,7 +15,8 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * Connection-specific commands supported by Redis. @@ -24,6 +25,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked public interface RedisConnectionCommands { /** @@ -41,8 +43,7 @@ public interface RedisConnectionCommands { * @return the message or {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ECHO */ - @Nullable - byte[] echo(byte[] message); + byte[] echo(byte @NonNull [] message); /** * Test connection. @@ -50,6 +51,5 @@ public interface RedisConnectionCommands { * @return Server response message - usually {@literal PONG}. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PING */ - @Nullable String ping(); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java index fce11eb2f6..c5f314b965 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisGeoCommands.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs.Flag; import java.util.LinkedHashSet; import java.util.List; @@ -23,6 +23,10 @@ import java.util.Set; import java.util.stream.Collectors; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -31,7 +35,6 @@ import org.springframework.data.geo.Point; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -42,6 +45,7 @@ * @author Mark Paluch * @since 1.8 */ +@NullUnmarked public interface RedisGeoCommands { /** @@ -53,8 +57,7 @@ public interface RedisGeoCommands { * @return Number of elements added. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOADD */ - @Nullable - Long geoAdd(byte[] key, Point point, byte[] member); + Long geoAdd(byte @NonNull [] key, @NonNull Point point, byte @NonNull [] member); /** * Add {@link GeoLocation} to {@literal key}. @@ -64,8 +67,7 @@ public interface RedisGeoCommands { * @return Number of elements added. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOADD */ - @Nullable - default Long geoAdd(byte[] key, GeoLocation location) { + default Long geoAdd(byte @NonNull [] key, @NonNull GeoLocation location) { Assert.notNull(key, "Key must not be null"); Assert.notNull(location, "Location must not be null"); @@ -81,8 +83,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return Number of elements added. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOADD */ - @Nullable - Long geoAdd(byte[] key, Map memberCoordinateMap); + Long geoAdd(byte @NonNull [] key, @NonNull Map memberCoordinateMap); /** * Add {@link GeoLocation}s to {@literal key} @@ -92,8 +93,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return Number of elements added. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOADD */ - @Nullable - Long geoAdd(byte[] key, Iterable> locations); + Long geoAdd(byte @NonNull [] key, @NonNull Iterable<@NonNull GeoLocation> locations); /** * Get the {@link Distance} between {@literal member1} and {@literal member2}. @@ -104,8 +104,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return can be {@literal null}. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEODIST */ - @Nullable - Distance geoDist(byte[] key, byte[] member1, byte[] member2); + Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2); /** * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. @@ -117,8 +116,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return can be {@literal null}. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEODIST */ - @Nullable - Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric); + Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2, @NonNull Metric metric); /** * Get Geohash representation of the position for one or more {@literal member}s. @@ -128,8 +126,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return empty list when key or members do not exists. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOHASH */ - @Nullable - List geoHash(byte[] key, byte[]... members); + List<@NonNull String> geoHash(byte @NonNull [] key, byte @NonNull [] @NonNull... members); /** * Get the {@link Point} representation of positions for one or more {@literal member}s. @@ -139,8 +136,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return empty {@link List} when key of members do not exist. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEOPOS */ - @Nullable - List geoPos(byte[] key, byte[]... members); + List<@NonNull Point> geoPos(byte @NonNull [] key, byte @NonNull [] @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -150,8 +146,7 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> geoRadius(byte[] key, Circle within); + GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. @@ -162,8 +157,8 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args); + GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within, + @NonNull GeoRadiusCommandArgs args); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -175,8 +170,8 @@ default Long geoAdd(byte[] key, GeoLocation location) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - default GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + default GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + double radius) { return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); } @@ -190,8 +185,8 @@ default GeoResults> geoRadiusByMember(byte[] key, byte[] mem * @return {@literal null} when used in pipeline / transaction.. * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius); + GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates, given {@link Distance} @@ -204,9 +199,8 @@ default GeoResults> geoRadiusByMember(byte[] key, byte[] mem * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, - GeoRadiusCommandArgs args); + GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius, @NonNull GeoRadiusCommandArgs args); /** * Remove the {@literal member}s. @@ -216,8 +210,7 @@ GeoResults> geoRadiusByMember(byte[] key, byte[] member, Dis * @return Number of elements removed. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREM */ - @Nullable - Long geoRemove(byte[] key, byte[]... members); + Long geoRemove(byte @NonNull [] key, byte @NonNull [] @NonNull... members); /** * Return the members of a geo set which are within the borders of the area specified by a given {@link GeoShape @@ -231,9 +224,8 @@ GeoResults> geoRadiusByMember(byte[] key, byte[] member, Dis * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchCommandArgs args); + GeoResults> geoSearch(byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchCommandArgs args); /** * Query the members of a geo set which are within the borders of the area specified by a given {@link GeoShape shape} @@ -247,9 +239,8 @@ GeoResults> geoSearch(byte[] key, GeoReference refer * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - Long geoSearchStore(byte[] destKey, byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchStoreCommandArgs args); + Long geoSearchStore(byte @NonNull [] destKey, byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchStoreCommandArgs args); /** * Arguments to be used with {@link RedisGeoCommands}. @@ -257,13 +248,14 @@ Long geoSearchStore(byte[] destKey, byte[] key, GeoReference reference, * @author Christoph Strobl * @since 2.6 */ + @NullMarked interface GeoCommandArgs { /** * @return can be {@literal null}. */ @Nullable - public Direction getSortDirection(); + Direction getSortDirection(); /** * @return can be {@literal null}. @@ -327,13 +319,14 @@ static GeoCommandFlag storeDist() { * @author Christoph Strobl * @since 2.6 */ + @NullMarked class GeoSearchCommandArgs implements GeoCommandArgs, Cloneable { protected final Set flags = new LinkedHashSet<>(2, 1); - @Nullable protected Long limit; + protected @Nullable Long limit; - @Nullable protected Direction sortDirection; + protected @Nullable Direction sortDirection; private GeoSearchCommandArgs() {} @@ -436,16 +429,14 @@ public Set getFlags() { /** * @return can be {@literal null}. */ - @Nullable - public Long getLimit() { + public @Nullable Long getLimit() { return limit; } /** * @return can be {@literal null}. */ - @Nullable - public Direction getSortDirection() { + public @Nullable Direction getSortDirection() { return sortDirection; } @@ -470,6 +461,7 @@ protected GeoSearchCommandArgs clone() { * @author Mark Paluch * @since 2.6 */ + @NullMarked class GeoSearchStoreCommandArgs implements GeoCommandArgs, Cloneable { private final Set flags = new LinkedHashSet<>(2, 1); @@ -568,16 +560,14 @@ public Set getFlags() { /** * @return can be {@literal null}. */ - @Nullable - public Long getLimit() { + public @Nullable Long getLimit() { return limit; } /** * @return can be {@literal null}. */ - @Nullable - public Direction getSortDirection() { + public @Nullable Direction getSortDirection() { return sortDirection; } @@ -607,6 +597,7 @@ protected GeoSearchStoreCommandArgs clone() { * @author Christoph Strobl * @since 1.8 */ + @NullMarked class GeoRadiusCommandArgs extends GeoSearchCommandArgs implements Cloneable { private GeoRadiusCommandArgs() {} @@ -708,6 +699,7 @@ protected GeoRadiusCommandArgs clone() { * @param * @since 1.8 */ + @NullMarked class GeoLocation extends org.springframework.data.redis.domain.geo.GeoLocation { public GeoLocation(T name, Point point) { @@ -725,6 +717,7 @@ public String toString() { * @author Christoph Strobl * @since 1.8 */ + @NullMarked enum DistanceUnit implements Metric { METERS(6378137, "m"), KILOMETERS(6378.137, "km"), MILES(3963.191, "mi"), FEET(20925646.325, "ft"); diff --git a/src/main/java/org/springframework/data/redis/connection/RedisHashCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisHashCommands.java index cd99e4a516..f0d9e77dd3 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisHashCommands.java @@ -21,9 +21,10 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -34,6 +35,7 @@ * @author Mark Paluch * @author Tihomir Mateev */ +@NullUnmarked public interface RedisHashCommands { /** @@ -45,8 +47,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HSET */ - @Nullable - Boolean hSet(byte[] key, byte[] field, byte[] value); + Boolean hSet(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value); /** * Set the {@code value} of a hash {@code field} only if {@code field} does not exist. @@ -57,8 +58,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HSETNX */ - @Nullable - Boolean hSetNX(byte[] key, byte[] field, byte[] value); + Boolean hSetNX(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value); /** * Get value for given {@code field} from hash at {@code key}. @@ -68,8 +68,7 @@ public interface RedisHashCommands { * @return {@literal null} when key or field do not exists or when used in pipeline / transaction. * @see Redis Documentation: HGET */ - @Nullable - byte[] hGet(byte[] key, byte[] field); + byte[] hGet(byte @NonNull [] key, byte @NonNull [] field); /** * Get values for given {@code fields} from hash at {@code key}. Values are in the order of the requested keys Absent @@ -80,8 +79,7 @@ public interface RedisHashCommands { * @return empty {@link List} if key does not exist. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HMGET */ - @Nullable - List hMGet(byte[] key, byte[]... fields); + List hMGet(byte @NonNull [] key, byte @NonNull [] @NonNull... fields); /** * Set multiple hash fields to multiple values using data provided in {@code hashes} @@ -90,7 +88,7 @@ public interface RedisHashCommands { * @param hashes must not be {@literal null}. * @see Redis Documentation: HMSET */ - void hMSet(byte[] key, Map hashes); + void hMSet(byte @NonNull [] key, Map hashes); /** * Increment {@code value} of a hash {@code field} by the given {@code delta}. @@ -101,8 +99,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HINCRBY */ - @Nullable - Long hIncrBy(byte[] key, byte[] field, long delta); + Long hIncrBy(byte @NonNull [] key, byte @NonNull [] field, long delta); /** * Increment {@code value} of a hash {@code field} by the given {@code delta}. @@ -113,8 +110,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HINCRBYFLOAT */ - @Nullable - Double hIncrBy(byte[] key, byte[] field, double delta); + Double hIncrBy(byte @NonNull [] key, byte @NonNull [] field, double delta); /** * Determine if given hash {@code field} exists. @@ -124,8 +120,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HEXISTS */ - @Nullable - Boolean hExists(byte[] key, byte[] field); + Boolean hExists(byte @NonNull [] key, byte @NonNull [] field); /** * Delete given hash {@code fields}. @@ -135,8 +130,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HDEL */ - @Nullable - Long hDel(byte[] key, byte[]... fields); + Long hDel(byte @NonNull [] key, byte @NonNull [] @NonNull... fields); /** * Get size of hash at {@code key}. @@ -145,8 +139,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HLEN */ - @Nullable - Long hLen(byte[] key); + Long hLen(byte @NonNull [] key); /** * Get key set (fields) of hash at {@code key}. @@ -155,8 +148,7 @@ public interface RedisHashCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HKEYS? */ - @Nullable - Set hKeys(byte[] key); + Set hKeys(byte @NonNull [] key); /** * Get entry set (values) of hash at {@code field}. @@ -165,8 +157,7 @@ public interface RedisHashCommands { * @return empty {@link List} if key does not exist. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HVALS */ - @Nullable - List hVals(byte[] key); + List hVals(byte @NonNull [] key); /** * Get entire hash stored at {@code key}. @@ -175,8 +166,7 @@ public interface RedisHashCommands { * @return empty {@link Map} if key does not exist or {@literal null} when used in pipeline / transaction. * @see Redis Documentation: HGETALL */ - @Nullable - Map hGetAll(byte[] key); + Map hGetAll(byte @NonNull [] key); /** * Return a random field from the hash stored at {@code key}. @@ -186,8 +176,7 @@ public interface RedisHashCommands { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - byte[] hRandField(byte[] key); + byte[] hRandField(byte @NonNull [] key); /** * Return a random field from the hash along with its value stored at {@code key}. @@ -197,8 +186,7 @@ public interface RedisHashCommands { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map.Entry hRandFieldWithValues(byte[] key); + Map.Entry hRandFieldWithValues(byte @NonNull [] key); /** * Return a random field from the hash stored at {@code key}. If the provided {@code count} argument is positive, @@ -212,8 +200,7 @@ public interface RedisHashCommands { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List hRandField(byte[] key, long count); + List hRandField(byte @NonNull [] key, long count); /** * Return a random field from the hash along with its value stored at {@code key}. If the provided {@code count} @@ -227,8 +214,7 @@ public interface RedisHashCommands { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List> hRandFieldWithValues(byte[] key, long count); + List> hRandFieldWithValues(byte @NonNull [] key, long count); /** * Use a {@link Cursor} to iterate over entries in hash at {@code key}. @@ -239,7 +225,7 @@ public interface RedisHashCommands { * @since 1.4 * @see Redis Documentation: HSCAN */ - Cursor> hScan(byte[] key, ScanOptions options); + Cursor> hScan(byte @NonNull [] key, ScanOptions options); /** * Returns the length of the value associated with {@code field} in the hash stored at {@code key}. If the {@code key} @@ -251,8 +237,7 @@ public interface RedisHashCommands { * @since 2.1 * @see Redis Documentation: HSTRLEN */ - @Nullable - Long hStrLen(byte[] key, byte[] field); + Long hStrLen(byte @NonNull [] key, byte @NonNull [] field); /** * Apply a given {@link org.springframework.data.redis.core.types.Expiration} to the given {@literal fields}. @@ -266,8 +251,8 @@ public interface RedisHashCommands { * such field; * @since 3.5 */ - default @Nullable List applyHashFieldExpiration(byte[] key, - org.springframework.data.redis.core.types.Expiration expiration, byte[]... fields) { + default List<@NonNull Long> applyHashFieldExpiration(byte @NonNull [] key, + org.springframework.data.redis.core.types.@NonNull Expiration expiration, byte @NonNull [] @NonNull... fields) { return applyHashFieldExpiration(key, expiration, ExpirationOptions.none(), fields); } @@ -282,9 +267,9 @@ public interface RedisHashCommands { * condition is not met); {@code -2} indicating there is no such field; * @since 3.5 */ - @Nullable - default List applyHashFieldExpiration(byte[] key, - org.springframework.data.redis.core.types.Expiration expiration, ExpirationOptions options, byte[]... fields) { + default List<@NonNull Long> applyHashFieldExpiration(byte @NonNull [] key, + org.springframework.data.redis.core.types.@NonNull Expiration expiration, @NonNull ExpirationOptions options, + byte @NonNull [] @NonNull... fields) { if (expiration.isPersistent()) { return hPersist(key, fields); @@ -331,8 +316,7 @@ default List applyHashFieldExpiration(byte[] key, * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - default List hExpire(byte[] key, long seconds, byte[]... fields) { + default List<@NonNull Long> hExpire(byte @NonNull [] key, long seconds, byte @NonNull [] @NonNull... fields) { return hExpire(key, seconds, ExpirationOptions.Condition.ALWAYS, fields); } @@ -350,8 +334,8 @@ default List hExpire(byte[] key, long seconds, byte[]... fields) { * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - default List hExpire(byte[] key, Duration ttl, byte[]... fields) { + default List<@NonNull Long> hExpire(byte @NonNull [] key, @NonNull Duration ttl, + byte @NonNull [] @NonNull... fields) { return hExpire(key, ttl.toSeconds(), fields); } @@ -370,8 +354,8 @@ default List hExpire(byte[] key, Duration ttl, byte[]... fields) { * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - List hExpire(byte[] key, long seconds, ExpirationOptions.Condition condition, byte[]... fields); + List<@NonNull Long> hExpire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields); /** * Set time to live for given {@code fields} in milliseconds. @@ -387,8 +371,7 @@ default List hExpire(byte[] key, Duration ttl, byte[]... fields) { * @see Redis Documentation: HPEXPIRE * @since 3.5 */ - @Nullable - default List hpExpire(byte[] key, long millis, byte[]... fields) { + default List<@NonNull Long> hpExpire(byte @NonNull [] key, long millis, byte @NonNull [] @NonNull... fields) { return hpExpire(key, millis, ExpirationOptions.Condition.ALWAYS, fields); } @@ -406,8 +389,8 @@ default List hpExpire(byte[] key, long millis, byte[]... fields) { * @see Redis Documentation: HPEXPIRE * @since 3.5 */ - @Nullable - default List hpExpire(byte[] key, Duration ttl, byte[]... fields) { + default List<@NonNull Long> hpExpire(byte @NonNull [] key, @NonNull Duration ttl, + byte @NonNull [] @NonNull... fields) { return hpExpire(key, ttl.toMillis(), fields); } @@ -427,8 +410,8 @@ default List hpExpire(byte[] key, Duration ttl, byte[]... fields) { * @see Redis Documentation: HPEXPIRE * @since 3.5 */ - @Nullable - List hpExpire(byte[] key, long millis, ExpirationOptions.Condition condition, byte[]... fields); + List<@NonNull Long> hpExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields); /** * Set the expiration for given {@code field} as a {@literal UNIX} timestamp. @@ -443,8 +426,7 @@ default List hpExpire(byte[] key, Duration ttl, byte[]... fields) { * @see Redis Documentation: HEXPIREAT * @since 3.5 */ - @Nullable - default List hExpireAt(byte[] key, long unixTime, byte[]... fields) { + default List hExpireAt(byte @NonNull [] key, long unixTime, byte @NonNull [] @NonNull... fields) { return hExpireAt(key, unixTime, ExpirationOptions.Condition.ALWAYS, fields); } @@ -463,8 +445,8 @@ default List hExpireAt(byte[] key, long unixTime, byte[]... fields) { * @see Redis Documentation: HEXPIREAT * @since 3.5 */ - @Nullable - List hExpireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition, byte[]... fields); + List<@NonNull Long> hExpireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields); /** * Set the expiration for given {@code field} as a {@literal UNIX} timestamp in milliseconds. @@ -479,8 +461,8 @@ default List hExpireAt(byte[] key, long unixTime, byte[]... fields) { * @see Redis Documentation: HPEXPIREAT * @since 3.5 */ - @Nullable - default List hpExpireAt(byte[] key, long unixTimeInMillis, byte[]... fields) { + default List<@NonNull Long> hpExpireAt(byte @NonNull [] key, long unixTimeInMillis, + byte @NonNull [] @NonNull... fields) { return hpExpireAt(key, unixTimeInMillis, ExpirationOptions.Condition.ALWAYS, fields); } @@ -499,9 +481,8 @@ default List hpExpireAt(byte[] key, long unixTimeInMillis, byte[]... field * @see Redis Documentation: HPEXPIREAT * @since 3.5 */ - @Nullable - List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition, - byte[]... fields); + List<@NonNull Long> hpExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition, byte @NonNull [] @NonNull... fields); /** * Remove the expiration from given {@code field}. @@ -515,8 +496,7 @@ List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HPERSIST * @since 3.5 */ - @Nullable - List hPersist(byte[] key, byte[]... fields); + List<@NonNull Long> hPersist(byte @NonNull [] key, byte @NonNull [] @NonNull... fields); /** * Get the time to live for {@code fields} in seconds. @@ -530,8 +510,7 @@ List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hTtl(byte[] key, byte[]... fields); + List<@NonNull Long> hTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields); /** * Get the time to live for {@code fields} in and convert it to the given {@link TimeUnit}. @@ -546,8 +525,7 @@ List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hTtl(byte[] key, TimeUnit timeUnit, byte[]... fields); + List<@NonNull Long> hTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit, byte @NonNull [] @NonNull... fields); /** * Get the time to live for {@code fields} in milliseconds. @@ -561,6 +539,5 @@ List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hpTtl(byte[] key, byte[]... fields); + List<@NonNull Long> hpTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisHyperLogLogCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisHyperLogLogCommands.java index 67fa08a4ad..0d3a458048 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisHyperLogLogCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisHyperLogLogCommands.java @@ -15,7 +15,8 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * {@literal HyperLogLog} specific commands supported by Redis. @@ -24,6 +25,7 @@ * @author Mark Paluch * @since 1.5 */ +@NullUnmarked public interface RedisHyperLogLogCommands { /** @@ -34,8 +36,7 @@ public interface RedisHyperLogLogCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PFADD */ - @Nullable - Long pfAdd(byte[] key, byte[]... values); + Long pfAdd(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Return the approximated cardinality of the structures observed by the HyperLogLog at {@literal key(s)}. @@ -44,8 +45,7 @@ public interface RedisHyperLogLogCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PFCOUNT */ - @Nullable - Long pfCount(byte[]... keys); + Long pfCount(byte @NonNull [] @NonNull... keys); /** * Merge N different HyperLogLogs at {@literal sourceKeys} into a single {@literal destinationKey}. @@ -54,6 +54,6 @@ public interface RedisHyperLogLogCommands { * @param sourceKeys must not be {@literal null}. * @see Redis Documentation: PFMERGE */ - void pfMerge(byte[] destinationKey, byte[]... sourceKeys); + void pfMerge(byte @NonNull [] destinationKey, byte @NonNull [] @NonNull... sourceKeys); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java index 4319dd8705..8b15d15c13 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisKeyCommands.java @@ -21,10 +21,12 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.KeyScanOptions; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -36,6 +38,7 @@ * @author Mark Paluch * @author ihaohong */ +@NullUnmarked public interface RedisKeyCommands { /** @@ -48,8 +51,7 @@ public interface RedisKeyCommands { * @see Redis Documentation: COPY * @since 2.6 */ - @Nullable - Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace); + Boolean copy(byte @NonNull [] sourceKey, byte @NonNull [] targetKey, boolean replace); /** * Determine if given {@code key} exists. @@ -58,8 +60,7 @@ public interface RedisKeyCommands { * @return {@literal true} if key exists. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: EXISTS */ - @Nullable - default Boolean exists(byte[] key) { + default Boolean exists(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); Long count = exists(new byte[][] { key }); @@ -75,8 +76,7 @@ default Boolean exists(byte[] key) { * transaction. * @since 2.1 */ - @Nullable - Long exists(byte[]... keys); + Long exists(byte @NonNull [] @NonNull... keys); /** * Delete given {@code keys}. @@ -85,8 +85,7 @@ default Boolean exists(byte[] key) { * @return The number of keys that were removed. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DEL */ - @Nullable - Long del(byte[]... keys); + Long del(byte @NonNull [] @NonNull... keys); /** * Unlink the {@code keys} from the keyspace. Unlike with {@link #del(byte[]...)} the actual memory reclaiming here @@ -97,8 +96,7 @@ default Boolean exists(byte[] key) { * @see Redis Documentation: UNLINK * @since 2.1 */ - @Nullable - Long unlink(byte[]... keys); + Long unlink(byte @NonNull [] @NonNull... keys); /** * Determine the type stored at {@code key}. @@ -107,8 +105,7 @@ default Boolean exists(byte[] key) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: TYPE */ - @Nullable - DataType type(byte[] key); + DataType type(byte @NonNull [] key); /** * Alter the last access time of given {@code key(s)}. @@ -118,8 +115,7 @@ default Boolean exists(byte[] key) { * @see Redis Documentation: TOUCH * @since 2.1 */ - @Nullable - Long touch(byte[]... keys); + Long touch(byte @NonNull [] @NonNull... keys); /** * Find all keys matching the given {@code pattern}. @@ -128,8 +124,7 @@ default Boolean exists(byte[] key) { * @return empty {@link Set} if no match found. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: KEYS */ - @Nullable - Set keys(byte[] pattern); + Set keys(byte @NonNull [] pattern); /** * Use a {@link Cursor} to iterate over keys. @@ -139,19 +134,19 @@ default Boolean exists(byte[] key) { * @since 2.4 * @see Redis Documentation: SCAN */ - default Cursor scan(KeyScanOptions options) { + default Cursor scan(@NonNull KeyScanOptions options) { return scan((ScanOptions) options); } /** * Use a {@link Cursor} to iterate over keys. * - * @param options must not be {@literal null}. + * @param options can be {@literal null}. * @return never {@literal null}. * @since 1.4 * @see Redis Documentation: SCAN */ - Cursor scan(ScanOptions options); + Cursor scan(@Nullable ScanOptions options); /** * Return a random key from the keyspace. @@ -159,7 +154,6 @@ default Cursor scan(KeyScanOptions options) { * @return {@literal null} if no keys available or when used in pipeline or transaction. * @see Redis Documentation: RANDOMKEY */ - @Nullable byte[] randomKey(); /** @@ -169,7 +163,7 @@ default Cursor scan(KeyScanOptions options) { * @param newKey must not be {@literal null}. * @see Redis Documentation: RENAME */ - void rename(byte[] oldKey, byte[] newKey); + void rename(byte @NonNull [] oldKey, byte @NonNull [] newKey); /** * Rename key {@code oldKey} to {@code newKey} only if {@code newKey} does not exist. @@ -179,8 +173,7 @@ default Cursor scan(KeyScanOptions options) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RENAMENX */ - @Nullable - Boolean renameNX(byte[] oldKey, byte[] newKey); + Boolean renameNX(byte @NonNull [] oldKey, byte @NonNull [] newKey); /** * @param key must not be {@literal null}. @@ -196,9 +189,8 @@ default Cursor scan(KeyScanOptions options) { * @see Redis Documentation: PEXPIREAT * @see Redis Documentation: PERSIST */ - @Nullable - default Boolean applyExpiration(byte[] key, org.springframework.data.redis.core.types.Expiration expiration, - ExpirationOptions options) { + default Boolean applyExpiration(byte @NonNull [] key, + org.springframework.data.redis.core.types.@NonNull Expiration expiration, @NonNull ExpirationOptions options) { if (expiration.isPersistent()) { return persist(key); @@ -242,8 +234,7 @@ default Boolean applyExpiration(byte[] key, org.springframework.data.redis.core. * skipped because of the provided arguments. * @see Redis Documentation: EXPIRE */ - @Nullable - default Boolean expire(byte[] key, long seconds) { + default Boolean expire(byte @NonNull [] key, long seconds) { return expire(key, seconds, ExpirationOptions.Condition.ALWAYS); } @@ -258,8 +249,7 @@ default Boolean expire(byte[] key, long seconds) { * @see Redis Documentation: EXPIRE * @since 3.5 */ - @Nullable - Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition condition); + Boolean expire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition); /** * Set time to live for given {@code key} using {@link Duration#toSeconds() seconds} precision. @@ -272,8 +262,7 @@ default Boolean expire(byte[] key, long seconds) { * @see Redis Documentation: EXPIRE * @since 3.5 */ - @Nullable - default Boolean expire(byte[] key, Duration duration) { + default Boolean expire(byte @NonNull [] key, @NonNull Duration duration) { return expire(key, duration.toSeconds()); } @@ -287,8 +276,7 @@ default Boolean expire(byte[] key, Duration duration) { * skipped because of the provided arguments. * @see Redis Documentation: PEXPIRE */ - @Nullable - default Boolean pExpire(byte[] key, long millis) { + default Boolean pExpire(byte @NonNull [] key, long millis) { return pExpire(key, millis, ExpirationOptions.Condition.ALWAYS); } @@ -303,8 +291,7 @@ default Boolean pExpire(byte[] key, long millis) { * @see Redis Documentation: PEXPIRE * @since 3.5 */ - @Nullable - Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition condition); + Boolean pExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition); /** * Set time to live for given {@code key} using {@link Duration#toMillis() milliseconds} precision. @@ -317,8 +304,7 @@ default Boolean pExpire(byte[] key, long millis) { * @see Redis Documentation: PEXPIRE * @since 3.5 */ - @Nullable - default Boolean pExpire(byte[] key, Duration duration) { + default Boolean pExpire(byte @NonNull [] key, @NonNull Duration duration) { return pExpire(key, duration.toMillis()); } @@ -332,8 +318,7 @@ default Boolean pExpire(byte[] key, Duration duration) { * skipped because of the provided arguments. * @see Redis Documentation: EXPIREAT */ - @Nullable - default Boolean expireAt(byte[] key, long unixTime) { + default Boolean expireAt(byte @NonNull [] key, long unixTime) { return expireAt(key, unixTime, ExpirationOptions.Condition.ALWAYS); } @@ -348,8 +333,7 @@ default Boolean expireAt(byte[] key, long unixTime) { * @see Redis Documentation: EXPIREAT * @since 3.5 */ - @Nullable - Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition); + Boolean expireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition); /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp in {@link Instant#getEpochSecond() seconds} @@ -363,8 +347,7 @@ default Boolean expireAt(byte[] key, long unixTime) { * @see Redis Documentation: EXPIREAT * @since 3.5 */ - @Nullable - default Boolean expireAt(byte[] key, Instant unixTime) { + default Boolean expireAt(byte @NonNull [] key, @NonNull Instant unixTime) { return expireAt(key, unixTime.getEpochSecond()); } @@ -378,8 +361,7 @@ default Boolean expireAt(byte[] key, Instant unixTime) { * skipped because of the provided arguments. * @see Redis Documentation: PEXPIREAT */ - @Nullable - default Boolean pExpireAt(byte[] key, long unixTimeInMillis) { + default Boolean pExpireAt(byte @NonNull [] key, long unixTimeInMillis) { return pExpireAt(key, unixTimeInMillis, ExpirationOptions.Condition.ALWAYS); } @@ -394,8 +376,7 @@ default Boolean pExpireAt(byte[] key, long unixTimeInMillis) { * @see Redis Documentation: PEXPIREAT * @since 3.5 */ - @Nullable - Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition); + Boolean pExpireAt(byte @NonNull [] key, long unixTimeInMillis, ExpirationOptions.@NonNull Condition condition); /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp in {@link Instant#toEpochMilli() @@ -409,8 +390,7 @@ default Boolean pExpireAt(byte[] key, long unixTimeInMillis) { * @see Redis Documentation: PEXPIREAT * @since 3.5 */ - @Nullable - default Boolean pExpireAt(byte[] key, Instant unixTime) { + default Boolean pExpireAt(byte @NonNull [] key, @NonNull Instant unixTime) { return pExpireAt(key, unixTime.toEpochMilli()); } @@ -421,8 +401,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PERSIST */ - @Nullable - Boolean persist(byte[] key); + Boolean persist(byte @NonNull [] key); /** * Move given {@code key} to database with {@code index}. @@ -432,8 +411,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MOVE */ - @Nullable - Boolean move(byte[] key, int dbIndex); + Boolean move(byte @NonNull [] key, int dbIndex); /** * Get the time to live for {@code key} in seconds. @@ -442,8 +420,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: TTL */ - @Nullable - Long ttl(byte[] key); + Long ttl(byte @NonNull [] key); /** * Get the time to live for {@code key} in and convert it to the given {@link TimeUnit}. @@ -454,8 +431,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @since 1.8 * @see Redis Documentation: TTL */ - @Nullable - Long ttl(byte[] key, TimeUnit timeUnit); + Long ttl(byte @NonNull [] key, @NonNull TimeUnit timeUnit); /** * Get the precise time to live for {@code key} in milliseconds. @@ -464,8 +440,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PTTL */ - @Nullable - Long pTtl(byte[] key); + Long pTtl(byte @NonNull [] key); /** * Get the precise time to live for {@code key} in and convert it to the given {@link TimeUnit}. @@ -476,31 +451,28 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @since 1.8 * @see Redis Documentation: PTTL */ - @Nullable - Long pTtl(byte[] key, TimeUnit timeUnit); + Long pTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit); /** * Sort the elements for {@code key}. * * @param key must not be {@literal null}. - * @param params must not be {@literal null}. + * @param params can be {@literal null}. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - List sort(byte[] key, SortParameters params); + List sort(byte @NonNull [] key, @Nullable SortParameters params); /** * Sort the elements for {@code key} and store result in {@code storeKey}. * * @param key must not be {@literal null}. - * @param params must not be {@literal null}. + * @param params can be {@literal null}. * @param storeKey must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - Long sort(byte[] key, SortParameters params, byte[] storeKey); + Long sort(byte @NonNull [] key, @Nullable SortParameters params, byte @NonNull [] storeKey); /** * Retrieve serialized version of the value stored at {@code key}. @@ -509,8 +481,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @return {@literal null} if key does not exist or when used in pipeline / transaction. * @see Redis Documentation: DUMP */ - @Nullable - byte[] dump(byte[] key); + byte[] dump(byte @NonNull [] key); /** * Create {@code key} using the {@code serializedValue}, previously obtained using {@link #dump(byte[])}. @@ -520,7 +491,7 @@ default Boolean pExpireAt(byte[] key, Instant unixTime) { * @param serializedValue must not be {@literal null}. * @see Redis Documentation: RESTORE */ - default void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { + default void restore(byte @NonNull [] key, long ttlInMillis, byte @NonNull [] serializedValue) { restore(key, ttlInMillis, serializedValue, false); } @@ -534,7 +505,7 @@ default void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { * @since 2.1 * @see Redis Documentation: RESTORE */ - void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolean replace); + void restore(byte @NonNull [] key, long ttlInMillis, byte @NonNull [] serializedValue, boolean replace); /** * Get the type of internal representation used for storing the value at the given {@code key}. @@ -546,8 +517,7 @@ default void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { * @see Redis Documentation: OBJECT ENCODING * @since 2.1 */ - @Nullable - ValueEncoding encodingOf(byte[] key); + ValueEncoding encodingOf(byte @NonNull [] key); /** * Get the {@link Duration} since the object stored at the given {@code key} is idle. @@ -558,8 +528,7 @@ default void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { * @see Redis Documentation: OBJECT IDLETIME * @since 2.1 */ - @Nullable - Duration idletime(byte[] key); + Duration idletime(byte @NonNull [] key); /** * Get the number of references of the value associated with the specified {@code key}. @@ -570,7 +539,6 @@ default void restore(byte[] key, long ttlInMillis, byte[] serializedValue) { * @see Redis Documentation: OBJECT REFCOUNT * @since 2.1 */ - @Nullable - Long refcount(byte[] key); + Long refcount(byte @NonNull [] key); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisListCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisListCommands.java index 18852d2f17..8fc5f4c1c7 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisListCommands.java @@ -17,7 +17,9 @@ import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.util.CollectionUtils; /** @@ -28,6 +30,7 @@ * @author Mark Paluch * @author dengliming */ +@NullUnmarked public interface RedisListCommands { /** @@ -73,8 +76,7 @@ public static Direction last() { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable - Long rPush(byte[] key, byte[]... values); + Long rPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Returns the index of matching elements inside the list stored at given {@literal key}.
@@ -86,8 +88,7 @@ public static Direction last() { * @see Redis Documentation: LPOS * @since 2.4 */ - @Nullable - default Long lPos(byte[] key, byte[] element) { + default Long lPos(byte @NonNull [] key, byte @NonNull [] element) { return CollectionUtils.firstElement(lPos(key, element, null, null)); } @@ -104,8 +105,7 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: LPOS * @since 2.4 */ - @Nullable - List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Nullable Integer count); + List lPos(byte @NonNull [] key, byte @NonNull[] element, @Nullable Integer rank, @Nullable Integer count); /** * Prepend {@code values} to {@code key}. @@ -115,8 +115,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable - Long lPush(byte[] key, byte[]... values); + Long lPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Append {@code values} to {@code key} only if the list exists. @@ -126,8 +125,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSHX */ - @Nullable - Long rPushX(byte[] key, byte[] value); + Long rPushX(byte @NonNull [] key, byte @NonNull [] value); /** * Prepend {@code values} to {@code key} only if the list exists. @@ -137,8 +135,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSHX */ - @Nullable - Long lPushX(byte[] key, byte[] value); + Long lPushX(byte @NonNull [] key, byte @NonNull [] value); /** * Get the size of list stored at {@code key}. @@ -147,8 +144,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LLEN */ - @Nullable - Long lLen(byte[] key); + Long lLen(byte @NonNull [] key); /** * Get elements between {@code start} and {@code end} from list at {@code key}. @@ -160,8 +156,7 @@ default Long lPos(byte[] key, byte[] element) { * pipeline / transaction. * @see Redis Documentation: LRANGE */ - @Nullable - List lRange(byte[] key, long start, long end); + List lRange(byte @NonNull [] key, long start, long end); /** * Trim list at {@code key} to elements between {@code start} and {@code end}. @@ -171,7 +166,7 @@ default Long lPos(byte[] key, byte[] element) { * @param end * @see Redis Documentation: LTRIM */ - void lTrim(byte[] key, long start, long end); + void lTrim(byte @NonNull [] key, long start, long end); /** * Get element at {@code index} form list at {@code key}. @@ -181,8 +176,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when index is out of range or when used in pipeline / transaction. * @see Redis Documentation: LINDEX */ - @Nullable - byte[] lIndex(byte[] key, long index); + byte[] lIndex(byte @NonNull [] key, long index); /** * Insert {@code value} {@link Position#BEFORE} or {@link Position#AFTER} existing {@code pivot} for {@code key}. @@ -194,8 +188,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LINSERT */ - @Nullable - Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value); + Long lInsert(byte @NonNull [] key, @NonNull Position where, byte @NonNull [] pivot, byte @NonNull [] value); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -211,8 +204,8 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: LMOVE * @see #bLMove(byte[], byte[], Direction, Direction, double) */ - @Nullable - byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to); + byte[] lMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -231,8 +224,8 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: BLMOVE * @see #lMove(byte[], byte[], Direction, Direction) */ - @Nullable - byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to, double timeout); + byte[] bLMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to, double timeout); /** * Set the {@code value} list element at {@code index}. @@ -242,7 +235,7 @@ default Long lPos(byte[] key, byte[] element) { * @param value * @see Redis Documentation: LSET */ - void lSet(byte[] key, long index, byte[] value); + void lSet(byte @NonNull [] key, long index, byte @NonNull [] value); /** * Removes the first {@code count} occurrences of {@code value} from the list stored at {@code key}. @@ -253,8 +246,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LREM */ - @Nullable - Long lRem(byte[] key, long count, byte[] value); + Long lRem(byte @NonNull [] key, long count, byte @NonNull [] value); /** * Removes and returns first element in list stored at {@code key}. @@ -263,8 +255,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: LPOP */ - @Nullable - byte[] lPop(byte[] key); + byte[] lPop(byte @NonNull [] key); /** * Removes and returns first {@code} elements in list stored at {@code key}. @@ -275,8 +266,7 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: LPOP * @since 2.6 */ - @Nullable - List lPop(byte[] key, long count); + List lPop(byte @NonNull [] key, long count); /** * Removes and returns last element in list stored at {@code key}. @@ -285,8 +275,7 @@ default Long lPos(byte[] key, byte[] element) { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: RPOP */ - @Nullable - byte[] rPop(byte[] key); + byte[] rPop(byte @NonNull [] key); /** * Removes and returns last {@code} elements in list stored at {@code key}. @@ -297,8 +286,7 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: RPOP * @since 2.6 */ - @Nullable - List rPop(byte[] key, long count); + List rPop(byte @NonNull [] key, long count); /** * Removes and returns first element from lists stored at {@code keys}.
@@ -312,7 +300,7 @@ default Long lPos(byte[] key, byte[] element) { * @see #lPop(byte[]) */ @Nullable - List bLPop(int timeout, byte[]... keys); + List bLPop(int timeout, byte @NonNull [] @NonNull... keys); /** * Removes and returns last element from lists stored at {@code keys}.
@@ -325,8 +313,7 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: BRPOP * @see #rPop(byte[]) */ - @Nullable - List bRPop(int timeout, byte[]... keys); + List bRPop(int timeout, byte @NonNull [] @NonNull... keys); /** * Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value. @@ -336,8 +323,7 @@ default Long lPos(byte[] key, byte[] element) { * @return can be {@literal null}. * @see Redis Documentation: RPOPLPUSH */ - @Nullable - byte[] rPopLPush(byte[] srcKey, byte[] dstKey); + byte[] rPopLPush(byte @NonNull [] srcKey, byte @NonNull [] dstKey); /** * Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value.
@@ -350,6 +336,5 @@ default Long lPos(byte[] key, byte[] element) { * @see Redis Documentation: BRPOPLPUSH * @see #rPopLPush(byte[], byte[]) */ - @Nullable - byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey); + byte[] bRPopLPush(int timeout, byte @NonNull [] srcKey, byte @NonNull [] dstKey); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisNode.java b/src/main/java/org/springframework/data/redis/connection/RedisNode.java index 3e117e0d36..86b9703d7b 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisNode.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisNode.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -192,8 +192,7 @@ private static String[] getHostAndPortFromBracketedHost(String hostPortString) { /** * @return can be {@literal null}. */ - @Nullable - public String getHost() { + public @Nullable String getHost() { return host; } @@ -208,8 +207,7 @@ public boolean hasValidHost() { /** * @return can be {@literal null}. */ - @Nullable - public Integer getPort() { + public @Nullable Integer getPort() { return port; } @@ -223,12 +221,11 @@ public String asString() { } @Override - @Nullable - public String getName() { + public @Nullable String getName() { return this.name; } - public void setName(String name) { + public void setName(@Nullable String name) { this.name = name; } @@ -236,8 +233,7 @@ public void setName(String name) { * @return can be {@literal null}. * @since 1.7 */ - @Nullable - public String getMasterId() { + public @Nullable String getMasterId() { return masterId; } @@ -245,8 +241,7 @@ public String getMasterId() { * @return can be {@literal null}. * @since 1.7 */ - @Nullable - public String getId() { + public @Nullable String getId() { return id; } @@ -262,8 +257,7 @@ public void setId(String id) { * @return can be {@literal null}. * @since 1.7 */ - @Nullable - public NodeType getType() { + public @Nullable NodeType getType() { return type; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisPassword.java b/src/main/java/org/springframework/data/redis/connection/RedisPassword.java index 3fcb4ce343..4041bc5ecb 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisPassword.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisPassword.java @@ -20,7 +20,7 @@ import java.util.Optional; import java.util.function.Function; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -66,7 +66,7 @@ public static RedisPassword of(@Nullable String passwordAsString) { * @param passwordAsChars the password as char array. * @return the {@link RedisPassword} for {@code passwordAsChars}. */ - public static RedisPassword of(@Nullable char[] passwordAsChars) { + public static RedisPassword of(char @Nullable[] passwordAsChars) { return Optional.ofNullable(passwordAsChars) // .filter(it -> !ObjectUtils.isEmpty(passwordAsChars)) // diff --git a/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java b/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java index 0f4cd4c9e5..7f36673028 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisPipelineException.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.lang.Nullable; /** * Exception thrown when executing/closing a pipeline that contains one or multiple invalid/incorrect statements. The diff --git a/src/main/java/org/springframework/data/redis/connection/RedisPubSubCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisPubSubCommands.java index 00283e80ce..f076eb381c 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisPubSubCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisPubSubCommands.java @@ -15,7 +15,9 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; /** * PubSub-specific Redis commands. @@ -24,6 +26,7 @@ * @author Mark Paluch * @author Christoph Strobl */ +@NullUnmarked public interface RedisPubSubCommands { /** @@ -49,8 +52,7 @@ public interface RedisPubSubCommands { * @return the number of clients that received the message or {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PUBLISH */ - @Nullable - Long publish(byte[] channel, byte[] message); + Long publish(byte @NonNull [] channel, byte @NonNull [] message); /** * Subscribes the connection to the given channels. Once subscribed, a connection enters listening mode and can only @@ -62,7 +64,7 @@ public interface RedisPubSubCommands { * @param channels channel names, must not be {@literal null}. * @see Redis Documentation: SUBSCRIBE */ - void subscribe(MessageListener listener, byte[]... channels); + void subscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... channels); /** * Subscribes the connection to all channels matching the given patterns. Once subscribed, a connection enters @@ -75,5 +77,5 @@ public interface RedisPubSubCommands { * @param patterns channel name patterns, must not be {@literal null}. * @see Redis Documentation: PSUBSCRIBE */ - void pSubscribe(MessageListener listener, byte[]... patterns); + void pSubscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... patterns); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisScriptingCommands.java index ce54c205cd..2805b07a3c 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisScriptingCommands.java @@ -17,7 +17,8 @@ import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * Scripting commands. @@ -27,6 +28,7 @@ * @author David Liu * @author Mark Paluch */ +@NullUnmarked public interface RedisScriptingCommands { /** @@ -51,8 +53,7 @@ public interface RedisScriptingCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SCRIPT LOAD */ - @Nullable - String scriptLoad(byte[] script); + String scriptLoad(byte @NonNull [] script); /** * Check if given {@code scriptShas} exist in script cache. @@ -62,8 +63,7 @@ public interface RedisScriptingCommands { * transaction. * @see Redis Documentation: SCRIPT EXISTS */ - @Nullable - List scriptExists(String... scriptShas); + List<@NonNull Boolean> scriptExists(@NonNull String @NonNull... scriptShas); /** * Evaluate given {@code script}. @@ -75,8 +75,8 @@ public interface RedisScriptingCommands { * @return script result. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: EVAL */ - @Nullable - T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs); + T eval(byte @NonNull [] script, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs); /** * Evaluate given {@code scriptSha}. @@ -88,8 +88,8 @@ public interface RedisScriptingCommands { * @return script result. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: EVALSHA */ - @Nullable - T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs); + T evalSha(@NonNull String scriptSha, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs); /** * Evaluate given {@code scriptSha}. @@ -102,6 +102,6 @@ public interface RedisScriptingCommands { * @since 1.5 * @see Redis Documentation: EVALSHA */ - @Nullable - T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs); + T evalSha(byte @NonNull [] scriptSha, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSentinelCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisSentinelCommands.java index 0a3882e643..62482c6bfa 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSentinelCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSentinelCommands.java @@ -17,6 +17,9 @@ import java.util.Collection; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; + /** * Redis Sentinel-specific commands. * @@ -25,6 +28,7 @@ * @since 1.4 * @see Redis Sentinel Documentation */ +@NullUnmarked public interface RedisSentinelCommands { /** @@ -32,14 +36,14 @@ public interface RedisSentinelCommands { * * @param master must not be {@literal null}. */ - void failover(NamedNode master); + void failover(@NonNull NamedNode master); /** * Get a {@link Collection} of monitored masters and their state. * * @return Collection of {@link RedisServer}s. Never {@literal null}. */ - Collection masters(); + Collection<@NonNull RedisServer> masters(); /** * Show list of replicas for given {@literal master}. @@ -47,7 +51,7 @@ public interface RedisSentinelCommands { * @param master must not be {@literal null}. * @return Collection of {@link RedisServer}s. Never {@literal null}. */ - Collection replicas(NamedNode master); + Collection<@NonNull RedisServer> replicas(@NonNull NamedNode master); /** * Removes given {@literal master}. The server will no longer be monitored and will no longer be returned by @@ -55,7 +59,7 @@ public interface RedisSentinelCommands { * * @param master must not be {@literal null}. */ - void remove(NamedNode master); + void remove(@NonNull NamedNode master); /** * Tell sentinel to start monitoring a new {@literal master} with the specified {@link RedisServer#getName()}, @@ -63,6 +67,6 @@ public interface RedisSentinelCommands { * * @param master must not be {@literal null}. */ - void monitor(RedisServer master); + void monitor(@NonNull RedisServer master); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSentinelConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisSentinelConfiguration.java index 5839a8f701..ade8ca4ea3 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSentinelConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSentinelConfiguration.java @@ -23,10 +23,10 @@ import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.data.redis.connection.RedisConfiguration.SentinelConfiguration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -205,8 +205,7 @@ public void setMaster(NamedNode master) { this.master = master; } - @Nullable - public NamedNode getMaster() { + public @Nullable NamedNode getMaster() { return master; } @@ -275,9 +274,8 @@ public void setUsername(@Nullable String username) { this.dataNodeUsername = username; } - @Nullable @Override - public String getUsername() { + public @Nullable String getUsername() { return this.dataNodeUsername; } @@ -294,9 +292,8 @@ public void setPassword(RedisPassword password) { this.dataNodePassword = password; } - @Nullable @Override - public String getSentinelUsername() { + public @Nullable String getSentinelUsername() { return this.sentinelUsername; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSentinelConnection.java b/src/main/java/org/springframework/data/redis/connection/RedisSentinelConnection.java index 34f0db6003..00f06b11c8 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSentinelConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSentinelConnection.java @@ -17,10 +17,13 @@ import java.io.Closeable; +import org.jspecify.annotations.NullUnmarked; + /** * @author Christoph Strobl * @since 1.4 */ +@NullUnmarked public interface RedisSentinelConnection extends RedisSentinelCommands, Closeable { /** diff --git a/src/main/java/org/springframework/data/redis/connection/RedisServer.java b/src/main/java/org/springframework/data/redis/connection/RedisServer.java index bd363598c6..39fe3a8c5d 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisServer.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisServer.java @@ -17,6 +17,7 @@ import java.util.Properties; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -79,10 +80,10 @@ public RedisServer(String host, int port) { * @param port * @param properties may be {@literal null} */ - public RedisServer(String host, int port, Properties properties) { + public RedisServer(String host, int port, @Nullable Properties properties) { super(host, port); - this.properties = properties; + this.properties = properties != null ? properties : new Properties(); String name = host + ":" + port; if (properties != null && properties.containsKey(INFO.NAME.key)) { @@ -106,7 +107,7 @@ public static RedisServer newServerFrom(Properties properties) { return new RedisServer(host, port, properties); } - public void setQuorum(Long quorum) { + public void setQuorum(@Nullable Long quorum) { if (quorum == null) { this.properties.remove(INFO.QUORUM.key); @@ -116,11 +117,11 @@ public void setQuorum(Long quorum) { this.properties.put(INFO.QUORUM.key, quorum.toString()); } - public String getRunId() { + public @Nullable String getRunId() { return get(INFO.RUN_ID); } - public String getFlags() { + public @Nullable String getFlags() { return get(INFO.FLAGS); } @@ -133,35 +134,35 @@ public boolean isMaster() { return role.equalsIgnoreCase("master"); } - public Long getPendingCommands() { + public @Nullable Long getPendingCommands() { return getLongValueOf(INFO.PENDING_COMMANDS); } - public Long getLastPingSent() { + public @Nullable Long getLastPingSent() { return getLongValueOf(INFO.LAST_PING_SENT); } - public Long getLastOkPingReply() { + public @Nullable Long getLastOkPingReply() { return getLongValueOf(INFO.LAST_OK_PING_REPLY); } - public Long getDownAfterMilliseconds() { + public @Nullable Long getDownAfterMilliseconds() { return getLongValueOf(INFO.DOWN_AFTER_MILLISECONDS); } - public Long getInfoRefresh() { + public @Nullable Long getInfoRefresh() { return getLongValueOf(INFO.INFO_REFRESH); } - public String getRoleReported() { + public @Nullable String getRoleReported() { return get(INFO.ROLE_REPORTED); } - public Long roleReportedTime() { + public @Nullable Long roleReportedTime() { return getLongValueOf(INFO.ROLE_REPORTED_TIME); } - public Long getConfigEpoch() { + public @Nullable Long getConfigEpoch() { return getLongValueOf(INFO.CONFIG_EPOCH); } @@ -171,23 +172,23 @@ public Long getConfigEpoch() { * @return * @since 2.1 */ - public Long getNumberReplicas() { + public @Nullable Long getNumberReplicas() { return getLongValueOf(INFO.NUMBER_SLAVES); } - public Long getNumberOtherSentinels() { + public @Nullable Long getNumberOtherSentinels() { return getLongValueOf(INFO.NUMBER_OTHER_SENTINELS); } - public Long getQuorum() { + public @Nullable Long getQuorum() { return getLongValueOf(INFO.QUORUM); } - public Long getFailoverTimeout() { + public @Nullable Long getFailoverTimeout() { return getLongValueOf(INFO.FAILOVER_TIMEOUT); } - public Long getParallelSyncs() { + public @Nullable Long getParallelSyncs() { return getLongValueOf(INFO.PARALLEL_SYNCS); } @@ -195,7 +196,7 @@ public Long getParallelSyncs() { * @param info must not be null * @return {@literal null} if no entry found for requested {@link INFO}. */ - public String get(INFO info) { + public @Nullable String get(INFO info) { Assert.notNull(info, "Cannot retrieve client information for 'null'"); return get(info.key); @@ -205,13 +206,13 @@ public String get(INFO info) { * @param key must not be {@literal null} or {@literal empty}. * @return {@literal null} if no entry found for requested {@code key}. */ - public String get(String key) { + public @Nullable String get(String key) { Assert.hasText(key, "Cannot get information for 'empty' / 'null' key."); return this.properties.getProperty(key); } - private Long getLongValueOf(INFO info) { + private @Nullable Long getLongValueOf(INFO info) { String value = get(info); return value == null ? null : Long.valueOf(value); diff --git a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java index f21e6281fd..9f2c1f4aab 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java @@ -19,8 +19,10 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.types.RedisClientInfo; -import org.springframework.lang.Nullable; /** * Server-specific commands supported by Redis. @@ -31,6 +33,7 @@ * @author Mark Paluch * @author Dennis Neufeld */ +@NullUnmarked public interface RedisServerCommands { enum ShutdownOption { @@ -72,7 +75,6 @@ enum FlushOption { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LASTSAVE */ - @Nullable Long lastSave(); /** @@ -88,7 +90,6 @@ enum FlushOption { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DBSIZE */ - @Nullable Long dbSize(); /** @@ -105,7 +106,7 @@ enum FlushOption { * @see Redis Documentation: FLUSHDB * @since 2.7 */ - void flushDb(FlushOption option); + void flushDb(@NonNull FlushOption option); /** * Delete all all keys from all databases. @@ -121,7 +122,7 @@ enum FlushOption { * @see Redis Documentation: FLUSHALL * @since 2.7 */ - void flushAll(FlushOption option); + void flushAll(@NonNull FlushOption option); /** * Load {@literal default} server information like @@ -134,7 +135,6 @@ enum FlushOption { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INFO */ - @Nullable Properties info(); /** @@ -143,8 +143,7 @@ enum FlushOption { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INFO */ - @Nullable - Properties info(String section); + Properties info(@NonNull String section); /** * Shutdown server. @@ -156,10 +155,11 @@ enum FlushOption { /** * Shutdown server. * + * @param option shutdown options if applicable. * @see Redis Documentation: SHUTDOWN * @since 1.3 */ - void shutdown(ShutdownOption option); + void shutdown(@Nullable ShutdownOption option); /** * Load configuration parameters for given {@code pattern} from server. @@ -168,8 +168,7 @@ enum FlushOption { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: CONFIG GET */ - @Nullable - Properties getConfig(String pattern); + Properties getConfig(@NonNull String pattern); /** * Set server configuration for {@code param} to {@code value}. @@ -178,7 +177,7 @@ enum FlushOption { * @param value must not be {@literal null}. * @see Redis Documentation: CONFIG SET */ - void setConfig(String param, String value); + void setConfig(@NonNull String param, @NonNull String value); /** * Reset statistic counters on server.
@@ -203,7 +202,6 @@ enum FlushOption { * @since 1.1 * @see Redis Documentation: TIME */ - @Nullable default Long time() { return time(TimeUnit.MILLISECONDS); } @@ -216,8 +214,7 @@ default Long time() { * @since 2.5 * @see Redis Documentation: TIME */ - @Nullable - Long time(TimeUnit timeUnit); + Long time(@NonNull TimeUnit timeUnit); /** * Closes a given client connection identified by {@literal host:port}. @@ -227,7 +224,7 @@ default Long time() { * @since 1.3 * @see Redis Documentation: CLIENT KILL */ - void killClient(String host, int port); + void killClient(@NonNull String host, int port); /** * Assign given name to current connection. @@ -236,7 +233,7 @@ default Long time() { * @since 1.3 * @see Redis Documentation: CLIENT SETNAME */ - void setClientName(byte[] name); + void setClientName(byte @NonNull [] name); /** * Returns the name of the current connection. @@ -245,7 +242,6 @@ default Long time() { * @return {@literal null} when used in pipeline / transaction. * @since 1.3 */ - @Nullable String getClientName(); /** @@ -255,8 +251,7 @@ default Long time() { * @since 1.3 * @see Redis Documentation: CLIENT LIST */ - @Nullable - List getClientList(); + List<@NonNull RedisClientInfo> getClientList(); /** * Change redis replication setting to new master. @@ -266,7 +261,7 @@ default Long time() { * @since 3.0 * @see Redis Documentation: REPLICAOF */ - void replicaOf(String host, int port); + void replicaOf(@NonNull String host, int port); /** * Change server into master. @@ -287,7 +282,7 @@ default Long time() { * @since 1.7 * @see Redis Documentation: MIGRATE */ - void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option); + void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option); /** * Atomically transfer a key from a source Redis instance to a destination Redis instance. On success the key is @@ -301,6 +296,7 @@ default Long time() { * @since 1.7 * @see Redis Documentation: MIGRATE */ - void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout); + void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option, + long timeout); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java index 26dcb1976f..f46a3fe19a 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSetCommands.java @@ -18,9 +18,10 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; /** * Set-specific commands supported by Redis. @@ -29,6 +30,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked public interface RedisSetCommands { /** @@ -39,8 +41,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SADD */ - @Nullable - Long sAdd(byte[] key, byte[]... values); + Long sAdd(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Remove given {@code values} from set at {@code key} and return the number of removed elements. @@ -50,8 +51,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SREM */ - @Nullable - Long sRem(byte[] key, byte[]... values); + Long sRem(byte @NonNull [] key, byte @NonNull []... values); /** * Remove and return a random member from set at {@code key}. @@ -60,8 +60,7 @@ public interface RedisSetCommands { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: SPOP */ - @Nullable - byte[] sPop(byte[] key); + byte[] sPop(byte @NonNull [] key); /** * Remove and return {@code count} random members from set at {@code key}. @@ -72,8 +71,7 @@ public interface RedisSetCommands { * @see Redis Documentation: SPOP * @since 2.0 */ - @Nullable - List sPop(byte[] key, long count); + List sPop(byte @NonNull [] key, long count); /** * Move {@code value} from {@code srcKey} to {@code destKey} @@ -84,8 +82,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMOVE */ - @Nullable - Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value); + Boolean sMove(byte @NonNull [] srcKey, byte @NonNull [] destKey, byte @NonNull [] value); /** * Get size of set at {@code key}. @@ -94,8 +91,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SCARD */ - @Nullable - Long sCard(byte[] key); + Long sCard(byte @NonNull [] key); /** * Check if set at {@code key} contains {@code value}. @@ -105,8 +101,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SISMEMBER */ - @Nullable - Boolean sIsMember(byte[] key, byte[] value); + Boolean sIsMember(byte @NonNull [] key, byte @NonNull [] value); /** * Check if set at {@code key} contains one or more {@code values}. @@ -117,8 +112,7 @@ public interface RedisSetCommands { * @since 2.6 * @see Redis Documentation: SMISMEMBER */ - @Nullable - List sMIsMember(byte[] key, byte[]... values); + List<@NonNull Boolean> sMIsMember(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Diff all sets for given {@code keys}. @@ -127,8 +121,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFF */ - @Nullable - Set sDiff(byte[]... keys); + Set sDiff(byte @NonNull [] @NonNull... keys); /** * Diff all sets for given {@code keys} and store result in {@code destKey}. @@ -138,8 +131,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFFSTORE */ - @Nullable - Long sDiffStore(byte[] destKey, byte[]... keys); + Long sDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys); /** * Returns the members intersecting all given sets at {@code keys}. @@ -148,8 +140,7 @@ public interface RedisSetCommands { * @return empty {@link Set} if no intersection found. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTER */ - @Nullable - Set sInter(byte[]... keys); + Set sInter(byte @NonNull [] @NonNull... keys); /** * Intersect all given sets at {@code keys} and store result in {@code destKey}. @@ -159,8 +150,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTERSTORE */ - @Nullable - Long sInterStore(byte[] destKey, byte[]... keys); + Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys); /** * Union all sets at given {@code keys}. @@ -169,8 +159,7 @@ public interface RedisSetCommands { * @return empty {@link Set} if keys do not exist. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNION */ - @Nullable - Set sUnion(byte[]... keys); + Set sUnion(byte @NonNull [] @NonNull... keys); /** * Union all sets at given {@code keys} and store result in {@code destKey}. @@ -180,9 +169,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNIONSTORE */ - @Nullable - Long sUnionStore(byte[] destKey, byte[]... keys); - + Long sUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys); /** * Get all elements of set at {@code key}. @@ -191,8 +178,7 @@ public interface RedisSetCommands { * @return empty {@link Set} when key does not exist. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMEMBERS */ - @Nullable - Set sMembers(byte[] key); + Set sMembers(byte @NonNull [] key); /** * Get random element from set at {@code key}. @@ -201,8 +187,7 @@ public interface RedisSetCommands { * @return can be {@literal null}. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - byte[] sRandMember(byte[] key); + byte[] sRandMember(byte @NonNull [] key); /** * Get {@code count} random elements from set at {@code key}. @@ -212,8 +197,7 @@ public interface RedisSetCommands { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - List sRandMember(byte[] key, long count); + List sRandMember(byte @NonNull [] key, long count); /** * Use a {@link Cursor} to iterate over elements in set at {@code key}. @@ -224,5 +208,5 @@ public interface RedisSetCommands { * @since 1.4 * @see Redis Documentation: SCAN */ - Cursor sScan(byte[] key, ScanOptions options); + Cursor sScan(byte @NonNull [] key, ScanOptions options); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSocketConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisSocketConfiguration.java index e48799a659..eefd058efd 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSocketConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSocketConfiguration.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.connection; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConfiguration.DomainSocketConfiguration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -84,9 +84,8 @@ public void setUsername(@Nullable String username) { this.username = username; } - @Nullable @Override - public String getUsername() { + public @Nullable String getUsername() { return this.username; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStandaloneConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisStandaloneConfiguration.java index 8acb2a3be8..e2aa342ab6 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStandaloneConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStandaloneConfiguration.java @@ -15,10 +15,10 @@ */ package org.springframework.data.redis.connection; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConfiguration.WithDatabaseIndex; import org.springframework.data.redis.connection.RedisConfiguration.WithHostAndPort; import org.springframework.data.redis.connection.RedisConfiguration.WithPassword; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -113,9 +113,8 @@ public void setUsername(@Nullable String username) { this.username = username; } - @Nullable @Override - public String getUsername() { + public @Nullable String getUsername() { return this.username; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java index 66dd6f6051..132aaa7a93 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConfiguration.StaticMasterReplicaConfiguration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -129,9 +129,8 @@ public void setUsername(@Nullable String username) { this.username = username; } - @Nullable @Override - public String getUsername() { + public @Nullable String getUsername() { return this.username; } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisStreamCommands.java index 8385d70d34..f7a6fe6ad7 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStreamCommands.java @@ -23,12 +23,25 @@ import java.util.Map; import java.util.stream.Collectors; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; -import org.springframework.data.redis.connection.stream.*; +import org.springframework.data.redis.connection.stream.ByteRecord; +import org.springframework.data.redis.connection.stream.Consumer; +import org.springframework.data.redis.connection.stream.MapRecord; +import org.springframework.data.redis.connection.stream.PendingMessage; +import org.springframework.data.redis.connection.stream.PendingMessages; +import org.springframework.data.redis.connection.stream.PendingMessagesSummary; +import org.springframework.data.redis.connection.stream.ReadOffset; +import org.springframework.data.redis.connection.stream.RecordId; import org.springframework.data.redis.connection.stream.StreamInfo.XInfoConsumers; import org.springframework.data.redis.connection.stream.StreamInfo.XInfoGroups; import org.springframework.data.redis.connection.stream.StreamInfo.XInfoStream; -import org.springframework.lang.Nullable; +import org.springframework.data.redis.connection.stream.StreamOffset; +import org.springframework.data.redis.connection.stream.StreamReadOptions; +import org.springframework.data.redis.connection.stream.StreamRecords; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -44,6 +57,7 @@ * @see Redis Documentation - Streams * @since 2.2 */ +@NullUnmarked public interface RedisStreamCommands { /** @@ -55,8 +69,7 @@ public interface RedisStreamCommands { * @return length of acknowledged messages. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - @Nullable - default Long xAck(byte[] key, String group, String... recordIds) { + default Long xAck(byte @NonNull [] key, @NonNull String group, @NonNull String @NonNull... recordIds) { return xAck(key, group, Arrays.stream(recordIds).map(RecordId::of).toArray(RecordId[]::new)); } @@ -69,8 +82,7 @@ default Long xAck(byte[] key, String group, String... recordIds) { * @return length of acknowledged messages. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - @Nullable - Long xAck(byte[] key, String group, RecordId... recordIds); + Long xAck(byte @NonNull [] key, @NonNull String group, @NonNull RecordId @NonNull... recordIds); /** * Append a new record with the given {@link Map field/value pairs} as content to the stream stored at {@code key}. @@ -80,8 +92,7 @@ default Long xAck(byte[] key, String group, String... recordIds) { * @return the server generated {@link RecordId id}. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XADD */ - @Nullable - default RecordId xAdd(byte[] key, Map content) { + default RecordId xAdd(byte @NonNull [] key, @NonNull Map content) { return xAdd(StreamRecords.newRecord().in(key).ofMap(content)); } @@ -92,8 +103,7 @@ default RecordId xAdd(byte[] key, Map content) { * @param record the {@link MapRecord record} to append. * @return the {@link RecordId id} after save. {@literal null} when used in pipeline / transaction. */ - @Nullable - default RecordId xAdd(MapRecord record) { + default RecordId xAdd(@NonNull MapRecord record) { return xAdd(record, XAddOptions.none()); } @@ -107,8 +117,7 @@ default RecordId xAdd(MapRecord record) { * @return the {@link RecordId id} after save. {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - RecordId xAdd(MapRecord record, XAddOptions options); + RecordId xAdd(MapRecord record, @NonNull XAddOptions options); /** * Additional options applicable for {@literal XADD} command. @@ -118,6 +127,7 @@ default RecordId xAdd(MapRecord record) { * @author Liming Deng * @since 2.3 */ + @NullMarked class XAddOptions { private static final XAddOptions NONE = new XAddOptions(null, false, false, null); @@ -205,8 +215,7 @@ public boolean isNoMkStream() { * * @return can be {@literal null}. */ - @Nullable - public Long getMaxlen() { + public @Nullable Long getMaxlen() { return maxlen; } @@ -228,8 +237,7 @@ public boolean isApproximateTrimming() { * @return the minimum record Id to retain during trimming. * @since 2.7 */ - @Nullable - public RecordId getMinId() { + public @Nullable RecordId getMinId() { return minId; } @@ -283,8 +291,8 @@ public int hashCode() { * @see Redis Documentation: XCLAIM * @since 2.3 */ - @Nullable - List xClaimJustId(byte[] key, String group, String newOwner, XClaimOptions options); + List<@NonNull RecordId> xClaimJustId(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options); /** * Change the ownership of a pending message to the given new {@literal consumer}. @@ -298,9 +306,8 @@ public int hashCode() { * @see Redis Documentation: XCLAIM * @since 2.3 */ - @Nullable - default List xClaim(byte[] key, String group, String newOwner, Duration minIdleTime, - RecordId... recordIds) { + default List<@NonNull ByteRecord> xClaim(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull Duration minIdleTime, @NonNull RecordId @NonNull... recordIds) { return xClaim(key, group, newOwner, XClaimOptions.minIdle(minIdleTime).ids(recordIds)); } @@ -315,13 +322,14 @@ default List xClaim(byte[] key, String group, String newOwner, Durat * @see Redis Documentation: XCLAIM * @since 2.3 */ - @Nullable - List xClaim(byte[] key, String group, String newOwner, XClaimOptions options); + List<@NonNull ByteRecord> xClaim(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options); /** * @author Christoph Strobl * @since 2.3 */ + @NullMarked class XClaimOptions { private final List ids; @@ -438,8 +446,7 @@ public Duration getMinIdleTime() { * * @return can be {@literal null}. */ - @Nullable - public Duration getIdleTime() { + public @Nullable Duration getIdleTime() { return idleTime; } @@ -448,8 +455,7 @@ public Duration getIdleTime() { * * @return */ - @Nullable - public Instant getUnixTime() { + public @Nullable Instant getUnixTime() { return unixTime; } @@ -458,8 +464,7 @@ public Instant getUnixTime() { * * @return */ - @Nullable - public Long getRetryCount() { + public @Nullable Long getRetryCount() { return retryCount; } @@ -472,6 +477,7 @@ public boolean isForce() { return force; } + @NullMarked public static class XClaimOptionsBuilder { private final Duration minIdleTime; @@ -529,8 +535,7 @@ public XClaimOptions ids(String... ids) { * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XDEL */ - @Nullable - default Long xDel(byte[] key, String... recordIds) { + default Long xDel(byte @NonNull [] key, @NonNull String @NonNull... recordIds) { return xDel(key, Arrays.stream(recordIds).map(RecordId::of).toArray(RecordId[]::new)); } @@ -543,8 +548,7 @@ default Long xDel(byte[] key, String... recordIds) { * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XDEL */ - @Nullable - Long xDel(byte[] key, RecordId... recordIds); + Long xDel(byte @NonNull [] key, @NonNull RecordId @NonNull... recordIds); /** * Create a consumer group. @@ -554,8 +558,7 @@ default Long xDel(byte[] key, String... recordIds) { * @param readOffset the offset to start at. * @return {@literal ok} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset); + String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset); /** * Create a consumer group. @@ -567,8 +570,8 @@ default Long xDel(byte[] key, String... recordIds) { * @return {@literal ok} if successful. {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, boolean mkStream); + String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset, + boolean mkStream); /** * Delete a consumer from a consumer group. @@ -578,8 +581,7 @@ default Long xDel(byte[] key, String... recordIds) { * @param consumerName the name of the consumer to remove from the group. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerName) { + default Boolean xGroupDelConsumer(byte @NonNull [] key, @NonNull String groupName, @NonNull String consumerName) { return xGroupDelConsumer(key, Consumer.from(groupName, consumerName)); } @@ -590,8 +592,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @param consumer consumer identified by group name and consumer name. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean xGroupDelConsumer(byte[] key, Consumer consumer); + Boolean xGroupDelConsumer(byte @NonNull [] key, @NonNull Consumer consumer); /** * Destroy a consumer group. @@ -600,8 +601,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @param groupName name of the consumer group. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean xGroupDestroy(byte[] key, String groupName); + Boolean xGroupDestroy(byte @NonNull [] key, @NonNull String groupName); /** * Obtain general information about the stream stored at the specified {@literal key}. @@ -610,8 +610,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoStream xInfo(byte[] key); + XInfoStream xInfo(byte @NonNull [] key); /** * Obtain information about {@literal consumer groups} associated with the stream stored at the specified @@ -621,8 +620,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoGroups xInfoGroups(byte[] key); + XInfoGroups xInfoGroups(byte @NonNull [] key); /** * Obtain information about every consumer in a specific {@literal consumer group} for the stream stored at the @@ -633,8 +631,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoConsumers xInfoConsumers(byte[] key, String groupName); + XInfoConsumers xInfoConsumers(byte @NonNull [] key, @NonNull String groupName); /** * Get the length of a stream. @@ -643,8 +640,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @return length of the stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XLEN */ - @Nullable - Long xLen(byte[] key); + Long xLen(byte @NonNull [] key); /** * Obtain the {@link PendingMessagesSummary} for a given {@literal consumer group}. @@ -657,7 +653,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @since 2.3 */ @Nullable - PendingMessagesSummary xPending(byte[] key, String groupName); + PendingMessagesSummary xPending(byte @NonNull [] key, @NonNull String groupName); /** * Obtained detailed information about all pending messages for a given {@link Consumer}. @@ -668,8 +664,7 @@ default Boolean xGroupDelConsumer(byte[] key, String groupName, String consumerN * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - default PendingMessages xPending(byte[] key, Consumer consumer) { + default PendingMessages xPending(byte @NonNull [] key, @NonNull Consumer consumer) { return xPending(key, consumer.getGroup(), consumer.getName()); } @@ -683,8 +678,7 @@ default PendingMessages xPending(byte[] key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - default PendingMessages xPending(byte[] key, String groupName, String consumerName) { + default PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull String consumerName) { return xPending(key, groupName, XPendingOptions.unbounded().consumer(consumerName)); } @@ -701,8 +695,8 @@ default PendingMessages xPending(byte[] key, String groupName, String consumerNa * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - default PendingMessages xPending(byte[] key, String groupName, Range range, Long count) { + default PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull Range range, + @NonNull Long count) { return xPending(key, groupName, XPendingOptions.range(range, count)); } @@ -718,8 +712,8 @@ default PendingMessages xPending(byte[] key, String groupName, Range range, L * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - default PendingMessages xPending(byte[] key, Consumer consumer, Range range, Long count) { + default PendingMessages xPending(byte @NonNull [] key, @NonNull Consumer consumer, @NonNull Range range, + @NonNull Long count) { return xPending(key, consumer.getGroup(), consumer.getName(), range, count); } @@ -737,8 +731,8 @@ default PendingMessages xPending(byte[] key, Consumer consumer, Range range, * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - default PendingMessages xPending(byte[] key, String groupName, String consumerName, Range range, Long count) { + default PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull String consumerName, + @NonNull Range range, @NonNull Long count) { return xPending(key, groupName, XPendingOptions.range(range, count).consumer(consumerName)); } @@ -754,8 +748,7 @@ default PendingMessages xPending(byte[] key, String groupName, String consumerNa * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessages xPending(byte[] key, String groupName, XPendingOptions options); + PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull XPendingOptions options); /** * Value Object holding parameters for obtaining pending messages. @@ -763,6 +756,7 @@ default PendingMessages xPending(byte[] key, String groupName, String consumerNa * @author Christoph Strobl * @since 2.3 */ + @NullMarked class XPendingOptions { private final @Nullable String consumerName; @@ -833,16 +827,14 @@ public Range getRange() { /** * @return can be {@literal null}. */ - @Nullable - public Long getCount() { + public @Nullable Long getCount() { return count; } /** * @return can be {@literal null}. */ - @Nullable - public String getConsumerName() { + public @Nullable String getConsumerName() { return consumerName; } @@ -871,8 +863,7 @@ public boolean isLimited() { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - default List xRange(byte[] key, Range range) { + default List<@NonNull ByteRecord> xRange(byte @NonNull [] key, @NonNull Range<@NonNull String> range) { return xRange(key, range, Limit.unlimited()); } @@ -888,8 +879,7 @@ default List xRange(byte[] key, Range range) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - List xRange(byte[] key, Range range, Limit limit); + List<@NonNull ByteRecord> xRange(byte @NonNull [] key, @NonNull Range<@NonNull String> range, @NonNull Limit limit); /** * Read records from one or more {@link StreamOffset}s. @@ -898,8 +888,7 @@ default List xRange(byte[] key, Range range) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - default List xRead(StreamOffset... streams) { + default List<@NonNull ByteRecord> xRead(StreamOffset @NonNull... streams) { return xRead(StreamReadOptions.empty(), streams); } @@ -911,8 +900,8 @@ default List xRead(StreamOffset... streams) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - List xRead(StreamReadOptions readOptions, StreamOffset... streams); + List<@NonNull ByteRecord> xRead(@NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams); /** * Read records from one or more {@link StreamOffset}s using a consumer group. @@ -922,8 +911,8 @@ default List xRead(StreamOffset... streams) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - default List xReadGroup(Consumer consumer, StreamOffset... streams) { + default List<@NonNull ByteRecord> xReadGroup(@NonNull Consumer consumer, + @NonNull StreamOffset @NonNull... streams) { return xReadGroup(consumer, StreamReadOptions.empty(), streams); } @@ -936,8 +925,8 @@ default List xReadGroup(Consumer consumer, StreamOffset... s * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - List xReadGroup(Consumer consumer, StreamReadOptions readOptions, StreamOffset... streams); + List<@NonNull ByteRecord> xReadGroup(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams); /** * Read records from a stream within a specific {@link Range} in reverse order. @@ -947,8 +936,7 @@ default List xReadGroup(Consumer consumer, StreamOffset... s * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - default List xRevRange(byte[] key, Range range) { + default List<@NonNull ByteRecord> xRevRange(byte @NonNull [] key, @NonNull Range<@NonNull String> range) { return xRevRange(key, range, Limit.unlimited()); } @@ -961,8 +949,8 @@ default List xRevRange(byte[] key, Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - List xRevRange(byte[] key, Range range, Limit limit); + List<@NonNull ByteRecord> xRevRange(byte @NonNull [] key, @NonNull Range<@NonNull String> range, + @NonNull Limit limit); /** * Trims the stream to {@code count} elements. @@ -972,8 +960,7 @@ default List xRevRange(byte[] key, Range range) { * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XTRIM */ - @Nullable - Long xTrim(byte[] key, long count); + Long xTrim(byte @NonNull [] key, long count); /** * Trims the stream to {@code count} elements. @@ -985,6 +972,5 @@ default List xRevRange(byte[] key, Range range) { * @since 2.4 * @see Redis Documentation: XTRIM */ - @Nullable - Long xTrim(byte[] key, long count, boolean approximateTrimming); + Long xTrim(byte @NonNull [] key, long count, boolean approximateTrimming); } diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java index f591be4245..0ab0694dc0 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStringCommands.java @@ -19,9 +19,11 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; /** * String/Value-specific commands supported by Redis. @@ -31,6 +33,7 @@ * @author Mark Paluch * @author Marcin Grzejszczak */ +@NullUnmarked public interface RedisStringCommands { enum BitOperation { @@ -44,8 +47,7 @@ enum BitOperation { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: GET */ - @Nullable - byte[] get(byte[] key); + byte[] get(byte @NonNull [] key); /** * Return the value at {@code key} and delete the key. @@ -55,8 +57,7 @@ enum BitOperation { * @see Redis Documentation: GETDEL * @since 2.6 */ - @Nullable - byte[] getDel(byte[] key); + byte[] getDel(byte @NonNull [] key); /** * Return the value at {@code key} and expire the key by applying {@link Expiration}. @@ -71,8 +72,7 @@ enum BitOperation { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - byte[] getEx(byte[] key, Expiration expiration); + byte[] getEx(byte @NonNull [] key, @NonNull Expiration expiration); /** * Set {@code value} of {@code key} and return its old value. @@ -82,8 +82,7 @@ enum BitOperation { * @return {@literal null} if key did not exist before or when used in pipeline / transaction. * @see Redis Documentation: GETSET */ - @Nullable - byte[] getSet(byte[] key, byte[] value); + byte[] getSet(byte @NonNull [] key, byte @NonNull [] value); /** * Get multiple {@code keys}. Values are in the order of the requested keys Absent field values are represented using @@ -93,8 +92,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MGET */ - @Nullable - List mGet(byte[]... keys); + List mGet(byte @NonNull [] @NonNull... keys); /** * Set {@code value} for {@code key}. @@ -104,8 +102,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SET */ - @Nullable - Boolean set(byte[] key, byte[] value); + Boolean set(byte @NonNull [] key, byte @NonNull [] value); /** * Set {@code value} for {@code key} applying timeouts from {@code expiration} if set and inserting/updating values @@ -120,8 +117,7 @@ enum BitOperation { * @since 1.7 * @see Redis Documentation: SET */ - @Nullable - Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option); + Boolean set(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, @NonNull SetOption option); /** * Set {@code value} for {@code key}. Return the old string stored at key, or {@literal null} if key did not exist. An @@ -136,8 +132,8 @@ enum BitOperation { * @since 3.5 * @see Redis Documentation: SET */ - @Nullable - byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption option); + byte[] setGet(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option); /** * Set {@code value} for {@code key}, only if {@code key} does not exist. @@ -147,8 +143,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SETNX */ - @Nullable - Boolean setNX(byte[] key, byte[] value); + Boolean setNX(byte @NonNull [] key, byte @NonNull [] value); /** * Set the {@code value} and expiration in {@code seconds} for {@code key}. @@ -159,8 +154,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SETEX */ - @Nullable - Boolean setEx(byte[] key, long seconds, byte[] value); + Boolean setEx(byte @NonNull [] key, long seconds, byte @NonNull [] value); /** * Set the {@code value} and expiration in {@code milliseconds} for {@code key}. @@ -172,8 +166,7 @@ enum BitOperation { * @since 1.3 * @see Redis Documentation: PSETEX */ - @Nullable - Boolean pSetEx(byte[] key, long milliseconds, byte[] value); + Boolean pSetEx(byte @NonNull [] key, long milliseconds, byte @NonNull [] value); /** * Set multiple keys to multiple values using key-value pairs provided in {@code tuple}. @@ -182,8 +175,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MSET */ - @Nullable - Boolean mSet(Map tuple); + Boolean mSet(@NonNull Map tuple); /** * Set multiple keys to multiple values using key-value pairs provided in {@code tuple} only if the provided key does @@ -193,8 +185,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MSETNX */ - @Nullable - Boolean mSetNX(Map tuple); + Boolean mSetNX( @NonNull Map tuple); /** * Increment an integer value stored as string value of {@code key} by 1. @@ -203,8 +194,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCR */ - @Nullable - Long incr(byte[] key); + Long incr(byte @NonNull [] key); /** * Increment an integer value stored of {@code key} by {@code delta}. @@ -214,8 +204,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBY */ - @Nullable - Long incrBy(byte[] key, long value); + Long incrBy(byte @NonNull [] key, long value); /** * Increment a floating point number value of {@code key} by {@code delta}. @@ -225,8 +214,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBYFLOAT */ - @Nullable - Double incrBy(byte[] key, double value); + Double incrBy(byte @NonNull [] key, double value); /** * Decrement an integer value stored as string value of {@code key} by 1. @@ -235,8 +223,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DECR */ - @Nullable - Long decr(byte[] key); + Long decr(byte @NonNull [] key); /** * Decrement an integer value stored as string value of {@code key} by {@code value}. @@ -246,8 +233,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DECRBY */ - @Nullable - Long decrBy(byte[] key, long value); + Long decrBy(byte @NonNull [] key, long value); /** * Append a {@code value} to {@code key}. @@ -257,8 +243,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: APPEND */ - @Nullable - Long append(byte[] key, byte[] value); + Long append(byte @NonNull [] key, byte[] value); /** * Get a substring of value of {@code key} between {@code start} and {@code end}. @@ -269,8 +254,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GETRANGE */ - @Nullable - byte[] getRange(byte[] key, long start, long end); + byte[] getRange(byte @NonNull [] key, long start, long end); /** * Overwrite parts of {@code key} starting at the specified {@code offset} with given {@code value}. @@ -280,7 +264,7 @@ enum BitOperation { * @param offset * @see Redis Documentation: SETRANGE */ - void setRange(byte[] key, byte[] value, long offset); + void setRange(byte @NonNull [] key, byte @NonNull [] value, long offset); /** * Get the bit value at {@code offset} of value at {@code key}. @@ -290,8 +274,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GETBIT */ - @Nullable - Boolean getBit(byte[] key, long offset); + Boolean getBit(byte @NonNull [] key, long offset); /** * Sets the bit at {@code offset} in value stored at {@code key}. @@ -302,8 +285,7 @@ enum BitOperation { * @return the original bit value stored at {@code offset} or {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SETBIT */ - @Nullable - Boolean setBit(byte[] key, long offset, boolean value); + Boolean setBit(byte @NonNull [] key, long offset, boolean value); /** * Count the number of set bits (population counting) in value stored at {@code key}. @@ -312,8 +294,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: BITCOUNT */ - @Nullable - Long bitCount(byte[] key); + Long bitCount(byte @NonNull [] key); /** * Count the number of set bits (population counting) of value stored at {@code key} between {@code start} and @@ -325,8 +306,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: BITCOUNT */ - @Nullable - Long bitCount(byte[] key, long start, long end); + Long bitCount(byte @NonNull [] key, long start, long end); /** * Get / Manipulate specific integer fields of varying bit widths and arbitrary non (necessary) aligned offset stored @@ -337,8 +317,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @since 2.1 */ - @Nullable - List bitField(byte[] key, BitFieldSubCommands subCommands); + List bitField(byte @NonNull [] key, @NonNull BitFieldSubCommands subCommands); /** * Perform bitwise operations between strings. @@ -349,8 +328,7 @@ enum BitOperation { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: BITOP */ - @Nullable - Long bitOp(BitOperation op, byte[] destination, byte[]... keys); + Long bitOp(@NonNull BitOperation op, byte @NonNull [] destination, byte @NonNull [] @NonNull... keys); /** * Return the position of the first bit set to given {@code bit} in a string. @@ -362,8 +340,7 @@ enum BitOperation { * @see Redis Documentation: BITPOS * @since 2.1 */ - @Nullable - default Long bitPos(byte[] key, boolean bit) { + default Long bitPos(byte @NonNull [] key, boolean bit) { return bitPos(key, bit, Range.unbounded()); } @@ -380,8 +357,7 @@ default Long bitPos(byte[] key, boolean bit) { * @see Redis Documentation: BITPOS * @since 2.1 */ - @Nullable - Long bitPos(byte[] key, boolean bit, Range range); + Long bitPos(byte @NonNull [] key, boolean bit, @NonNull Range<@NonNull Long> range); /** * Get the length of the value stored at {@code key}. @@ -390,8 +366,7 @@ default Long bitPos(byte[] key, boolean bit) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: STRLEN */ - @Nullable - Long strLen(byte[] key); + Long strLen(byte @NonNull [] key); /** * {@code SET} command arguments for {@code NX}, {@code XX}. diff --git a/src/main/java/org/springframework/data/redis/connection/RedisSubscribedConnectionException.java b/src/main/java/org/springframework/data/redis/connection/RedisSubscribedConnectionException.java index 846a935c4d..f317e7efc2 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisSubscribedConnectionException.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisSubscribedConnectionException.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.connection; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.lang.Nullable; /** * Exception thrown when issuing commands on a connection that is subscribed and waiting for events. diff --git a/src/main/java/org/springframework/data/redis/connection/RedisTxCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisTxCommands.java index 56ad3634ea..fa5b52ea1a 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisTxCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisTxCommands.java @@ -17,6 +17,10 @@ import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; + /** * Transaction/Batch specific commands supported by Redis. * @@ -24,6 +28,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked public interface RedisTxCommands { /** @@ -41,7 +46,7 @@ public interface RedisTxCommands { * @return List of replies for each executed command. * @see Redis Documentation: EXEC */ - List exec(); + List<@Nullable Object> exec(); /** * Discard all commands issued after {@link #multi()}. @@ -56,7 +61,7 @@ public interface RedisTxCommands { * @param keys must not be {@literal null}. * @see Redis Documentation: WATCH */ - void watch(byte[]... keys); + void watch(byte @NonNull []... keys); /** * Flushes all the previously {@link #watch(byte[]...)} keys. diff --git a/src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java index 6ad0ecd59b..7c9c5c453a 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java @@ -20,12 +20,15 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.zset.Aggregate; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -40,6 +43,7 @@ * @author Andrey Shlykov * @author Shyngys Sapraliyev */ +@NullUnmarked public interface RedisZSetCommands { /** @@ -51,6 +55,7 @@ public interface RedisZSetCommands { * @deprecated since 3.0, use {@link org.springframework.data.domain.Range} or {@link #toRange()} instead. */ @Deprecated + @NullMarked class Range { @Nullable Boundary min; @@ -130,16 +135,14 @@ public Range lt(Object max) { /** * @return {@literal null} if not set. */ - @Nullable - public Boundary getMin() { + public @Nullable Boundary getMin() { return min; } /** * @return {@literal null} if not set. */ - @Nullable - public Boundary getMax() { + public @Nullable Boundary getMax() { return max; } @@ -161,8 +164,7 @@ static Boundary infinite() { this.including = including; } - @Nullable - public Object getValue() { + public @Nullable Object getValue() { return value; } @@ -177,7 +179,7 @@ public boolean isIncluding() { * @return a {@link org.springframework.data.domain.Range} object using bounds from this range. * @since 3.0 */ - public org.springframework.data.domain.Range toRange() { + public org.springframework.data.domain.Range<@NonNull T> toRange() { org.springframework.data.domain.Range.Bound lower = toBound(min); org.springframework.data.domain.Range.Bound upper = toBound(max); @@ -187,7 +189,7 @@ public org.springframework.data.domain.Range toRange() { private org.springframework.data.domain.Range.Bound toBound(@Nullable Boundary boundary) { - if (boundary == null || boundary.value == null) { + if (boundary == null || boundary.getValue() == null) { return org.springframework.data.domain.Range.Bound.unbounded(); } @@ -203,6 +205,7 @@ private org.springframework.data.domain.Range.Bound toBound(@Nullable Bo * @deprecated since 3.0, use {@link org.springframework.data.redis.connection.Limit} instead. */ @Deprecated + @NullMarked class Limit extends org.springframework.data.redis.connection.Limit { } @@ -214,6 +217,7 @@ class Limit extends org.springframework.data.redis.connection.Limit { * @since 2.5 * @see Redis Documentation: ZADD */ + @NullMarked class ZAddArgs { private static final ZAddArgs NONE = new ZAddArgs(EnumSet.noneOf(Flag.class)); @@ -374,8 +378,7 @@ public enum Flag { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - default Boolean zAdd(byte[] key, double score, byte[] value) { + default Boolean zAdd(byte @NonNull [] key, double score, byte @NonNull [] value) { return zAdd(key, score, value, ZAddArgs.NONE); } @@ -391,8 +394,7 @@ default Boolean zAdd(byte[] key, double score, byte[] value) { * @since 2.5 * @see Redis Documentation: ZADD */ - @Nullable - Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args); + Boolean zAdd(byte @NonNull [] key, double score, byte @NonNull [] value, @NonNull ZAddArgs args); /** * Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists. @@ -402,8 +404,7 @@ default Boolean zAdd(byte[] key, double score, byte[] value) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - default Long zAdd(byte[] key, Set tuples) { + default Long zAdd(byte @NonNull [] key, @NonNull Set<@NonNull Tuple> tuples) { return zAdd(key, tuples, ZAddArgs.NONE); } @@ -418,7 +419,7 @@ default Long zAdd(byte[] key, Set tuples) { * @since 2.5 * @see Redis Documentation: ZADD */ - Long zAdd(byte[] key, Set tuples, ZAddArgs args); + Long zAdd(byte @NonNull [] key, @NonNull Set<@NonNull Tuple> tuples, @NonNull ZAddArgs args); /** * Remove {@code values} from sorted set. Return number of removed elements. @@ -428,8 +429,7 @@ default Long zAdd(byte[] key, Set tuples) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREM */ - @Nullable - Long zRem(byte[] key, byte[]... values); + Long zRem(byte @NonNull [] key, byte @NonNull [] @Nullable... values); /** * Increment the score of element with {@code value} in sorted set by {@code increment}. @@ -440,8 +440,7 @@ default Long zAdd(byte[] key, Set tuples) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINCRBY */ - @Nullable - Double zIncrBy(byte[] key, double increment, byte[] value); + Double zIncrBy(byte @NonNull [] key, double increment, byte @NonNull [] value); /** * Get random element from sorted set at {@code key}. @@ -451,8 +450,7 @@ default Long zAdd(byte[] key, Set tuples) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - byte[] zRandMember(byte[] key); + byte @NonNull [] zRandMember(byte @NonNull [] key); /** * Get {@code count} random elements from sorted set at {@code key}. @@ -466,8 +464,7 @@ default Long zAdd(byte[] key, Set tuples) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List zRandMember(byte[] key, long count); + List zRandMember(byte @NonNull [] key, long count); /** * Get random element from sorted set at {@code key}. @@ -477,8 +474,7 @@ default Long zAdd(byte[] key, Set tuples) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - Tuple zRandMemberWithScore(byte[] key); + Tuple zRandMemberWithScore(byte @NonNull [] key); /** * Get {@code count} random elements from sorted set at {@code key}. @@ -492,8 +488,7 @@ default Long zAdd(byte[] key, Set tuples) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List zRandMemberWithScore(byte[] key, long count); + List<@NonNull Tuple> zRandMemberWithScore(byte @NonNull [] key, long count); /** * Determine the index of element with {@code value} in a sorted set. @@ -503,8 +498,7 @@ default Long zAdd(byte[] key, Set tuples) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANK */ - @Nullable - Long zRank(byte[] key, byte[] value); + Long zRank(byte @NonNull [] key, byte @NonNull [] value); /** * Determine the index of element with {@code value} in a sorted set when scored high to low. @@ -514,8 +508,7 @@ default Long zAdd(byte[] key, Set tuples) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANK */ - @Nullable - Long zRevRank(byte[] key, byte[] value); + Long zRevRank(byte @NonNull [] key, byte @NonNull [] value); /** * Get elements between {@code start} and {@code end} from sorted set. @@ -527,8 +520,7 @@ default Long zAdd(byte[] key, Set tuples) { * transaction. * @see Redis Documentation: ZRANGE */ - @Nullable - Set zRange(byte[] key, long start, long end); + Set zRange(byte @NonNull [] key, long start, long end); /** * Get set of {@link Tuple}s between {@code start} and {@code end} from sorted set. @@ -540,8 +532,7 @@ default Long zAdd(byte[] key, Set tuples) { * transaction. * @see Redis Documentation: ZRANGE */ - @Nullable - Set zRangeWithScores(byte[] key, long start, long end); + Set<@NonNull Tuple> zRangeWithScores(byte @NonNull [] key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -553,8 +544,7 @@ default Long zAdd(byte[] key, Set tuples) { * transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScore(byte[] key, double min, double max) { + default Set zRangeByScore(byte @NonNull [] key, double min, double max) { return zRangeByScore(key, org.springframework.data.domain.Range.closed(min, max)); } @@ -568,9 +558,8 @@ default Set zRangeByScore(byte[] key, double min, double max) { * @since 1.6 * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScoreWithScores(byte[] key, - org.springframework.data.domain.Range range) { + default Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRangeByScoreWithScores(key, range, Limit.unlimited()); } @@ -584,8 +573,7 @@ default Set zRangeByScoreWithScores(byte[] key, * transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScoreWithScores(byte[] key, double min, double max) { + default Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, double min, double max) { return zRangeByScoreWithScores(key, org.springframework.data.domain.Range.closed(min, max)); } @@ -602,8 +590,7 @@ default Set zRangeByScoreWithScores(byte[] key, double min, double max) { * transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { + default Set zRangeByScore(byte @NonNull [] key, double min, double max, long offset, long count) { return zRangeByScore(key, org.springframework.data.domain.Range.closed(min, max), new org.springframework.data.redis.connection.Limit().offset(Long.valueOf(offset).intValue()) .count(Long.valueOf(count).intValue())); @@ -622,8 +609,8 @@ default Set zRangeByScore(byte[] key, double min, double max, long offse * transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + default Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, double min, double max, long offset, + long count) { return zRangeByScoreWithScores(key, org.springframework.data.domain.Range.closed(min, max), new org.springframework.data.redis.connection.Limit().offset(Long.valueOf(offset).intValue()) .count(Long.valueOf(count).intValue())); @@ -641,9 +628,9 @@ default Set zRangeByScoreWithScores(byte[] key, double min, double max, l * @since 1.6 * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Get elements in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -655,8 +642,7 @@ Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.R * transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - Set zRevRange(byte[] key, long start, long end); + Set zRevRange(byte @NonNull [] key, long start, long end); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -668,8 +654,7 @@ Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.R * transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - Set zRevRangeWithScores(byte[] key, long start, long end); + Set<@NonNull Tuple> zRevRangeWithScores(byte @NonNull [] key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set ordered from high to low. @@ -681,8 +666,7 @@ Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.R * transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - default Set zRevRangeByScore(byte[] key, double min, double max) { + default Set zRevRangeByScore(byte @NonNull [] key, double min, double max) { return zRevRangeByScore(key, org.springframework.data.domain.Range.closed(min, max)); } @@ -697,8 +681,8 @@ default Set zRevRangeByScore(byte[] key, double min, double max) { * @since 1.6 * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - default Set zRevRangeByScore(byte[] key, org.springframework.data.domain.Range range) { + default Set zRevRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRevRangeByScore(key, range, Limit.unlimited()); } @@ -713,8 +697,7 @@ default Set zRevRangeByScore(byte[] key, org.springframework.data.domain * transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - default Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + default Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, double min, double max) { return zRevRangeByScoreWithScores(key, org.springframework.data.domain.Range.closed(min, max), Limit.unlimited()); } @@ -730,8 +713,8 @@ default Set zRevRangeByScoreWithScores(byte[] key, double min, double max * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - default Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + default Set zRevRangeByScore(byte @NonNull [] key, double min, double max, long offset, + long count) { return zRevRangeByScore(key, org.springframework.data.domain.Range.closed(min, max), new Limit().offset(Long.valueOf(offset).intValue()).count(Long.valueOf(count).intValue())); @@ -748,9 +731,9 @@ default Set zRevRangeByScore(byte[] key, double min, double max, long of * @since 1.6 * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set zRevRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRevRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Get set of {@link Tuple} in range from {@code start} to {@code end} where score is between {@code min} and @@ -764,8 +747,8 @@ Set zRevRangeByScore(byte[] key, org.springframework.data.domain.RangeRedis Documentation: ZREVRANGEBYSCORE */ - @Nullable - default Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + default Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, double min, double max, long offset, + long count) { return zRevRangeByScoreWithScores(key, org.springframework.data.domain.Range.closed(min, max), new org.springframework.data.redis.connection.Limit().offset(Long.valueOf(offset).intValue()) @@ -782,9 +765,8 @@ default Set zRevRangeByScoreWithScores(byte[] key, double min, double max * @since 1.6 * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - default Set zRevRangeByScoreWithScores(byte[] key, - org.springframework.data.domain.Range range) { + default Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRevRangeByScoreWithScores(key, range, Limit.unlimited()); } @@ -799,9 +781,9 @@ default Set zRevRangeByScoreWithScores(byte[] key, * @since 1.6 * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set zRevRangeByScoreWithScores(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Count number of elements within sorted set with scores between {@code min} and {@code max}. @@ -812,8 +794,7 @@ Set zRevRangeByScoreWithScores(byte[] key, org.springframework.data.domai * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCOUNT */ - @Nullable - default Long zCount(byte[] key, double min, double max) { + default Long zCount(byte @NonNull [] key, double min, double max) { return zCount(key, org.springframework.data.domain.Range.closed(min, max)); } @@ -826,8 +807,7 @@ default Long zCount(byte[] key, double min, double max) { * @since 1.6 * @see Redis Documentation: ZCOUNT */ - @Nullable - Long zCount(byte[] key, org.springframework.data.domain.Range range); + Long zCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range); /** * Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max} applying @@ -839,8 +819,7 @@ default Long zCount(byte[] key, double min, double max) { * @since 2.4 * @see Redis Documentation: ZLEXCOUNT */ - @Nullable - Long zLexCount(byte[] key, org.springframework.data.domain.Range range); + Long zLexCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. @@ -850,8 +829,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Tuple zPopMin(byte[] key); + Tuple zPopMin(byte @NonNull [] key); /** * Remove and return {@code count} values with their score having the lowest score from sorted set at {@code key}. @@ -862,8 +840,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Set zPopMin(byte[] key, long count); + Set<@NonNull Tuple> zPopMin(byte @NonNull [] key, long count); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}.
@@ -876,8 +853,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit); + Tuple bZPopMin(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}. @@ -887,8 +863,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - Tuple zPopMax(byte[] key); + Tuple zPopMax(byte @NonNull [] key); /** * Remove and return {@code count} values with their score having the highest score from sorted set at {@code key}. @@ -899,8 +874,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - Set zPopMax(byte[] key, long count); + Set<@NonNull Tuple> zPopMax(byte @NonNull [] key, long count); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}.
@@ -913,8 +887,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit); + Tuple bZPopMax(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit); /** * Get the size of sorted set with {@code key}. @@ -923,8 +896,7 @@ default Long zCount(byte[] key, double min, double max) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCARD */ - @Nullable - Long zCard(byte[] key); + Long zCard(byte @NonNull [] key); /** * Get the score of element with {@code value} from sorted set with key {@code key}. @@ -934,8 +906,7 @@ default Long zCount(byte[] key, double min, double max) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZSCORE */ - @Nullable - Double zScore(byte[] key, byte[] value); + Double zScore(byte @NonNull [] key, byte @NonNull [] value); /** * Get the scores of elements with {@code values} from sorted set with key {@code key}. @@ -946,8 +917,7 @@ default Long zCount(byte[] key, double min, double max) { * @see Redis Documentation: ZMSCORE * @since 2.6 */ - @Nullable - List zMScore(byte[] key, byte[]... values); + List<@NonNull Double> zMScore(byte @NonNull [] key, byte @NonNull [] @NonNull... values); /** * Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}. @@ -958,8 +928,7 @@ default Long zCount(byte[] key, double min, double max) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYRANK */ - @Nullable - Long zRemRange(byte[] key, long start, long end); + Long zRemRange(byte @NonNull [] key, long start, long end); /** * Remove all elements between the lexicographical {@link org.springframework.data.domain.Range}. @@ -970,7 +939,7 @@ default Long zCount(byte[] key, double min, double max) { * @since 2.5 * @see Redis Documentation: ZREMRANGEBYLEX */ - Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range); + Long zRemRangeByLex(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range); /** * Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}. @@ -981,8 +950,7 @@ default Long zCount(byte[] key, double min, double max) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYSCORE */ - @Nullable - default Long zRemRangeByScore(byte[] key, double min, double max) { + default Long zRemRangeByScore(byte @NonNull [] key, double min, double max) { return zRemRangeByScore(key, org.springframework.data.domain.Range.closed(min, max)); } @@ -995,8 +963,8 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 1.6 * @see Redis Documentation: ZREMRANGEBYSCORE */ - @Nullable - Long zRemRangeByScore(byte[] key, org.springframework.data.domain.Range range); + Long zRemRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range); /** * Diff sorted {@code sets}. @@ -1006,8 +974,7 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set zDiff(byte[]... sets); + Set zDiff(byte @NonNull [] @NonNull ... sets); /** * Diff sorted {@code sets}. @@ -1017,8 +984,7 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set zDiffWithScores(byte[]... sets); + Set<@NonNull Tuple> zDiffWithScores(byte @NonNull [] @NonNull... sets); /** * Diff sorted {@code sets} and store result in destination {@code destKey}. @@ -1029,8 +995,7 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - @Nullable - Long zDiffStore(byte[] destKey, byte[]... sets); + Long zDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1040,8 +1005,7 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInter(byte[]... sets); + Set zInter(byte @NonNull [] @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1051,8 +1015,7 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInterWithScores(byte[]... sets); + Set<@NonNull Tuple> zInterWithScores(byte @NonNull [] @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1064,8 +1027,8 @@ default Long zRemRangeByScore(byte[] key, double min, double max) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set zInterWithScores(Aggregate aggregate, int[] weights, byte[]... sets) { + default Set<@NonNull Tuple> zInterWithScores(@NonNull Aggregate aggregate, int[] weights, + byte @NonNull [] @NonNull... sets) { return zInterWithScores(aggregate, Weights.of(weights), sets); } @@ -1079,8 +1042,8 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, byte[].. * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets); + Set<@NonNull Tuple> zInterWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets); /** * Intersect sorted {@code sets} and store result in destination {@code destKey}. @@ -1090,8 +1053,7 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, byte[].. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long zInterStore(byte[] destKey, byte[]... sets); + Long zInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets); /** * Intersect sorted {@code sets} and store result in destination {@code destKey}. @@ -1103,8 +1065,8 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, byte[].. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - default Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + default Long zInterStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, int @NonNull [] weights, + byte @NonNull [] @NonNull... sets) { return zInterStore(destKey, aggregate, Weights.of(weights), sets); } @@ -1119,8 +1081,8 @@ default Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets); + Long zInterStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets); /** * Union sorted {@code sets}. @@ -1130,8 +1092,7 @@ default Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnion(byte[]... sets); + Set zUnion(byte @NonNull [] @NonNull... sets); /** * Union sorted {@code sets}. @@ -1141,8 +1102,7 @@ default Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnionWithScores(byte[]... sets); + Set<@NonNull Tuple> zUnionWithScores(byte @NonNull [] @NonNull... sets); /** * Union sorted {@code sets}. @@ -1154,8 +1114,8 @@ default Long zInterStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set zUnionWithScores(Aggregate aggregate, int[] weights, byte[]... sets) { + default @Nullable Set<@NonNull Tuple> zUnionWithScores(@NonNull Aggregate aggregate, int @NonNull [] weights, + byte @NonNull [] @NonNull... sets) { return zUnionWithScores(aggregate, Weights.of(weights), sets); } @@ -1169,8 +1129,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, byte[].. * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets); + Set<@NonNull Tuple> zUnionWithScores( @NonNull Aggregate aggregate, @NonNull Weights weights, byte @NonNull [] @NonNull... sets); /** * Union sorted {@code sets}. @@ -1179,8 +1138,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, byte[].. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long zUnionStore(byte[] destKey, byte[]... sets); + Long zUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets); /** * Union sorted {@code sets} and store result in destination {@code destKey}. @@ -1192,8 +1150,8 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, byte[].. * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - default Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byte[]... sets) { + default Long zUnionStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, int @NonNull [] weights, + byte @NonNull [] @NonNull... sets) { return zUnionStore(destKey, aggregate, Weights.of(weights), sets); } @@ -1208,8 +1166,8 @@ default Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets); + Long zUnionStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets); /** * Use a {@link Cursor} to iterate over elements in sorted set at {@code key}. @@ -1220,7 +1178,7 @@ default Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @since 1.4 * @see Redis Documentation: ZSCAN */ - Cursor zScan(byte[] key, ScanOptions options); + Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @Nullable ScanOptions options); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -1233,9 +1191,8 @@ default Long zUnionStore(byte[] destKey, Aggregate aggregate, int[] weights, byt * @see Redis Documentation: ZRANGEBYSCORE * @deprecated since 3.0, use {@link #zRangeByScore(byte[], org.springframework.data.domain.Range)} instead. */ - @Nullable @Deprecated - default Set zRangeByScore(byte[] key, String min, String max) { + default Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max) { return zRangeByScore(key, new Range().gte(min).lte(max).toRange()); } @@ -1248,8 +1205,8 @@ default Set zRangeByScore(byte[] key, String min, String max) { * @since 1.6 * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - default Set zRangeByScore(byte[] key, org.springframework.data.domain.Range range) { + default Set zRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRangeByScore(key, range, Limit.unlimited()); } @@ -1266,8 +1223,8 @@ default Set zRangeByScore(byte[] key, org.springframework.data.domain.Ra * @since 1.5 * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set zRangeByScore(byte[] key, String min, String max, long offset, long count); + Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max, long offset, + long count); /** * Get elements in range from {@code Limit#count} to {@code Limit#offset} where score is between {@code Range#min} and @@ -1280,9 +1237,9 @@ default Set zRangeByScore(byte[] key, org.springframework.data.domain.Ra * @since 1.6 * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set zRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Get all the elements in the sorted set at {@literal key} in lexicographical ordering. @@ -1292,8 +1249,7 @@ Set zRangeByScore(byte[] key, org.springframework.data.domain.RangeRedis Documentation: ZRANGEBYLEX */ - @Nullable - default Set zRangeByLex(byte[] key) { + default Set zRangeByLex(byte @NonNull [] key) { return zRangeByLex(key, org.springframework.data.domain.Range.unbounded()); } @@ -1307,8 +1263,8 @@ default Set zRangeByLex(byte[] key) { * @since 1.6 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - default Set zRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + default Set zRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRangeByLex(key, range, Limit.unlimited()); } @@ -1323,9 +1279,9 @@ default Set zRangeByLex(byte[] key, org.springframework.data.domain.Rang * @since 1.6 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - Set zRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Get all the elements in the sorted set at {@literal key} in reversed lexicographical ordering. @@ -1335,8 +1291,7 @@ Set zRangeByLex(byte[] key, org.springframework.data.domain.RangeRedis Documentation: ZREVRANGEBYLEX */ - @Nullable - default Set zRevRangeByLex(byte[] key) { + default Set zRevRangeByLex(byte @NonNull [] key) { return zRevRangeByLex(key, org.springframework.data.domain.Range.unbounded()); } @@ -1350,8 +1305,8 @@ default Set zRevRangeByLex(byte[] key) { * @since 2.4 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - default Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + default Set zRevRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { return zRevRangeByLex(key, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -1366,9 +1321,9 @@ default Set zRevRangeByLex(byte[] key, org.springframework.data.domain.R * @since 2.4 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRevRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE , but stores the result in the {@literal dstKey} destination key. @@ -1380,8 +1335,8 @@ Set zRevRangeByLex(byte[] key, org.springframework.data.domain.RangeRedis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range) { + default Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -1396,9 +1351,9 @@ default Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework. * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key. @@ -1410,8 +1365,8 @@ Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.dom * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range) { + default Long zRangeStoreRevByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreRevByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -1426,9 +1381,9 @@ default Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframewo * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreRevByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key. @@ -1440,9 +1395,8 @@ Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data. * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range) { + default Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -1457,9 +1411,9 @@ default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key. @@ -1471,9 +1425,8 @@ Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.d * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range) { + default Long zRangeStoreRevByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreRevByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -1488,9 +1441,8 @@ default Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreRevByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); } diff --git a/src/main/java/org/springframework/data/redis/connection/ReturnType.java b/src/main/java/org/springframework/data/redis/connection/ReturnType.java index b39a9684ce..3945a6a50a 100644 --- a/src/main/java/org/springframework/data/redis/connection/ReturnType.java +++ b/src/main/java/org/springframework/data/redis/connection/ReturnType.java @@ -17,7 +17,7 @@ import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/src/main/java/org/springframework/data/redis/connection/SentinelMasterId.java b/src/main/java/org/springframework/data/redis/connection/SentinelMasterId.java index ce778884d7..62aee026c1 100644 --- a/src/main/java/org/springframework/data/redis/connection/SentinelMasterId.java +++ b/src/main/java/org/springframework/data/redis/connection/SentinelMasterId.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/SortParameters.java b/src/main/java/org/springframework/data/redis/connection/SortParameters.java index 27804b98fe..86cacc7ff3 100644 --- a/src/main/java/org/springframework/data/redis/connection/SortParameters.java +++ b/src/main/java/org/springframework/data/redis/connection/SortParameters.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Entity containing the parameters for the SORT operation. @@ -76,16 +76,14 @@ public long getCount() { * * @return {@code BY} pattern. {@literal null} if not set. */ - @Nullable - byte[] getByPattern(); + byte @Nullable[] getByPattern(); /** * Returns the pattern (if set) for retrieving external keys ({@code GET}). Can be null if nothing is specified. * * @return {@code GET} pattern. {@literal null} if not set. */ - @Nullable - byte[][] getGetPattern(); + byte @Nullable[][] getGetPattern(); /** * Returns the sorting limit (range or pagination). Can be null if nothing is specified. diff --git a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java index dfcc585130..3eae672f4d 100644 --- a/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java @@ -23,6 +23,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; @@ -53,7 +56,6 @@ import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; /** @@ -75,6 +77,7 @@ * @see RedisSerializer * @see StringRedisTemplate */ +@NullUnmarked public interface StringRedisConnection extends RedisConnection { /** @@ -94,7 +97,7 @@ interface StringTuple extends Tuple { * @return execution result. * @see RedisCommands#execute(String, byte[]...) */ - Object execute(String command, String... args); + Object execute(@NonNull String command, String... args); /** * 'Native' or 'raw' execution of the given command along-side the given arguments. The command is executed as is, @@ -105,7 +108,7 @@ interface StringTuple extends Tuple { * @return execution result. * @see RedisCommands#execute(String, byte[]...) */ - Object execute(String command); + Object execute(@NonNull String command); /** * Determine if given {@code key} exists. @@ -115,7 +118,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: EXISTS * @see RedisKeyCommands#exists(byte[]) */ - Boolean exists(String key); + Boolean exists(@NonNull String key); /** * Count how many of the given {@code keys} exist. @@ -126,8 +129,7 @@ interface StringTuple extends Tuple { * @see RedisKeyCommands#exists(byte[][]) * @since 2.1 */ - @Nullable - Long exists(String... keys); + Long exists(@NonNull String @NonNull... keys); /** * Delete given {@code keys}. @@ -137,7 +139,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: DEL * @see RedisKeyCommands#del(byte[]...) */ - Long del(String... keys); + Long del(@NonNull String @NonNull... keys); /** * Copy given {@code sourceKey} to {@code targetKey}. @@ -149,7 +151,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: COPY * @see RedisKeyCommands#copy(byte[], byte[], boolean) */ - Boolean copy(String sourceKey, String targetKey, boolean replace); + Boolean copy(@NonNull String sourceKey, @NonNull String targetKey, boolean replace); /** * Unlink the {@code keys} from the keyspace. Unlike with {@link #del(String...)} the actual memory reclaiming here @@ -160,8 +162,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: UNLINK * @since 2.1 */ - @Nullable - Long unlink(String... keys); + Long unlink(@NonNull String @NonNull... keys); /** * Determine the type stored at {@code key}. @@ -171,7 +172,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: TYPE * @see RedisKeyCommands#type(byte[]) */ - DataType type(String key); + DataType type(@NonNull String key); /** * Alter the last access time of given {@code key(s)}. @@ -181,8 +182,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: TOUCH * @since 2.1 */ - @Nullable - Long touch(String... keys); + Long touch(@NonNull String @NonNull... keys); /** * Find all keys matching the given {@code pattern}. @@ -192,7 +192,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: KEYS * @see RedisKeyCommands#keys(byte[]) */ - Collection keys(String pattern); + Collection keys(@NonNull String pattern); /** * Rename key {@code oldKey} to {@code newKey}. @@ -202,7 +202,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: RENAME * @see RedisKeyCommands#rename(byte[], byte[]) */ - void rename(String oldKey, String newKey); + void rename(@NonNull String oldKey, @NonNull String newKey); /** * Rename key {@code oldKey} to {@code newKey} only if {@code newKey} does not exist. @@ -213,7 +213,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: RENAMENX * @see RedisKeyCommands#renameNX(byte[], byte[]) */ - Boolean renameNX(String oldKey, String newKey); + Boolean renameNX(@NonNull String oldKey, @NonNull String newKey); /** * Set time to live for given {@code key} in seconds. @@ -224,7 +224,7 @@ interface StringTuple extends Tuple { * @see Redis Documentation: EXPIRE * @see RedisKeyCommands#expire(byte[], long) */ - default Boolean expire(String key, long seconds) { + default Boolean expire(@NonNull String key, long seconds) { return expire(key, seconds, ExpirationOptions.Condition.ALWAYS); } @@ -239,7 +239,7 @@ default Boolean expire(String key, long seconds) { * @see Redis Documentation: EXPIRE * @see RedisKeyCommands#expire(byte[], long) */ - Boolean expire(String key, long seconds, ExpirationOptions.Condition condition); + Boolean expire(@NonNull String key, long seconds, ExpirationOptions.@NonNull Condition condition); /** * Set time to live for given {@code key} in milliseconds. @@ -250,7 +250,7 @@ default Boolean expire(String key, long seconds) { * @see Redis Documentation: PEXPIRE * @see RedisKeyCommands#pExpire(byte[], long) */ - default Boolean pExpire(String key, long millis) { + default Boolean pExpire(@NonNull String key, long millis) { return pExpire(key, millis, ExpirationOptions.Condition.ALWAYS); } @@ -265,7 +265,7 @@ default Boolean pExpire(String key, long millis) { * @see Redis Documentation: PEXPIRE * @see RedisKeyCommands#pExpire(byte[], long) */ - Boolean pExpire(String key, long millis, ExpirationOptions.Condition condition); + Boolean pExpire(@NonNull String key, long millis, ExpirationOptions.@NonNull Condition condition); /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp. @@ -276,7 +276,7 @@ default Boolean pExpire(String key, long millis) { * @see Redis Documentation: EXPIREAT * @see RedisKeyCommands#expireAt(byte[], long) */ - default Boolean expireAt(String key, long unixTime) { + default Boolean expireAt(@NonNull String key, long unixTime) { return expireAt(key, unixTime, ExpirationOptions.Condition.ALWAYS); } @@ -291,7 +291,7 @@ default Boolean expireAt(String key, long unixTime) { * @see Redis Documentation: EXPIREAT * @see RedisKeyCommands#expireAt(byte[], long) */ - Boolean expireAt(String key, long unixTime, ExpirationOptions.Condition condition); + Boolean expireAt(@NonNull String key, long unixTime, ExpirationOptions.@NonNull Condition condition); /** * Set the expiration for given {@code key} as a {@literal UNIX} timestamp in milliseconds. @@ -302,7 +302,7 @@ default Boolean expireAt(String key, long unixTime) { * @see Redis Documentation: PEXPIREAT * @see RedisKeyCommands#pExpireAt(byte[], long) */ - default Boolean pExpireAt(String key, long unixTimeInMillis) { + default Boolean pExpireAt(@NonNull String key, long unixTimeInMillis) { return pExpireAt(key, unixTimeInMillis, ExpirationOptions.Condition.ALWAYS); } @@ -317,7 +317,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: PEXPIREAT * @see RedisKeyCommands#pExpireAt(byte[], long) */ - Boolean pExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condition condition); + Boolean pExpireAt(@NonNull String key, long unixTimeInMillis, ExpirationOptions.@NonNull Condition condition); /** * Remove the expiration from given {@code key}. @@ -327,7 +327,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: PERSIST * @see RedisKeyCommands#persist(byte[]) */ - Boolean persist(String key); + Boolean persist(@NonNull String key); /** * Move given {@code key} to database with {@code index}. @@ -338,7 +338,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: MOVE * @see RedisKeyCommands#move(byte[], int) */ - Boolean move(String key, int dbIndex); + Boolean move(@NonNull String key, int dbIndex); /** * Get the time to live for {@code key} in seconds. @@ -348,7 +348,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: TTL * @see RedisKeyCommands#ttl(byte[]) */ - Long ttl(String key); + Long ttl(@NonNull String key); /** * Get the time to live for {@code key} in and convert it to the given {@link TimeUnit}. @@ -360,7 +360,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: TTL * @see RedisKeyCommands#ttl(byte[], TimeUnit) */ - Long ttl(String key, TimeUnit timeUnit); + Long ttl(@NonNull String key, @NonNull TimeUnit timeUnit); /** * Get the precise time to live for {@code key} in milliseconds. @@ -370,7 +370,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: PTTL * @see RedisKeyCommands#pTtl(byte[]) */ - Long pTtl(String key); + Long pTtl(@NonNull String key); /** * Get the precise time to live for {@code key} in and convert it to the given {@link TimeUnit}. @@ -382,7 +382,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: PTTL * @see RedisKeyCommands#pTtl(byte[], TimeUnit) */ - Long pTtl(String key, TimeUnit timeUnit); + Long pTtl(@NonNull String key, @NonNull TimeUnit timeUnit); /** * Returns {@code message} via server roundtrip. @@ -392,7 +392,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: ECHO * @see RedisConnectionCommands#echo(byte[]) */ - String echo(String message); + String echo(@NonNull String message); /** * Sort the elements for {@code key}. @@ -402,7 +402,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @return * @see Redis Documentation: SORT */ - List sort(String key, SortParameters params); + List sort(@NonNull String key, @NonNull SortParameters params); /** * Sort the elements for {@code key} and store result in {@code storeKey}. @@ -413,7 +413,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @return * @see Redis Documentation: SORT */ - Long sort(String key, SortParameters params, String storeKey); + Long sort(@NonNull String key, @NonNull SortParameters params, @NonNull String storeKey); /** * Get the type of internal representation used for storing the value at the given {@code key}. @@ -423,8 +423,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @throws IllegalArgumentException if {@code key} is {@literal null}. * @since 2.1 */ - @Nullable - ValueEncoding encodingOf(String key); + ValueEncoding encodingOf(@NonNull String key); /** * Get the {@link Duration} since the object stored at the given {@code key} is idle. @@ -434,8 +433,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @throws IllegalArgumentException if {@code key} is {@literal null}. * @since 2.1 */ - @Nullable - Duration idletime(String key); + Duration idletime(@NonNull String key); /** * Get the number of references of the value associated with the specified {@code key}. @@ -445,8 +443,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @throws IllegalArgumentException if {@code key} is {@literal null}. * @since 2.1 */ - @Nullable - Long refcount(String key); + Long refcount(@NonNull String key); // ------------------------------------------------------------------------- // Methods dealing with values/Redis strings @@ -460,7 +457,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GET * @see RedisStringCommands#get(byte[]) */ - String get(String key); + String get(@NonNull String key); /** * Return the value at {@code key} and delete the key. @@ -470,8 +467,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GETDEL * @since 2.6 */ - @Nullable - String getDel(String key); + String getDel(@NonNull String key); /** * Return the value at {@code key} and expire the key by applying {@link Expiration}. @@ -482,8 +478,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - String getEx(String key, Expiration expiration); + String getEx(@NonNull String key, @NonNull Expiration expiration); /** * Set {@code value} of {@code key} and return its old value. @@ -494,7 +489,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GETSET * @see RedisStringCommands#getSet(byte[], byte[]) */ - String getSet(String key, String value); + String getSet(@NonNull String key, String value); /** * Get multiple {@code keys}. Values are in the order of the requested keys. @@ -504,7 +499,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: MGET * @see RedisStringCommands#mGet(byte[]...) */ - List mGet(String... keys); + List mGet(@NonNull String @NonNull... keys); /** * Set {@code value} for {@code key}. @@ -514,8 +509,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SET * @see RedisStringCommands#set(byte[], byte[]) */ - @Nullable - Boolean set(String key, String value); + Boolean set(@NonNull String key, @NonNull String value); /** * Set {@code value} for {@code key} applying timeouts from {@code expiration} if set and inserting/updating values @@ -530,8 +524,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SET * @see RedisStringCommands#set(byte[], byte[], Expiration, SetOption) */ - @Nullable - Boolean set(String key, String value, Expiration expiration, SetOption option); + Boolean set(@NonNull String key, @NonNull String value, @Nullable Expiration expiration, @Nullable SetOption option); /** * Set {@code value} for {@code key}, only if {@code key} does not exist. @@ -542,8 +535,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SETNX * @see RedisStringCommands#setNX(byte[], byte[]) */ - @Nullable - Boolean setNX(String key, String value); + Boolean setNX(@NonNull String key, @NonNull String value); /** * Set the {@code value} and expiration in {@code seconds} for {@code key}. @@ -554,8 +546,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SETEX * @see RedisStringCommands#setEx(byte[], long, byte[]) */ - @Nullable - Boolean setEx(String key, long seconds, String value); + Boolean setEx(@NonNull String key, long seconds, @NonNull String value); /** * Set the {@code value} and expiration in {@code milliseconds} for {@code key}. @@ -567,8 +558,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: PSETEX * @see RedisStringCommands#pSetEx(byte[], long, byte[]) */ - @Nullable - Boolean pSetEx(String key, long milliseconds, String value); + Boolean pSetEx(@NonNull String key, long milliseconds, @NonNull String value); /** * Set multiple keys to multiple values using key-value pairs provided in {@code tuple}. @@ -577,8 +567,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: MSET * @see RedisStringCommands#mSet(Map) */ - @Nullable - Boolean mSetString(Map tuple); + Boolean mSetString(@NonNull Map<@NonNull String, String> tuple); /** * Set multiple keys to multiple values using key-value pairs provided in {@code tuple} only if the provided key does @@ -588,7 +577,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: MSETNX * @see RedisStringCommands#mSetNX(Map) */ - Boolean mSetNXString(Map tuple); + Boolean mSetNXString(@NonNull Map<@NonNull String, String> tuple); /** * Increment an integer value stored as string value of {@code key} by 1. @@ -598,7 +587,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: INCR * @see RedisStringCommands#incr(byte[]) */ - Long incr(String key); + Long incr(@NonNull String key); /** * Increment an integer value stored of {@code key} by {@code delta}. @@ -609,7 +598,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: INCRBY * @see RedisStringCommands#incrBy(byte[], long) */ - Long incrBy(String key, long value); + Long incrBy(@NonNull String key, long value); /** * Increment a floating point number value of {@code key} by {@code delta}. @@ -620,7 +609,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: INCRBYFLOAT * @see RedisStringCommands#incrBy(byte[], double) */ - Double incrBy(String key, double value); + Double incrBy(@NonNull String key, double value); /** * Decrement an integer value stored as string value of {@code key} by 1. @@ -630,7 +619,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: DECR * @see RedisStringCommands#decr(byte[]) */ - Long decr(String key); + Long decr(@NonNull String key); /** * Decrement an integer value stored as string value of {@code key} by {@code value}. @@ -641,7 +630,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: DECRBY * @see RedisStringCommands#decrBy(byte[], long) */ - Long decrBy(String key, long value); + Long decrBy(@NonNull String key, long value); /** * Append a {@code value} to {@code key}. @@ -652,7 +641,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: APPEND * @see RedisStringCommands#append(byte[], byte[]) */ - Long append(String key, String value); + Long append(@NonNull String key, String value); /** * Get a substring of value of {@code key} between {@code start} and {@code end}. @@ -664,7 +653,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GETRANGE * @see RedisStringCommands#getRange(byte[], long, long) */ - String getRange(String key, long start, long end); + String getRange(@NonNull String key, long start, long end); /** * Overwrite parts of {@code key} starting at the specified {@code offset} with given {@code value}. @@ -675,7 +664,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SETRANGE * @see RedisStringCommands#setRange(byte[], byte[], long) */ - void setRange(String key, String value, long offset); + void setRange(@NonNull String key, String value, long offset); /** * Get the bit value at {@code offset} of value at {@code key}. @@ -686,7 +675,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: GETBIT * @see RedisStringCommands#getBit(byte[], long) */ - Boolean getBit(String key, long offset); + Boolean getBit(@NonNull String key, long offset); /** * Sets the bit at {@code offset} in value stored at {@code key}. @@ -698,7 +687,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: SETBIT * @see RedisStringCommands#setBit(byte[], long, boolean) */ - Boolean setBit(String key, long offset, boolean value); + Boolean setBit(@NonNull String key, long offset, boolean value); /** * Count the number of set bits (population counting) in value stored at {@code key}. @@ -708,7 +697,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: BITCOUNT * @see RedisStringCommands#bitCount(byte[]) */ - Long bitCount(String key); + Long bitCount(@NonNull String key); /** * Count the number of set bits (population counting) of value stored at {@code key} between {@code start} and @@ -721,7 +710,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: BITCOUNT * @see RedisStringCommands#bitCount(byte[], long, long) */ - Long bitCount(String key, long start, long end); + Long bitCount(@NonNull String key, long start, long end); /** * Perform bitwise operations between strings. @@ -733,7 +722,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: BITOP * @see RedisStringCommands#bitOp(BitOperation, byte[], byte[]...) */ - Long bitOp(BitOperation op, String destination, String... keys); + Long bitOp(@NonNull BitOperation op, @NonNull String destination, @NonNull String @NonNull... keys); /** * Return the position of the first bit set to given {@code bit} in a string. @@ -745,7 +734,7 @@ default Boolean pExpireAt(String key, long unixTimeInMillis) { * @see Redis Documentation: BITPOS * @since 2.1 */ - default Long bitPos(String key, boolean bit) { + default Long bitPos(@NonNull String key, boolean bit) { return bitPos(key, bit, org.springframework.data.domain.Range.unbounded()); } @@ -763,8 +752,7 @@ default Long bitPos(String key, boolean bit) { * @see Redis Documentation: BITPOS * @since 2.1 */ - @Nullable - Long bitPos(String key, boolean bit, org.springframework.data.domain.Range range); + Long bitPos(@NonNull String key, boolean bit, org.springframework.data.domain.@NonNull Range range); /** * Get the length of the value stored at {@code key}. @@ -774,7 +762,7 @@ default Long bitPos(String key, boolean bit) { * @see Redis Documentation: STRLEN * @see RedisStringCommands#strLen(byte[]) */ - Long strLen(String key); + Long strLen(@NonNull String key); // ------------------------------------------------------------------------- // Methods dealing with Redis Lists @@ -789,7 +777,7 @@ default Long bitPos(String key, boolean bit) { * @see Redis Documentation: RPUSH * @see RedisListCommands#rPush(byte[], byte[]...) */ - Long rPush(String key, String... values); + Long rPush(@NonNull String key, @NonNull String @NonNull... values); /** * Returns the index of matching elements inside the list stored at given {@literal key}.
@@ -801,8 +789,7 @@ default Long bitPos(String key, boolean bit) { * @see Redis Documentation: LPOS * @since 2.4 */ - @Nullable - default Long lPos(String key, String element) { + default Long lPos(@NonNull String key, @NonNull String element) { return CollectionUtils.firstElement(lPos(key, element, null, null)); } @@ -819,7 +806,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LPOS * @since 2.4 */ - List lPos(String key, String element, @Nullable Integer rank, @Nullable Integer count); + List lPos(@NonNull String key, @NonNull String element, @Nullable Integer rank, @Nullable Integer count); /** * Prepend {@code values} to {@code key}. @@ -830,7 +817,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LPUSH * @see RedisListCommands#lPush(byte[], byte[]...) */ - Long lPush(String key, String... values); + Long lPush(@NonNull String key, @NonNull String @NonNull... values); /** * Append {@code values} to {@code key} only if the list exists. @@ -841,7 +828,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: RPUSHX * @see RedisListCommands#rPushX(byte[], byte[]) */ - Long rPushX(String key, String value); + Long rPushX(@NonNull String key, @NonNull String value); /** * Prepend {@code values} to {@code key} only if the list exists. @@ -852,7 +839,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LPUSHX * @see RedisListCommands#lPushX(byte[], byte[]) */ - Long lPushX(String key, String value); + Long lPushX(@NonNull String key, @NonNull String value); /** * Get the size of list stored at {@code key}. @@ -862,7 +849,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LLEN * @see RedisListCommands#lLen(byte[]) */ - Long lLen(String key); + Long lLen(@NonNull String key); /** * Get elements between {@code start} and {@code end} from list at {@code key}. @@ -874,7 +861,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LRANGE * @see RedisListCommands#lRange(byte[], long, long) */ - List lRange(String key, long start, long end); + List lRange(@NonNull String key, long start, long end); /** * Trim list at {@code key} to elements between {@code start} and {@code end}. @@ -885,7 +872,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LTRIM * @see RedisListCommands#lTrim(byte[], long, long) */ - void lTrim(String key, long start, long end); + void lTrim(@NonNull String key, long start, long end); /** * Get element at {@code index} form list at {@code key}. @@ -896,7 +883,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LINDEX * @see RedisListCommands#lIndex(byte[], long) */ - String lIndex(String key, long index); + String lIndex(@NonNull String key, long index); /** * Insert {@code value} {@link Position#BEFORE} or {@link Position#AFTER} existing {@code pivot} for {@code key}. @@ -909,7 +896,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LINSERT * @see RedisListCommands#lIndex(byte[], long) */ - Long lInsert(String key, Position where, String pivot, String value); + Long lInsert(@NonNull String key, @NonNull Position where, @NonNull String pivot, String value); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -926,8 +913,8 @@ default Long lPos(String key, String element) { * @see #bLMove(byte[], byte[], Direction, Direction, double) * @see #lMove(byte[], byte[], Direction, Direction) */ - @Nullable - String lMove(String sourceKey, String destinationKey, Direction from, Direction to); + String lMove(@NonNull String sourceKey, @NonNull String destinationKey, @NonNull Direction from, + @NonNull Direction to); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -945,8 +932,8 @@ default Long lPos(String key, String element) { * @see #lMove(byte[], byte[], Direction, Direction) * @see #bLMove(byte[], byte[], Direction, Direction, double) */ - @Nullable - String bLMove(String sourceKey, String destinationKey, Direction from, Direction to, double timeout); + String bLMove(@NonNull String sourceKey, @NonNull String destinationKey, @NonNull Direction from, + @NonNull Direction to, double timeout); /** * Set the {@code value} list element at {@code index}. @@ -957,7 +944,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LSET * @see RedisListCommands#lSet(byte[], long, byte[]) */ - void lSet(String key, long index, String value); + void lSet(@NonNull String key, long index, String value); /** * Removes the first {@code count} occurrences of {@code value} from the list stored at {@code key}. @@ -969,7 +956,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LREM * @see RedisListCommands#lRem(byte[], long, byte[]) */ - Long lRem(String key, long count, String value); + Long lRem(@NonNull String key, long count, String value); /** * Removes and returns first element in list stored at {@code key}. @@ -979,7 +966,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: LPOP * @see RedisListCommands#lPop(byte[]) */ - String lPop(String key); + String lPop(@NonNull String key); /** * Removes and returns first {@code} elements in list stored at {@code key}. @@ -991,7 +978,7 @@ default Long lPos(String key, String element) { * @see RedisListCommands#lPop(byte[], long) * @since 2.6 */ - List lPop(String key, long count); + List lPop(@NonNull String key, long count); /** * Removes and returns last element in list stored at {@code key}. @@ -1001,7 +988,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: RPOP * @see RedisListCommands#rPop(byte[]) */ - String rPop(String key); + String rPop(@NonNull String key); /** * Removes and returns last {@code} elements in list stored at {@code key}. @@ -1013,7 +1000,7 @@ default Long lPos(String key, String element) { * @see RedisListCommands#rPop(byte[], long) * @since 2.6 */ - List rPop(String key, long count); + List rPop(@NonNull String key, long count); /** * Removes and returns first element from lists stored at {@code keys} (see: {@link #lPop(byte[])}).
@@ -1025,7 +1012,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: BLPOP * @see RedisListCommands#bLPop(int, byte[]...) */ - List bLPop(int timeout, String... keys); + List bLPop(int timeout, @NonNull String @NonNull... keys); /** * Removes and returns last element from lists stored at {@code keys} (see: {@link #rPop(byte[])}).
@@ -1037,7 +1024,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: BRPOP * @see RedisListCommands#bRPop(int, byte[]...) */ - List bRPop(int timeout, String... keys); + List bRPop(int timeout, @NonNull String @NonNull... keys); /** * Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value. @@ -1048,7 +1035,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: RPOPLPUSH * @see RedisListCommands#rPopLPush(byte[], byte[]) */ - String rPopLPush(String srcKey, String dstKey); + String rPopLPush(@NonNull String srcKey, @NonNull String dstKey); /** * Remove the last element from list at {@code srcKey}, append it to {@code dstKey} and return its value (see @@ -1062,7 +1049,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: BRPOPLPUSH * @see RedisListCommands#bRPopLPush(int, byte[], byte[]) */ - String bRPopLPush(int timeout, String srcKey, String dstKey); + String bRPopLPush(int timeout, @NonNull String srcKey, @NonNull String dstKey); // ------------------------------------------------------------------------- // Methods dealing with Redis Sets @@ -1077,7 +1064,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SADD * @see RedisSetCommands#sAdd(byte[], byte[]...) */ - Long sAdd(String key, String... values); + Long sAdd(@NonNull String key, String... values); /** * Remove given {@code values} from set at {@code key} and return the number of removed elements. @@ -1088,7 +1075,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SREM * @see RedisSetCommands#sRem(byte[], byte[]...) */ - Long sRem(String key, String... values); + Long sRem(@NonNull String key, String... values); /** * Remove and return a random member from set at {@code key}. @@ -1098,7 +1085,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SPOP * @see RedisSetCommands#sPop(byte[]) */ - String sPop(String key); + String sPop(@NonNull String key); /** * Remove and return {@code count} random members from set at {@code key}. @@ -1110,7 +1097,7 @@ default Long lPos(String key, String element) { * @see RedisSetCommands#sPop(byte[], long) * @since 2.0 */ - List sPop(String key, long count); + List sPop(@NonNull String key, long count); /** * Move {@code value} from {@code srcKey} to {@code destKey} @@ -1122,7 +1109,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SMOVE * @see RedisSetCommands#sMove(byte[], byte[], byte[]) */ - Boolean sMove(String srcKey, String destKey, String value); + Boolean sMove(@NonNull String srcKey, @NonNull String destKey, String value); /** * Get size of set at {@code key}. @@ -1132,7 +1119,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SCARD * @see RedisSetCommands#sCard(byte[]) */ - Long sCard(String key); + Long sCard(@NonNull String key); /** * Check if set at {@code key} contains {@code value}. @@ -1143,7 +1130,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SISMEMBER * @see RedisSetCommands#sIsMember(byte[], byte[]) */ - Boolean sIsMember(String key, String value); + Boolean sIsMember(@NonNull String key, String value); /** * Check if set at {@code key} contains one or more {@code values}. @@ -1155,8 +1142,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SMISMEMBER * @see RedisSetCommands#sMIsMember(byte[], byte[]...) */ - @Nullable - List sMIsMember(String key, String... values); + List sMIsMember(@NonNull String key, String... values); /** * Returns the members intersecting all given sets at {@code keys}. @@ -1166,7 +1152,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SINTER * @see RedisSetCommands#sInter(byte[]...) */ - Set sInter(String... keys); + Set sInter(@NonNull String @NonNull... keys); /** * Intersect all given sets at {@code keys} and store result in {@code destKey}. @@ -1177,7 +1163,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SINTERSTORE * @see RedisSetCommands#sInterStore(byte[], byte[]...) */ - Long sInterStore(String destKey, String... keys); + Long sInterStore(@NonNull String destKey, @NonNull String @NonNull... keys); /** * Union all sets at given {@code keys}. @@ -1229,7 +1215,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SMEMBERS * @see RedisSetCommands#sMembers(byte[]) */ - Set sMembers(String key); + Set sMembers(@NonNull String key); /** * Get random element from set at {@code key}. @@ -1239,7 +1225,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SRANDMEMBER * @see RedisSetCommands#sRandMember(byte[]) */ - String sRandMember(String key); + String sRandMember(@NonNull String key); /** * Get {@code count} random elements from set at {@code key}. @@ -1250,7 +1236,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SRANDMEMBER * @see RedisSetCommands#sRem(byte[], byte[]...) */ - List sRandMember(String key, long count); + List sRandMember(@NonNull String key, long count); /** * Use a {@link Cursor} to iterate over elements in set at {@code key}. @@ -1262,7 +1248,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: SCAN * @see RedisSetCommands#sScan(byte[], ScanOptions) */ - Cursor sScan(String key, ScanOptions options); + Cursor sScan(@NonNull String key, ScanOptions options); // ------------------------------------------------------------------------- // Methods dealing with Redis Sorted Sets @@ -1278,7 +1264,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZADD * @see RedisZSetCommands#zAdd(byte[], double, byte[]) */ - Boolean zAdd(String key, double score, String value); + Boolean zAdd(@NonNull String key, double score, String value); /** * Add the {@code value} to a sorted set at {@code key}, or update its {@code score} depending on the given @@ -1293,7 +1279,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZADD * @see RedisZSetCommands#zAdd(byte[], double, byte[], ZAddArgs) */ - Boolean zAdd(String key, double score, String value, ZAddArgs args); + Boolean zAdd(@NonNull String key, double score, String value, ZAddArgs args); /** * Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists. @@ -1304,7 +1290,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZADD * @see RedisZSetCommands#zAdd(byte[], Set) */ - Long zAdd(String key, Set tuples); + Long zAdd(@NonNull String key, Set tuples); /** * Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} depending on the given @@ -1318,8 +1304,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZADD * @see RedisZSetCommands#zAdd(byte[], Set, ZAddArgs) */ - @Nullable - Long zAdd(String key, Set tuples, ZAddArgs args); + Long zAdd(@NonNull String key, Set tuples, ZAddArgs args); /** * Remove {@code values} from sorted set. Return number of removed elements. @@ -1330,7 +1315,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREM * @see RedisZSetCommands#zRem(byte[], byte[]...) */ - Long zRem(String key, String... values); + Long zRem(@NonNull String key, String... values); /** * Increment the score of element with {@code value} in sorted set by {@code increment}. @@ -1342,7 +1327,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZINCRBY * @see RedisZSetCommands#zIncrBy(byte[], double, byte[]) */ - Double zIncrBy(String key, double increment, String value); + Double zIncrBy(@NonNull String key, double increment, String value); /** * Get random element from sorted set at {@code key}. @@ -1352,8 +1337,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - String zRandMember(String key); + String zRandMember(@NonNull String key); /** * Get {@code count} random elements from sorted set at {@code key}. @@ -1367,8 +1351,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List zRandMember(String key, long count); + List zRandMember(@NonNull String key, long count); /** * Get random element from sorted set at {@code key}. @@ -1378,8 +1361,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - StringTuple zRandMemberWithScore(String key); + StringTuple zRandMemberWithScore(@NonNull String key); /** * Get {@code count} random elements from sorted set at {@code key}. @@ -1393,8 +1375,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List zRandMemberWithScores(String key, long count); + List zRandMemberWithScores(@NonNull String key, long count); /** * Determine the index of element with {@code value} in a sorted set. @@ -1405,7 +1386,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANK * @see RedisZSetCommands#zRank(byte[], byte[]) */ - Long zRank(String key, String value); + Long zRank(@NonNull String key, String value); /** * Determine the index of element with {@code value} in a sorted set when scored high to low. @@ -1416,7 +1397,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANK * @see RedisZSetCommands#zRevRank(byte[], byte[]) */ - Long zRevRank(String key, String value); + Long zRevRank(@NonNull String key, String value); /** * Get elements between {@code start} and {@code end} from sorted set. @@ -1428,7 +1409,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGE * @see RedisZSetCommands#zRange(byte[], long, long) */ - Set zRange(String key, long start, long end); + Set zRange(@NonNull String key, long start, long end); /** * Get set of {@link Tuple}s between {@code start} and {@code end} from sorted set. @@ -1440,7 +1421,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGE * @see RedisZSetCommands#zRangeWithScores(byte[], long, long) */ - Set zRangeWithScores(String key, long start, long end); + Set zRangeWithScores(@NonNull String key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -1452,7 +1433,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScore(byte[], double, double) */ - Set zRangeByScore(String key, double min, double max); + Set zRangeByScore(@NonNull String key, double min, double max); /** * Get set of {@link Tuple}s where score is between {@code min} and {@code max} from sorted set. @@ -1464,7 +1445,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double) */ - Set zRangeByScoreWithScores(String key, double min, double max); + Set zRangeByScoreWithScores(@NonNull String key, double min, double max); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -1479,7 +1460,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScore(byte[], double, double, long, long) */ - Set zRangeByScore(String key, double min, double max, long offset, long count); + Set zRangeByScore(@NonNull String key, double min, double max, long offset, long count); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} where score is between {@code min} and @@ -1494,7 +1475,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScoreWithScores(byte[], double, double, long, long) */ - Set zRangeByScoreWithScores(String key, double min, double max, long offset, long count); + Set zRangeByScoreWithScores(@NonNull String key, double min, double max, long offset, long count); /** * Get elements in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -1506,7 +1487,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGE * @see RedisZSetCommands#zRevRange(byte[], long, long) */ - Set zRevRange(String key, long start, long end); + Set zRevRange(@NonNull String key, long start, long end); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -1518,7 +1499,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGE * @see RedisZSetCommands#zRevRangeWithScores(byte[], long, long) */ - Set zRevRangeWithScores(String key, long start, long end); + Set zRevRangeWithScores(@NonNull String key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set ordered from high to low. @@ -1530,7 +1511,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGE * @see RedisZSetCommands#zRevRangeByScore(byte[], double, double) */ - Set zRevRangeByScore(String key, double min, double max); + Set zRevRangeByScore(@NonNull String key, double min, double max); /** * Get set of {@link Tuple} where score is between {@code min} and {@code max} from sorted set ordered from high to @@ -1543,7 +1524,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGEBYSCORE * @see RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double) */ - Set zRevRangeByScoreWithScores(String key, double min, double max); + Set zRevRangeByScoreWithScores(@NonNull String key, double min, double max); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -1558,7 +1539,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGEBYSCORE * @see RedisZSetCommands#zRevRangeByScore(byte[], double, double, long, long) */ - Set zRevRangeByScore(String key, double min, double max, long offset, long count); + Set zRevRangeByScore(@NonNull String key, double min, double max, long offset, long count); /** * Get set of {@link Tuple} in range from {@code start} to {@code end} where score is between {@code min} and @@ -1573,7 +1554,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREVRANGEBYSCORE * @see RedisZSetCommands#zRevRangeByScoreWithScores(byte[], double, double, long, long) */ - Set zRevRangeByScoreWithScores(String key, double min, double max, long offset, long count); + Set zRevRangeByScoreWithScores(@NonNull String key, double min, double max, long offset, long count); /** * Count number of elements within sorted set with scores between {@code min} and {@code max}. @@ -1585,7 +1566,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZCOUNT * @see RedisZSetCommands#zCount(byte[], double, double) */ - Long zCount(String key, double min, double max); + Long zCount(@NonNull String key, double min, double max); /** * Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max} applying @@ -1598,8 +1579,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZLEXCOUNT * @see RedisZSetCommands#zLexCount(byte[], org.springframework.data.domain.Range) */ - @Nullable - Long zLexCount(String key, org.springframework.data.domain.Range range); + Long zLexCount(@NonNull String key, org.springframework.data.domain.@NonNull Range range); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. @@ -1609,8 +1589,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Tuple zPopMin(String key); + Tuple zPopMin(@NonNull String key); /** * Remove and return {@code count} values with their score having the lowest score from sorted set at {@code key}. @@ -1621,8 +1600,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Set zPopMin(String key, long count); + Set zPopMin(@NonNull String key, long count); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. Blocks @@ -1635,8 +1613,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - StringTuple bZPopMin(String key, long timeout, TimeUnit unit); + StringTuple bZPopMin(@NonNull String key, long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}. @@ -1646,8 +1623,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - StringTuple zPopMax(String key); + StringTuple zPopMax(@NonNull String key); /** * Remove and return {@code count} values with their score having the highest score from sorted set at {@code key}. @@ -1658,8 +1634,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - Set zPopMax(String key, long count); + Set zPopMax(@NonNull String key, long count); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}. Blocks @@ -1672,8 +1647,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - StringTuple bZPopMax(String key, long timeout, TimeUnit unit); + StringTuple bZPopMax(@NonNull String key, long timeout, @NonNull TimeUnit unit); /** * Get the size of sorted set with {@code key}. @@ -1683,7 +1657,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZCARD * @see RedisZSetCommands#zCard(byte[]) */ - Long zCard(String key); + Long zCard(@NonNull String key); /** * Get the score of element with {@code value} from sorted set with key {@code key}. @@ -1694,7 +1668,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZSCORE * @see RedisZSetCommands#zScore(byte[], byte[]) */ - Double zScore(String key, String value); + Double zScore(@NonNull String key, String value); /** * Get the scores of elements with {@code values} from sorted set with key {@code key}. @@ -1706,7 +1680,7 @@ default Long lPos(String key, String element) { * @see RedisZSetCommands#zMScore(byte[], byte[][]) * @since 2.6 */ - List zMScore(String key, String... values); + List zMScore(@NonNull String key, String... values); /** * Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}. @@ -1718,7 +1692,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREMRANGEBYRANK * @see RedisZSetCommands#zRemRange(byte[], long, long) */ - Long zRemRange(String key, long start, long end); + Long zRemRange(@NonNull String key, long start, long end); /** * Remove all elements between the lexicographical {@link Range}. @@ -1729,7 +1703,7 @@ default Long lPos(String key, String element) { * @since 2.5 * @see Redis Documentation: ZREMRANGEBYLEX */ - Long zRemRangeByLex(String key, org.springframework.data.domain.Range range); + Long zRemRangeByLex(@NonNull String key, org.springframework.data.domain.@NonNull Range range); /** * Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}. @@ -1741,7 +1715,7 @@ default Long lPos(String key, String element) { * @see Redis Documentation: ZREMRANGEBYSCORE * @see RedisZSetCommands#zRemRangeByScore(byte[], double, double) */ - Long zRemRangeByScore(String key, double min, double max); + Long zRemRangeByScore(@NonNull String key, double min, double max); /** * Diff sorted {@code sets}. @@ -1751,8 +1725,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set zDiff(String... sets); + Set zDiff(@NonNull String @NonNull... sets); /** * Diff sorted {@code sets}. @@ -1762,8 +1735,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set zDiffWithScores(String... sets); + Set zDiffWithScores(@NonNull String @NonNull... sets); /** * Diff sorted {@code sets} and store result in destination {@code destKey}. @@ -1774,8 +1746,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - @Nullable - Long zDiffStore(String destKey, String... sets); + Long zDiffStore(@NonNull String destKey, @NonNull String @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1785,8 +1756,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInter(String... sets); + Set zInter(@NonNull String @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1796,8 +1766,7 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInterWithScores(String... sets); + Set zInterWithScores(@NonNull String @NonNull... sets); /** * Intersect sorted {@code sets}. @@ -1809,8 +1778,8 @@ default Long lPos(String key, String element) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set zInterWithScores(Aggregate aggregate, int[] weights, String... sets) { + default Set zInterWithScores(@NonNull Aggregate aggregate, int @NonNull [] weights, + @NonNull String @NonNull... sets) { return zInterWithScores(aggregate, Weights.of(weights), sets); } @@ -1824,8 +1793,8 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set zInterWithScores(Aggregate aggregate, Weights weights, String... sets); + Set zInterWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + @NonNull String @NonNull... sets); /** * Intersect sorted {@code sets} and store result in destination {@code key}. @@ -1836,7 +1805,7 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZINTERSTORE * @see RedisZSetCommands#zInterStore(byte[], byte[]...) */ - Long zInterStore(String destKey, String... sets); + Long zInterStore(@NonNull String destKey, @NonNull String @NonNull... sets); /** * Intersect sorted {@code sets} and store result in destination {@code key}. @@ -1849,7 +1818,8 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZINTERSTORE * @see RedisZSetCommands#zInterStore(byte[], Aggregate, int[], byte[]...) */ - Long zInterStore(String destKey, Aggregate aggregate, int[] weights, String... sets); + Long zInterStore(@NonNull String destKey, @NonNull Aggregate aggregate, int @NonNull [] weights, + @NonNull String @NonNull... sets); /** * Union sorted {@code sets}. @@ -1859,8 +1829,7 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnion(String... sets); + Set zUnion(@NonNull String @NonNull... sets); /** * Union sorted {@code sets}. @@ -1870,8 +1839,7 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnionWithScores(String... sets); + Set zUnionWithScores(@NonNull String @NonNull... sets); /** * Union sorted {@code sets}. @@ -1883,8 +1851,8 @@ default Set zInterWithScores(Aggregate aggregate, int[] weights, St * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set zUnionWithScores(Aggregate aggregate, int[] weights, String... sets) { + default Set zUnionWithScores(@NonNull Aggregate aggregate, int @NonNull [] weights, + @NonNull String @NonNull... sets) { return zUnionWithScores(aggregate, Weights.of(weights), sets); } @@ -1898,8 +1866,8 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set zUnionWithScores(Aggregate aggregate, Weights weights, String... sets); + Set zUnionWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + @NonNull String @NonNull... sets); /** * Union sorted {@code sets} and store result in destination {@code key}. @@ -1910,7 +1878,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZUNIONSTORE * @see RedisZSetCommands#zUnionStore(byte[], byte[]...) */ - Long zUnionStore(String destKey, String... sets); + Long zUnionStore(@NonNull String destKey, @NonNull String @NonNull... sets); /** * Union sorted {@code sets} and store result in destination {@code key}. @@ -1923,19 +1891,20 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZUNIONSTORE * @see RedisZSetCommands#zUnionStore(byte[], Aggregate, int[], byte[]...) */ - Long zUnionStore(String destKey, Aggregate aggregate, int[] weights, String... sets); + Long zUnionStore(@NonNull String destKey, @NonNull Aggregate aggregate, int @NonNull [] weights, + @NonNull String @NonNull... sets); /** * Use a {@link Cursor} to iterate over elements in sorted set at {@code key}. * * @param key must not be {@literal null}. - * @param options must not be {@literal null}. + * @param options can be {@literal null}. * @return * @since 1.4 * @see Redis Documentation: ZSCAN * @see RedisZSetCommands#zScan(byte[], ScanOptions) */ - Cursor zScan(String key, ScanOptions options); + Cursor zScan(@NonNull String key, ScanOptions options); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -1948,7 +1917,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScore(byte[], String, String) */ - Set zRangeByScore(String key, String min, String max); + Set zRangeByScore(@NonNull String key, @NonNull String min, @NonNull String max); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -1964,7 +1933,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZRANGEBYSCORE * @see RedisZSetCommands#zRangeByScore(byte[], double, double, long, long) */ - Set zRangeByScore(String key, String min, String max, long offset, long count); + Set zRangeByScore(@NonNull String key, @NonNull String min, @NonNull String max, long offset, long count); /** * Get all the elements in the sorted set at {@literal key} in lexicographical ordering. @@ -1975,7 +1944,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZRANGEBYLEX * @see RedisZSetCommands#zRangeByLex(byte[]) */ - Set zRangeByLex(String key); + Set zRangeByLex(@NonNull String key); /** * Get all the elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering. @@ -1987,7 +1956,7 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * @see Redis Documentation: ZRANGEBYLEX * @see RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.domain.Range) */ - Set zRangeByLex(String key, org.springframework.data.domain.Range range); + Set zRangeByLex(@NonNull String key, org.springframework.data.domain.@NonNull Range range); /** * Get all the elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering. Result is @@ -1995,15 +1964,15 @@ default Set zUnionWithScores(Aggregate aggregate, int[] weights, St * * @param key must not be {@literal null}. * @param range must not be {@literal null}. - * @param limit can be {@literal null}. + * @param limit must not be {@literal null}. * @return * @since 1.6 * @see Redis Documentation: ZRANGEBYLEX * @see RedisZSetCommands#zRangeByLex(byte[], org.springframework.data.domain.Range, * org.springframework.data.redis.connection.Limit) */ - Set zRangeByLex(String key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRangeByLex(@NonNull String key, org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Get all the elements in the sorted set at {@literal key} in reversed lexicographical ordering. @@ -2014,7 +1983,7 @@ Set zRangeByLex(String key, org.springframework.data.domain.RangeRedis Documentation: ZREVRANGEBYLEX * @see RedisZSetCommands#zRevRangeByLex(byte[]) */ - default Set zRevRangeByLex(String key) { + default Set zRevRangeByLex(@NonNull String key) { return zRevRangeByLex(key, org.springframework.data.domain.Range.unbounded()); } @@ -2028,7 +1997,8 @@ default Set zRevRangeByLex(String key) { * @see Redis Documentation: ZREVRANGEBYLEX * @see RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.domain.Range) */ - default Set zRevRangeByLex(String key, org.springframework.data.domain.Range range) { + default Set zRevRangeByLex(@NonNull String key, + org.springframework.data.domain.@NonNull Range range) { return zRevRangeByLex(key, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -2045,8 +2015,8 @@ default Set zRevRangeByLex(String key, org.springframework.data.domain.R * @see RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.domain.Range, * org.springframework.data.redis.connection.Limit) */ - Set zRevRangeByLex(String key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Set zRevRangeByLex(@NonNull String key, org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE , but stores the result in the {@literal dstKey} destination key. @@ -2058,8 +2028,8 @@ Set zRevRangeByLex(String key, org.springframework.data.domain.RangeRedis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.domain.Range range) { + default Long zRangeStoreByLex(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -2074,9 +2044,9 @@ default Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework. * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreByLex(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key. @@ -2088,8 +2058,8 @@ Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.dom * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range range) { + default Long zRangeStoreRevByLex(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreRevByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -2104,9 +2074,9 @@ default Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframewo * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreRevByLex(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key. @@ -2118,9 +2088,8 @@ Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data. * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreByScore(String dstKey, String srcKey, - org.springframework.data.domain.Range range) { + default Long zRangeStoreByScore(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -2135,9 +2104,9 @@ default Long zRangeStoreByScore(String dstKey, String srcKey, * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreByScore(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key. @@ -2149,9 +2118,8 @@ Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.d * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long zRangeStoreRevByScore(String dstKey, String srcKey, - org.springframework.data.domain.Range range) { + default Long zRangeStoreRevByScore(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range) { return zRangeStoreRevByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -2166,10 +2134,9 @@ default Long zRangeStoreRevByScore(String dstKey, String srcKey, * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long zRangeStoreRevByScore(String dstKey, String srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + Long zRangeStoreRevByScore(@NonNull String dstKey, @NonNull String srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); // ------------------------------------------------------------------------- // Methods dealing with Redis Hashes @@ -2185,7 +2152,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HSET * @see RedisHashCommands#hSet(byte[], byte[], byte[]) */ - Boolean hSet(String key, String field, String value); + Boolean hSet(@NonNull String key, @NonNull String field, String value); /** * Set the {@code value} of a hash {@code field} only if {@code field} does not exist. @@ -2197,7 +2164,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HSETNX * @see RedisHashCommands#hSetNX(byte[], byte[], byte[]) */ - Boolean hSetNX(String key, String field, String value); + Boolean hSetNX(@NonNull String key, @NonNull String field, String value); /** * Get value for given {@code field} from hash at {@code key}. @@ -2208,7 +2175,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HGET * @see RedisHashCommands#hGet(byte[], byte[]) */ - String hGet(String key, String field); + String hGet(@NonNull String key, @NonNull String field); /** * Get values for given {@code fields} from hash at {@code key}. @@ -2219,7 +2186,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HMGET * @see RedisHashCommands#hMGet(byte[], byte[]...) */ - List hMGet(String key, String... fields); + List hMGet(@NonNull String key, @NonNull String @NonNull... fields); /** * Set multiple hash fields to multiple values using data provided in {@code hashes} @@ -2229,7 +2196,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HMSET * @see RedisHashCommands#hMGet(byte[], byte[]...) */ - void hMSet(String key, Map hashes); + void hMSet(@NonNull String key, @NonNull Map<@NonNull String, String> hashes); /** * Increment {@code value} of a hash {@code field} by the given {@code delta}. @@ -2241,7 +2208,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HINCRBY * @see RedisHashCommands#hIncrBy(byte[], byte[], long) */ - Long hIncrBy(String key, String field, long delta); + Long hIncrBy(@NonNull String key, @NonNull String field, long delta); /** * Increment {@code value} of a hash {@code field} by the given {@code delta}. @@ -2253,7 +2220,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HINCRBYFLOAT * @see RedisHashCommands#hIncrBy(byte[], byte[], double) */ - Double hIncrBy(String key, String field, double delta); + Double hIncrBy(@NonNull String key, @NonNull String field, double delta); /** * Return a random field from the hash stored at {@code key}. @@ -2263,8 +2230,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - String hRandField(String key); + String hRandField(@NonNull String key); /** * Return a random field from the hash along with its value stored at {@code key}. @@ -2274,8 +2240,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map.Entry hRandFieldWithValues(String key); + Map.@Nullable Entry hRandFieldWithValues(@NonNull String key); /** * Return a random field from the hash stored at {@code key}. If the provided {@code count} argument is positive, @@ -2289,8 +2254,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List hRandField(String key, long count); + List hRandField(@NonNull String key, long count); /** * Return a random field from the hash along with its value stored at {@code key}. If the provided {@code count} @@ -2304,8 +2268,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List> hRandFieldWithValues(String key, long count); + List> hRandFieldWithValues(@NonNull String key, long count); /** * Determine if given hash {@code field} exists. @@ -2316,7 +2279,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HEXISTS * @see RedisHashCommands#hExists(byte[], byte[]) */ - Boolean hExists(String key, String field); + Boolean hExists(@NonNull String key, @NonNull String field); /** * Delete given hash {@code fields}. @@ -2327,7 +2290,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HDEL * @see RedisHashCommands#hDel(byte[], byte[]...) */ - Long hDel(String key, String... fields); + Long hDel(@NonNull String key, @NonNull String @NonNull... fields); /** * Get size of hash at {@code key}. @@ -2337,7 +2300,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HLEN * @see RedisHashCommands#hLen(byte[]) */ - Long hLen(String key); + Long hLen(@NonNull String key); /** * Get key set (fields) of hash at {@code key}. @@ -2347,7 +2310,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HKEYS? * @see RedisHashCommands#hKeys(byte[]) */ - Set hKeys(String key); + Set hKeys(@NonNull String key); /** * Get entry set (values) of hash at {@code field}. @@ -2357,7 +2320,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HVALS * @see RedisHashCommands#hVals(byte[]) */ - List hVals(String key); + List hVals(@NonNull String key); /** * Get entire hash stored at {@code key}. @@ -2367,7 +2330,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HGETALL * @see RedisHashCommands#hGetAll(byte[]) */ - Map hGetAll(String key); + Map hGetAll(@NonNull String key); /** * Use a {@link Cursor} to iterate over entries in hash at {@code key}. @@ -2379,7 +2342,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HSCAN * @see RedisHashCommands#hScan(byte[], ScanOptions) */ - Cursor> hScan(String key, ScanOptions options); + Cursor> hScan(@NonNull String key, ScanOptions options); /** * Returns the length of the value associated with {@code field} in the hash stored at {@code key}. If the key or the @@ -2390,8 +2353,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @return {@literal null} when used in pipeline / transaction. * @since 2.1 */ - @Nullable - Long hStrLen(String key, String field); + Long hStrLen(@NonNull String key, @NonNull String field); /** * Set time to live for given {@code field} in seconds. @@ -2406,8 +2368,7 @@ Long zRangeStoreRevByScore(String dstKey, String srcKey, * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - default List hExpire(String key, long seconds, String... fields) { + default List hExpire(@NonNull String key, long seconds, @NonNull String @NonNull... fields) { return hExpire(key, seconds, ExpirationOptions.Condition.ALWAYS, fields); } @@ -2425,8 +2386,8 @@ default List hExpire(String key, long seconds, String... fields) { * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - List hExpire(String key, long seconds, ExpirationOptions.Condition condition, String... fields); + List hExpire(@NonNull String key, long seconds, ExpirationOptions.@NonNull Condition condition, + @NonNull String @NonNull... fields); /** * Set time to live for given {@code field} in milliseconds. @@ -2441,8 +2402,7 @@ default List hExpire(String key, long seconds, String... fields) { * @see Redis Documentation: HPEXPIRE * @since 3.5 */ - @Nullable - default List hpExpire(String key, long millis, String... fields) { + default List hpExpire(@NonNull String key, long millis, @NonNull String @NonNull... fields) { return hpExpire(key, millis, ExpirationOptions.Condition.ALWAYS, fields); } @@ -2460,8 +2420,8 @@ default List hpExpire(String key, long millis, String... fields) { * @see Redis Documentation: HPEXPIRE * @since 3.5 */ - @Nullable - List hpExpire(String key, long millis, ExpirationOptions.Condition condition, String... fields); + List hpExpire(@NonNull String key, long millis, ExpirationOptions.@NonNull Condition condition, + @NonNull String @NonNull... fields); /** * Set the expiration for given {@code field} as a {@literal UNIX} timestamp. @@ -2476,8 +2436,7 @@ default List hpExpire(String key, long millis, String... fields) { * @see Redis Documentation: HEXPIREAT * @since 3.5 */ - @Nullable - default List hExpireAt(String key, long unixTime, String... fields) { + default List hExpireAt(@NonNull String key, long unixTime, @NonNull String @NonNull... fields) { return hExpireAt(key, unixTime, ExpirationOptions.Condition.ALWAYS, fields); } @@ -2495,8 +2454,8 @@ default List hExpireAt(String key, long unixTime, String... fields) { * @see Redis Documentation: HEXPIREAT * @since 3.5 */ - @Nullable - List hExpireAt(String key, long unixTime, ExpirationOptions.Condition condition, String... fields); + List hExpireAt(@NonNull String key, long unixTime, ExpirationOptions.@NonNull Condition condition, + @NonNull String @NonNull... fields); /** * Set the expiration for given {@code field} as a {@literal UNIX} timestamp in milliseconds. @@ -2511,8 +2470,7 @@ default List hExpireAt(String key, long unixTime, String... fields) { * @see Redis Documentation: HPEXPIREAT * @since 3.5 */ - @Nullable - default List hpExpireAt(String key, long unixTimeInMillis, String... fields) { + default List hpExpireAt(@NonNull String key, long unixTimeInMillis, @NonNull String @NonNull... fields) { return hpExpireAt(key, unixTimeInMillis, ExpirationOptions.Condition.ALWAYS, fields); } @@ -2530,9 +2488,8 @@ default List hpExpireAt(String key, long unixTimeInMillis, String... field * @see Redis Documentation: HPEXPIREAT * @since 3.5 */ - @Nullable - List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condition condition, - String... fields); + List hpExpireAt(@NonNull String key, long unixTimeInMillis, ExpirationOptions.@NonNull Condition condition, + @NonNull String @NonNull... fields); /** * Remove the expiration from given {@code field}. @@ -2546,8 +2503,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HPERSIST * @since 3.5 */ - @Nullable - List hPersist(String key, String... fields); + List hPersist(@NonNull String key, @NonNull String @NonNull... fields); /** * Get the time to live for {@code fields} in seconds. @@ -2561,8 +2517,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hTtl(String key, String... fields); + List hTtl(@NonNull String key, @NonNull String @NonNull... fields); /** * Get the time to live for {@code fields} in and convert it to the given {@link TimeUnit}. @@ -2577,8 +2532,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hTtl(String key, TimeUnit timeUnit, String... fields); + List hTtl(@NonNull String key, @NonNull TimeUnit timeUnit, @NonNull String @NonNull... fields); /** * Get the time to live for {@code fields} in seconds. @@ -2592,8 +2546,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - List hpTtl(String key, String... fields); + List hpTtl(@NonNull String key, @NonNull String @NonNull... fields); // ------------------------------------------------------------------------- // Methods dealing with HyperLogLog @@ -2609,7 +2562,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: PFADD * @see RedisHyperLogLogCommands#pfAdd(byte[], byte[]...) */ - Long pfAdd(String key, String... values); + Long pfAdd(@NonNull String key, String... values); /** * Return the approximated cardinality of the structures observed by the HyperLogLog at {@literal key(s)}. @@ -2619,7 +2572,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: PFCOUNT * @see RedisHyperLogLogCommands#pfCount(byte[]...) */ - Long pfCount(String... keys); + Long pfCount(@NonNull String @NonNull... keys); /** * Merge N different HyperLogLogs at {@literal sourceKeys} into a single {@literal destinationKey}. @@ -2629,7 +2582,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: PFMERGE * @see RedisHyperLogLogCommands#pfMerge(byte[], byte[]...) */ - void pfMerge(String destinationKey, String... sourceKeys); + void pfMerge(@NonNull String destinationKey, @NonNull String @NonNull... sourceKeys); // ------------------------------------------------------------------------- // Methods dealing with Redis Geo-Indexes @@ -2646,7 +2599,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOADD * @see RedisGeoCommands#geoAdd(byte[], Point, byte[]) */ - Long geoAdd(String key, Point point, String member); + Long geoAdd(@NonNull String key, @NonNull Point point, @NonNull String member); /** * Add {@link GeoLocation} to {@literal key}. @@ -2658,7 +2611,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOADD * @see RedisGeoCommands#geoAdd(byte[], GeoLocation) */ - Long geoAdd(String key, GeoLocation location); + Long geoAdd(@NonNull String key, @NonNull GeoLocation location); /** * Add {@link Map} of member / {@link Point} pairs to {@literal key}. @@ -2670,7 +2623,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOADD * @see RedisGeoCommands#geoAdd(byte[], Map) */ - Long geoAdd(String key, Map memberCoordinateMap); + Long geoAdd(@NonNull String key, @NonNull Map<@NonNull String, @NonNull Point> memberCoordinateMap); /** * Add {@link GeoLocation}s to {@literal key} @@ -2682,7 +2635,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOADD * @see RedisGeoCommands#geoAdd(byte[], Iterable) */ - Long geoAdd(String key, Iterable> locations); + Long geoAdd(@NonNull String key, @NonNull Iterable<@NonNull GeoLocation> locations); /** * Get the {@link Distance} between {@literal member1} and {@literal member2}. @@ -2695,7 +2648,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEODIST * @see RedisGeoCommands#geoDist(byte[], byte[], byte[]) */ - Distance geoDist(String key, String member1, String member2); + Distance geoDist(@NonNull String key, @NonNull String member1, @NonNull String member2); /** * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. @@ -2709,7 +2662,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEODIST * @see RedisGeoCommands#geoDist(byte[], byte[], byte[], Metric) */ - Distance geoDist(String key, String member1, String member2, Metric metric); + Distance geoDist(@NonNull String key, @NonNull String member1, @NonNull String member2, @NonNull Metric metric); /** * Get geohash representation of the position for one or more {@literal member}s. @@ -2721,7 +2674,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOHASH * @see RedisGeoCommands#geoHash(byte[], byte[]...) */ - List geoHash(String key, String... members); + List geoHash(@NonNull String key, @NonNull String @NonNull... members); /** * Get the {@link Point} representation of positions for one or more {@literal member}s. @@ -2733,7 +2686,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEOPOS * @see RedisGeoCommands#geoPos(byte[], byte[]...) */ - List geoPos(String key, String... members); + List geoPos(@NonNull String key, @NonNull String @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -2745,7 +2698,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEORADIUS * @see RedisGeoCommands#geoRadius(byte[], Circle) */ - GeoResults> geoRadius(String key, Circle within); + GeoResults> geoRadius(@NonNull String key, @NonNull Circle within); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. @@ -2758,7 +2711,8 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEORADIUS * @see RedisGeoCommands#geoRadius(byte[], Circle, GeoRadiusCommandArgs) */ - GeoResults> geoRadius(String key, Circle within, GeoRadiusCommandArgs args); + GeoResults> geoRadius(@NonNull String key, @NonNull Circle within, + @NonNull GeoRadiusCommandArgs args); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -2772,7 +2726,7 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEORADIUSBYMEMBER * @see RedisGeoCommands#geoRadiusByMember(byte[], byte[], double) */ - GeoResults> geoRadiusByMember(String key, String member, double radius); + GeoResults> geoRadiusByMember(@NonNull String key, @NonNull String member, double radius); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -2786,7 +2740,8 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEORADIUSBYMEMBER * @see RedisGeoCommands#geoRadiusByMember(byte[], byte[], Distance) */ - GeoResults> geoRadiusByMember(String key, String member, Distance radius); + GeoResults> geoRadiusByMember(@NonNull String key, @NonNull String member, + @NonNull Distance radius); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -2801,8 +2756,8 @@ List hpExpireAt(String key, long unixTimeInMillis, ExpirationOptions.Condi * @see Redis Documentation: GEORADIUSBYMEMBER * @see RedisGeoCommands#geoRadiusByMember(byte[], byte[], Distance, GeoRadiusCommandArgs) */ - GeoResults> geoRadiusByMember(String key, String member, Distance radius, - GeoRadiusCommandArgs args); + GeoResults> geoRadiusByMember(@NonNull String key, @NonNull String member, + @NonNull Distance radius, @NonNull GeoRadiusCommandArgs args); /** * Remove the {@literal member}s. @@ -2814,7 +2769,7 @@ GeoResults> geoRadiusByMember(String key, String member, Dis * @see Redis Documentation: ZREM * @see RedisGeoCommands#geoRemove(byte[], byte[]...) */ - Long geoRemove(String key, String... members); + Long geoRemove(@NonNull String key, @NonNull String @NonNull... members); /** * Return the members of a geo set which are within the borders of the area specified by a given {@link GeoShape @@ -2828,9 +2783,8 @@ GeoResults> geoRadiusByMember(String key, String member, Dis * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - GeoResults> geoSearch(String key, GeoReference reference, GeoShape predicate, - GeoSearchCommandArgs args); + GeoResults> geoSearch(@NonNull String key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchCommandArgs args); /** * Query the members of a geo set which are within the borders of the area specified by a given {@link GeoShape shape} @@ -2844,9 +2798,8 @@ GeoResults> geoSearch(String key, GeoReference refer * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - Long geoSearchStore(String destKey, String key, GeoReference reference, GeoShape predicate, - GeoSearchStoreCommandArgs args); + Long geoSearchStore(String destKey, @NonNull String key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchStoreCommandArgs args); // ------------------------------------------------------------------------- // Methods dealing with Redis Pub/Sub @@ -2861,7 +2814,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: PUBLISH * @see RedisPubSubCommands#publish(byte[], byte[]) */ - Long publish(String channel, String message); + Long publish(@NonNull String channel, @NonNull String message); /** * Subscribes the connection to the given channels. Once subscribed, a connection enters listening mode and can only @@ -2874,7 +2827,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: SUBSCRIBE * @see RedisPubSubCommands#subscribe(MessageListener, byte[]...) */ - void subscribe(MessageListener listener, String... channels); + void subscribe(@NonNull MessageListener listener, @NonNull String @NonNull... channels); /** * Subscribes the connection to all channels matching the given patterns. Once subscribed, a connection enters @@ -2888,7 +2841,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: PSUBSCRIBE * @see RedisPubSubCommands#pSubscribe(MessageListener, byte[]...) */ - void pSubscribe(MessageListener listener, String... patterns); + void pSubscribe(@NonNull MessageListener listener, @NonNull String @NonNull... patterns); // ------------------------------------------------------------------------- // Methods dealing with Redis Lua Scripting @@ -2903,7 +2856,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: SCRIPT LOAD * @see RedisScriptingCommands#scriptLoad(byte[]) */ - String scriptLoad(String script); + String scriptLoad(@NonNull String script); /** * Evaluate given {@code script}. @@ -2916,7 +2869,8 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: EVAL * @see RedisScriptingCommands#eval(byte[], ReturnType, int, byte[]...) */ - T eval(String script, ReturnType returnType, int numKeys, String... keysAndArgs); + T eval(@NonNull String script, @NonNull ReturnType returnType, int numKeys, + @NonNull String @NonNull... keysAndArgs); /** * Evaluate given {@code scriptSha}. @@ -2929,7 +2883,8 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: EVALSHA * @see RedisScriptingCommands#evalSha(String, ReturnType, int, byte[]...) */ - T evalSha(String scriptSha, ReturnType returnType, int numKeys, String... keysAndArgs); + T evalSha(@NonNull String scriptSha, @NonNull ReturnType returnType, int numKeys, + @NonNull String @NonNull... keysAndArgs); /** * Assign given name to current connection. @@ -2939,7 +2894,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @see Redis Documentation: CLIENT SETNAME * @see RedisServerCommands#setClientName(byte[]) */ - void setClientName(String name); + void setClientName(@NonNull String name); /** * Request information and statistics about connected clients. @@ -2959,7 +2914,7 @@ Long geoSearchStore(String destKey, String key, GeoReference reference, * @param command must not be {@literal null}. * @return */ - List bitfield(String key, BitFieldSubCommands command); + List bitfield(@NonNull String key, @NonNull BitFieldSubCommands command); // ------------------------------------------------------------------------- // Methods dealing with Redis Streams @@ -2984,12 +2939,11 @@ static RecordId[] entryIds(String... entryIds) { * @since 2.2 * @see Redis Documentation: XACK */ - @Nullable - default Long xAck(String key, String group, String... entryIds) { + default Long xAck(@NonNull String key, @NonNull String group, @NonNull String @NonNull... entryIds) { return xAck(key, group, entryIds(entryIds)); } - Long xAck(String key, String group, RecordId... recordIds); + Long xAck(@NonNull String key, @NonNull String group, @NonNull RecordId @NonNull... recordIds); /** * Append a record to the stream {@code key}. @@ -3000,8 +2954,7 @@ default Long xAck(String key, String group, String... entryIds) { * @since 2.2 * @see Redis Documentation: XADD */ - @Nullable - default RecordId xAdd(String key, Map body) { + default RecordId xAdd(@NonNull String key, @NonNull Map<@NonNull String, String> body) { return xAdd(StreamRecords.newRecord().in(key).ofStrings(body)); } @@ -3012,8 +2965,7 @@ default RecordId xAdd(String key, Map body) { * @return the record Id. {@literal null} when used in pipeline / transaction. * @since 2.2 */ - @Nullable - default RecordId xAdd(StringRecord record) { + default RecordId xAdd(@NonNull StringRecord record) { return xAdd(record, XAddOptions.none()); } @@ -3025,8 +2977,7 @@ default RecordId xAdd(StringRecord record) { * @return the record Id. {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - RecordId xAdd(StringRecord record, XAddOptions options); + RecordId xAdd(@NonNull StringRecord record, @NonNull XAddOptions options); /** * Change the ownership of a pending message to the given new {@literal consumer} without increasing the delivered @@ -3040,7 +2991,8 @@ default RecordId xAdd(StringRecord record) { * @see Redis Documentation: XCLAIM * @since 2.3 */ - List xClaimJustId(String key, String group, String newOwner, XClaimOptions options); + List xClaimJustId(@NonNull String key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options); /** * Change the ownership of a pending message to the given new {@literal consumer}. @@ -3054,8 +3006,8 @@ default RecordId xAdd(StringRecord record) { * @see Redis Documentation: XCLAIM * @since 2.3 */ - default List xClaim(String key, String group, String newOwner, Duration minIdleTime, - RecordId... recordIds) { + default List xClaim(@NonNull String key, @NonNull String group, @NonNull String newOwner, + @NonNull Duration minIdleTime, @NonNull RecordId @NonNull... recordIds) { return xClaim(key, group, newOwner, XClaimOptions.minIdle(minIdleTime).ids(recordIds)); } @@ -3070,7 +3022,8 @@ default List xClaim(String key, String group, String newOwner, Dur * @see Redis Documentation: XCLAIM * @since 2.3 */ - List xClaim(String key, String group, String newOwner, XClaimOptions options); + List xClaim(@NonNull String key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options); /** * Removes the specified entries from the stream. Returns the number of items deleted, that may be different from the @@ -3082,12 +3035,11 @@ default List xClaim(String key, String group, String newOwner, Dur * @since 2.2 * @see Redis Documentation: XDEL */ - @Nullable - default Long xDel(String key, String... entryIds) { + default Long xDel(@NonNull String key, @NonNull String @NonNull... entryIds) { return xDel(key, entryIds(entryIds)); } - Long xDel(String key, RecordId... recordIds); + Long xDel(@NonNull String key, @NonNull RecordId @NonNull... recordIds); /** * Create a consumer group. @@ -3098,8 +3050,7 @@ default Long xDel(String key, String... entryIds) { * @since 2.2 * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - String xGroupCreate(String key, ReadOffset readOffset, String group); + String xGroupCreate(@NonNull String key, @NonNull ReadOffset readOffset, @NonNull String group); /** * Create a consumer group. @@ -3112,8 +3063,7 @@ default Long xDel(String key, String... entryIds) { * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - String xGroupCreate(String key, ReadOffset readOffset, String group, boolean mkStream); + String xGroupCreate(@NonNull String key, @NonNull ReadOffset readOffset, @NonNull String group, boolean mkStream); /** * Delete a consumer from a consumer group. @@ -3123,8 +3073,7 @@ default Long xDel(String key, String... entryIds) { * @since 2.2 * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean xGroupDelConsumer(String key, Consumer consumer); + Boolean xGroupDelConsumer(@NonNull String key, @NonNull Consumer consumer); /** * Destroy a consumer group. @@ -3134,8 +3083,7 @@ default Long xDel(String key, String... entryIds) { * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. * @since 2.2 */ - @Nullable - Boolean xGroupDestroy(String key, String group); + Boolean xGroupDestroy(@NonNull String key, String group); /** * Obtain general information about the stream stored at the specified {@literal key}. @@ -3144,8 +3092,7 @@ default Long xDel(String key, String... entryIds) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoStream xInfo(String key); + XInfoStream xInfo(@NonNull String key); /** * Obtain information about {@literal consumer groups} associated with the stream stored at the specified @@ -3155,8 +3102,7 @@ default Long xDel(String key, String... entryIds) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoGroups xInfoGroups(String key); + XInfoGroups xInfoGroups(@NonNull String key); /** * Obtain information about every consumer in a specific {@literal consumer group} for the stream stored at the @@ -3167,8 +3113,7 @@ default Long xDel(String key, String... entryIds) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - @Nullable - XInfoConsumers xInfoConsumers(String key, String groupName); + XInfoConsumers xInfoConsumers(@NonNull String key, @NonNull String groupName); /** * Get the length of a stream. @@ -3178,8 +3123,7 @@ default Long xDel(String key, String... entryIds) { * @since 2.2 * @see Redis Documentation: XLEN */ - @Nullable - Long xLen(String key); + Long xLen(@NonNull String key); /** * Obtain the {@link PendingMessagesSummary} for a given {@literal consumer group}. @@ -3191,8 +3135,7 @@ default Long xDel(String key, String... entryIds) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessagesSummary xPending(String key, String groupName); + PendingMessagesSummary xPending(@NonNull String key, @NonNull String groupName); /** * Obtain detailed information about pending {@link PendingMessage messages} for a given @@ -3208,9 +3151,8 @@ default Long xDel(String key, String... entryIds) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessages xPending(String key, String groupName, String consumerName, - org.springframework.data.domain.Range range, Long count); + PendingMessages xPending(@NonNull String key, @NonNull String groupName, @NonNull String consumerName, + org.springframework.data.domain.@NonNull Range range, @NonNull Long count); /** * Obtain detailed information about pending {@link PendingMessage messages} for a given @@ -3225,9 +3167,8 @@ PendingMessages xPending(String key, String groupName, String consumerName, * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessages xPending(String key, String groupName, org.springframework.data.domain.Range range, - Long count); + PendingMessages xPending(@NonNull String key, @NonNull String groupName, + org.springframework.data.domain.@NonNull Range range, @NonNull Long count); /** * Obtain detailed information about pending {@link PendingMessage messages} applying given {@link XPendingOptions @@ -3241,8 +3182,7 @@ PendingMessages xPending(String key, String groupName, org.springframework.data. * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessages xPending(String key, String groupName, XPendingOptions options); + PendingMessages xPending(@NonNull String key, @NonNull String groupName, @NonNull XPendingOptions options); /** * Read records from a stream within a specific {@link Range}. @@ -3253,8 +3193,7 @@ PendingMessages xPending(String key, String groupName, org.springframework.data. * @since 2.2 * @see Redis Documentation: XRANGE */ - @Nullable - default List xRange(String key, org.springframework.data.domain.Range range) { + default List xRange(@NonNull String key, org.springframework.data.domain.@NonNull Range range) { return xRange(key, range, org.springframework.data.redis.connection.Limit.unlimited()); } @@ -3269,9 +3208,8 @@ default List xRange(String key, org.springframework.data.domain.Ra * @since 2.2 * @see Redis Documentation: XRANGE */ - @Nullable - List xRange(String key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + List xRange(@NonNull String key, org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Read records from one or more {@link StreamOffset}s. @@ -3281,8 +3219,7 @@ List xRange(String key, org.springframework.data.domain.RangeRedis Documentation: XREAD */ - @Nullable - default List xReadAsString(StreamOffset stream) { + default List xReadAsString(@NonNull StreamOffset stream) { return xReadAsString(StreamReadOptions.empty(), new StreamOffset[] { stream }); } @@ -3294,8 +3231,7 @@ default List xReadAsString(StreamOffset stream) { * @since 2.2 * @see Redis Documentation: XREAD */ - @Nullable - default List xReadAsString(StreamOffset... streams) { + default List xReadAsString(@NonNull StreamOffset... streams) { return xReadAsString(StreamReadOptions.empty(), streams); } @@ -3308,8 +3244,8 @@ default List xReadAsString(StreamOffset... streams) { * @since 2.2 * @see Redis Documentation: XREAD */ - @Nullable - default List xReadAsString(StreamReadOptions readOptions, StreamOffset stream) { + default List xReadAsString(@NonNull StreamReadOptions readOptions, + @NonNull StreamOffset stream) { return xReadAsString(readOptions, new StreamOffset[] { stream }); } @@ -3322,8 +3258,7 @@ default List xReadAsString(StreamReadOptions readOptions, StreamOf * @since 2.2 * @see Redis Documentation: XREAD */ - @Nullable - List xReadAsString(StreamReadOptions readOptions, StreamOffset... streams); + List xReadAsString(@NonNull StreamReadOptions readOptions, @NonNull StreamOffset... streams); /** * Read records from one or more {@link StreamOffset}s using a consumer group. @@ -3334,8 +3269,7 @@ default List xReadAsString(StreamReadOptions readOptions, StreamOf * @since 2.2 * @see Redis Documentation: XREADGROUP */ - @Nullable - default List xReadGroupAsString(Consumer consumer, StreamOffset stream) { + default List xReadGroupAsString(@NonNull Consumer consumer, @NonNull StreamOffset stream) { return xReadGroupAsString(consumer, StreamReadOptions.empty(), new StreamOffset[] { stream }); } @@ -3348,8 +3282,8 @@ default List xReadGroupAsString(Consumer consumer, StreamOffsetRedis Documentation: XREADGROUP */ - @Nullable - default List xReadGroupAsString(Consumer consumer, StreamOffset... streams) { + default List xReadGroupAsString(@NonNull Consumer consumer, + @NonNull StreamOffset @NonNull... streams) { return xReadGroupAsString(consumer, StreamReadOptions.empty(), streams); } @@ -3363,9 +3297,8 @@ default List xReadGroupAsString(Consumer consumer, StreamOffsetRedis Documentation: XREADGROUP */ - @Nullable - default List xReadGroupAsString(Consumer consumer, StreamReadOptions readOptions, - StreamOffset stream) { + default List xReadGroupAsString(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset stream) { return xReadGroupAsString(consumer, readOptions, new StreamOffset[] { stream }); } @@ -3379,9 +3312,8 @@ default List xReadGroupAsString(Consumer consumer, StreamReadOptio * @since 2.2 * @see Redis Documentation: XREADGROUP */ - @Nullable - List xReadGroupAsString(Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams); + List xReadGroupAsString(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams); /** * Read records from a stream within a specific {@link Range} in reverse order. @@ -3392,8 +3324,8 @@ List xReadGroupAsString(Consumer consumer, StreamReadOptions readO * @since 2.2 * @see Redis Documentation: XREVRANGE */ - @Nullable - default List xRevRange(String key, org.springframework.data.domain.Range range) { + default List xRevRange(@NonNull String key, + org.springframework.data.domain.@NonNull Range range) { return xRevRange(key, range, Limit.unlimited()); } @@ -3408,9 +3340,8 @@ default List xRevRange(String key, org.springframework.data.domain * @since 2.2 * @see Redis Documentation: XREVRANGE */ - @Nullable - List xRevRange(String key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit); + List xRevRange(@NonNull String key, org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit); /** * Trims the stream to {@code count} elements. @@ -3421,8 +3352,7 @@ List xRevRange(String key, org.springframework.data.domain.RangeRedis Documentation: XTRIM */ - @Nullable - Long xTrim(String key, long count); + Long xTrim(@NonNull String key, long count); /** * Trims the stream to {@code count} elements. @@ -3434,6 +3364,5 @@ List xRevRange(String key, org.springframework.data.domain.RangeRedis Documentation: XTRIM */ - @Nullable - Long xTrim(String key, long count, boolean approximateTrimming); + Long xTrim(@NonNull String key, long count, boolean approximateTrimming); } diff --git a/src/main/java/org/springframework/data/redis/connection/ValueEncoding.java b/src/main/java/org/springframework/data/redis/connection/ValueEncoding.java index b0d573639a..200b66011f 100644 --- a/src/main/java/org/springframework/data/redis/connection/ValueEncoding.java +++ b/src/main/java/org/springframework/data/redis/connection/ValueEncoding.java @@ -17,7 +17,7 @@ import java.util.Optional; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** @@ -104,11 +104,10 @@ enum RedisValueEncoding implements ValueEncoding { } @Override - public String raw() { + public @Nullable String raw() { return raw; } - @Nullable static Optional lookup(@Nullable String encoding) { for (ValueEncoding valueEncoding : values()) { diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index 2d4eb2cb59..7d7cc7cb4b 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; @@ -44,7 +44,6 @@ import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -352,8 +351,7 @@ public static Converter, Properties> mapToPropertiesConverter() * @return given {@literal seconds} as {@link Duration} or {@literal null}. * @since 2.1 */ - @Nullable - public static Duration secondsToDuration(@Nullable Long seconds) { + public static @Nullable Duration secondsToDuration(@Nullable Long seconds) { return seconds != null ? Duration.ofSeconds(seconds) : null; } @@ -495,8 +493,8 @@ static class DistanceConverter implements Converter { * @param metric can be {@literal null}. Defaults to {@link DistanceUnit#METERS}. * @return never {@literal null}. */ - DistanceConverter(Metric metric) { - this.metric = ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric; + DistanceConverter(@Nullable Metric metric) { + this.metric = (metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric)) ? DistanceUnit.METERS : metric; } @Override @@ -521,6 +519,7 @@ public DeserializingGeoResultsConverter(RedisSerializer serializer) { } @Override + @SuppressWarnings("NullAway") public GeoResults> convert(GeoResults> source) { List>> values = new ArrayList<>(source.getContent().size()); diff --git a/src/main/java/org/springframework/data/redis/connection/convert/TransactionResultConverter.java b/src/main/java/org/springframework/data/redis/connection/convert/TransactionResultConverter.java index 2655245ceb..a7dde5dc4d 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/TransactionResultConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/TransactionResultConverter.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Queue; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.RedisSystemException; @@ -46,7 +47,7 @@ public TransactionResultConverter(Queue> txResults, } @Override - public List convert(List execResults) { + public @Nullable List<@Nullable Object> convert(List execResults) { if (execResults.size() != txResults.size()) { diff --git a/src/main/java/org/springframework/data/redis/connection/convert/package-info.java b/src/main/java/org/springframework/data/redis/connection/convert/package-info.java index b58fb458a5..c7d8eb32b6 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/package-info.java @@ -1,6 +1,5 @@ /** * Redis specific converters used for sending data and parsing responses. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection.convert; diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/DefaultJedisClientConfiguration.java b/src/main/java/org/springframework/data/redis/connection/jedis/DefaultJedisClientConfiguration.java index fee76a291f..e79dc9879b 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/DefaultJedisClientConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/DefaultJedisClientConfiguration.java @@ -23,7 +23,7 @@ import javax.net.ssl.SSLSocketFactory; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Default implementation of {@literal JedisClientConfiguration}. diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClientConfiguration.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClientConfiguration.java index 6cf9357dfa..17766bf423 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClientConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClientConfiguration.java @@ -27,7 +27,7 @@ import javax.net.ssl.SSLSocketFactory; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java index 51f6f3cd14..6064ed14b2 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java @@ -37,6 +37,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.PropertyAccessor; import org.springframework.dao.DataAccessException; @@ -46,16 +50,39 @@ import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisSystemException; -import org.springframework.data.redis.connection.*; +import org.springframework.data.redis.connection.ClusterCommandExecutor; import org.springframework.data.redis.connection.ClusterCommandExecutor.ClusterCommandCallback; import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiKeyClusterCommandCallback; import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult; +import org.springframework.data.redis.connection.ClusterInfo; +import org.springframework.data.redis.connection.ClusterNodeResourceProvider; +import org.springframework.data.redis.connection.ClusterTopology; +import org.springframework.data.redis.connection.ClusterTopologyProvider; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.data.redis.connection.RedisClusterCommands; +import org.springframework.data.redis.connection.RedisClusterConnection; +import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; +import org.springframework.data.redis.connection.RedisClusterServerCommands; +import org.springframework.data.redis.connection.RedisCommands; +import org.springframework.data.redis.connection.RedisGeoCommands; +import org.springframework.data.redis.connection.RedisHashCommands; +import org.springframework.data.redis.connection.RedisHyperLogLogCommands; +import org.springframework.data.redis.connection.RedisKeyCommands; +import org.springframework.data.redis.connection.RedisListCommands; +import org.springframework.data.redis.connection.RedisPipelineException; +import org.springframework.data.redis.connection.RedisScriptingCommands; +import org.springframework.data.redis.connection.RedisSentinelConnection; +import org.springframework.data.redis.connection.RedisSetCommands; +import org.springframework.data.redis.connection.RedisStreamCommands; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.connection.RedisSubscribedConnectionException; +import org.springframework.data.redis.connection.RedisZSetCommands; +import org.springframework.data.redis.connection.Subscription; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -75,6 +102,7 @@ * @author John Blum * @since 1.7 */ +@NullUnmarked public class JedisClusterConnection implements RedisClusterConnection { private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( @@ -107,7 +135,7 @@ public class JedisClusterConnection implements RedisClusterConnection { * * @param cluster must not be {@literal null}. */ - public JedisClusterConnection(JedisCluster cluster) { + public JedisClusterConnection(@NonNull JedisCluster cluster) { Assert.notNull(cluster, "JedisCluster must not be null"); @@ -137,7 +165,7 @@ public JedisClusterConnection(JedisCluster cluster) { * @param cluster must not be {@literal null}. * @param executor must not be {@literal null}. */ - public JedisClusterConnection(JedisCluster cluster, ClusterCommandExecutor executor) { + public JedisClusterConnection(@NonNull JedisCluster cluster, @NonNull ClusterCommandExecutor executor) { this(cluster, executor, new JedisClusterTopologyProvider(cluster)); } @@ -150,8 +178,8 @@ public JedisClusterConnection(JedisCluster cluster, ClusterCommandExecutor execu * @param topologyProvider must not be {@literal null}. * @since 2.2 */ - public JedisClusterConnection(JedisCluster cluster, ClusterCommandExecutor executor, - ClusterTopologyProvider topologyProvider) { + public JedisClusterConnection(@NonNull JedisCluster cluster, @NonNull ClusterCommandExecutor executor, + @NonNull ClusterTopologyProvider topologyProvider) { Assert.notNull(cluster, "JedisCluster must not be null"); Assert.notNull(executor, "ClusterCommandExecutor must not be null"); @@ -164,23 +192,21 @@ public JedisClusterConnection(JedisCluster cluster, ClusterCommandExecutor execu this.disposeClusterCommandExecutorOnClose = false; } - @Nullable @Override - public Object execute(String command, byte[]... args) { + public Object execute(@NonNull String command, byte @NonNull [] @NonNull... args) { Assert.notNull(command, "Command must not be null"); Assert.notNull(args, "Args must not be null"); - JedisClusterCommandCallback commandCallback = jedis -> - jedis.sendCommand(JedisClientUtils.getCommand(command), args); + JedisClusterCommandCallback commandCallback = jedis -> jedis + .sendCommand(JedisClientUtils.getCommand(command), args); return this.clusterCommandExecutor.executeCommandOnArbitraryNode(commandCallback).getValue(); } - @Nullable @Override @SuppressWarnings("unchecked") - public T execute(String command, byte[] key, Collection args) { + public T execute(@NonNull String command, byte @NonNull [] key, @NonNull Collection args) { Assert.notNull(command, "Command must not be null"); Assert.notNull(key, "Key must not be null"); @@ -190,8 +216,8 @@ public T execute(String command, byte[] key, Collection args) { RedisClusterNode keyMaster = this.topologyProvider.getTopology().getKeyServingMasterNode(key); - JedisClusterCommandCallback commandCallback = jedis -> - (T) jedis.sendCommand(JedisClientUtils.getCommand(command), commandArgs); + JedisClusterCommandCallback commandCallback = jedis -> (T) jedis + .sendCommand(JedisClientUtils.getCommand(command), commandArgs); return this.clusterCommandExecutor.executeCommandOnSingleNode(commandCallback, keyMaster).getValue(); } @@ -232,16 +258,16 @@ private static byte[][] getCommandArguments(byte[] key, Collection args) * @return command result as delivered by the underlying Redis driver. Can be {@literal null}. * @since 2.1 */ - @Nullable @SuppressWarnings("unchecked") - public List execute(String command, Collection keys, Collection args) { + public List execute(@NonNull String command, @NonNull Collection keys, + @NonNull Collection args) { Assert.notNull(command, "Command must not be null"); Assert.notNull(keys, "Key must not be null"); Assert.notNull(args, "Args must not be null"); - JedisMultiKeyClusterCommandCallback commandCallback = (jedis, key) -> - (T) jedis.sendCommand(JedisClientUtils.getCommand(command), getCommandArguments(key, args)); + JedisMultiKeyClusterCommandCallback commandCallback = (jedis, + key) -> (T) jedis.sendCommand(JedisClientUtils.getCommand(command), getCommandArguments(key, args)); return this.clusterCommandExecutor.executeMultiKeyCommand(commandCallback, keys).resultsAsList(); @@ -363,7 +389,7 @@ public Subscription getSubscription() { } @Override - public Long publish(byte[] channel, byte[] message) { + public Long publish(byte @NonNull [] channel, byte @NonNull [] message) { try { return this.cluster.publish(channel, message); @@ -373,7 +399,7 @@ public Long publish(byte[] channel, byte[] message) { } @Override - public void subscribe(MessageListener listener, byte[]... channels) { + public void subscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... channels) { if (isSubscribed()) { String message = "Connection already subscribed; use the connection Subscription to cancel or add new channels"; @@ -389,7 +415,7 @@ public void subscribe(MessageListener listener, byte[]... channels) { } @Override - public void pSubscribe(MessageListener listener, byte[]... patterns) { + public void pSubscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... patterns) { if (isSubscribed()) { String message = "Connection already subscribed; use the connection Subscription to cancel or add new channels"; @@ -414,11 +440,11 @@ public void select(int dbIndex) { } @Override - public byte[] echo(byte[] message) { + public byte[] echo(byte @NonNull [] message) { throw new InvalidDataAccessApiUsageException("Echo not supported in cluster mode"); } - @Override @Nullable + @Override public String ping() { JedisClusterCommandCallback command = Jedis::ping; @@ -427,7 +453,7 @@ public String ping() { } @Override - public String ping(RedisClusterNode node) { + public String ping(@NonNull RedisClusterNode node) { JedisClusterCommandCallback command = Jedis::ping; @@ -439,7 +465,7 @@ public String ping(RedisClusterNode node) { */ @Override - public void clusterSetSlot(RedisClusterNode node, int slot, AddSlots mode) { + public void clusterSetSlot(@NonNull RedisClusterNode node, int slot, @NonNull AddSlots mode) { Assert.notNull(node, "Node must not be null"); Assert.notNull(mode, "AddSlots mode must not be null"); @@ -458,12 +484,12 @@ public void clusterSetSlot(RedisClusterNode node, int slot, AddSlots mode) { } @Override - public List clusterGetKeysInSlot(int slot, Integer count) { + public List clusterGetKeysInSlot(int slot, @NonNull Integer count) { RedisClusterNode node = clusterGetNodeForSlot(slot); - JedisClusterCommandCallback> command = jedis -> - JedisConverters.stringListToByteList().convert(jedis.clusterGetKeysInSlot(slot, nullSafeIntValue(count))); + JedisClusterCommandCallback> command = jedis -> JedisConverters.stringListToByteList() + .convert(jedis.clusterGetKeysInSlot(slot, nullSafeIntValue(count))); NodeResult> result = this.clusterCommandExecutor.executeCommandOnSingleNode(command, node); @@ -475,7 +501,7 @@ private int nullSafeIntValue(@Nullable Integer value) { } @Override - public void clusterAddSlots(RedisClusterNode node, int... slots) { + public void clusterAddSlots(@NonNull RedisClusterNode node, int @NonNull... slots) { JedisClusterCommandCallback command = jedis -> jedis.clusterAddSlots(slots); @@ -483,7 +509,7 @@ public void clusterAddSlots(RedisClusterNode node, int... slots) { } @Override - public void clusterAddSlots(RedisClusterNode node, SlotRange range) { + public void clusterAddSlots(@NonNull RedisClusterNode node, @NonNull SlotRange range) { Assert.notNull(range, "Range must not be null"); @@ -501,7 +527,7 @@ public Long clusterCountKeysInSlot(int slot) { } @Override - public void clusterDeleteSlots(RedisClusterNode node, int... slots) { + public void clusterDeleteSlots(@NonNull RedisClusterNode node, int @NonNull... slots) { JedisClusterCommandCallback command = jedis -> jedis.clusterDelSlots(slots); @@ -509,7 +535,7 @@ public void clusterDeleteSlots(RedisClusterNode node, int... slots) { } @Override - public void clusterDeleteSlotsInRange(RedisClusterNode node, SlotRange range) { + public void clusterDeleteSlotsInRange(@NonNull RedisClusterNode node, @NonNull SlotRange range) { Assert.notNull(range, "Range must not be null"); @@ -517,7 +543,7 @@ public void clusterDeleteSlotsInRange(RedisClusterNode node, SlotRange range) { } @Override - public void clusterForget(RedisClusterNode node) { + public void clusterForget(@NonNull RedisClusterNode node) { Set nodes = new LinkedHashSet<>(this.topologyProvider.getTopology().getActiveMasterNodes()); RedisClusterNode nodeToRemove = this.topologyProvider.getTopology().lookup(node); @@ -531,7 +557,7 @@ public void clusterForget(RedisClusterNode node) { @Override @SuppressWarnings("all") - public void clusterMeet(RedisClusterNode node) { + public void clusterMeet(@NonNull RedisClusterNode node) { Assert.notNull(node, "Cluster node must not be null for CLUSTER MEET command"); Assert.hasText(node.getHost(), "Node to meet cluster must have a host"); @@ -543,7 +569,7 @@ public void clusterMeet(RedisClusterNode node) { } @Override - public void clusterReplicate(RedisClusterNode master, RedisClusterNode replica) { + public void clusterReplicate(@NonNull RedisClusterNode master, @NonNull RedisClusterNode replica) { RedisClusterNode masterNode = this.topologyProvider.getTopology().lookup(master); @@ -553,20 +579,20 @@ public void clusterReplicate(RedisClusterNode master, RedisClusterNode replica) } @Override - public Integer clusterGetSlotForKey(byte[] key) { + public Integer clusterGetSlotForKey(byte @NonNull [] key) { - JedisClusterCommandCallback command = jedis -> - Long.valueOf(jedis.clusterKeySlot(JedisConverters.toString(key))).intValue(); + JedisClusterCommandCallback command = jedis -> Long + .valueOf(jedis.clusterKeySlot(JedisConverters.toString(key))).intValue(); return this.clusterCommandExecutor.executeCommandOnArbitraryNode(command).getValue(); } @Override - public RedisClusterNode clusterGetNodeForKey(byte[] key) { + public RedisClusterNode clusterGetNodeForKey(byte @NonNull [] key) { return this.topologyProvider.getTopology().getKeyServingMasterNode(key); } - @Override @Nullable + @Override public RedisClusterNode clusterGetNodeForSlot(int slot) { for (RedisClusterNode node : topologyProvider.getTopology().getSlotServingNodes(slot)) { @@ -584,7 +610,7 @@ public Set clusterGetNodes() { } @Override - public Set clusterGetReplicas(RedisClusterNode master) { + public Set clusterGetReplicas(@NonNull RedisClusterNode master) { Assert.notNull(master, "Master cannot be null"); @@ -600,14 +626,13 @@ public Set clusterGetReplicas(RedisClusterNode master) { @Override public Map> clusterGetMasterReplicaMap() { - JedisClusterCommandCallback> command = jedis -> - JedisConverters.toSetOfRedisClusterNodes(jedis.clusterSlaves(jedis.clusterMyId())); + JedisClusterCommandCallback> command = jedis -> JedisConverters + .toSetOfRedisClusterNodes(jedis.clusterSlaves(jedis.clusterMyId())); Set activeMasterNodes = this.topologyProvider.getTopology().getActiveMasterNodes(); - List>> nodeResults = - this.clusterCommandExecutor.executeCommandAsyncOnNodes(command,activeMasterNodes) - .getResults(); + List>> nodeResults = this.clusterCommandExecutor + .executeCommandAsyncOnNodes(command, activeMasterNodes).getResults(); Map> result = new LinkedHashMap<>(); @@ -631,7 +656,6 @@ public ClusterInfo clusterGetClusterInfo() { /* * Little helpers to make it work */ - protected DataAccessException convertJedisAccessException(Exception cause) { DataAccessException translated = EXCEPTION_TRANSLATION.translate(cause); @@ -718,16 +742,17 @@ protected interface JedisMultiKeyClusterCommandCallback extends MultiKeyClust * @author Mark Paluch * @since 1.7 */ + @NullMarked static class JedisClusterNodeResourceProvider implements ClusterNodeResourceProvider { private final JedisCluster cluster; private final ClusterTopologyProvider topologyProvider; - private final ClusterConnectionProvider connectionHandler; + private final @Nullable ClusterConnectionProvider connectionHandler; /** * Creates new {@link JedisClusterNodeResourceProvider}. * - * @param cluster must not be {@literal null}. + * @param cluster should not be {@literal null}. * @param topologyProvider must not be {@literal null}. */ JedisClusterNodeResourceProvider(JedisCluster cluster, ClusterTopologyProvider topologyProvider) { @@ -735,15 +760,11 @@ static class JedisClusterNodeResourceProvider implements ClusterNodeResourceProv this.cluster = cluster; this.topologyProvider = topologyProvider; - if (cluster != null) { + PropertyAccessor accessor = new DirectFieldAccessFallbackBeanWrapper(cluster); + this.connectionHandler = accessor.isReadableProperty("connectionHandler") + ? (ClusterConnectionProvider) accessor.getPropertyValue("connectionHandler") + : null; - PropertyAccessor accessor = new DirectFieldAccessFallbackBeanWrapper(cluster); - this.connectionHandler = accessor.isReadableProperty("connectionHandler") - ? (ClusterConnectionProvider) accessor.getPropertyValue("connectionHandler") - : null; - } else { - this.connectionHandler = null; - } } @Override @@ -766,8 +787,7 @@ public Jedis getResourceForSpecificNode(RedisClusterNode node) { throw new DataAccessResourceFailureException("Node %s is unknown to cluster".formatted(node)); } - @Nullable - private ConnectionPool getResourcePoolForSpecificNode(RedisClusterNode node) { + private @Nullable ConnectionPool getResourcePoolForSpecificNode(RedisClusterNode node) { Map clusterNodes = cluster.getClusterNodes(); HostAndPort hap = new HostAndPort(node.getHost(), @@ -781,7 +801,7 @@ private ConnectionPool getResourcePoolForSpecificNode(RedisClusterNode node) { return null; } - private Connection getConnectionForSpecificNode(RedisClusterNode node) { + private @Nullable Connection getConnectionForSpecificNode(RedisClusterNode node) { RedisClusterNode member = topologyProvider.getTopology().lookup(node); @@ -798,7 +818,7 @@ private Connection getConnectionForSpecificNode(RedisClusterNode node) { } @Override - public void returnResourceForSpecificNode(RedisClusterNode node, Object client) { + public void returnResourceForSpecificNode(@NonNull RedisClusterNode node, @NonNull Object client) { ((Jedis) client).close(); } } @@ -810,6 +830,7 @@ public void returnResourceForSpecificNode(RedisClusterNode node, Object client) * @author Mark Paluch * @since 1.7 */ + @NullMarked public static class JedisClusterTopologyProvider implements ClusterTopologyProvider { private final JedisCluster cluster; @@ -845,6 +866,7 @@ public JedisClusterTopologyProvider(JedisCluster cluster, Duration cacheTimeout) } @Override + @SuppressWarnings("NullAway") public ClusterTopology getTopology() { JedisClusterTopology topology = cached; diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterGeoCommands.java index 35c7db73f3..f830f64efb 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterGeoCommands.java @@ -24,6 +24,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.DataAccessException; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -40,6 +42,7 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class JedisClusterGeoCommands implements RedisGeoCommands { private final JedisClusterConnection connection; @@ -51,7 +54,7 @@ class JedisClusterGeoCommands implements RedisGeoCommands { } @Override - public Long geoAdd(byte[] key, Point point, byte[] member) { + public Long geoAdd(byte @NonNull [] key, @NonNull Point point, byte @NonNull [] member) { Assert.notNull(key, "Key must not be null"); Assert.notNull(point, "Point must not be null"); @@ -65,7 +68,7 @@ public Long geoAdd(byte[] key, Point point, byte[] member) { } @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { + public Long geoAdd(byte @NonNull [] key, @NonNull Map memberCoordinateMap) { Assert.notNull(key, "Key must not be null"); Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null"); @@ -83,7 +86,7 @@ public Long geoAdd(byte[] key, Map memberCoordinateMap) { } @Override - public Long geoAdd(byte[] key, Iterable> locations) { + public Long geoAdd(byte @NonNull [] key, @NonNull Iterable<@NonNull GeoLocation> locations) { Assert.notNull(key, "Key must not be null"); Assert.notNull(locations, "Locations must not be null"); @@ -101,7 +104,7 @@ public Long geoAdd(byte[] key, Iterable> locations) { } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member1, "Member1 must not be null"); @@ -116,7 +119,8 @@ public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2, + @NonNull Metric metric) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member1, "Member1 must not be null"); @@ -133,7 +137,7 @@ public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metri } @Override - public List geoHash(byte[] key, byte[]... members) { + public List<@NonNull String> geoHash(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -147,7 +151,7 @@ public List geoHash(byte[] key, byte[]... members) { } @Override - public List geoPos(byte[] key, byte[]... members) { + public List<@NonNull Point> geoPos(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -161,7 +165,7 @@ public List geoPos(byte[] key, byte[]... members) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -176,7 +180,8 @@ public GeoResults> geoRadius(byte[] key, Circle within) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within, + @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -195,7 +200,8 @@ public GeoResults> geoRadius(byte[] key, Circle within, GeoR } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -211,8 +217,8 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, - GeoRadiusCommandArgs args) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius, @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -232,13 +238,13 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public Long geoRemove(byte[] key, byte[]... members) { + public Long geoRemove(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { return connection.zRem(key, members); } @Override - public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchCommandArgs args) { + public GeoResults> geoSearch(byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchCommandArgs args) { Assert.notNull(key, "Key must not be null"); GeoSearchParam params = JedisConverters.toGeoSearchParams(reference, predicate, args); @@ -253,8 +259,8 @@ public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchStoreCommandArgs args) { + public Long geoSearchStore(byte @NonNull [] destKey, byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchStoreCommandArgs args) { Assert.notNull(destKey, "Destination Key must not be null"); Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java index 551a17d153..77bb8034f0 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterHashCommands.java @@ -26,6 +26,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.connection.RedisHashCommands; @@ -33,7 +34,6 @@ import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -146,9 +146,9 @@ public Double hIncrBy(byte[] key, byte[] field, double delta) { } } - @Nullable + @Override - public byte[] hRandField(byte[] key) { + public byte @Nullable[] hRandField(byte[] key) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java index 559c15bf86..a7a99b8418 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java @@ -32,6 +32,8 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; @@ -49,7 +51,6 @@ import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -60,6 +61,7 @@ * @author Dan Smith * @since 2.0 */ +@NullUnmarked class JedisClusterKeyCommands implements RedisKeyCommands { private final JedisClusterConnection connection; @@ -69,7 +71,7 @@ class JedisClusterKeyCommands implements RedisKeyCommands { } @Override - public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { + public Boolean copy(byte @NonNull [] sourceKey, byte @NonNull [] targetKey, boolean replace) { Assert.notNull(sourceKey, "source key must not be null"); Assert.notNull(targetKey, "target key must not be null"); @@ -78,7 +80,7 @@ public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { } @Override - public Long del(byte[]... keys) { + public Long del(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -97,9 +99,8 @@ public Long del(byte[]... keys) { .resultsAsList().size(); } - @Nullable @Override - public Long unlink(byte[]... keys) { + public Long unlink(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -108,7 +109,7 @@ public Long unlink(byte[]... keys) { } @Override - public DataType type(byte[] key) { + public DataType type(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -119,9 +120,8 @@ public DataType type(byte[] key) { } } - @Nullable @Override - public Long touch(byte[]... keys) { + public Long touch(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -130,7 +130,7 @@ public Long touch(byte[]... keys) { } @Override - public Set keys(byte[] pattern) { + public Set keys(byte @NonNull [] pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -145,7 +145,7 @@ public Set keys(byte[] pattern) { return keys; } - public Set keys(RedisClusterNode node, byte[] pattern) { + public Set keys(@NonNull RedisClusterNode node, byte @NonNull [] pattern) { Assert.notNull(node, "RedisClusterNode must not be null"); Assert.notNull(pattern, "Pattern must not be null"); @@ -156,7 +156,7 @@ public Set keys(RedisClusterNode node, byte[] pattern) { } @Override - public Cursor scan(ScanOptions options) { + public Cursor scan(@NonNull ScanOptions options) { throw new InvalidDataAccessApiUsageException("Scan is not supported across multiple nodes within a cluster"); } @@ -168,7 +168,7 @@ public Cursor scan(ScanOptions options) { * @return never {@literal null}. * @since 2.1 */ - Cursor scan(RedisClusterNode node, ScanOptions options) { + Cursor scan(@NonNull RedisClusterNode node, @NonNull ScanOptions options) { Assert.notNull(node, "RedisClusterNode must not be null"); Assert.notNull(options, "Options must not be null"); @@ -176,10 +176,10 @@ Cursor scan(RedisClusterNode node, ScanOptions options) { return connection.getClusterCommandExecutor() .executeCommandOnSingleNode((JedisClusterCommandCallback>) client -> { - return new ScanCursor(0, options) { + return new ScanCursor(0, options) { @Override - protected ScanIteration doScan(CursorId cursorId, ScanOptions options) { + protected ScanIteration doScan(@NonNull CursorId cursorId, @NonNull ScanOptions options) { ScanParams params = JedisConverters.toScanParams(options); ScanResult result = client.scan(cursorId.getCursorId(), params); @@ -215,7 +215,7 @@ public byte[] randomKey() { return null; } - public byte[] randomKey(RedisClusterNode node) { + public byte[] randomKey(@NonNull RedisClusterNode node) { Assert.notNull(node, "RedisClusterNode must not be null"); @@ -225,7 +225,7 @@ public byte[] randomKey(RedisClusterNode node) { } @Override - public void rename(byte[] oldKey, byte[] newKey) { + public void rename(byte @NonNull [] oldKey, byte @NonNull [] newKey) { Assert.notNull(oldKey, "Old key must not be null"); Assert.notNull(newKey, "New key must not be null"); @@ -250,7 +250,7 @@ public void rename(byte[] oldKey, byte[] newKey) { } @Override - public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { + public Boolean renameNX(byte @NonNull [] sourceKey, byte @NonNull [] targetKey) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(targetKey, "Target key must not be null"); @@ -276,7 +276,7 @@ public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { } @Override - public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition condition) { + public Boolean expire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -293,7 +293,7 @@ public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition cond } @Override - public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition condition) { + public Boolean pExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -309,7 +309,7 @@ public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition cond } @Override - public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition) { + public Boolean expireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -326,7 +326,8 @@ public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition c } @Override - public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition) { + public Boolean pExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -343,7 +344,7 @@ public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Co } @Override - public Boolean persist(byte[] key) { + public Boolean persist(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -355,12 +356,12 @@ public Boolean persist(byte[] key) { } @Override - public Boolean move(byte[] key, int dbIndex) { + public Boolean move(byte @NonNull [] key, int dbIndex) { throw new InvalidDataAccessApiUsageException("Cluster mode does not allow moving keys"); } @Override - public Long ttl(byte[] key) { + public Long ttl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -372,7 +373,7 @@ public Long ttl(byte[] key) { } @Override - public Long ttl(byte[] key, TimeUnit timeUnit) { + public Long ttl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -384,7 +385,7 @@ public Long ttl(byte[] key, TimeUnit timeUnit) { } @Override - public Long pTtl(byte[] key) { + public Long pTtl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -396,7 +397,7 @@ public Long pTtl(byte[] key) { } @Override - public Long pTtl(byte[] key, TimeUnit timeUnit) { + public Long pTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -408,7 +409,7 @@ public Long pTtl(byte[] key, TimeUnit timeUnit) { } @Override - public byte[] dump(byte[] key) { + public byte[] dump(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -420,7 +421,7 @@ public byte[] dump(byte[] key) { } @Override - public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolean replace) { + public void restore(byte @NonNull [] key, long ttlInMillis, byte @NonNull [] serializedValue, boolean replace) { Assert.notNull(key, "Key must not be null"); Assert.notNull(serializedValue, "Serialized value must not be null"); @@ -438,7 +439,7 @@ public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolea } @Override - public List sort(byte[] key, SortParameters params) { + public List sort(byte @NonNull [] key, @NonNull SortParameters params) { Assert.notNull(key, "Key must not be null"); @@ -450,7 +451,7 @@ public List sort(byte[] key, SortParameters params) { } @Override - public Long sort(byte[] key, SortParameters params, byte[] storeKey) { + public Long sort(byte @NonNull [] key, @NonNull SortParameters params, byte @NonNull [] storeKey) { Assert.notNull(key, "Key must not be null"); @@ -469,9 +470,8 @@ public Long sort(byte[] key, SortParameters params, byte[] storeKey) { return (long) sorted.size(); } - @Nullable @Override - public Long exists(byte[]... keys) { + public Long exists(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -489,9 +489,8 @@ public Long exists(byte[]... keys) { .resultsAsList().stream().mapToLong(val -> ObjectUtils.nullSafeEquals(val, Boolean.TRUE) ? 1 : 0).sum(); } - @Nullable @Override - public ValueEncoding encodingOf(byte[] key) { + public ValueEncoding encodingOf(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -502,9 +501,8 @@ public ValueEncoding encodingOf(byte[] key) { } } - @Nullable @Override - public Duration idletime(byte[] key) { + public Duration idletime(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -515,9 +513,8 @@ public Duration idletime(byte[] key) { } } - @Nullable @Override - public Long refcount(byte[] key) { + public Long refcount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java index 3b259f36e1..7a258aa0cc 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterListCommands.java @@ -22,11 +22,13 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.RedisListCommands; import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisMultiKeyClusterCommandCallback; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -37,16 +39,17 @@ * @author dengliming * @since 2.0 */ +@NullUnmarked class JedisClusterListCommands implements RedisListCommands { private final JedisClusterConnection connection; - JedisClusterListCommands(JedisClusterConnection connection) { + JedisClusterListCommands( @NonNull JedisClusterConnection connection) { this.connection = connection; } @Override - public Long rPush(byte[] key, byte[]... values) { + public Long rPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); @@ -58,7 +61,8 @@ public Long rPush(byte[] key, byte[]... values) { } @Override - public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Nullable Integer count) { + public List lPos(byte @NonNull [] key, byte @NonNull [] element, @Nullable Integer rank, + @Nullable Integer count) { Assert.notNull(key, "Key must not be null"); Assert.notNull(element, "Element must not be null"); @@ -82,7 +86,7 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null } @Override - public Long lPush(byte[] key, byte[]... values) { + public Long lPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -96,7 +100,7 @@ public Long lPush(byte[] key, byte[]... values) { } @Override - public Long rPushX(byte[] key, byte[] value) { + public Long rPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -109,7 +113,7 @@ public Long rPushX(byte[] key, byte[] value) { } @Override - public Long lPushX(byte[] key, byte[] value) { + public Long lPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -122,7 +126,7 @@ public Long lPushX(byte[] key, byte[] value) { } @Override - public Long lLen(byte[] key) { + public Long lLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -134,7 +138,7 @@ public Long lLen(byte[] key) { } @Override - public List lRange(byte[] key, long start, long end) { + public List lRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -146,7 +150,7 @@ public List lRange(byte[] key, long start, long end) { } @Override - public void lTrim(byte[] key, long start, long end) { + public void lTrim(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -158,7 +162,7 @@ public void lTrim(byte[] key, long start, long end) { } @Override - public byte[] lIndex(byte[] key, long index) { + public byte[] lIndex(byte @NonNull [] key, long index) { Assert.notNull(key, "Key must not be null"); @@ -170,7 +174,7 @@ public byte[] lIndex(byte[] key, long index) { } @Override - public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { + public Long lInsert(byte @NonNull [] key, @NonNull Position where, byte @NonNull [] pivot, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); @@ -182,7 +186,8 @@ public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { } @Override - public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to) { + public byte[] lMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -198,7 +203,8 @@ public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Dir } @Override - public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to, double timeout) { + public byte[] bLMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to, double timeout) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -214,7 +220,7 @@ public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Di } @Override - public void lSet(byte[] key, long index, byte[] value) { + public void lSet(byte @NonNull [] key, long index, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -227,7 +233,7 @@ public void lSet(byte[] key, long index, byte[] value) { } @Override - public Long lRem(byte[] key, long count, byte[] value) { + public Long lRem(byte @NonNull [] key, long count, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -240,7 +246,7 @@ public Long lRem(byte[] key, long count, byte[] value) { } @Override - public byte[] lPop(byte[] key) { + public byte[] lPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -252,7 +258,7 @@ public byte[] lPop(byte[] key) { } @Override - public List lPop(byte[] key, long count) { + public List lPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -276,7 +282,7 @@ public byte[] rPop(byte[] key) { } @Override - public List rPop(byte[] key, long count) { + public List rPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -288,7 +294,7 @@ public List rPop(byte[] key, long count) { } @Override - public List bLPop(int timeout, byte[]... keys) { + public List bLPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -309,7 +315,7 @@ public List bLPop(int timeout, byte[]... keys) { } @Override - public List bRPop(int timeout, byte[]... keys) { + public List bRPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -330,7 +336,7 @@ public List bRPop(int timeout, byte[]... keys) { } @Override - public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { + public byte[] rPopLPush(byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -349,7 +355,7 @@ public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { } @Override - public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { + public byte[] bRPopLPush(int timeout, byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterScriptingCommands.java index 9e845f032e..c74b262cf7 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterScriptingCommands.java @@ -20,6 +20,8 @@ import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterCommandExecutor; import org.springframework.data.redis.connection.RedisScriptingCommands; @@ -31,11 +33,12 @@ * @author Pavel Khokhlov * @since 2.0 */ +@NullUnmarked class JedisClusterScriptingCommands implements RedisScriptingCommands { private final JedisClusterConnection connection; - JedisClusterScriptingCommands(JedisClusterConnection connection) { + JedisClusterScriptingCommands(@NonNull JedisClusterConnection connection) { this.connection = connection; } @@ -62,7 +65,7 @@ public void scriptKill() { } @Override - public String scriptLoad(byte[] script) { + public String scriptLoad(byte @NonNull [] script) { Assert.notNull(script, "Script must not be null"); @@ -78,13 +81,14 @@ public String scriptLoad(byte[] script) { } @Override - public List scriptExists(String... scriptShas) { + public List scriptExists(@NonNull String @NonNull... scriptShas) { throw new InvalidDataAccessApiUsageException("ScriptExists is not supported in cluster environment"); } @Override @SuppressWarnings("unchecked") - public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T eval(byte @NonNull [] script, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(script, "Script must not be null"); @@ -96,13 +100,15 @@ public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... k } @Override - public T evalSha(String scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(@NonNull String scriptSha, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { return evalSha(JedisConverters.toBytes(scriptSha), returnType, numKeys, keysAndArgs); } @Override @SuppressWarnings("unchecked") - public T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(byte @NonNull [] scriptSha, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(scriptSha, "Script digest must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java index 1c6045faf9..ae4e3c4d8a 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java @@ -26,6 +26,9 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult; import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult; @@ -35,7 +38,6 @@ import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisClusterCommandCallback; import org.springframework.data.redis.core.types.RedisClientInfo; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -44,16 +46,17 @@ * @author Dennis Neufeld * @since 2.0 */ +@NullUnmarked class JedisClusterServerCommands implements RedisClusterServerCommands { private final JedisClusterConnection connection; - JedisClusterServerCommands(JedisClusterConnection connection) { + JedisClusterServerCommands(@NonNull JedisClusterConnection connection) { this.connection = connection; } @Override - public void bgReWriteAof(RedisClusterNode node) { + public void bgReWriteAof(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::bgrewriteaof, node); } @@ -70,7 +73,7 @@ public void bgSave() { } @Override - public void bgSave(RedisClusterNode node) { + public void bgSave(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::bgsave, node); } @@ -88,7 +91,7 @@ public Long lastSave() { } @Override - public Long lastSave(RedisClusterNode node) { + public Long lastSave(@NonNull RedisClusterNode node) { return executeCommandOnSingleNode(Jedis::lastsave, node).getValue(); } @@ -98,7 +101,7 @@ public void save() { } @Override - public void save(RedisClusterNode node) { + public void save(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::save, node); } @@ -119,7 +122,7 @@ public Long dbSize() { } @Override - public Long dbSize(RedisClusterNode node) { + public Long dbSize(@NonNull RedisClusterNode node) { return executeCommandOnSingleNode(Jedis::dbSize, node).getValue(); } @@ -129,17 +132,17 @@ public void flushDb() { } @Override - public void flushDb(FlushOption option) { + public void flushDb(@NonNull FlushOption option) { executeCommandOnAllNodes(it -> it.flushDB(JedisConverters.toFlushMode(option))); } @Override - public void flushDb(RedisClusterNode node) { + public void flushDb(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::flushDB, node); } @Override - public void flushDb(RedisClusterNode node, FlushOption option) { + public void flushDb(@NonNull RedisClusterNode node, @NonNull FlushOption option) { executeCommandOnSingleNode(it -> it.flushDB(JedisConverters.toFlushMode(option)), node); } @@ -150,18 +153,18 @@ public void flushAll() { } @Override - public void flushAll(FlushOption option) { + public void flushAll(@NonNull FlushOption option) { connection.getClusterCommandExecutor().executeCommandOnAllNodes( (JedisClusterCommandCallback) it -> it.flushAll(JedisConverters.toFlushMode(option))); } @Override - public void flushAll(RedisClusterNode node) { + public void flushAll(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::flushAll, node); } @Override - public void flushAll(RedisClusterNode node, FlushOption option) { + public void flushAll(@NonNull RedisClusterNode node, @NonNull FlushOption option) { executeCommandOnSingleNode(it -> it.flushAll(JedisConverters.toFlushMode(option)), node); } @@ -185,12 +188,12 @@ public Properties info() { } @Override - public Properties info(RedisClusterNode node) { + public Properties info(@NonNull RedisClusterNode node) { return JedisConverters.toProperties(executeCommandOnSingleNode(Jedis::info, node).getValue()); } @Override - public Properties info(String section) { + public Properties info(@NonNull String section) { Assert.notNull(section, "Section must not be null"); @@ -211,7 +214,7 @@ public Properties info(String section) { } @Override - public Properties info(RedisClusterNode node, String section) { + public Properties info(@NonNull RedisClusterNode node, @NonNull String section) { Assert.notNull(section, "Section must not be null"); @@ -227,7 +230,7 @@ public void shutdown() { } @Override - public void shutdown(RedisClusterNode node) { + public void shutdown(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(jedis -> { jedis.shutdown(); return null; @@ -235,7 +238,7 @@ public void shutdown(RedisClusterNode node) { } @Override - public void shutdown(ShutdownOption option) { + public void shutdown(@NonNull ShutdownOption option) { if (option == null) { shutdown(); @@ -246,15 +249,14 @@ public void shutdown(ShutdownOption option) { } @Override - public Properties getConfig(String pattern) { + public Properties getConfig(@NonNull String pattern) { Assert.notNull(pattern, "Pattern must not be null"); JedisClusterCommandCallback> command = jedis -> jedis.configGet(pattern); List>> nodeResults = connection.getClusterCommandExecutor() - .executeCommandOnAllNodes(command) - .getResults(); + .executeCommandOnAllNodes(command).getResults(); Properties nodesConfiguration = new Properties(); @@ -273,7 +275,7 @@ public Properties getConfig(String pattern) { } @Override - public Properties getConfig(RedisClusterNode node, String pattern) { + public Properties getConfig(@NonNull RedisClusterNode node, @NonNull String pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -285,7 +287,7 @@ public Properties getConfig(RedisClusterNode node, String pattern) { } @Override - public void setConfig(String param, String value) { + public void setConfig(@NonNull String param, @NonNull String value) { Assert.notNull(param, "Parameter must not be null"); Assert.notNull(value, "Value must not be null"); @@ -295,7 +297,7 @@ public void setConfig(String param, String value) { } @Override - public void setConfig(RedisClusterNode node, String param, String value) { + public void setConfig(@NonNull RedisClusterNode node, @NonNull String param, @NonNull String value) { Assert.notNull(param, "Parameter must not be null"); Assert.notNull(value, "Value must not be null"); @@ -316,17 +318,17 @@ public void rewriteConfig() { } @Override - public void resetConfigStats(RedisClusterNode node) { + public void resetConfigStats(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::configResetStat, node); } @Override - public void rewriteConfig(RedisClusterNode node) { + public void rewriteConfig(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(Jedis::configRewrite, node); } @Override - public Long time(TimeUnit timeUnit) { + public Long time(@NonNull TimeUnit timeUnit) { return convertListOfStringToTime( connection.getClusterCommandExecutor() @@ -335,7 +337,7 @@ public Long time(TimeUnit timeUnit) { } @Override - public Long time(RedisClusterNode node, TimeUnit timeUnit) { + public Long time(@NonNull RedisClusterNode node, @NonNull TimeUnit timeUnit) { return convertListOfStringToTime( connection.getClusterCommandExecutor() @@ -344,7 +346,7 @@ public Long time(RedisClusterNode node, TimeUnit timeUnit) { } @Override - public void killClient(String host, int port) { + public void killClient(@NonNull String host, int port) { Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'"); String hostAndPort = "%s:%d".formatted(host, port); @@ -355,7 +357,7 @@ public void killClient(String host, int port) { } @Override - public void setClientName(byte[] name) { + public void setClientName(byte @NonNull [] name) { throw new InvalidDataAccessApiUsageException("CLIENT SETNAME is not supported in cluster environment"); } @@ -365,7 +367,7 @@ public String getClientName() { } @Override - public List getClientList() { + public List<@NonNull RedisClientInfo> getClientList() { Collection map = connection.getClusterCommandExecutor() .executeCommandOnAllNodes((JedisClusterCommandCallback) Jedis::clientList).resultsAsList(); @@ -378,14 +380,14 @@ public List getClientList() { } @Override - public List getClientList(RedisClusterNode node) { + public List<@NonNull RedisClientInfo> getClientList(@NonNull RedisClusterNode node) { return JedisConverters .toListOfRedisClientInformation(executeCommandOnSingleNode(Jedis::clientList, node).getValue()); } @Override - public void replicaOf(String host, int port) { + public void replicaOf(@NonNull String host, int port) { throw new InvalidDataAccessApiUsageException( "REPLICAOF is not supported in cluster environment; Please use CLUSTER REPLICATE"); } @@ -397,12 +399,13 @@ public void replicaOfNoOne() { } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option) { migrate(key, target, dbIndex, option, Long.MAX_VALUE); } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option, + long timeout) { Assert.notNull(key, "Key must not be null"); Assert.notNull(target, "Target node must not be null"); @@ -414,7 +417,7 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable Migrate node); } - private Long convertListOfStringToTime(List serverTimeInformation, TimeUnit timeUnit) { + private Long convertListOfStringToTime(List<@NonNull String> serverTimeInformation, TimeUnit timeUnit) { Assert.notEmpty(serverTimeInformation, "Received invalid result from server; Expected 2 items in collection"); Assert.isTrue(serverTimeInformation.size() == 2, @@ -423,11 +426,12 @@ private Long convertListOfStringToTime(List serverTimeInformation, TimeU return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1), timeUnit); } - private NodeResult executeCommandOnSingleNode(JedisClusterCommandCallback cmd, RedisClusterNode node) { + private NodeResult executeCommandOnSingleNode(@NonNull JedisClusterCommandCallback cmd, + @NonNull RedisClusterNode node) { return connection.getClusterCommandExecutor().executeCommandOnSingleNode(cmd, node); } - private MultiNodeResult executeCommandOnAllNodes(JedisClusterCommandCallback cmd) { + private MultiNodeResult executeCommandOnAllNodes(@NonNull JedisClusterCommandCallback cmd) { return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java index c25def525f..6a9fc6ef31 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterSetCommands.java @@ -199,7 +199,7 @@ public Set sInter(byte[]... keys) { } } - if (result.isEmpty()) { + if (result == null || result.isEmpty()) { return Collections.emptySet(); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStringCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStringCommands.java index af51cafe3d..e9e3e51364 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterStringCommands.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range; @@ -34,7 +36,6 @@ import org.springframework.data.redis.connection.lettuce.LettuceConverters; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -45,16 +46,17 @@ * @author Marcin Grzejszczak * @since 2.0 */ +@NullUnmarked class JedisClusterStringCommands implements RedisStringCommands { private final JedisClusterConnection connection; - JedisClusterStringCommands(JedisClusterConnection connection) { + JedisClusterStringCommands(@NonNull JedisClusterConnection connection) { this.connection = connection; } @Override - public byte[] get(byte[] key) { + public byte[] get(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -65,9 +67,8 @@ public byte[] get(byte[] key) { } } - @Nullable @Override - public byte[] getDel(byte[] key) { + public byte[] getDel(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -78,9 +79,8 @@ public byte[] getDel(byte[] key) { } } - @Nullable @Override - public byte[] getEx(byte[] key, Expiration expiration) { + public byte[] getEx(byte @NonNull [] key, @NonNull Expiration expiration) { Assert.notNull(key, "Key must not be null"); Assert.notNull(expiration, "Expiration must not be null"); @@ -93,7 +93,7 @@ public byte[] getEx(byte[] key, Expiration expiration) { } @Override - public byte[] getSet(byte[] key, byte[] value) { + public byte[] getSet(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -106,7 +106,7 @@ public byte[] getSet(byte[] key, byte[] value) { } @Override - public List mGet(byte[]... keys) { + public List mGet(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -121,7 +121,7 @@ public List mGet(byte[]... keys) { } @Override - public Boolean set(byte[] key, byte[] value) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -134,7 +134,8 @@ public Boolean set(byte[] key, byte[] value) { } @Override - public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -152,7 +153,8 @@ public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption op } @Override - public byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public byte[] setGet(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -170,7 +172,7 @@ public byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption } @Override - public Boolean setNX(byte[] key, byte[] value) { + public Boolean setNX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -183,7 +185,7 @@ public Boolean setNX(byte[] key, byte[] value) { } @Override - public Boolean setEx(byte[] key, long seconds, byte[] value) { + public Boolean setEx(byte @NonNull [] key, long seconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -200,7 +202,7 @@ public Boolean setEx(byte[] key, long seconds, byte[] value) { } @Override - public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { + public Boolean pSetEx(byte @NonNull [] key, long milliseconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -213,7 +215,7 @@ public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { } @Override - public Boolean mSet(Map tuples) { + public Boolean mSet(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -235,7 +237,7 @@ public Boolean mSet(Map tuples) { } @Override - public Boolean mSetNX(Map tuples) { + public Boolean mSetNX(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -257,7 +259,7 @@ public Boolean mSetNX(Map tuples) { } @Override - public Long incr(byte[] key) { + public Long incr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -269,7 +271,7 @@ public Long incr(byte[] key) { } @Override - public Long incrBy(byte[] key, long value) { + public Long incrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -281,7 +283,7 @@ public Long incrBy(byte[] key, long value) { } @Override - public Double incrBy(byte[] key, double value) { + public Double incrBy(byte @NonNull [] key, double value) { Assert.notNull(key, "Key must not be null"); @@ -293,7 +295,7 @@ public Double incrBy(byte[] key, double value) { } @Override - public Long decr(byte[] key) { + public Long decr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -305,7 +307,7 @@ public Long decr(byte[] key) { } @Override - public Long decrBy(byte[] key, long value) { + public Long decrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -317,7 +319,7 @@ public Long decrBy(byte[] key, long value) { } @Override - public Long append(byte[] key, byte[] value) { + public Long append(byte @NonNull [] key, byte[] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -330,7 +332,7 @@ public Long append(byte[] key, byte[] value) { } @Override - public byte[] getRange(byte[] key, long start, long end) { + public byte[] getRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -342,7 +344,7 @@ public byte[] getRange(byte[] key, long start, long end) { } @Override - public void setRange(byte[] key, byte[] value, long offset) { + public void setRange(byte @NonNull [] key, byte @NonNull [] value, long offset) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -355,7 +357,7 @@ public void setRange(byte[] key, byte[] value, long offset) { } @Override - public Boolean getBit(byte[] key, long offset) { + public Boolean getBit(byte @NonNull [] key, long offset) { Assert.notNull(key, "Key must not be null"); @@ -367,7 +369,7 @@ public Boolean getBit(byte[] key, long offset) { } @Override - public Boolean setBit(byte[] key, long offset, boolean value) { + public Boolean setBit(byte @NonNull [] key, long offset, boolean value) { Assert.notNull(key, "Key must not be null"); @@ -379,7 +381,7 @@ public Boolean setBit(byte[] key, long offset, boolean value) { } @Override - public Long bitCount(byte[] key) { + public Long bitCount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -391,7 +393,7 @@ public Long bitCount(byte[] key) { } @Override - public Long bitCount(byte[] key, long start, long end) { + public Long bitCount(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -403,7 +405,7 @@ public Long bitCount(byte[] key, long start, long end) { } @Override - public List bitField(byte[] key, BitFieldSubCommands subCommands) { + public List bitField(byte @NonNull [] key, @NonNull BitFieldSubCommands subCommands) { Assert.notNull(key, "Key must not be null"); Assert.notNull(subCommands, "Command must not be null"); @@ -418,7 +420,7 @@ public List bitField(byte[] key, BitFieldSubCommands subCommands) { } @Override - public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { + public Long bitOp(@NonNull BitOperation op, byte @NonNull [] destination, byte @NonNull [] @NonNull... keys) { Assert.notNull(op, "BitOperation must not be null"); Assert.notNull(destination, "Destination key must not be null"); @@ -437,7 +439,7 @@ public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { } @Override - public Long bitPos(byte[] key, boolean bit, Range range) { + public Long bitPos(byte @NonNull [] key, boolean bit, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null Use Range.unbounded() instead"); @@ -456,7 +458,7 @@ public Long bitPos(byte[] key, boolean bit, Range range) { } @Override - public Long strLen(byte[] key) { + public Long strLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); try { diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java index b7bc9b5f92..e52ffa0557 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java @@ -29,6 +29,9 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; @@ -42,7 +45,7 @@ import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; /** @@ -57,19 +60,20 @@ * @author John Blum * @since 2.0 */ +@NullUnmarked class JedisClusterZSetCommands implements RedisZSetCommands { - private static final SetConverter TUPLE_SET_CONVERTER = - new SetConverter<>(JedisConverters::toTuple); + private static final SetConverter TUPLE_SET_CONVERTER = new SetConverter<>( + JedisConverters::toTuple); private final JedisClusterConnection connection; - JedisClusterZSetCommands(JedisClusterConnection connection) { + JedisClusterZSetCommands(@NonNull JedisClusterConnection connection) { this.connection = connection; } @Override - public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { + public Boolean zAdd(byte @NonNull [] key, double score, byte @NonNull [] value, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -83,7 +87,7 @@ public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { } @Override - public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { + public Long zAdd(byte @NonNull [] key, @NonNull Set<@NonNull Tuple> tuples, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(tuples, "Tuples must not be null"); @@ -96,7 +100,7 @@ public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { } @Override - public Long zRem(byte[] key, byte[]... values) { + public Long zRem(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -111,7 +115,7 @@ public Long zRem(byte[] key, byte[]... values) { } @Override - public Double zIncrBy(byte[] key, double increment, byte[] value) { + public Double zIncrBy(byte @NonNull [] key, double increment, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -124,7 +128,7 @@ public Double zIncrBy(byte[] key, double increment, byte[] value) { } @Override - public byte[] zRandMember(byte[] key) { + public byte[] zRandMember(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -136,7 +140,7 @@ public byte[] zRandMember(byte[] key) { } @Override - public List zRandMember(byte[] key, long count) { + public List zRandMember(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -148,7 +152,7 @@ public List zRandMember(byte[] key, long count) { } @Override - public Tuple zRandMemberWithScore(byte[] key) { + public Tuple zRandMemberWithScore(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -162,7 +166,7 @@ public Tuple zRandMemberWithScore(byte[] key) { } @Override - public List zRandMemberWithScore(byte[] key, long count) { + public List zRandMemberWithScore(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -176,7 +180,7 @@ public List zRandMemberWithScore(byte[] key, long count) { } @Override - public Long zRank(byte[] key, byte[] value) { + public Long zRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -189,7 +193,7 @@ public Long zRank(byte[] key, byte[] value) { } @Override - public Long zRevRank(byte[] key, byte[] value) { + public Long zRevRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -202,7 +206,7 @@ public Long zRevRank(byte[] key, byte[] value) { } @Override - public Set zRange(byte[] key, long start, long end) { + public Set zRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -214,8 +218,9 @@ public Set zRange(byte[] key, long start, long end) { } @Override - public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZRANGEBYSCOREWITHSCORES"); @@ -237,8 +242,9 @@ public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.d } @Override - public Set zRevRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCORE"); @@ -260,9 +266,9 @@ public Set zRevRangeByScore(byte[] key, org.springframework.data.domain. } @Override - public Set zRevRangeByScoreWithScores(byte[] key, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZREVRANGEBYSCOREWITHSCORES"); @@ -284,7 +290,7 @@ public Set zRevRangeByScoreWithScores(byte[] key, } @Override - public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZCOUNT"); @@ -302,7 +308,7 @@ public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zLexCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -317,9 +323,8 @@ public Long zLexCount(byte[] key, org.springframework.data.domain.Range } } - @Nullable @Override - public Tuple zPopMin(byte[] key) { + public Tuple zPopMin(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -331,9 +336,8 @@ public Tuple zPopMin(byte[] key) { } } - @Nullable @Override - public Set zPopMin(byte[] key, long count) { + public Set zPopMin(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -344,9 +348,8 @@ public Set zPopMin(byte[] key, long count) { } } - @Nullable @Override - public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMin(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -358,9 +361,8 @@ public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { } } - @Nullable @Override - public Tuple zPopMax(byte[] key) { + public Tuple zPopMax(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -372,9 +374,8 @@ public Tuple zPopMax(byte[] key) { } } - @Nullable @Override - public Set zPopMax(byte[] key, long count) { + public Set zPopMax(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -385,9 +386,8 @@ public Set zPopMax(byte[] key, long count) { } } - @Nullable @Override - public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMax(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -400,7 +400,8 @@ public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { } @Override - public Long zRemRangeByScore(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZREMRANGEBYSCORE"); @@ -419,8 +420,9 @@ public Long zRemRangeByScore(byte[] key, org.springframework.data.domain.Range zRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set<@NonNull byte[]> zRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range cannot be null for ZRANGEBYSCORE"); @@ -442,8 +444,9 @@ public Set zRangeByScore(byte[] key, org.springframework.data.domain.Ran } @Override - public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null for ZRANGEBYLEX"); @@ -464,7 +467,7 @@ public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range } @Override - public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByLex(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX"); @@ -480,8 +483,9 @@ public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range zRevRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null for ZREVRANGEBYLEX"); @@ -502,19 +506,22 @@ public Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Ra } @Override - public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByLex(dstKey, srcKey, range, limit, false); } @Override - public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByLex(dstKey, srcKey, range, limit, true); } - private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit, boolean rev) { + private Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit, boolean rev) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -543,23 +550,23 @@ private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework. @Nullable @Override - public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByScore(dstKey, srcKey, range, limit, false); } @Nullable @Override - public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByScore(dstKey, srcKey, range, limit, true); } - private Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit, boolean rev) { + private Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit, boolean rev) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -589,7 +596,7 @@ private Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, } @Override - public Set zRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -601,7 +608,7 @@ public Set zRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRangeByScore(byte[] key, double min, double max) { + public Set zRangeByScore(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -613,7 +620,7 @@ public Set zRangeByScore(byte[] key, double min, double max) { } @Override - public Set zRangeByScoreWithScores(byte[] key, double min, double max) { + public Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -625,7 +632,7 @@ public Set zRangeByScoreWithScores(byte[] key, double min, double max) { } @Override - public Set zRangeByScore(byte[] key, double min, double max, long offset, long count) { + public Set zRangeByScore(byte @NonNull [] key, double min, double max, long offset, long count) { Assert.notNull(key, "Key must not be null"); @@ -642,7 +649,8 @@ public Set zRangeByScore(byte[] key, double min, double max, long offset } @Override - public Set zRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + public Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, double min, double max, long offset, + long count) { Assert.notNull(key, "Key must not be null"); @@ -659,7 +667,7 @@ public Set zRangeByScoreWithScores(byte[] key, double min, double max, lo } @Override - public Set zRevRange(byte[] key, long start, long end) { + public Set zRevRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -671,7 +679,7 @@ public Set zRevRange(byte[] key, long start, long end) { } @Override - public Set zRevRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRevRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -683,7 +691,7 @@ public Set zRevRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRevRangeByScore(byte[] key, double min, double max) { + public Set zRevRangeByScore(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -695,7 +703,7 @@ public Set zRevRangeByScore(byte[] key, double min, double max) { } @Override - public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) { + public Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -707,7 +715,7 @@ public Set zRevRangeByScoreWithScores(byte[] key, double min, double max) } @Override - public Set zRevRangeByScore(byte[] key, double min, double max, long offset, long count) { + public Set zRevRangeByScore(byte @NonNull [] key, double min, double max, long offset, long count) { Assert.notNull(key, "Key must not be null"); @@ -724,7 +732,8 @@ public Set zRevRangeByScore(byte[] key, double min, double max, long off } @Override - public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, long offset, long count) { + public Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, double min, double max, long offset, + long count) { Assert.notNull(key, "Key must not be null"); @@ -741,7 +750,7 @@ public Set zRevRangeByScoreWithScores(byte[] key, double min, double max, } @Override - public Long zCount(byte[] key, double min, double max) { + public Long zCount(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -753,7 +762,7 @@ public Long zCount(byte[] key, double min, double max) { } @Override - public Long zCard(byte[] key) { + public Long zCard(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -765,7 +774,7 @@ public Long zCard(byte[] key) { } @Override - public Double zScore(byte[] key, byte[] value) { + public Double zScore(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -778,7 +787,7 @@ public Double zScore(byte[] key, byte[] value) { } @Override - public List zMScore(byte[] key, byte[][] values) { + public List zMScore(byte @NonNull [] key, byte @NonNull [] @NonNull [] values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -791,7 +800,7 @@ public List zMScore(byte[] key, byte[][] values) { } @Override - public Long zRemRange(byte[] key, long start, long end) { + public Long zRemRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -803,7 +812,7 @@ public Long zRemRange(byte[] key, long start, long end) { } @Override - public Long zRemRangeByScore(byte[] key, double min, double max) { + public Long zRemRangeByScore(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -815,7 +824,7 @@ public Long zRemRangeByScore(byte[] key, double min, double max) { } @Override - public Set zDiff(byte[]... sets) { + public Set zDiff(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -832,7 +841,7 @@ public Set zDiff(byte[]... sets) { } @Override - public Set zDiffWithScores(byte[]... sets) { + public Set zDiffWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -849,7 +858,7 @@ public Set zDiffWithScores(byte[]... sets) { } @Override - public Long zDiffStore(byte[] destKey, byte[]... sets) { + public Long zDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -869,7 +878,7 @@ public Long zDiffStore(byte[] destKey, byte[]... sets) { } @Override - public Set zInter(byte[]... sets) { + public Set zInter(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -886,15 +895,15 @@ public Set zInter(byte[]... sets) { } @Override - public Set zInterWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { try { - return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() - .zinterWithScores(new ZParams(), sets))); + return JedisConverters + .toSet(JedisConverters.toTupleList(connection.getCluster().zinterWithScores(new ZParams(), sets))); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -904,7 +913,8 @@ public Set zInterWithScores(byte[]... sets) { } @Override - public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -915,8 +925,8 @@ public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]. if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { try { - return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() - .zinterWithScores(toZParams(aggregate, weights), sets))); + return JedisConverters.toSet( + JedisConverters.toTupleList(connection.getCluster().zinterWithScores(toZParams(aggregate, weights), sets))); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -926,7 +936,7 @@ public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zInterStore(byte[] destKey, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -947,7 +957,8 @@ public Long zInterStore(byte[] destKey, byte[]... sets) { } @Override - public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -970,7 +981,7 @@ public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Set zUnion(byte[]... sets) { + public Set zUnion(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -987,15 +998,15 @@ public Set zUnion(byte[]... sets) { } @Override - public Set zUnionWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { try { - return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() - .zunionWithScores(new ZParams(), sets))); + return JedisConverters + .toSet(JedisConverters.toTupleList(connection.getCluster().zunionWithScores(new ZParams(), sets))); } catch (Exception ex) { throw convertJedisAccessException(ex); } @@ -1005,7 +1016,8 @@ public Set zUnionWithScores(byte[]... sets) { } @Override - public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -1016,8 +1028,8 @@ public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]. if (ClusterSlotHashUtil.isSameSlotForAllKeys(sets)) { try { - return JedisConverters.toSet(JedisConverters.toTupleList(connection.getCluster() - .zunionWithScores(toZParams(aggregate, weights), sets))); + return JedisConverters.toSet( + JedisConverters.toTupleList(connection.getCluster().zunionWithScores(toZParams(aggregate, weights), sets))); } catch (Exception ex) { throw convertJedisAccessException(ex); @@ -1028,7 +1040,7 @@ public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zUnionStore(byte[] destKey, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -1049,7 +1061,8 @@ public Long zUnionStore(byte[] destKey, byte[]... sets) { } @Override - public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -1074,7 +1087,7 @@ public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Cursor zScan(byte[] key, ScanOptions options) { + public Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); @@ -1094,7 +1107,7 @@ protected ScanIteration doScan(CursorId cursorId, ScanOptions options) { } @Override - public Set zRangeByScore(byte[] key, String min, String max) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max) { Assert.notNull(key, "Key must not be null"); @@ -1107,7 +1120,8 @@ public Set zRangeByScore(byte[] key, String min, String max) { } @Override - public Set zRangeByScore(byte[] key, String min, String max, long offset, long count) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max, + long offset, long count) { Assert.notNull(key, "Key must not be null"); @@ -1135,8 +1149,8 @@ private static ZParams toZParams(Aggregate aggregate, Weights weights) { return new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name())); } - @Nullable - private static Tuple toTuple(@Nullable KeyValue keyValue) { + @Contract("null -> null") + private @Nullable static Tuple toTuple(@Nullable KeyValue keyValue) { if (keyValue != null) { redis.clients.jedis.resps.Tuple tuple = keyValue.getValue(); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index 5888498d2b..6ba179d9b9 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -41,19 +41,38 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.RedisSystemException; -import org.springframework.data.redis.connection.*; +import org.springframework.data.redis.connection.AbstractRedisConnection; +import org.springframework.data.redis.connection.FutureResult; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.data.redis.connection.RedisCommands; +import org.springframework.data.redis.connection.RedisGeoCommands; +import org.springframework.data.redis.connection.RedisHashCommands; +import org.springframework.data.redis.connection.RedisHyperLogLogCommands; +import org.springframework.data.redis.connection.RedisKeyCommands; +import org.springframework.data.redis.connection.RedisListCommands; +import org.springframework.data.redis.connection.RedisNode; +import org.springframework.data.redis.connection.RedisPipelineException; +import org.springframework.data.redis.connection.RedisScriptingCommands; +import org.springframework.data.redis.connection.RedisServerCommands; +import org.springframework.data.redis.connection.RedisSetCommands; +import org.springframework.data.redis.connection.RedisStreamCommands; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.connection.RedisSubscribedConnectionException; +import org.springframework.data.redis.connection.RedisZSetCommands; +import org.springframework.data.redis.connection.Subscription; import org.springframework.data.redis.connection.convert.TransactionResultConverter; import org.springframework.data.redis.connection.jedis.JedisInvoker.ResponseCommands; import org.springframework.data.redis.connection.jedis.JedisResult.JedisResultBuilder; import org.springframework.data.redis.connection.jedis.JedisResult.JedisStatusResult; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -77,10 +96,11 @@ * @author John Blum * @see redis.clients.jedis.Jedis */ +@NullUnmarked public class JedisConnection extends AbstractRedisConnection { - private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = - new FallbackExceptionTranslationStrategy(JedisExceptionConverter.INSTANCE); + private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( + JedisExceptionConverter.INSTANCE); private boolean convertPipelineAndTxResults = true; @@ -110,8 +130,7 @@ public class JedisConnection extends AbstractRedisConnection { private final Log LOGGER = LogFactory.getLog(getClass()); - @SuppressWarnings("rawtypes") - private List pipelinedResults = new ArrayList<>(); + @SuppressWarnings("rawtypes") private List pipelinedResults = new ArrayList<>(); private final @Nullable Pool pool; @@ -126,7 +145,7 @@ public class JedisConnection extends AbstractRedisConnection { * * @param jedis {@link Jedis} client. */ - public JedisConnection(Jedis jedis) { + public JedisConnection(@NonNull Jedis jedis) { this(jedis, null, 0); } @@ -137,7 +156,7 @@ public JedisConnection(Jedis jedis) { * @param pool {@link Pool} of Redis connections; can be null, if no pool is used. * @param dbIndex {@link Integer index} of the Redis database to use. */ - public JedisConnection(Jedis jedis, Pool pool, int dbIndex) { + public JedisConnection(@NonNull Jedis jedis, @Nullable Pool pool, int dbIndex) { this(jedis, pool, dbIndex, null); } @@ -150,7 +169,8 @@ public JedisConnection(Jedis jedis, Pool pool, int dbIndex) { * @param clientName {@link String name} given to this client; can be {@literal null}. * @since 1.8 */ - protected JedisConnection(Jedis jedis, @Nullable Pool pool, int dbIndex, @Nullable String clientName) { + protected JedisConnection(@NonNull Jedis jedis, @Nullable Pool pool, int dbIndex, + @Nullable String clientName) { this(jedis, pool, createConfig(dbIndex, clientName), createConfig(dbIndex, clientName)); } @@ -163,8 +183,8 @@ protected JedisConnection(Jedis jedis, @Nullable Pool pool, int dbIndex, * @param sentinelConfig {@literal Redis Sentinel} configuration * @since 2.5 */ - protected JedisConnection(Jedis jedis, @Nullable Pool pool, JedisClientConfig nodeConfig, - JedisClientConfig sentinelConfig) { + protected JedisConnection(@NonNull Jedis jedis, @Nullable Pool pool, @NonNull JedisClientConfig nodeConfig, + @NonNull JedisClientConfig sentinelConfig) { this.jedis = jedis; this.pool = pool; @@ -187,8 +207,7 @@ private static DefaultJedisClientConfig createConfig(int dbIndex, @Nullable Stri return DefaultJedisClientConfig.builder().database(dbIndex).clientName(clientName).build(); } - @Nullable - private Object doInvoke(boolean status, Function directFunction, + private @Nullable Object doInvoke(boolean status, Function directFunction, Function> pipelineFunction, Converter converter, Supplier nullDefault) { @@ -284,7 +303,7 @@ public RedisServerCommands serverCommands() { } @Override - public Object execute(String command, byte[]... args) { + public Object execute(@NonNull String command, byte @NonNull []... args) { Assert.hasText(command, "A valid command needs to be specified"); Assert.notNull(args, "Arguments must not be null"); @@ -327,8 +346,7 @@ public void close() throws DataAccessException { // Return connection to the pool if (this.pool != null) { jedis.close(); - } - else { + } else { doExceptionThrowingOperationSafely(jedis::disconnect, "Failed to disconnect during close"); } } @@ -366,7 +384,7 @@ public void openPipeline() { } @Override - public List closePipeline() { + public List<@Nullable Object> closePipeline() { if (pipeline != null) { try { @@ -380,7 +398,7 @@ public List closePipeline() { return Collections.emptyList(); } - private List convertPipelineResults() { + private List<@Nullable Object> convertPipelineResults() { List results = new ArrayList<>(); @@ -417,7 +435,7 @@ private List convertPipelineResults() { return results; } - void pipeline(JedisResult result) { + void pipeline(@NonNull JedisResult result) { if (isQueueing()) { transaction(result); @@ -426,12 +444,12 @@ void pipeline(JedisResult result) { } } - void transaction(FutureResult> result) { + void transaction(@NonNull FutureResult> result) { txResults.add(result); } @Override - public byte[] echo(byte[] message) { + public byte[] echo(byte @NonNull [] message) { Assert.notNull(message, "Message must not be null"); @@ -457,7 +475,7 @@ public void discard() { } @Override - public List exec() { + public List<@Nullable Object> exec() { try { @@ -479,8 +497,7 @@ public List exec() { } } - @Nullable - public Pipeline getPipeline() { + public @Nullable Pipeline getPipeline() { return this.pipeline; } @@ -493,8 +510,7 @@ public Pipeline getRequiredPipeline() { return pipeline; } - @Nullable - public Transaction getTransaction() { + public @Nullable Transaction getTransaction() { return this.transaction; } @@ -507,6 +523,7 @@ public Transaction getRequiredTransaction() { return transaction; } + @NonNull public Jedis getJedis() { return this.jedis; } @@ -517,6 +534,7 @@ public Jedis getJedis() { * @return the {@link JedisInvoker}. * @since 2.5 */ + @NonNull JedisInvoker invoke() { return this.invoker; } @@ -528,6 +546,7 @@ JedisInvoker invoke() { * @return the {@link JedisInvoker}. * @since 2.5 */ + @NonNull JedisInvoker invokeStatus() { return this.statusInvoker; } @@ -573,7 +592,7 @@ public void unwatch() { } @Override - public void watch(byte[]... keys) { + public void watch(byte @NonNull [] @NonNull... keys) { if (isQueueing()) { throw new InvalidDataAccessApiUsageException("WATCH is not supported when a transaction is active"); @@ -591,7 +610,7 @@ public void watch(byte[]... keys) { // @Override - public Long publish(byte[] channel, byte[] message) { + public Long publish(byte @NonNull [] channel, byte @NonNull [] message) { return invoke().just(jedis -> jedis.publish(channel, message)); } @@ -607,7 +626,7 @@ public boolean isSubscribed() { } @Override - public void pSubscribe(MessageListener listener, byte[]... patterns) { + public void pSubscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... patterns) { if (isSubscribed()) { throw new RedisSubscribedConnectionException( @@ -628,7 +647,7 @@ public void pSubscribe(MessageListener listener, byte[]... patterns) { } @Override - public void subscribe(MessageListener listener, byte[]... channels) { + public void subscribe(@NonNull MessageListener listener, byte @NonNull [] @NonNull... channels) { if (isSubscribed()) { throw new RedisSubscribedConnectionException( @@ -659,7 +678,7 @@ public void setConvertPipelineAndTxResults(boolean convertPipelineAndTxResults) } @Override - protected boolean isActive(RedisNode node) { + protected boolean isActive(@NonNull RedisNode node) { Jedis verification = null; @@ -678,16 +697,15 @@ protected boolean isActive(RedisNode node) { } @Override - protected JedisSentinelConnection getSentinelConnection(RedisNode sentinel) { + protected JedisSentinelConnection getSentinelConnection(@NonNull RedisNode sentinel) { return new JedisSentinelConnection(getJedis(sentinel)); } - protected Jedis getJedis(RedisNode node) { + protected Jedis getJedis(@NonNull RedisNode node) { return new Jedis(new HostAndPort(node.getHost(), node.getPort()), this.sentinelConfig); } - @Nullable - private T doWithJedis(Function callback) { + private @Nullable T doWithJedis(@NonNull Function<@NonNull Jedis, T> callback) { try { return callback.apply(getJedis()); @@ -696,7 +714,7 @@ private T doWithJedis(Function callback) { } } - private void doWithJedis(Consumer callback) { + private void doWithJedis(@NonNull Consumer<@NonNull Jedis> callback) { try { callback.accept(getJedis()); @@ -709,15 +727,13 @@ private void doExceptionThrowingOperationSafely(ExceptionThrowingOperation opera try { operation.run(); - } - catch (Exception ex) { + } catch (Exception ex) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(logMessage, ex); } } } - @FunctionalInterface private interface ExceptionThrowingOperation { void run() throws Exception; diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java index 01cb4badec..21be414ff8 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactory.java @@ -43,6 +43,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.SmartLifecycle; @@ -58,7 +59,6 @@ import org.springframework.data.redis.connection.RedisConfiguration.WithDatabaseIndex; import org.springframework.data.redis.connection.RedisConfiguration.WithPassword; import org.springframework.data.redis.connection.jedis.JedisClusterConnection.JedisClusterTopologyProvider; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -247,7 +247,7 @@ public JedisConnectionFactory(RedisSentinelConfiguration sentinelConfiguration, * @param poolConfig pool configuration. Defaulted to new instance if {@literal null}. * @since 1.4 */ - public JedisConnectionFactory(RedisSentinelConfiguration sentinelConfiguration, + public JedisConnectionFactory(@Nullable RedisSentinelConfiguration sentinelConfiguration, @Nullable JedisPoolConfig poolConfig) { this.configuration = sentinelConfiguration; @@ -353,13 +353,11 @@ public void setUseSsl(boolean useSsl) { * * @return password for authentication. */ - @Nullable - public String getPassword() { + public @Nullable String getPassword() { return getRedisPassword().map(String::new).orElse(null); } - @Nullable - private String getRedisUsername() { + private @Nullable String getRedisUsername() { return RedisConfiguration.getUsernameOrElse(this.configuration, standaloneConfig::getUsername); } @@ -466,8 +464,7 @@ public void setUsePool(boolean usePool) { * * @return the poolConfig */ - @Nullable - public GenericObjectPoolConfig getPoolConfig() { + public @Nullable GenericObjectPoolConfig getPoolConfig() { return clientConfiguration.getPoolConfig().orElse(null); } @@ -519,8 +516,7 @@ public void setDatabase(int index) { * @return the client name. * @since 1.8 */ - @Nullable - public String getClientName() { + public @Nullable String getClientName() { return clientConfiguration.getClientName().orElse(null); } @@ -549,8 +545,7 @@ public JedisClientConfiguration getClientConfiguration() { * @return the {@link RedisStandaloneConfiguration}. * @since 2.0 */ - @Nullable - public RedisStandaloneConfiguration getStandaloneConfiguration() { + public @Nullable RedisStandaloneConfiguration getStandaloneConfiguration() { return this.standaloneConfig; } @@ -558,8 +553,7 @@ public RedisStandaloneConfiguration getStandaloneConfiguration() { * @return the {@link RedisStandaloneConfiguration}, may be {@literal null}. * @since 2.0 */ - @Nullable - public RedisSentinelConfiguration getSentinelConfiguration() { + public @Nullable RedisSentinelConfiguration getSentinelConfiguration() { return RedisConfiguration.isSentinelConfiguration(configuration) ? (RedisSentinelConfiguration) configuration : null; } @@ -568,8 +562,7 @@ public RedisSentinelConfiguration getSentinelConfiguration() { * @return the {@link RedisClusterConfiguration}, may be {@literal null}. * @since 2.0 */ - @Nullable - public RedisClusterConfiguration getClusterConfiguration() { + public @Nullable RedisClusterConfiguration getClusterConfiguration() { return RedisConfiguration.isClusterConfiguration(configuration) ? (RedisClusterConfiguration) configuration : null; } @@ -722,6 +715,7 @@ JedisClientConfig createSentinelClientConfig(SentinelConfiguration sentinelConfi } @Override + @SuppressWarnings("NullAway") public void start() { State current = this.state.getAndUpdate(state -> isCreatedOrStopped(state) ? State.STARTING : state); @@ -803,6 +797,7 @@ public boolean isRunning() { return State.STARTED.equals(this.state.get()); } + @SuppressWarnings("NullAway") private Pool createPool() { if (isRedisSentinelAware()) { @@ -818,6 +813,7 @@ private Pool createPool() { * @return the {@link Pool} to use. Never {@literal null}. * @since 1.4 */ + @SuppressWarnings("NullAway") protected Pool createRedisSentinelPool(RedisSentinelConfiguration config) { GenericObjectPoolConfig poolConfig = getPoolConfig() != null ? getPoolConfig() : new JedisPoolConfig(); @@ -949,6 +945,7 @@ protected JedisConnection postProcessConnection(JedisConnection connection) { } @Override + @SuppressWarnings("NullAway") public RedisClusterConnection getClusterConnection() { assertInitialized(); @@ -976,7 +973,7 @@ protected JedisClusterConnection postProcessConnection(JedisClusterConnection co } @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { return EXCEPTION_TRANSLATION.translate(ex); } @@ -1054,6 +1051,7 @@ private MutableJedisClientConfiguration getMutableConfiguration() { return (MutableJedisClientConfiguration) clientConfiguration; } + @SuppressWarnings("NullAway") private void assertInitialized() { State current = state.get(); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java index 6be56d07b0..0a6eb08b7c 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.domain.Sort; import org.springframework.data.geo.Distance; @@ -84,7 +85,7 @@ import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; import org.springframework.data.redis.domain.geo.RadiusShape; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -187,13 +188,13 @@ static byte[] toBytes(Cursor.CursorId source) { return toBytes(source.getCursorId()); } - @Nullable - public static byte[] toBytes(@Nullable String source) { + @Contract("null -> null;!null -> !null") + public static byte @Nullable [] toBytes(@Nullable String source) { return source == null ? null : SafeEncoder.encode(source); } - @Nullable - public static String toString(@Nullable byte[] source) { + @Contract("null -> null;!null -> !null") + public static @Nullable String toString(byte @Nullable [] source) { return source == null ? null : SafeEncoder.encode(source); } @@ -204,7 +205,7 @@ public static String toString(@Nullable byte[] source) { * @return the {@link ValueEncoding} for given {@code source}. Never {@literal null}. * @since 2.1 */ - public static ValueEncoding toEncoding(byte[] source) { + public static ValueEncoding toEncoding(byte @Nullable [] source) { return ValueEncoding.of(toString(source)); } @@ -259,33 +260,33 @@ public static byte[][] toByteArrays(Map source) { return result; } - @Nullable - public static SortingParams toSortingParams(@Nullable SortParameters params) { + @Contract("null -> null;!null -> !null") + public static @Nullable SortingParams toSortingParams(@Nullable SortParameters params) { - SortingParams jedisParams = null; + if (params == null) { + return null; + } - if (params != null) { - jedisParams = new SortingParams(); - byte[] byPattern = params.getByPattern(); - if (byPattern != null) { - jedisParams.by(params.getByPattern()); - } - byte[][] getPattern = params.getGetPattern(); - if (getPattern != null) { - jedisParams.get(getPattern); - } - Range limit = params.getLimit(); - if (limit != null) { - jedisParams.limit((int) limit.getStart(), (int) limit.getCount()); - } - Order order = params.getOrder(); - if (order != null && order.equals(Order.DESC)) { - jedisParams.desc(); - } - Boolean isAlpha = params.isAlphabetic(); - if (isAlpha != null && isAlpha) { - jedisParams.alpha(); - } + SortingParams jedisParams = new SortingParams(); + byte[] byPattern = params.getByPattern(); + if (byPattern != null) { + jedisParams.by(params.getByPattern()); + } + byte[][] getPattern = params.getGetPattern(); + if (getPattern != null) { + jedisParams.get(getPattern); + } + Range limit = params.getLimit(); + if (limit != null) { + jedisParams.limit((int) limit.getStart(), (int) limit.getCount()); + } + Order order = params.getOrder(); + if (order != null && order.equals(Order.DESC)) { + jedisParams.desc(); + } + Boolean isAlpha = params.isAlphabetic(); + if (isAlpha != null && isAlpha) { + jedisParams.alpha(); } return jedisParams; @@ -307,7 +308,7 @@ public static BitOP toBitOp(BitOperation bitOp) { * * @since 1.6 */ - public static byte[] boundaryToBytesForZRange(@Nullable org.springframework.data.domain.Range.Bound boundary, + public static byte[] boundaryToBytesForZRange(org.springframework.data.domain.Range.@Nullable Bound boundary, byte[] defaultValue) { if (boundary == null || !boundary.isBounded()) { @@ -324,7 +325,7 @@ public static byte[] boundaryToBytesForZRange(@Nullable org.springframework.data * @since 1.6 */ public static byte[] boundaryToBytesForZRangeByLex( - @Nullable org.springframework.data.domain.Range.Bound boundary, byte[] defaultValue) { + org.springframework.data.domain.Range.@Nullable Bound boundary, byte[] defaultValue) { if (boundary == null || !boundary.isBounded()) { return defaultValue; @@ -544,7 +545,7 @@ public static ListConverter geoCoordin * @since 2.5 */ @Nullable - static Point toPoint(@Nullable redis.clients.jedis.GeoCoordinate geoCoordinate) { + static Point toPoint(redis.clients.jedis.@Nullable GeoCoordinate geoCoordinate) { return geoCoordinate == null ? null : new Point(geoCoordinate.getLongitude(), geoCoordinate.getLatitude()); } @@ -618,6 +619,7 @@ static ZAddParams toZAddParams(ZAddArgs source) { * * @since 1.8 */ + @SuppressWarnings("NullAway") public static GeoRadiusParam toGeoRadiusParam(GeoRadiusCommandArgs source) { GeoRadiusParam param = GeoRadiusParam.geoRadiusParam(); @@ -700,7 +702,7 @@ public static byte[][] toBitfieldCommandArguments(BitFieldSubCommands source) { return args.toArray(new byte[0][0]); } - static FlushMode toFlushMode(@Nullable RedisServerCommands.FlushOption option) { + static FlushMode toFlushMode(RedisServerCommands.@Nullable FlushOption option) { if (option == null) { return FlushMode.SYNC; @@ -849,6 +851,7 @@ public GeoResultConverter(Metric metric) { } @Override + @SuppressWarnings("NullAway") public GeoResult> convert(GeoRadiusResponse source) { Point point = JedisConverters.toPoint(source.getCoordinate()); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisExceptionConverter.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisExceptionConverter.java index 50d594afa7..368e24a874 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisExceptionConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisExceptionConverter.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.net.UnknownHostException; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -43,7 +44,7 @@ public class JedisExceptionConverter implements Converter memberCoordinateMap) { + public Long geoAdd(byte @NonNull [] key, @NonNull Map memberCoordinateMap) { Assert.notNull(key, "Key must not be null"); Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null"); @@ -76,7 +79,7 @@ public Long geoAdd(byte[] key, Map memberCoordinateMap) { } @Override - public Long geoAdd(byte[] key, Iterable> locations) { + public Long geoAdd(byte @NonNull [] key, @NonNull Iterable<@NonNull GeoLocation> locations) { Assert.notNull(key, "Key must not be null"); Assert.notNull(locations, "Locations must not be null"); @@ -91,7 +94,7 @@ public Long geoAdd(byte[] key, Iterable> locations) { } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member1, "Member1 must not be null"); @@ -104,7 +107,8 @@ public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2, + @NonNull Metric metric) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member1, "Member1 must not be null"); @@ -119,7 +123,7 @@ public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metri } @Override - public List geoHash(byte[] key, byte[]... members) { + public List geoHash(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -130,7 +134,7 @@ public List geoHash(byte[] key, byte[]... members) { } @Override - public List geoPos(byte[] key, byte[]... members) { + public List<@NonNull Point> geoPos(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -141,7 +145,7 @@ public List geoPos(byte[] key, byte[]... members) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -157,7 +161,8 @@ public GeoResults> geoRadius(byte[] key, Circle within) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within, + @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -175,7 +180,8 @@ public GeoResults> geoRadius(byte[] key, Circle within, GeoR } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -190,8 +196,8 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, - GeoRadiusCommandArgs args) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius, @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -208,13 +214,13 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public Long geoRemove(byte[] key, byte[]... members) { + public Long geoRemove(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { return connection.zSetCommands().zRem(key, members); } @Override - public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchCommandArgs args) { + public GeoResults> geoSearch(byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchCommandArgs args) { Assert.notNull(key, "Key must not be null"); @@ -226,8 +232,8 @@ public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchStoreCommandArgs args) { + public Long geoSearchStore(byte @NonNull [] destKey, byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchStoreCommandArgs args) { Assert.notNull(destKey, "Destination Key must not be null"); Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java index 33189c27b4..32a5d8b54d 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHashCommands.java @@ -28,6 +28,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.connection.RedisHashCommands; @@ -37,7 +40,6 @@ import org.springframework.data.redis.core.KeyBoundCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -49,6 +51,7 @@ * @author Tihomir Mateev * @since 2.0 */ +@NullUnmarked class JedisHashCommands implements RedisHashCommands { private final JedisConnection connection; @@ -58,7 +61,7 @@ class JedisHashCommands implements RedisHashCommands { } @Override - public Boolean hSet(byte[] key, byte[] field, byte[] value) { + public Boolean hSet(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -69,7 +72,7 @@ public Boolean hSet(byte[] key, byte[] field, byte[] value) { } @Override - public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { + public Boolean hSetNX(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -80,7 +83,7 @@ public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { } @Override - public Long hDel(byte[] key, byte[]... fields) { + public Long hDel(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { Assert.notNull(key, "Key must not be null"); Assert.notNull(fields, "Fields must not be null"); @@ -89,7 +92,7 @@ public Long hDel(byte[] key, byte[]... fields) { } @Override - public Boolean hExists(byte[] key, byte[] field) { + public Boolean hExists(byte @NonNull [] key, byte @NonNull [] field) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Fields must not be null"); @@ -98,7 +101,7 @@ public Boolean hExists(byte[] key, byte[] field) { } @Override - public byte[] hGet(byte[] key, byte[] field) { + public byte[] hGet(byte @NonNull [] key, byte @NonNull [] field) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -107,16 +110,15 @@ public byte[] hGet(byte[] key, byte[] field) { } @Override - public Map hGetAll(byte[] key) { + public Map hGetAll(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(Jedis::hgetAll, PipelineBinaryCommands::hgetAll, key); } - @Nullable @Override - public byte[] hRandField(byte[] key) { + public byte[] hRandField(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -125,7 +127,7 @@ public byte[] hRandField(byte[] key) { @Nullable @Override - public Entry hRandFieldWithValues(byte[] key) { + public Entry hRandFieldWithValues(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -135,7 +137,7 @@ public Entry hRandFieldWithValues(byte[] key) { @Nullable @Override - public List hRandField(byte[] key, long count) { + public List hRandField(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -144,7 +146,8 @@ public List hRandField(byte[] key, long count) { @Nullable @Override - public List> hRandFieldWithValues(byte[] key, long count) { + public List<@NonNull Entry> hRandFieldWithValues(byte @NonNull [] key, + long count) { Assert.notNull(key, "Key must not be null"); @@ -163,7 +166,7 @@ public List> hRandFieldWithValues(byte[] key, long count) } @Override - public Long hIncrBy(byte[] key, byte[] field, long delta) { + public Long hIncrBy(byte @NonNull [] key, byte @NonNull [] field, long delta) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -172,7 +175,7 @@ public Long hIncrBy(byte[] key, byte[] field, long delta) { } @Override - public Double hIncrBy(byte[] key, byte[] field, double delta) { + public Double hIncrBy(byte @NonNull [] key, byte @NonNull [] field, double delta) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -181,7 +184,7 @@ public Double hIncrBy(byte[] key, byte[] field, double delta) { } @Override - public Set hKeys(byte[] key) { + public Set hKeys(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -189,7 +192,7 @@ public Set hKeys(byte[] key) { } @Override - public Long hLen(byte[] key) { + public Long hLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -197,7 +200,7 @@ public Long hLen(byte[] key) { } @Override - public List hMGet(byte[] key, byte[]... fields) { + public List hMGet(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { Assert.notNull(key, "Key must not be null"); Assert.notNull(fields, "Fields must not be null"); @@ -206,7 +209,7 @@ public List hMGet(byte[] key, byte[]... fields) { } @Override - public void hMSet(byte[] key, Map hashes) { + public void hMSet(byte @NonNull [] key, @NonNull Map hashes) { Assert.notNull(key, "Key must not be null"); Assert.notNull(hashes, "Hashes must not be null"); @@ -215,7 +218,7 @@ public void hMSet(byte[] key, Map hashes) { } @Override - public List hVals(byte[] key) { + public List hVals(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -223,11 +226,13 @@ public List hVals(byte[] key) { } @Override - public Cursor> hScan(byte[] key, ScanOptions options) { + public Cursor<@NonNull Entry> hScan(byte @NonNull [] key, + @NonNull ScanOptions options) { return hScan(key, CursorId.initial(), options); } - public Cursor> hScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor<@NonNull Entry> hScan(byte @NonNull [] key, + @NonNull CursorId cursorId, @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); @@ -256,7 +261,8 @@ protected void doClose() { } @Override - public List hExpire(byte[] key, long seconds, ExpirationOptions.Condition condition, byte[]... fields) { + public List<@NonNull Long> hExpire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields) { if (condition == ExpirationOptions.Condition.ALWAYS) { return connection.invoke().just(Jedis::hexpire, PipelineBinaryCommands::hexpire, key, seconds, fields); @@ -267,7 +273,8 @@ public List hExpire(byte[] key, long seconds, ExpirationOptions.Condition } @Override - public List hpExpire(byte[] key, long millis, ExpirationOptions.Condition condition, byte[]... fields) { + public List<@NonNull Long> hpExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields) { if (condition == ExpirationOptions.Condition.ALWAYS) { return connection.invoke().just(Jedis::hpexpire, PipelineBinaryCommands::hpexpire, key, millis, fields); @@ -278,7 +285,8 @@ public List hpExpire(byte[] key, long millis, ExpirationOptions.Condition } @Override - public List hExpireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition, byte[]... fields) { + public List<@NonNull Long> hExpireAt(byte @NonNull [] key, long unixTime, + ExpirationOptions.@NonNull Condition condition, byte @NonNull [] @NonNull... fields) { if (condition == ExpirationOptions.Condition.ALWAYS) { return connection.invoke().just(Jedis::hexpireAt, PipelineBinaryCommands::hexpireAt, key, unixTime, fields); @@ -289,8 +297,8 @@ public List hExpireAt(byte[] key, long unixTime, ExpirationOptions.Conditi } @Override - public List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition, - byte[]... fields) { + public List<@NonNull Long> hpExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition, byte @NonNull [] @NonNull... fields) { if (condition == ExpirationOptions.Condition.ALWAYS) { return connection.invoke().just(Jedis::hpexpireAt, PipelineBinaryCommands::hpexpireAt, key, unixTimeInMillis, @@ -299,27 +307,28 @@ public List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOption ExpiryOption option = ExpiryOption.valueOf(condition.name()); return connection.invoke().just(Jedis::hpexpireAt, PipelineBinaryCommands::hpexpireAt, key, unixTimeInMillis, - fields); + option, fields); } @Override - public List hPersist(byte[] key, byte[]... fields) { + public List<@NonNull Long> hPersist(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().just(Jedis::hpersist, PipelineBinaryCommands::hpersist, key, fields); } @Override - public List hTtl(byte[] key, byte[]... fields) { + public List<@NonNull Long> hTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().just(Jedis::httl, PipelineBinaryCommands::httl, key, fields); } @Override - public List hTtl(byte[] key, TimeUnit timeUnit, byte[]... fields) { + public List<@NonNull Long> hTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit, + byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(Jedis::httl, PipelineBinaryCommands::httl, key, fields) .toList(Converters.secondsToTimeUnit(timeUnit)); } @Override - public List hpTtl(byte[] key, byte[]... fields) { + public List<@NonNull Long> hpTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().just(Jedis::hpttl, PipelineBinaryCommands::hpttl, key, fields); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java index 25393cf2af..5d92e25f96 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisHyperLogLogCommands.java @@ -18,6 +18,8 @@ import redis.clients.jedis.Jedis; import redis.clients.jedis.commands.PipelineBinaryCommands; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisHyperLogLogCommands; import org.springframework.util.Assert; @@ -26,16 +28,17 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class JedisHyperLogLogCommands implements RedisHyperLogLogCommands { private final JedisConnection connection; - JedisHyperLogLogCommands(JedisConnection connection) { + JedisHyperLogLogCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Long pfAdd(byte[] key, byte[]... values) { + public Long pfAdd(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notEmpty(values, "PFADD requires at least one non 'null' value"); Assert.noNullElements(values, "Values for PFADD must not contain 'null'"); @@ -44,7 +47,7 @@ public Long pfAdd(byte[] key, byte[]... values) { } @Override - public Long pfCount(byte[]... keys) { + public Long pfCount(byte @NonNull [] @NonNull... keys) { Assert.notEmpty(keys, "PFCOUNT requires at least one non 'null' key"); Assert.noNullElements(keys, "Keys for PFCOUNT must not contain 'null'"); @@ -53,7 +56,7 @@ public Long pfCount(byte[]... keys) { } @Override - public void pfMerge(byte[] destinationKey, byte[]... sourceKeys) { + public void pfMerge(byte @NonNull [] destinationKey, byte @NonNull [] @NonNull... sourceKeys) { Assert.notNull(destinationKey, "Destination key must not be null"); Assert.notNull(sourceKeys, "Source keys must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java index 586a35eca2..67b32e925a 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java @@ -31,11 +31,11 @@ import java.util.function.Function; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.convert.Converters; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -77,8 +77,7 @@ class JedisInvoker { * * @param function must not be {@literal null}. */ - @Nullable - R just(ConnectionFunction0 function) { + @Nullable R just(ConnectionFunction0<@Nullable R> function) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -93,8 +92,7 @@ R just(ConnectionFunction0 function) { * @param function must not be {@literal null}. * @param pipelineFunction must not be {@literal null}. */ - @Nullable - R just(ConnectionFunction0 function, PipelineFunction0 pipelineFunction) { + @Nullable R just(ConnectionFunction0<@Nullable R> function, PipelineFunction0<@Nullable R> pipelineFunction) { Assert.notNull(function, "ConnectionFunction must not be null"); Assert.notNull(pipelineFunction, "PipelineFunction must not be null"); @@ -109,8 +107,7 @@ R just(ConnectionFunction0 function, PipelineFunction0 pipelineFunctio * @param pipelineFunction must not be {@literal null}. * @param t1 first argument. */ - @Nullable - R just(ConnectionFunction1 function, PipelineFunction1 pipelineFunction, T1 t1) { + @Nullable R just(ConnectionFunction1 function, PipelineFunction1 pipelineFunction, T1 t1) { Assert.notNull(function, "ConnectionFunction must not be null"); Assert.notNull(pipelineFunction, "PipelineFunction must not be null"); @@ -126,8 +123,7 @@ R just(ConnectionFunction1 function, PipelineFunction1 pip * @param t1 first argument. * @param t2 second argument. */ - @Nullable - R just(ConnectionFunction2 function, PipelineFunction2 pipelineFunction, T1 t1, + @Nullable R just(ConnectionFunction2 function, PipelineFunction2 pipelineFunction, T1 t1, T2 t2) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -145,8 +141,7 @@ R just(ConnectionFunction2 function, PipelineFunction2 R just(ConnectionFunction3 function, PipelineFunction3 pipelineFunction, + @Nullable R just(ConnectionFunction3 function, PipelineFunction3 pipelineFunction, T1 t1, T2 t2, T3 t3) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -165,9 +160,8 @@ R just(ConnectionFunction3 function, PipelineFunc * @param t3 third argument. * @param t4 fourth argument. */ - @Nullable - R just(ConnectionFunction4 function, - PipelineFunction4 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4) { + @Nullable R just(ConnectionFunction4 function, + PipelineFunction4 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4) { Assert.notNull(function, "ConnectionFunction must not be null"); Assert.notNull(pipelineFunction, "PipelineFunction must not be null"); @@ -187,9 +181,8 @@ R just(ConnectionFunction4 function, * @param t4 fourth argument. * @param t5 fifth argument. */ - @Nullable - R just(ConnectionFunction5 function, - PipelineFunction5 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + @Nullable R just(ConnectionFunction5 function, + PipelineFunction5 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { Assert.notNull(function, "ConnectionFunction must not be null"); Assert.notNull(pipelineFunction, "PipelineFunction must not be null"); @@ -210,9 +203,8 @@ R just(ConnectionFunction5 functi * @param t5 fifth argument. * @param t6 sixth argument. */ - @Nullable - R just(ConnectionFunction6 function, - PipelineFunction6 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { + @Nullable R just(ConnectionFunction6 function, + PipelineFunction6 pipelineFunction, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) { Assert.notNull(function, "ConnectionFunction must not be null"); Assert.notNull(pipelineFunction, "PipelineFunction must not be null"); @@ -548,8 +540,7 @@ interface SingleInvocationSpec { * @param target type. * @return the converted result, can be {@literal null}. */ - @Nullable - default T orElse(Converter converter, @Nullable T nullDefault) { + default @Nullable T orElse(Converter converter, @Nullable T nullDefault) { return getOrElse(converter, () -> nullDefault); } @@ -562,8 +553,7 @@ default T orElse(Converter converter, @Nullable T nullDefault) { * @param target type. * @return the converted result, can be {@literal null}. */ - @Nullable - T getOrElse(Converter converter, Supplier nullDefault); + @Nullable T getOrElse(Converter converter, Supplier nullDefault); } /** @@ -936,13 +926,12 @@ static class DefaultSingleInvocationSpec implements SingleInvocationSpec { } @Override - public T get(Converter converter) { + public @Nullable T get(Converter converter) { return getOrElse(converter, () -> null); } - @Nullable @Override - public T getOrElse(Converter converter, Supplier nullDefault) { + public @Nullable T getOrElse(Converter converter, Supplier nullDefault) { Assert.notNull(converter, "Converter must not be null"); @@ -1027,10 +1016,9 @@ default T invoke(Function callFunction, Function null); } - @Nullable @SuppressWarnings({ "unchecked", "rawtypes" }) - default T invoke(Function callFunction, Function> pipelineFunction, - Converter converter, Supplier nullDefault) { + default @Nullable T invoke(Function callFunction, Function> pipelineFunction, + Converter converter, Supplier<@Nullable T> nullDefault) { return (T) doInvoke((Function) callFunction, (Function) pipelineFunction, (Converter) converter, (Supplier) nullDefault); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java index 9d4465b410..183c8f8e23 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisKeyCommands.java @@ -29,6 +29,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.ExpirationOptions; @@ -43,7 +46,6 @@ import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -53,25 +55,25 @@ * @author ihaohong * @since 2.0 */ +@NullUnmarked class JedisKeyCommands implements RedisKeyCommands { private final JedisConnection connection; - JedisKeyCommands(JedisConnection connection) { + JedisKeyCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Boolean exists(byte[] key) { + public Boolean exists(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(JedisBinaryCommands::exists, PipelineBinaryCommands::exists, key); } - @Nullable @Override - public Long exists(byte[]... keys) { + public Long exists(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -80,7 +82,7 @@ public Long exists(byte[]... keys) { } @Override - public Long del(byte[]... keys) { + public Long del(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -88,7 +90,8 @@ public Long del(byte[]... keys) { return connection.invoke().just(JedisBinaryCommands::del, PipelineBinaryCommands::del, keys); } - public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { + @Override + public Boolean copy(byte @NonNull [] sourceKey, byte @NonNull [] targetKey, boolean replace) { Assert.notNull(sourceKey, "source key must not be null"); Assert.notNull(targetKey, "target key must not be null"); @@ -97,9 +100,8 @@ public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { replace); } - @Nullable @Override - public Long unlink(byte[]... keys) { + public Long unlink(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -107,7 +109,7 @@ public Long unlink(byte[]... keys) { } @Override - public DataType type(byte[] key) { + public DataType type(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -115,9 +117,8 @@ public DataType type(byte[] key) { .get(JedisConverters.stringToDataType()); } - @Nullable @Override - public Long touch(byte[]... keys) { + public Long touch(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -125,7 +126,7 @@ public Long touch(byte[]... keys) { } @Override - public Set keys(byte[] pattern) { + public Set keys(byte @NonNull [] pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -133,7 +134,7 @@ public Set keys(byte[] pattern) { } @Override - public Cursor scan(ScanOptions options) { + public Cursor scan(@NonNull ScanOptions options) { return scan(CursorId.initial(), options != null ? options : ScanOptions.NONE); } @@ -143,7 +144,7 @@ public Cursor scan(ScanOptions options) { * @param options * @return */ - public Cursor scan(CursorId cursorId, ScanOptions options) { + public Cursor scan(@NonNull CursorId cursorId, @NonNull ScanOptions options) { return new ScanCursor(cursorId, options) { @@ -188,7 +189,7 @@ public byte[] randomKey() { } @Override - public void rename(byte[] oldKey, byte[] newKey) { + public void rename(byte @NonNull [] oldKey, byte @NonNull [] newKey) { Assert.notNull(oldKey, "Old key must not be null"); Assert.notNull(newKey, "New key must not be null"); @@ -197,7 +198,7 @@ public void rename(byte[] oldKey, byte[] newKey) { } @Override - public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { + public Boolean renameNX(byte @NonNull [] sourceKey, byte @NonNull [] targetKey) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(targetKey, "Target key must not be null"); @@ -208,7 +209,7 @@ public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { } @Override - public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition condition) { + public Boolean expire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -227,7 +228,7 @@ public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition cond } @Override - public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition condition) { + public Boolean pExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -242,7 +243,7 @@ public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition cond } @Override - public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition) { + public Boolean expireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -258,7 +259,8 @@ public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition c } @Override - public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition) { + public Boolean pExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -275,7 +277,7 @@ public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Co } @Override - public Boolean persist(byte[] key) { + public Boolean persist(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -284,7 +286,7 @@ public Boolean persist(byte[] key) { } @Override - public Boolean move(byte[] key, int dbIndex) { + public Boolean move(byte @NonNull [] key, int dbIndex) { Assert.notNull(key, "Key must not be null"); @@ -292,7 +294,7 @@ public Boolean move(byte[] key, int dbIndex) { } @Override - public Long ttl(byte[] key) { + public Long ttl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -300,7 +302,7 @@ public Long ttl(byte[] key) { } @Override - public Long ttl(byte[] key, TimeUnit timeUnit) { + public Long ttl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -309,7 +311,7 @@ public Long ttl(byte[] key, TimeUnit timeUnit) { } @Override - public Long pTtl(byte[] key) { + public Long pTtl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -317,7 +319,7 @@ public Long pTtl(byte[] key) { } @Override - public Long pTtl(byte[] key, TimeUnit timeUnit) { + public Long pTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -326,7 +328,7 @@ public Long pTtl(byte[] key, TimeUnit timeUnit) { } @Override - public List sort(byte[] key, SortParameters params) { + public List sort(byte @NonNull [] key, @Nullable SortParameters params) { Assert.notNull(key, "Key must not be null"); @@ -340,7 +342,7 @@ public List sort(byte[] key, SortParameters params) { } @Override - public Long sort(byte[] key, @Nullable SortParameters params, byte[] storeKey) { + public Long sort(byte @NonNull [] key, @Nullable SortParameters params, byte @NonNull [] storeKey) { Assert.notNull(key, "Key must not be null"); @@ -355,7 +357,7 @@ public Long sort(byte[] key, @Nullable SortParameters params, byte[] storeKey) { } @Override - public byte[] dump(byte[] key) { + public byte[] dump(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -363,7 +365,7 @@ public byte[] dump(byte[] key) { } @Override - public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolean replace) { + public void restore(byte @NonNull [] key, long ttlInMillis, byte @NonNull [] serializedValue, boolean replace) { Assert.notNull(key, "Key must not be null"); Assert.notNull(serializedValue, "Serialized value must not be null"); @@ -383,9 +385,8 @@ public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolea (int) ttlInMillis, serializedValue); } - @Nullable @Override - public ValueEncoding encodingOf(byte[] key) { + public ValueEncoding encodingOf(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -393,9 +394,8 @@ public ValueEncoding encodingOf(byte[] key) { .getOrElse(JedisConverters::toEncoding, () -> RedisValueEncoding.VACANT); } - @Nullable @Override - public Duration idletime(byte[] key) { + public Duration idletime(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -403,9 +403,8 @@ public Duration idletime(byte[] key) { .get(Converters::secondsToDuration); } - @Nullable @Override - public Long refcount(byte[] key) { + public Long refcount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java index a7bb1dd619..de1c29e1a1 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisListCommands.java @@ -23,8 +23,10 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisListCommands; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -33,16 +35,17 @@ * @author dengliming * @since 2.0 */ +@NullUnmarked class JedisListCommands implements RedisListCommands { private final JedisConnection connection; - JedisListCommands(JedisConnection connection) { + JedisListCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Long rPush(byte[] key, byte[]... values) { + public Long rPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); @@ -50,7 +53,8 @@ public Long rPush(byte[] key, byte[]... values) { } @Override - public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Nullable Integer count) { + public List lPos(byte @NonNull [] key, byte @NonNull [] element, @Nullable Integer rank, + @Nullable Integer count) { Assert.notNull(key, "Key must not be null"); Assert.notNull(element, "Element must not be null"); @@ -70,7 +74,7 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null } @Override - public Long lPush(byte[] key, byte[]... values) { + public Long lPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -80,7 +84,7 @@ public Long lPush(byte[] key, byte[]... values) { } @Override - public Long rPushX(byte[] key, byte[] value) { + public Long rPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -89,7 +93,7 @@ public Long rPushX(byte[] key, byte[] value) { } @Override - public Long lPushX(byte[] key, byte[] value) { + public Long lPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -98,7 +102,7 @@ public Long lPushX(byte[] key, byte[] value) { } @Override - public Long lLen(byte[] key) { + public Long lLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -106,7 +110,7 @@ public Long lLen(byte[] key) { } @Override - public List lRange(byte[] key, long start, long end) { + public List lRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -114,7 +118,7 @@ public List lRange(byte[] key, long start, long end) { } @Override - public void lTrim(byte[] key, long start, long end) { + public void lTrim(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -122,7 +126,7 @@ public void lTrim(byte[] key, long start, long end) { } @Override - public byte[] lIndex(byte[] key, long index) { + public byte[] lIndex(byte @NonNull [] key, long index) { Assert.notNull(key, "Key must not be null"); @@ -130,7 +134,7 @@ public byte[] lIndex(byte[] key, long index) { } @Override - public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { + public Long lInsert(byte @NonNull [] key, @NonNull Position where, byte @NonNull [] pivot, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); @@ -139,7 +143,8 @@ public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { } @Override - public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to) { + public byte[] lMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -151,7 +156,8 @@ public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Dir } @Override - public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to, double timeout) { + public byte[] bLMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to, double timeout) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -163,7 +169,7 @@ public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Di } @Override - public void lSet(byte[] key, long index, byte[] value) { + public void lSet(byte @NonNull [] key, long index, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -172,7 +178,7 @@ public void lSet(byte[] key, long index, byte[] value) { } @Override - public Long lRem(byte[] key, long count, byte[] value) { + public Long lRem(byte @NonNull [] key, long count, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -181,7 +187,7 @@ public Long lRem(byte[] key, long count, byte[] value) { } @Override - public byte[] lPop(byte[] key) { + public byte[] lPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -189,7 +195,7 @@ public byte[] lPop(byte[] key) { } @Override - public List lPop(byte[] key, long count) { + public List lPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -197,7 +203,7 @@ public List lPop(byte[] key, long count) { } @Override - public byte[] rPop(byte[] key) { + public byte[] rPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -205,7 +211,7 @@ public byte[] rPop(byte[] key) { } @Override - public List rPop(byte[] key, long count) { + public List rPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -213,7 +219,7 @@ public List rPop(byte[] key, long count) { } @Override - public List bLPop(int timeout, byte[]... keys) { + public List bLPop(int timeout, byte @NonNull []... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -222,7 +228,7 @@ public List bLPop(int timeout, byte[]... keys) { } @Override - public List bRPop(int timeout, byte[]... keys) { + public List bRPop(int timeout, byte @NonNull []... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -231,7 +237,7 @@ public List bRPop(int timeout, byte[]... keys) { } @Override - public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { + public byte[] rPopLPush(byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -240,7 +246,7 @@ public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { } @Override - public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { + public byte[] bRPopLPush(int timeout, byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java index 16b1483103..30466ea2fa 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisResult.java @@ -19,9 +19,9 @@ import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.FutureResult; -import org.springframework.lang.Nullable; /** * Jedis specific {@link FutureResult} implementation.
diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java index 0398623c5e..34b13dc2d5 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptReturnConverter.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.ReturnType; -import org.springframework.lang.Nullable; /** * Converts the value returned by Jedis script eval to the expected {@link ReturnType} @@ -35,8 +35,8 @@ public JedisScriptReturnConverter(ReturnType returnType) { this.returnType = returnType; } - @SuppressWarnings("unchecked") - public Object convert(@Nullable Object result) { + @SuppressWarnings({ "unchecked", "NullAway" }) + public @Nullable Object convert(@Nullable Object result) { if (result instanceof String stringResult) { // evalsha converts byte[] to String. Convert back for consistency return JedisConverters.toBytes(stringResult); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java index 5f7b76d592..0127870471 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java @@ -20,6 +20,8 @@ import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisScriptingCommands; import org.springframework.data.redis.connection.ReturnType; import org.springframework.util.Assert; @@ -29,12 +31,13 @@ * @author Ivan Kripakov * @since 2.0 */ +@NullUnmarked class JedisScriptingCommands implements RedisScriptingCommands { private static final byte[] SAMPLE_KEY = new byte[0]; private final JedisConnection connection; - JedisScriptingCommands(JedisConnection connection) { + JedisScriptingCommands(@NonNull JedisConnection connection) { this.connection = connection; } @@ -49,7 +52,7 @@ public void scriptKill() { } @Override - public String scriptLoad(byte[] script) { + public String scriptLoad(byte @NonNull [] script) { Assert.notNull(script, "Script must not be null"); @@ -58,7 +61,7 @@ public String scriptLoad(byte[] script) { } @Override - public List scriptExists(String... scriptSha1) { + public List<@NonNull Boolean> scriptExists(@NonNull String @NonNull... scriptSha1) { Assert.notNull(scriptSha1, "Script digests must not be null"); Assert.noNullElements(scriptSha1, "Script digests must not contain null elements"); @@ -73,7 +76,8 @@ public List scriptExists(String... scriptSha1) { @Override @SuppressWarnings("unchecked") - public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T eval(byte @NonNull [] script, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(script, "Script must not be null"); @@ -84,21 +88,22 @@ public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... k } @Override - public T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(@NonNull String scriptSha1, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { return evalSha(JedisConverters.toBytes(scriptSha1), returnType, numKeys, keysAndArgs); } @Override @SuppressWarnings("unchecked") - public T evalSha(byte[] scriptSha, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(byte @NonNull [] scriptSha, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(scriptSha, "Script digest must not be null"); JedisScriptReturnConverter converter = new JedisScriptReturnConverter(returnType); return (T) connection.invoke() .from(Jedis::evalsha, ScriptingKeyPipelineBinaryCommands::evalsha, scriptSha, numKeys, keysAndArgs) - .getOrElse(converter, () -> converter.convert(null) - ); + .getOrElse(converter, () -> converter.convert(null)); } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSentinelConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSentinelConnection.java index 15dcb28db0..0fcd36619f 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSentinelConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSentinelConnection.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection.jedis; +import org.jspecify.annotations.Nullable; +import org.springframework.lang.Contract; import redis.clients.jedis.Jedis; import java.io.IOException; @@ -36,7 +38,11 @@ public class JedisSentinelConnection implements RedisSentinelConnection { private Jedis jedis; public JedisSentinelConnection(RedisNode sentinel) { - this(sentinel.getHost(), sentinel.getPort()); + + Assert.notNull(sentinel.getHost(), "Sentinel.getHost() must not be null"); + Assert.notNull(sentinel.getPort(), "Sentinel.getHost() must not be null"); + + this.jedis = new Jedis(sentinel.getHost(), sentinel.getPort()); } public JedisSentinelConnection(String host, int port) { @@ -67,6 +73,8 @@ public List masters() { public List replicas(NamedNode master) { Assert.notNull(master, "Master node cannot be 'null' when loading replicas"); + Assert.notNull(master.getName(), "Master node cannot be 'null' when loading replicas"); + return replicas(master.getName()); } @@ -92,7 +100,8 @@ public void remove(NamedNode master) { * @param masterName * @see RedisSentinelCommands#remove(NamedNode) */ - public void remove(String masterName) { + @Contract("null -> fail") + public void remove(@Nullable String masterName) { Assert.hasText(masterName, "Name of redis master cannot be 'null' or empty when trying to remove"); jedis.sentinelRemove(masterName); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java index a7e0feca2b..0181c55a1c 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java @@ -22,11 +22,13 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.types.RedisClientInfo; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -34,11 +36,12 @@ * @author Dennis Neufeld * @since 2.0 */ +@NullUnmarked class JedisServerCommands implements RedisServerCommands { private final JedisConnection connection; - JedisServerCommands(JedisConnection connection) { + JedisServerCommands(@NonNull JedisConnection connection) { this.connection = connection; } @@ -73,7 +76,7 @@ public void flushDb() { } @Override - public void flushDb(FlushOption option) { + public void flushDb(@NonNull FlushOption option) { connection.invokeStatus().just(j -> j.flushDB(JedisConverters.toFlushMode(option))); } @@ -83,7 +86,7 @@ public void flushAll() { } @Override - public void flushAll(FlushOption option) { + public void flushAll(@NonNull FlushOption option) { connection.invokeStatus().just(j -> j.flushAll(JedisConverters.toFlushMode(option))); } @@ -93,7 +96,7 @@ public Properties info() { } @Override - public Properties info(String section) { + public Properties info(@NonNull String section) { Assert.notNull(section, "Section must not be null"); @@ -109,7 +112,7 @@ public void shutdown() { } @Override - public void shutdown(ShutdownOption option) { + public void shutdown(@Nullable ShutdownOption option) { if (option == null) { shutdown(); @@ -122,7 +125,7 @@ public void shutdown(ShutdownOption option) { } @Override - public Properties getConfig(String pattern) { + public Properties getConfig(@NonNull String pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -130,7 +133,7 @@ public Properties getConfig(String pattern) { } @Override - public void setConfig(String param, String value) { + public void setConfig(@NonNull String param, @NonNull String value) { Assert.notNull(param, "Parameter must not be null"); Assert.notNull(value, "Value must not be null"); @@ -149,7 +152,7 @@ public void rewriteConfig() { } @Override - public Long time(TimeUnit timeUnit) { + public Long time(@NonNull TimeUnit timeUnit) { Assert.notNull(timeUnit, "TimeUnit must not be null"); @@ -157,7 +160,7 @@ public Long time(TimeUnit timeUnit) { } @Override - public void killClient(String host, int port) { + public void killClient(@NonNull String host, int port) { Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'"); @@ -165,7 +168,7 @@ public void killClient(String host, int port) { } @Override - public void setClientName(byte[] name) { + public void setClientName(byte @NonNull [] name) { Assert.notNull(name, "Name must not be null"); @@ -178,12 +181,12 @@ public String getClientName() { } @Override - public List getClientList() { + public List<@NonNull RedisClientInfo> getClientList() { return connection.invokeStatus().from(Jedis::clientList).get(JedisConverters::toListOfRedisClientInformation); } @Override - public void replicaOf(String host, int port) { + public void replicaOf(@NonNull String host, int port) { Assert.hasText(host, "Host must not be null for 'REPLICAOF' command"); @@ -196,12 +199,13 @@ public void replicaOfNoOne() { } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option) { migrate(key, target, dbIndex, option, Long.MAX_VALUE); } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option, + long timeout) { Assert.notNull(key, "Key must not be null"); Assert.notNull(target, "Target node must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java index c2521b82db..ed5aca3b80 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSetCommands.java @@ -24,6 +24,8 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisSetCommands; import org.springframework.data.redis.core.Cursor; @@ -38,16 +40,17 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class JedisSetCommands implements RedisSetCommands { private final JedisConnection connection; - JedisSetCommands(JedisConnection connection) { + JedisSetCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Long sAdd(byte[] key, byte[]... values) { + public Long sAdd(byte @NonNull [] key, byte @NonNull []... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -57,7 +60,7 @@ public Long sAdd(byte[] key, byte[]... values) { } @Override - public Long sCard(byte[] key) { + public Long sCard(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -65,7 +68,7 @@ public Long sCard(byte[] key) { } @Override - public Set sDiff(byte[]... keys) { + public Set sDiff(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -74,7 +77,7 @@ public Set sDiff(byte[]... keys) { } @Override - public Long sDiffStore(byte[] destKey, byte[]... keys) { + public Long sDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -84,7 +87,7 @@ public Long sDiffStore(byte[] destKey, byte[]... keys) { } @Override - public Set sInter(byte[]... keys) { + public Set sInter(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -93,7 +96,7 @@ public Set sInter(byte[]... keys) { } @Override - public Long sInterStore(byte[] destKey, byte[]... keys) { + public Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -103,7 +106,7 @@ public Long sInterStore(byte[] destKey, byte[]... keys) { } @Override - public Boolean sIsMember(byte[] key, byte[] value) { + public Boolean sIsMember(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -112,7 +115,7 @@ public Boolean sIsMember(byte[] key, byte[] value) { } @Override - public List sMIsMember(byte[] key, byte[]... values) { + public List<@NonNull Boolean> sMIsMember(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -122,7 +125,7 @@ public List sMIsMember(byte[] key, byte[]... values) { } @Override - public Set sMembers(byte[] key) { + public Set sMembers(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -130,7 +133,7 @@ public Set sMembers(byte[] key) { } @Override - public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { + public Boolean sMove(byte @NonNull [] srcKey, byte @NonNull [] destKey, byte @NonNull [] value) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(destKey, "Destination key must not be null"); @@ -141,7 +144,7 @@ public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { } @Override - public byte[] sPop(byte[] key) { + public byte[] sPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -149,7 +152,7 @@ public byte[] sPop(byte[] key) { } @Override - public List sPop(byte[] key, long count) { + public List sPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -157,7 +160,7 @@ public List sPop(byte[] key, long count) { } @Override - public byte[] sRandMember(byte[] key) { + public byte[] sRandMember(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -165,7 +168,7 @@ public byte[] sRandMember(byte[] key) { } @Override - public List sRandMember(byte[] key, long count) { + public List sRandMember(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -177,7 +180,7 @@ public List sRandMember(byte[] key, long count) { } @Override - public Long sRem(byte[] key, byte[]... values) { + public Long sRem(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -187,7 +190,7 @@ public Long sRem(byte[] key, byte[]... values) { } @Override - public Set sUnion(byte[]... keys) { + public Set sUnion(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -196,7 +199,7 @@ public Set sUnion(byte[]... keys) { } @Override - public Long sUnionStore(byte[] destKey, byte[]... keys) { + public Long sUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -206,7 +209,7 @@ public Long sUnionStore(byte[] destKey, byte[]... keys) { } @Override - public Cursor sScan(byte[] key, ScanOptions options) { + public Cursor sScan(byte @NonNull [] key, @NonNull ScanOptions options) { return sScan(key, CursorId.initial(), options); } @@ -217,14 +220,16 @@ public Cursor sScan(byte[] key, ScanOptions options) { * @return * @since 3.2.1 */ - public Cursor sScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor sScan(byte @NonNull [] key, @NonNull CursorId cursorId, + @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); return new KeyBoundCursor(key, cursorId, options) { @Override - protected ScanIteration doScan(byte[] key, CursorId cursorId, ScanOptions options) { + protected ScanIteration doScan(byte @NonNull [] key, @NonNull CursorId cursorId, + @NonNull ScanOptions options) { if (isQueueing() || isPipelined()) { throw new InvalidDataAccessApiUsageException("'SSCAN' cannot be called in pipeline / transaction mode"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStreamCommands.java index 483b299c9c..7e46fee2f7 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStreamCommands.java @@ -32,6 +32,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.RedisStreamCommands; @@ -52,16 +54,17 @@ * @author Dengliming * @since 2.3 */ +@NullUnmarked class JedisStreamCommands implements RedisStreamCommands { private final JedisConnection connection; - JedisStreamCommands(JedisConnection connection) { + JedisStreamCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Long xAck(byte[] key, String group, RecordId... recordIds) { + public Long xAck(byte @NonNull [] key, @NonNull String group, @NonNull RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.hasText(group, "Group name must not be null or empty"); @@ -72,7 +75,7 @@ public Long xAck(byte[] key, String group, RecordId... recordIds) { } @Override - public RecordId xAdd(MapRecord record, XAddOptions options) { + public RecordId xAdd(@NonNull MapRecord record, @NonNull XAddOptions options) { Assert.notNull(record, "Record must not be null"); Assert.notNull(record.getStream(), "Stream must not be null"); @@ -85,7 +88,8 @@ public RecordId xAdd(MapRecord record, XAddOptions optio } @Override - public List xClaimJustId(byte[] key, String group, String newOwner, XClaimOptions options) { + public List<@NonNull RecordId> xClaimJustId(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options) { Assert.notNull(key, "Key must not be null"); Assert.notNull(group, "Group must not be null"); @@ -101,7 +105,8 @@ public List xClaimJustId(byte[] key, String group, String newOwner, XC } @Override - public List xClaim(byte[] key, String group, String newOwner, XClaimOptions options) { + public List<@NonNull ByteRecord> xClaim(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options) { Assert.notNull(key, "Key must not be null"); Assert.notNull(group, "Group must not be null"); @@ -117,7 +122,7 @@ public List xClaim(byte[] key, String group, String newOwner, XClaim } @Override - public Long xDel(byte[] key, RecordId... recordIds) { + public Long xDel(byte @NonNull [] key, @NonNull RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.notNull(recordIds, "recordIds must not be null"); @@ -127,12 +132,13 @@ public Long xDel(byte[] key, RecordId... recordIds) { } @Override - public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset) { + public String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset) { return xGroupCreate(key, groupName, readOffset, false); } @Override - public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, boolean mkStream) { + public String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset, + boolean mkStream) { Assert.notNull(key, "Key must not be null"); Assert.hasText(groupName, "Group name must not be null or empty"); @@ -143,7 +149,7 @@ public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, } @Override - public Boolean xGroupDelConsumer(byte[] key, Consumer consumer) { + public Boolean xGroupDelConsumer(byte @NonNull [] key, @NonNull Consumer consumer) { Assert.notNull(key, "Key must not be null"); Assert.notNull(consumer, "Consumer must not be null"); @@ -153,7 +159,7 @@ public Boolean xGroupDelConsumer(byte[] key, Consumer consumer) { } @Override - public Boolean xGroupDestroy(byte[] key, String groupName) { + public Boolean xGroupDestroy(byte @NonNull [] key, @NonNull String groupName) { Assert.notNull(key, "Key must not be null"); Assert.hasText(groupName, "Group name must not be null or empty"); @@ -164,7 +170,7 @@ public Boolean xGroupDestroy(byte[] key, String groupName) { } @Override - public StreamInfo.XInfoStream xInfo(byte[] key) { + public StreamInfo.XInfoStream xInfo(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -175,7 +181,7 @@ public StreamInfo.XInfoStream xInfo(byte[] key) { } @Override - public StreamInfo.XInfoGroups xInfoGroups(byte[] key) { + public StreamInfo.XInfoGroups xInfoGroups(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -189,7 +195,7 @@ public StreamInfo.XInfoGroups xInfoGroups(byte[] key) { } @Override - public StreamInfo.XInfoConsumers xInfoConsumers(byte[] key, String groupName) { + public StreamInfo.XInfoConsumers xInfoConsumers(byte @NonNull [] key, @NonNull String groupName) { Assert.notNull(key, "Key must not be null"); Assert.hasText(groupName, "Group name must not be null or empty"); @@ -206,7 +212,7 @@ public StreamInfo.XInfoConsumers xInfoConsumers(byte[] key, String groupName) { } @Override - public Long xLen(byte[] key) { + public Long xLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -214,7 +220,7 @@ public Long xLen(byte[] key) { } @Override - public PendingMessagesSummary xPending(byte[] key, String groupName) { + public PendingMessagesSummary xPending(byte @NonNull [] key, @NonNull String groupName) { Assert.notNull(key, "Key must not be null"); @@ -224,7 +230,7 @@ public PendingMessagesSummary xPending(byte[] key, String groupName) { } @Override - public PendingMessages xPending(byte[] key, String groupName, XPendingOptions options) { + public PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull XPendingOptions options) { Assert.notNull(key, "Key must not be null"); Assert.notNull(groupName, "GroupName must not be null"); @@ -239,7 +245,7 @@ public PendingMessages xPending(byte[] key, String groupName, XPendingOptions op } @Override - public List xRange(byte[] key, Range range, Limit limit) { + public List<@NonNull ByteRecord> xRange(byte @NonNull [] key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -255,7 +261,8 @@ public List xRange(byte[] key, Range range, Limit limit) { } @Override - public List xRead(StreamReadOptions readOptions, StreamOffset... streams) { + public List<@NonNull ByteRecord> xRead(@NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { Assert.notNull(readOptions, "StreamReadOptions must not be null"); Assert.notNull(streams, "StreamOffsets must not be null"); @@ -268,8 +275,8 @@ public List xRead(StreamReadOptions readOptions, StreamOffset xReadGroup(Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams) { + public List<@NonNull ByteRecord> xReadGroup(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset... streams) { Assert.notNull(consumer, "Consumer must not be null"); Assert.notNull(readOptions, "StreamReadOptions must not be null"); @@ -284,7 +291,7 @@ public List xReadGroup(Consumer consumer, StreamReadOptions readOpti } @Override - public List xRevRange(byte[] key, Range range, Limit limit) { + public List<@NonNull ByteRecord> xRevRange(byte @NonNull [] key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -299,12 +306,12 @@ public List xRevRange(byte[] key, Range range, Limit limit) } @Override - public Long xTrim(byte[] key, long count) { + public Long xTrim(byte @NonNull [] key, long count) { return xTrim(key, count, false); } @Override - public Long xTrim(byte[] key, long count, boolean approximateTrimming) { + public Long xTrim(byte @NonNull [] key, long count, boolean approximateTrimming) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java index 392591e36a..dcc55f36cd 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java @@ -23,12 +23,14 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.RedisStringCommands; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -38,6 +40,7 @@ * @author Marcin Grzejszczak * @since 2.0 */ +@NullUnmarked class JedisStringCommands implements RedisStringCommands { private final JedisConnection connection; @@ -47,25 +50,23 @@ class JedisStringCommands implements RedisStringCommands { } @Override - public byte[] get(byte[] key) { + public byte[] get(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(Jedis::get, PipelineBinaryCommands::get, key); } - @Nullable @Override - public byte[] getDel(byte[] key) { + public byte[] getDel(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(Jedis::getDel, PipelineBinaryCommands::getDel, key); } - @Nullable @Override - public byte[] getEx(byte[] key, Expiration expiration) { + public byte[] getEx(byte @NonNull [] key, @NonNull Expiration expiration) { Assert.notNull(key, "Key must not be null"); Assert.notNull(expiration, "Expiration must not be null"); @@ -75,7 +76,7 @@ public byte[] getEx(byte[] key, Expiration expiration) { } @Override - public byte[] getSet(byte[] key, byte[] value) { + public byte[] getSet(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -84,7 +85,7 @@ public byte[] getSet(byte[] key, byte[] value) { } @Override - public List mGet(byte[]... keys) { + public List mGet(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -93,7 +94,7 @@ public List mGet(byte[]... keys) { } @Override - public Boolean set(byte[] key, byte[] value) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -103,7 +104,8 @@ public Boolean set(byte[] key, byte[] value) { } @Override - public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -118,8 +120,8 @@ public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption op } @Override - @Nullable - public byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public byte @Nullable [] setGet(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -133,7 +135,7 @@ public byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption } @Override - public Boolean setNX(byte[] key, byte[] value) { + public Boolean setNX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -143,7 +145,7 @@ public Boolean setNX(byte[] key, byte[] value) { } @Override - public Boolean setEx(byte[] key, long seconds, byte[] value) { + public Boolean setEx(byte @NonNull [] key, long seconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -157,7 +159,7 @@ public Boolean setEx(byte[] key, long seconds, byte[] value) { } @Override - public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { + public Boolean pSetEx(byte @NonNull [] key, long milliseconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -167,7 +169,7 @@ public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { } @Override - public Boolean mSet(Map tuples) { + public Boolean mSet(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -176,7 +178,7 @@ public Boolean mSet(Map tuples) { } @Override - public Boolean mSetNX(Map tuples) { + public Boolean mSetNX(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -185,7 +187,7 @@ public Boolean mSetNX(Map tuples) { } @Override - public Long incr(byte[] key) { + public Long incr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -193,7 +195,7 @@ public Long incr(byte[] key) { } @Override - public Long incrBy(byte[] key, long value) { + public Long incrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -201,7 +203,7 @@ public Long incrBy(byte[] key, long value) { } @Override - public Double incrBy(byte[] key, double value) { + public Double incrBy(byte @NonNull [] key, double value) { Assert.notNull(key, "Key must not be null"); @@ -209,7 +211,7 @@ public Double incrBy(byte[] key, double value) { } @Override - public Long decr(byte[] key) { + public Long decr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -217,7 +219,7 @@ public Long decr(byte[] key) { } @Override - public Long decrBy(byte[] key, long value) { + public Long decrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -225,7 +227,7 @@ public Long decrBy(byte[] key, long value) { } @Override - public Long append(byte[] key, byte[] value) { + public Long append(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -234,7 +236,7 @@ public Long append(byte[] key, byte[] value) { } @Override - public byte[] getRange(byte[] key, long start, long end) { + public byte[] getRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -242,7 +244,7 @@ public byte[] getRange(byte[] key, long start, long end) { } @Override - public void setRange(byte[] key, byte[] value, long offset) { + public void setRange(byte @NonNull [] key, byte @NonNull [] value, long offset) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -251,7 +253,7 @@ public void setRange(byte[] key, byte[] value, long offset) { } @Override - public Boolean getBit(byte[] key, long offset) { + public Boolean getBit(byte @NonNull [] key, long offset) { Assert.notNull(key, "Key must not be null"); @@ -259,7 +261,7 @@ public Boolean getBit(byte[] key, long offset) { } @Override - public Boolean setBit(byte[] key, long offset, boolean value) { + public Boolean setBit(byte @NonNull [] key, long offset, boolean value) { Assert.notNull(key, "Key must not be null"); @@ -267,7 +269,7 @@ public Boolean setBit(byte[] key, long offset, boolean value) { } @Override - public Long bitCount(byte[] key) { + public Long bitCount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -275,7 +277,7 @@ public Long bitCount(byte[] key) { } @Override - public Long bitCount(byte[] key, long start, long end) { + public Long bitCount(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -283,7 +285,7 @@ public Long bitCount(byte[] key, long start, long end) { } @Override - public List bitField(byte[] key, BitFieldSubCommands subCommands) { + public List bitField(byte @NonNull [] key, @NonNull BitFieldSubCommands subCommands) { Assert.notNull(key, "Key must not be null"); Assert.notNull(subCommands, "Command must not be null"); @@ -293,7 +295,7 @@ public List bitField(byte[] key, BitFieldSubCommands subCommands) { } @Override - public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { + public Long bitOp(@NonNull BitOperation op, byte @NonNull [] destination, byte @NonNull [] @NonNull... keys) { Assert.notNull(op, "BitOperation must not be null"); Assert.notNull(destination, "Destination key must not be null"); @@ -306,9 +308,8 @@ public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { destination, keys); } - @Nullable @Override - public Long bitPos(byte[] key, boolean bit, Range range) { + public Long bitPos(byte @NonNull [] key, boolean bit, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null Use Range.unbounded() instead"); @@ -326,7 +327,7 @@ public Long bitPos(byte[] key, boolean bit, Range range) { } @Override - public Long strLen(byte[] key) { + public Long strLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSubscription.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSubscription.java index 6d34e4628d..105cba99c1 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisSubscription.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisSubscription.java @@ -16,10 +16,9 @@ package org.springframework.data.redis.connection.jedis; import redis.clients.jedis.BinaryJedisPubSub; - +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.util.AbstractSubscription; -import org.springframework.lang.Nullable; /** * Jedis specific subscription. @@ -30,8 +29,8 @@ class JedisSubscription extends AbstractSubscription { private final BinaryJedisPubSub jedisPubSub; - JedisSubscription(MessageListener listener, BinaryJedisPubSub jedisPubSub, @Nullable byte[][] channels, - @Nullable byte[][] patterns) { + JedisSubscription(MessageListener listener, BinaryJedisPubSub jedisPubSub, byte @Nullable[][] channels, + byte @Nullable[][] patterns) { super(listener, channels, patterns); this.jedisPubSub = jedisPubSub; } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java index e3cef50537..b71fe11011 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java @@ -29,6 +29,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.zset.Aggregate; @@ -39,7 +42,6 @@ import org.springframework.data.redis.core.KeyBoundCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -53,16 +55,17 @@ * @author John Blum * @since 2.0 */ +@NullUnmarked class JedisZSetCommands implements RedisZSetCommands { private final JedisConnection connection; - JedisZSetCommands(JedisConnection connection) { + JedisZSetCommands(@NonNull JedisConnection connection) { this.connection = connection; } @Override - public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { + public Boolean zAdd(byte @NonNull [] key, double score, byte @NonNull [] value, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -73,7 +76,7 @@ public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { } @Override - public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { + public Long zAdd(byte @NonNull [] key, @NonNull Set<@NonNull Tuple> tuples, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(tuples, "Tuples must not be null"); @@ -85,7 +88,7 @@ public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { } @Override - public Long zRem(byte[] key, byte[]... values) { + public Long zRem(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -95,7 +98,7 @@ public Long zRem(byte[] key, byte[]... values) { } @Override - public Double zIncrBy(byte[] key, double increment, byte[] value) { + public Double zIncrBy(byte @NonNull [] key, double increment, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -104,7 +107,7 @@ public Double zIncrBy(byte[] key, double increment, byte[] value) { } @Override - public byte[] zRandMember(byte[] key) { + public byte[] zRandMember(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -112,7 +115,7 @@ public byte[] zRandMember(byte[] key) { } @Override - public List zRandMember(byte[] key, long count) { + public List zRandMember(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -120,7 +123,7 @@ public List zRandMember(byte[] key, long count) { } @Override - public Tuple zRandMemberWithScore(byte[] key) { + public Tuple zRandMemberWithScore(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -136,7 +139,7 @@ public Tuple zRandMemberWithScore(byte[] key) { } @Override - public List zRandMemberWithScore(byte[] key, long count) { + public List<@NonNull Tuple> zRandMemberWithScore(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -146,7 +149,7 @@ public List zRandMemberWithScore(byte[] key, long count) { } @Override - public Long zRank(byte[] key, byte[] value) { + public Long zRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -155,7 +158,7 @@ public Long zRank(byte[] key, byte[] value) { } @Override - public Long zRevRank(byte[] key, byte[] value) { + public Long zRevRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); @@ -163,7 +166,7 @@ public Long zRevRank(byte[] key, byte[] value) { } @Override - public Set zRange(byte[] key, long start, long end) { + public Set<@NonNull byte[]> zRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -171,7 +174,7 @@ public Set zRange(byte[] key, long start, long end) { } @Override - public Set zRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -181,8 +184,9 @@ public Set zRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null"); @@ -205,7 +209,7 @@ public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.d } @Override - public Set zRevRange(byte[] key, long start, long end) { + public Set zRevRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -213,7 +217,7 @@ public Set zRevRange(byte[] key, long start, long end) { } @Override - public Set zRevRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRevRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -223,8 +227,9 @@ public Set zRevRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRevRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREVRANGEBYSCORE must not be null"); @@ -245,9 +250,9 @@ public Set zRevRangeByScore(byte[] key, org.springframework.data.domain. } @Override - public Set zRevRangeByScoreWithScores(byte[] key, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREVRANGEBYSCOREWITHSCORES must not be null"); @@ -270,7 +275,7 @@ public Set zRevRangeByScoreWithScores(byte[] key, } @Override - public Long zCount(byte[] key, double min, double max) { + public Long zCount(byte @NonNull [] key, double min, double max) { Assert.notNull(key, "Key must not be null"); @@ -278,7 +283,7 @@ public Long zCount(byte[] key, double min, double max) { } @Override - public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -292,7 +297,7 @@ public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zLexCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -303,18 +308,16 @@ public Long zLexCount(byte[] key, org.springframework.data.domain.Range return connection.invoke().just(Jedis::zlexcount, PipelineBinaryCommands::zlexcount, key, min, max); } - @Nullable @Override - public Tuple zPopMin(byte[] key) { + public Tuple zPopMin(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(Jedis::zpopmin, PipelineBinaryCommands::zpopmin, key).get(JedisConverters::toTuple); } - @Nullable @Override - public Set zPopMin(byte[] key, long count) { + public Set zPopMin(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -322,9 +325,8 @@ public Set zPopMin(byte[] key, long count) { .toSet(JedisConverters::toTuple); } - @Nullable @Override - public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMin(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -334,18 +336,16 @@ public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { .get(JedisZSetCommands::toTuple); } - @Nullable @Override - public Tuple zPopMax(byte[] key) { + public Tuple zPopMax(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(Jedis::zpopmax, PipelineBinaryCommands::zpopmax, key).get(JedisConverters::toTuple); } - @Nullable @Override - public Set zPopMax(byte[] key, long count) { + public Set<@NonNull Tuple> zPopMax(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -353,9 +353,8 @@ public Set zPopMax(byte[] key, long count) { .toSet(JedisConverters::toTuple); } - @Nullable @Override - public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMax(byte @NonNull [] key, long timeout, @NonNull TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -366,7 +365,7 @@ public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { } @Override - public Long zCard(byte[] key) { + public Long zCard(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -374,7 +373,7 @@ public Long zCard(byte[] key) { } @Override - public Double zScore(byte[] key, byte[] value) { + public Double zScore(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -383,7 +382,7 @@ public Double zScore(byte[] key, byte[] value) { } @Override - public List zMScore(byte[] key, byte[][] values) { + public List<@NonNull Double> zMScore(byte @NonNull [] key, byte @NonNull [] @NonNull [] values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Value must not be null"); @@ -392,7 +391,7 @@ public List zMScore(byte[] key, byte[][] values) { } @Override - public Long zRemRange(byte[] key, long start, long end) { + public Long zRemRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -400,7 +399,7 @@ public Long zRemRange(byte[] key, long start, long end) { } @Override - public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByLex(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX"); @@ -412,7 +411,8 @@ public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREMRANGEBYSCORE must not be null"); @@ -426,7 +426,7 @@ public Long zRemRangeByScore(byte[] key, org.springframework.data.domain.Range zDiff(byte[]... sets) { + public Set zDiff(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -434,7 +434,7 @@ public Set zDiff(byte[]... sets) { } @Override - public Set zDiffWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zDiffWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -443,7 +443,7 @@ public Set zDiffWithScores(byte[]... sets) { } @Override - public Long zDiffStore(byte[] destKey, byte[]... sets) { + public Long zDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -452,7 +452,7 @@ public Long zDiffStore(byte[] destKey, byte[]... sets) { } @Override - public Set zInter(byte[]... sets) { + public Set zInter(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -460,7 +460,7 @@ public Set zInter(byte[]... sets) { } @Override - public Set zInterWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -470,7 +470,8 @@ public Set zInterWithScores(byte[]... sets) { } @Override - public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -482,7 +483,8 @@ public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -496,7 +498,7 @@ public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Long zInterStore(byte[] destKey, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -506,7 +508,7 @@ public Long zInterStore(byte[] destKey, byte[]... sets) { } @Override - public Set zUnion(byte[]... sets) { + public Set zUnion(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -514,7 +516,7 @@ public Set zUnion(byte[]... sets) { } @Override - public Set zUnionWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -524,7 +526,8 @@ public Set zUnionWithScores(byte[]... sets) { } @Override - public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -536,7 +539,8 @@ public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -551,7 +555,7 @@ public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Long zUnionStore(byte[] destKey, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -561,11 +565,10 @@ public Long zUnionStore(byte[] destKey, byte[]... sets) { } @Override - public Cursor zScan(byte[] key, ScanOptions options) { + public Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @NonNull ScanOptions options) { return zScan(key, CursorId.initial(), options); } - /** * @param key * @param cursorId @@ -573,14 +576,15 @@ public Cursor zScan(byte[] key, ScanOptions options) { * @return * @since 3.2.1 */ - public Cursor zScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @NonNull CursorId cursorId, @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); return new KeyBoundCursor(key, cursorId, options) { @Override - protected ScanIteration doScan(byte[] key, CursorId cursorId, ScanOptions options) { + protected ScanIteration doScan(byte @NonNull [] key, @NonNull CursorId cursorId, + @NonNull ScanOptions options) { if (isQueueing() || isPipelined()) { throw new InvalidDataAccessApiUsageException("'ZSCAN' cannot be called in pipeline / transaction mode"); @@ -603,7 +607,7 @@ protected void doClose() { } @Override - public Set zRangeByScore(byte[] key, String min, String max) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max) { Assert.notNull(key, "Key must not be null"); @@ -612,7 +616,8 @@ public Set zRangeByScore(byte[] key, String min, String max) { } @Override - public Set zRangeByScore(byte[] key, String min, String max, long offset, long count) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max, + long offset, long count) { Assert.notNull(key, "Key must not be null"); @@ -627,8 +632,9 @@ public Set zRangeByScore(byte[] key, String min, String max, long offset } @Override - public Set zRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null"); @@ -649,8 +655,9 @@ public Set zRangeByScore(byte[] key, org.springframework.data.domain.Ran } @Override - public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYLEX must not be null"); @@ -668,8 +675,9 @@ public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range } @Override - public Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREVRANGEBYLEX must not be null"); @@ -688,19 +696,22 @@ public Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Ra } @Override - public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByLex(dstKey, srcKey, range, limit, false); } @Override - public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByLex(dstKey, srcKey, range, limit, true); } - private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit, boolean rev) { + private Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit, boolean rev) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -717,22 +728,22 @@ private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework. } @Override - public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByScore(dstKey, srcKey, range, limit, false); } @Override - public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { return zRangeStoreByScore(dstKey, srcKey, range, limit, true); } - private Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit, boolean rev) { + private Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit, boolean rev) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -779,8 +790,7 @@ static ZRangeParams toZRangeParams(Protocol.Keyword by, byte[] min, byte[] max, return zRangeParams; } - @Nullable - private static Tuple toTuple(@Nullable KeyValue keyValue) { + private @Nullable static Tuple toTuple(@Nullable KeyValue keyValue) { return keyValue != null ? JedisConverters.toTuple(keyValue.getValue()) : null; } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/StreamConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/StreamConverters.java index a68eef451a..70419185f0 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/StreamConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/StreamConverters.java @@ -35,6 +35,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.RedisStreamCommands; import org.springframework.data.redis.connection.stream.ByteRecord; @@ -160,12 +161,10 @@ static PendingMessagesSummary toPendingMessagesSummary(String groupName, Object List objectList = (List) source; long total = BuilderFactory.LONG.build(objectList.get(0)); - Range.Bound lower = objectList.get(1) != null - ? Range.Bound.inclusive(JedisConverters.toString((byte[]) objectList.get(1))) - : Range.Bound.unbounded(); - Range.Bound upper = objectList.get(2) != null - ? Range.Bound.inclusive(JedisConverters.toString((byte[]) objectList.get(2))) - : Range.Bound.unbounded(); + + Range.Bound lower = boundOf(objectList.get(1)); + Range.Bound upper = boundOf(objectList.get(2)); + List> consumerObjList = (List>) objectList.get(3); Map map; @@ -182,6 +181,10 @@ static PendingMessagesSummary toPendingMessagesSummary(String groupName, Object return new PendingMessagesSummary(groupName, total, Range.of(lower, upper), map); } + static Range.Bound boundOf(@Nullable Object o) { + return o instanceof byte[] bytes ? Range.Bound.inclusive(JedisConverters.toString(bytes)) : Range.Bound.unbounded(); + } + /** * Convert the raw Jedis {@code xpending} result to {@link PendingMessages}. * @@ -202,6 +205,7 @@ static org.springframework.data.redis.connection.stream.PendingMessages toPendin return new PendingMessages(groupName, messages).withinRange(range); } + @SuppressWarnings("NullAway") public static XAddParams toXAddParams(RecordId recordId, RedisStreamCommands.XAddOptions options) { XAddParams params = new XAddParams(); @@ -262,6 +266,7 @@ public static XClaimParams toXClaimParams(RedisStreamCommands.XClaimOptions opti return params; } + @SuppressWarnings("NullAway") public static XReadParams toXReadParams(StreamReadOptions readOptions) { XReadParams params = XReadParams.xReadParams(); @@ -277,6 +282,7 @@ public static XReadParams toXReadParams(StreamReadOptions readOptions) { return params; } + @SuppressWarnings("NullAway") public static XReadGroupParams toXReadGroupParams(StreamReadOptions readOptions) { XReadGroupParams params = XReadGroupParams.xReadGroupParams(); @@ -301,7 +307,7 @@ public static XPendingParams toXPendingParams(RedisStreamCommands.XPendingOption Range range = (Range) options.getRange(); XPendingParams xPendingParams = XPendingParams.xPendingParams(StreamConverters.getLowerValue(range), - StreamConverters.getUpperValue(range), options.getCount().intValue()); + StreamConverters.getUpperValue(range), options.getCount() != null ? options.getCount().intValue() : 0); if (options.hasConsumer()) { xPendingParams.consumer(options.getConsumerName()); diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/package-info.java b/src/main/java/org/springframework/data/redis/connection/jedis/package-info.java index c32ac1cab1..e380909792 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/package-info.java @@ -1,6 +1,5 @@ /** * Connection package for Jedis library. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection.jedis; diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java index 60564519fa..0cfe3e3ac1 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java @@ -28,8 +28,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -47,8 +47,7 @@ class ClusterConnectionProvider implements LettuceConnectionProvider, RedisClien private final Lock lock = new ReentrantLock(); - @Nullable - private final ReadFrom readFrom; + private @Nullable final ReadFrom readFrom; private final RedisClusterClient client; diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/DefaultLettuceClientConfiguration.java b/src/main/java/org/springframework/data/redis/connection/lettuce/DefaultLettuceClientConfiguration.java index 787e278d95..0df6bbcb2e 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/DefaultLettuceClientConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/DefaultLettuceClientConfiguration.java @@ -23,7 +23,7 @@ import java.time.Duration; import java.util.Optional; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Default implementation of {@literal LettuceClientConfiguration}. diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceByteBufferPubSubListenerWrapper.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceByteBufferPubSubListenerWrapper.java index c4bdc997a2..24d43345bb 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceByteBufferPubSubListenerWrapper.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceByteBufferPubSubListenerWrapper.java @@ -19,8 +19,8 @@ import java.nio.ByteBuffer; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.java index 4cc752877d..5e69e968e5 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClientConfiguration.java @@ -26,7 +26,7 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java index 41a7cb94e1..0dcfc46d9a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java @@ -34,6 +34,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -47,7 +49,6 @@ import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -285,7 +286,7 @@ public String ping() { } @Override - public String ping(RedisClusterNode node) { + public @Nullable String ping(RedisClusterNode node) { return this.clusterCommandExecutor.executeCommandOnSingleNode(pingCommand(), node).getValue(); } @@ -306,9 +307,9 @@ public Set clusterGetReplicas(RedisClusterNode master) { RedisClusterNode nodeToUse = this.topologyProvider.getTopology().lookup(master); LettuceClusterCommandCallback> command = client -> - LettuceConverters.toSetOfRedisClusterNodes(client.clusterSlaves(nodeToUse.getId())); + LettuceConverters.toSetOfRedisClusterNodes(client.clusterReplicas(nodeToUse.getId())); - return this.clusterCommandExecutor.executeCommandOnSingleNode(command, master).getValue(); + return this.clusterCommandExecutor.executeCommandOnSingleNode(command, master).getRequiredValue(); } @Override @@ -317,7 +318,7 @@ public Map> clusterGetMasterRepli Set activeMasterNodes = this.topologyProvider.getTopology().getActiveMasterNodes(); LettuceClusterCommandCallback> command = client -> - Converters.toSetOfRedisClusterNodes(client.clusterSlaves(client.clusterMyId())); + Converters.toSetOfRedisClusterNodes(client.clusterReplicas(client.clusterMyId())); List>> nodeResults = this.clusterCommandExecutor.executeCommandAsyncOnNodes(command,activeMasterNodes).getResults(); @@ -336,9 +337,9 @@ public Integer clusterGetSlotForKey(byte[] key) { return SlotHash.getSlot(key); } - @Nullable + @Override - public RedisClusterNode clusterGetNodeForSlot(int slot) { + public @Nullable RedisClusterNode clusterGetNodeForSlot(int slot) { Set nodes = topologyProvider.getTopology().getSlotServingNodes(slot); @@ -346,12 +347,12 @@ public RedisClusterNode clusterGetNodeForSlot(int slot) { } @Override - public RedisClusterNode clusterGetNodeForKey(byte[] key) { + public @Nullable RedisClusterNode clusterGetNodeForKey(byte[] key) { return clusterGetNodeForSlot(clusterGetSlotForKey(key)); } @Override - public ClusterInfo clusterGetClusterInfo() { + public @Nullable ClusterInfo clusterGetClusterInfo() { LettuceClusterCommandCallback command = client -> new ClusterInfo(LettuceConverters.toProperties(client.clusterInfo())); @@ -467,7 +468,7 @@ public void clusterReplicate(RedisClusterNode master, RedisClusterNode replica) } @Override - public Set keys(RedisClusterNode node, byte[] pattern) { + public @Nullable Set keys(RedisClusterNode node, byte[] pattern) { return new LettuceClusterKeyCommands(this).keys(node, pattern); } @@ -476,7 +477,7 @@ public Cursor scan(RedisClusterNode node, ScanOptions options) { return new LettuceClusterKeyCommands(this).scan(node, options); } - public byte[] randomKey(RedisClusterNode node) { + public byte @Nullable [] randomKey(RedisClusterNode node) { return new LettuceClusterKeyCommands(this).randomKey(node); } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java index 09eabc950e..93a843a7f5 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java @@ -21,6 +21,9 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.RedisClusterNode; @@ -29,7 +32,6 @@ import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -37,18 +39,19 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceClusterKeyCommands extends LettuceKeyCommands { private final LettuceClusterConnection connection; - LettuceClusterKeyCommands(LettuceClusterConnection connection) { + LettuceClusterKeyCommands(@NonNull LettuceClusterConnection connection) { super(connection); this.connection = connection; } @Override - public void rename(byte[] oldKey, byte[] newKey) { + public void rename(byte @NonNull [] oldKey, byte @NonNull [] newKey) { Assert.notNull(oldKey, "Old key must not be null"); Assert.notNull(newKey, "New key must not be null"); @@ -68,7 +71,7 @@ public void rename(byte[] oldKey, byte[] newKey) { } @Override - public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { + public Boolean renameNX(byte @NonNull [] sourceKey, byte @NonNull [] targetKey) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(targetKey, "Target key must not be null"); @@ -89,20 +92,18 @@ public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { } @Override - public Boolean move(byte[] key, int dbIndex) { + public Boolean move(byte @NonNull [] key, int dbIndex) { throw new InvalidDataAccessApiUsageException("MOVE not supported in CLUSTER mode"); } - @Nullable - public byte[] randomKey(RedisClusterNode node) { + public byte @Nullable [] randomKey(@NonNull RedisClusterNode node) { return connection.getClusterCommandExecutor() .executeCommandOnSingleNode((LettuceClusterCommandCallback) client -> client.randomkey(), node) .getValue(); } - @Nullable - public Set keys(RedisClusterNode node, byte[] pattern) { + public Set keys(@NonNull RedisClusterNode node, byte @NonNull [] pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -119,7 +120,7 @@ public Set keys(RedisClusterNode node, byte[] pattern) { * @return never {@literal null}. * @since 2.1 */ - Cursor scan(RedisClusterNode node, ScanOptions options) { + Cursor scan(@NonNull RedisClusterNode node, @NonNull ScanOptions options) { Assert.notNull(node, "RedisClusterNode must not be null"); Assert.notNull(options, "Options must not be null"); @@ -144,7 +145,7 @@ protected LettuceScanIteration doScan(io.lettuce.core.ScanCursor cursor, } @Override - public Long sort(byte[] key, SortParameters params, byte[] storeKey) { + public Long sort(byte @NonNull [] key, @NonNull SortParameters params, byte @NonNull [] storeKey) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterListCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterListCommands.java index 9c27d41b64..1b7e4cb623 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterListCommands.java @@ -21,6 +21,8 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.lettuce.LettuceClusterConnection.LettuceMultiKeyClusterCommandCallback; import org.springframework.util.Assert; @@ -31,18 +33,19 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceClusterListCommands extends LettuceListCommands { private final LettuceClusterConnection connection; - LettuceClusterListCommands(LettuceClusterConnection connection) { + LettuceClusterListCommands(@NonNull LettuceClusterConnection connection) { super(connection); this.connection = connection; } @Override - public List bLPop(int timeout, byte[]... keys) { + public List bLPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -65,7 +68,7 @@ public List bLPop(int timeout, byte[]... keys) { } @Override - public List bRPop(int timeout, byte[]... keys) { + public List bRPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -88,7 +91,7 @@ public List bRPop(int timeout, byte[]... keys) { } @Override - public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { + public byte[] rPopLPush(byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -103,7 +106,7 @@ public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { } @Override - public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { + public byte[] bRPopLPush(int timeout, byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java index d17f801899..ad557e680e 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java @@ -24,6 +24,8 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult; import org.springframework.data.redis.connection.ClusterCommandExecutor.NodeResult; @@ -39,63 +41,64 @@ * @author Dennis Neufeld * @since 2.0 */ +@NullUnmarked class LettuceClusterServerCommands extends LettuceServerCommands implements RedisClusterServerCommands { private final LettuceClusterConnection connection; - LettuceClusterServerCommands(LettuceClusterConnection connection) { + LettuceClusterServerCommands(@NonNull LettuceClusterConnection connection) { super(connection); this.connection = connection; } @Override - public void bgReWriteAof(RedisClusterNode node) { + public void bgReWriteAof(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::bgrewriteaof, node); } @Override - public void bgSave(RedisClusterNode node) { + public void bgSave(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::bgsave, node); } @Override - public Long lastSave(RedisClusterNode node) { + public Long lastSave(@NonNull RedisClusterNode node) { return executeCommandOnSingleNode(client -> client.lastsave().getTime(), node).getValue(); } @Override - public void save(RedisClusterNode node) { + public void save(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::save, node); } @Override - public Long dbSize(RedisClusterNode node) { + public Long dbSize(@NonNull RedisClusterNode node) { return executeCommandOnSingleNode(RedisServerCommands::dbsize, node).getValue(); } @Override - public void flushDb(RedisClusterNode node) { + public void flushDb(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::flushdb, node); } @Override - public void flushDb(RedisClusterNode node, FlushOption option) { + public void flushDb(@NonNull RedisClusterNode node, @NonNull FlushOption option) { executeCommandOnSingleNode(it -> it.flushdb(LettuceConverters.toFlushMode(option)), node); } @Override - public void flushAll(RedisClusterNode node) { + public void flushAll(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::flushall, node); } @Override - public void flushAll(RedisClusterNode node, FlushOption option) { + public void flushAll(@NonNull RedisClusterNode node, @NonNull FlushOption option) { executeCommandOnSingleNode(it -> it.flushall(LettuceConverters.toFlushMode(option)), node); } @Override - public Properties info(RedisClusterNode node) { + public Properties info(@NonNull RedisClusterNode node) { return LettuceConverters.toProperties(executeCommandOnSingleNode(RedisServerCommands::info, node).getValue()); } @@ -117,7 +120,7 @@ public Properties info() { } @Override - public Properties info(String section) { + public Properties info(@NonNull String section) { Assert.hasText(section, "Section must not be null or empty"); @@ -135,7 +138,7 @@ public Properties info(String section) { } @Override - public Properties info(RedisClusterNode node, String section) { + public Properties info(@NonNull RedisClusterNode node, @NonNull String section) { Assert.hasText(section, "Section must not be null or empty"); @@ -143,7 +146,7 @@ public Properties info(RedisClusterNode node, String section) { } @Override - public void shutdown(RedisClusterNode node) { + public void shutdown(@NonNull RedisClusterNode node) { executeCommandOnSingleNode((LettuceClusterCommandCallback) client -> { client.shutdown(true); @@ -152,7 +155,7 @@ public void shutdown(RedisClusterNode node) { } @Override - public Properties getConfig(String pattern) { + public Properties getConfig(@NonNull String pattern) { Assert.hasText(pattern, "Pattern must not be null or empty"); @@ -171,7 +174,7 @@ public Properties getConfig(String pattern) { } @Override - public Properties getConfig(RedisClusterNode node, String pattern) { + public Properties getConfig(@NonNull RedisClusterNode node, @NonNull String pattern) { Assert.hasText(pattern, "Pattern must not be null or empty"); @@ -179,7 +182,7 @@ public Properties getConfig(RedisClusterNode node, String pattern) { } @Override - public void setConfig(String param, String value) { + public void setConfig(@NonNull String param, @NonNull String value) { Assert.hasText(param, "Parameter must not be null or empty"); Assert.notNull(value, "Value must not be null"); @@ -188,7 +191,7 @@ public void setConfig(String param, String value) { } @Override - public void setConfig(RedisClusterNode node, String param, String value) { + public void setConfig(@NonNull RedisClusterNode node, @NonNull String param, @NonNull String value) { Assert.hasText(param, "Parameter must not be null or empty"); Assert.hasText(value, "Value must not be null or empty"); @@ -202,7 +205,7 @@ public void resetConfigStats() { } @Override - public void resetConfigStats(RedisClusterNode node) { + public void resetConfigStats(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::configResetstat, node); } @@ -212,12 +215,12 @@ public void rewriteConfig() { } @Override - public void rewriteConfig(RedisClusterNode node) { + public void rewriteConfig(@NonNull RedisClusterNode node) { executeCommandOnSingleNode(RedisServerCommands::configRewrite, node); } @Override - public Long time(RedisClusterNode node, TimeUnit timeUnit) { + public Long time(@NonNull RedisClusterNode node, @NonNull TimeUnit timeUnit) { return convertListOfStringToTime(executeCommandOnSingleNode(RedisServerCommands::time, node).getValue(), timeUnit); } @@ -234,14 +237,14 @@ public List getClientList() { } @Override - public List getClientList(RedisClusterNode node) { + public List getClientList(@NonNull RedisClusterNode node) { return LettuceConverters .toListOfRedisClientInformation(executeCommandOnSingleNode(RedisServerCommands::clientList, node).getValue()); } @Override - public void replicaOf(String host, int port) { + public void replicaOf(@NonNull String host, int port) { throw new InvalidDataAccessApiUsageException( "REPLICAOF is not supported in cluster environment; Please use CLUSTER REPLICATE."); } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java index fe646b3a1b..82f1c0420b 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java @@ -59,7 +59,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeanUtils; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; @@ -75,7 +77,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceResult.LettuceStatusResult; import org.springframework.data.redis.core.Cursor.CursorId; import org.springframework.data.redis.core.RedisCommand; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -102,6 +104,7 @@ * @author ihaohong * @author John Blum */ +@NullUnmarked public class LettuceConnection extends AbstractRedisConnection { private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( @@ -120,7 +123,7 @@ public LettuceTransactionResultConverter(Queue> txResults, } @Override - public List convert(List execResults) { + public @Nullable List<@Nullable Object> convert(List execResults) { // Lettuce Empty list means null (watched variable modified) return execResults.isEmpty() ? null : super.convert(execResults); } @@ -171,7 +174,7 @@ public List convert(List execResults) { * @param timeout The connection timeout (in milliseconds) * @param client The {@link RedisClient} to use when instantiating a native connection */ - public LettuceConnection(long timeout, RedisClient client) { + public LettuceConnection(long timeout, @NonNull RedisClient client) { this(null, timeout, client); } @@ -184,7 +187,7 @@ public LettuceConnection(long timeout, RedisClient client) { * @param client The {@link RedisClient} to use when making pub/sub, blocking, and tx connections */ public LettuceConnection(@Nullable StatefulRedisConnection sharedConnection, long timeout, - RedisClient client) { + @NonNull RedisClient client) { this(sharedConnection, timeout, client, 0); } @@ -198,8 +201,8 @@ public LettuceConnection(@Nullable StatefulRedisConnection share * @param defaultDbIndex The db index to use along with {@link RedisClient} when establishing a dedicated connection. * @since 1.7 */ - public LettuceConnection(@Nullable StatefulRedisConnection sharedConnection, long timeout, - @Nullable AbstractRedisClient client, int defaultDbIndex) { + public LettuceConnection(@Nullable StatefulRedisConnection sharedConnection, long timeout, + @NonNull AbstractRedisClient client, int defaultDbIndex) { this.connectionProvider = new StandaloneConnectionProvider((RedisClient) client, CODEC); this.asyncSharedConnection = sharedConnection; @@ -219,7 +222,7 @@ public LettuceConnection(@Nullable StatefulRedisConnection share * @since 2.0 */ public LettuceConnection(@Nullable StatefulRedisConnection sharedConnection, - LettuceConnectionProvider connectionProvider, long timeout, int defaultDbIndex) { + @NonNull LettuceConnectionProvider connectionProvider, long timeout, int defaultDbIndex) { this((StatefulConnection) sharedConnection, connectionProvider, timeout, defaultDbIndex); } @@ -235,7 +238,7 @@ public LettuceConnection(@Nullable StatefulRedisConnection share * @since 2.1 */ LettuceConnection(@Nullable StatefulConnection sharedConnection, - LettuceConnectionProvider connectionProvider, long timeout, int defaultDbIndex) { + @NonNull LettuceConnectionProvider connectionProvider, long timeout, int defaultDbIndex) { Assert.notNull(connectionProvider, "LettuceConnectionProvider must not be null"); @@ -544,6 +547,7 @@ public RedisClusterAsyncCommands getNativeConnection() { return isAlive(subscription) ? subscription.getNativeConnection().async() : getAsyncConnection(); } + @Contract("null -> false") private boolean isAlive(@Nullable LettuceSubscription subscription) { return subscription != null && subscription.isAlive(); } @@ -570,7 +574,7 @@ public void openPipeline() { } @Override - public List closePipeline() { + public List<@Nullable Object> closePipeline() { if (!isPipelined) { return Collections.emptyList(); @@ -653,12 +657,12 @@ public List closePipeline() { } @Override - public byte[] echo(byte[] message) { + public byte@Nullable [] echo(byte[] message) { return invoke().just(RedisClusterAsyncCommands::echo, message); } @Override - public String ping() { + public @Nullable String ping() { return invoke().just(RedisClusterAsyncCommands::ping); } @@ -682,7 +686,7 @@ public void discard() { @Override @SuppressWarnings({ "unchecked", "rawtypes" }) - public List exec() { + public @Nullable List<@Nullable Object> exec() { isMulti = false; @@ -799,7 +803,7 @@ public Long publish(byte[] channel, byte[] message) { } @Override - public Subscription getSubscription() { + public @Nullable Subscription getSubscription() { return this.subscription; } @@ -844,7 +848,7 @@ public void subscribe(MessageListener listener, byte[]... channels) { } @SuppressWarnings("unchecked") - T failsafeReadScanValues(List source, @SuppressWarnings("rawtypes") @Nullable Converter converter) { + @Nullable T failsafeReadScanValues(List source, @SuppressWarnings("rawtypes") @Nullable Converter converter) { try { return (T) (converter != null ? converter.convert(source) : source); @@ -999,8 +1003,7 @@ private StatefulRedisSentinelConnection getConnection(RedisNode getRedisURI(sentinel)); } - @Nullable - private T await(RedisFuture cmd) { + private @Nullable T await(RedisFuture cmd) { if (this.isMulti) { return null; @@ -1073,7 +1076,7 @@ private void validateCommandIfRunningInTransactionMode(ProtocolKeyword cmd, byte } } - private void validateCommand(ProtocolKeyword command, @Nullable byte[]... args) { + private void validateCommand(ProtocolKeyword command, byte @Nullable[]... args) { RedisCommand redisCommand = RedisCommand.failsafeCommandLookup(command.toString()); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java index befdfffe50..c89c7b802c 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java @@ -50,7 +50,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.SmartLifecycle; @@ -65,7 +65,6 @@ import org.springframework.data.redis.connection.RedisConfiguration.WithDatabaseIndex; import org.springframework.data.redis.connection.RedisConfiguration.WithPassword; import org.springframework.data.util.Optionals; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -620,8 +619,7 @@ public void setDatabase(int index) { * @return the client name or {@literal null} if not set. * @since 2.1 */ - @Nullable - public String getClientName() { + public @Nullable String getClientName() { return clientConfiguration.getClientName().orElse(null); } @@ -649,8 +647,7 @@ public void setClientName(@Nullable String clientName) { * @since 2.5 * @see #afterPropertiesSet() */ - @Nullable - public AbstractRedisClient getNativeClient() { + public @Nullable AbstractRedisClient getNativeClient() { assertStarted(); return this.client; } @@ -676,8 +673,7 @@ public AbstractRedisClient getRequiredNativeClient() { return client; } - @Nullable - private String getRedisUsername() { + private @Nullable String getRedisUsername() { return RedisConfiguration.getUsernameOrElse(configuration, standaloneConfig::getUsername); } @@ -686,8 +682,7 @@ private String getRedisUsername() { * * @return password for authentication or {@literal null} if not set. */ - @Nullable - public String getPassword() { + public @Nullable String getPassword() { return getRedisPassword().map(String::new).orElse(null); } @@ -742,8 +737,7 @@ public void setShutdownTimeout(long shutdownTimeout) { * @return {@literal null} if not set. * @since 1.7 */ - @Nullable - public ClientResources getClientResources() { + public @Nullable ClientResources getClientResources() { return clientConfiguration.getClientResources().orElse(null); } @@ -781,8 +775,7 @@ public RedisStandaloneConfiguration getStandaloneConfiguration() { * @return the {@link RedisSocketConfiguration} or {@literal null} if not set. * @since 2.1 */ - @Nullable - public RedisSocketConfiguration getSocketConfiguration() { + public @Nullable RedisSocketConfiguration getSocketConfiguration() { return isDomainSocketAware() ? (RedisSocketConfiguration) this.configuration : null; } @@ -790,8 +783,7 @@ public RedisSocketConfiguration getSocketConfiguration() { * @return the {@link RedisSentinelConfiguration}, may be {@literal null}. * @since 2.0 */ - @Nullable - public RedisSentinelConfiguration getSentinelConfiguration() { + public @Nullable RedisSentinelConfiguration getSentinelConfiguration() { return isRedisSentinelAware() ? (RedisSentinelConfiguration) this.configuration : null; } @@ -799,8 +791,7 @@ public RedisSentinelConfiguration getSentinelConfiguration() { * @return the {@link RedisClusterConfiguration}, may be {@literal null}. * @since 2.0 */ - @Nullable - public RedisClusterConfiguration getClusterConfiguration() { + public @Nullable RedisClusterConfiguration getClusterConfiguration() { return isClusterAware() ? (RedisClusterConfiguration) this.configuration : null; } @@ -1044,6 +1035,7 @@ private void dispose(@Nullable LettuceConnectionProvider connectionProvider) { } @Override + @SuppressWarnings("NullAway") public RedisConnection getConnection() { assertStarted(); @@ -1061,6 +1053,7 @@ public RedisConnection getConnection() { } @Override + @SuppressWarnings("NullAway") public RedisClusterConnection getClusterConnection() { assertStarted(); @@ -1080,6 +1073,7 @@ public RedisClusterConnection getClusterConnection() { } @Override + @SuppressWarnings("NullAway") public RedisSentinelConnection getSentinelConnection() { assertStarted(); @@ -1137,6 +1131,7 @@ protected LettuceClusterConnection doCreateLettuceClusterConnection( } @Override + @SuppressWarnings("NullAway") public LettuceReactiveRedisConnection getReactiveConnection() { assertStarted(); @@ -1151,6 +1146,7 @@ public LettuceReactiveRedisConnection getReactiveConnection() { } @Override + @SuppressWarnings("NullAway") public LettuceReactiveRedisClusterConnection getReactiveClusterConnection() { assertStarted(); @@ -1209,6 +1205,7 @@ public void validateConnection() { getOrCreateSharedReactiveConnection().validateConnection(); } + @SuppressWarnings("NullAway") private SharedConnection getOrCreateSharedConnection() { return doInLock(() -> { @@ -1221,6 +1218,7 @@ private SharedConnection getOrCreateSharedConnection() { }); } + @SuppressWarnings("NullAway") private SharedConnection getOrCreateSharedReactiveConnection() { return doInLock(() -> { @@ -1234,7 +1232,7 @@ private SharedConnection getOrCreateSharedReactiveConnection() { } @Override - public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) { return EXCEPTION_TRANSLATION.translate(ex); } @@ -1242,8 +1240,7 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { * @return the shared connection using {@code byte[]} encoding for imperative API use. {@literal null} if * {@link #getShareNativeConnection() connection sharing} is disabled or when connected to Redis Cluster. */ - @Nullable - protected StatefulRedisConnection getSharedConnection() { + protected @Nullable StatefulRedisConnection getSharedConnection() { return shareNativeConnection && !isClusterAware() ? (StatefulRedisConnection) getOrCreateSharedConnection().getConnection() @@ -1256,8 +1253,7 @@ protected StatefulRedisConnection getSharedConnection() { * Standalone/Sentinel/Master-Replica. * @since 2.5.7 */ - @Nullable - protected StatefulRedisClusterConnection getSharedClusterConnection() { + protected @Nullable StatefulRedisClusterConnection getSharedClusterConnection() { return shareNativeConnection && isClusterAware() ? (StatefulRedisClusterConnection) getOrCreateSharedConnection().getConnection() @@ -1269,8 +1265,7 @@ protected StatefulRedisClusterConnection getSharedClusterConnect * {@link #getShareNativeConnection() connection sharing} is disabled. * @since 2.0.1 */ - @Nullable - protected StatefulConnection getSharedReactiveConnection() { + protected @Nullable StatefulConnection getSharedReactiveConnection() { return shareNativeConnection ? getOrCreateSharedReactiveConnection().getConnection() : null; } @@ -1436,6 +1431,7 @@ private RedisClient createBasicClient() { return redisClient; } + @SuppressWarnings("NullAway") private void assertStarted() { State current = this.state.get(); @@ -1482,6 +1478,7 @@ private RedisURI createRedisSocketURIAndApplySettings(String socketPath) { .withTimeout(this.clientConfiguration.getCommandTimeout()).withDatabase(getDatabase()).build(); } + @SuppressWarnings("NullAway") private RedisURI.Builder applyAuthentication(RedisURI.Builder builder) { String username = getRedisUsername(); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java index 5548d2d1f6..22088ce845 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java @@ -15,18 +15,52 @@ */ package org.springframework.data.redis.connection.lettuce; -import static org.springframework.data.redis.connection.RedisGeoCommands.*; -import static org.springframework.data.redis.domain.geo.GeoReference.*; - -import io.lettuce.core.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoCommandArgs; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; +import static org.springframework.data.redis.domain.geo.GeoReference.GeoCoordinateReference; +import static org.springframework.data.redis.domain.geo.GeoReference.GeoMemberReference; + +import io.lettuce.core.BitFieldArgs; +import io.lettuce.core.FlushMode; +import io.lettuce.core.GeoArgs; +import io.lettuce.core.GeoCoordinates; +import io.lettuce.core.GeoSearch; +import io.lettuce.core.GeoWithin; +import io.lettuce.core.GetExArgs; +import io.lettuce.core.KeyScanArgs; +import io.lettuce.core.KeyValue; +import io.lettuce.core.LMoveArgs; +import io.lettuce.core.Range; +import io.lettuce.core.RedisURI; +import io.lettuce.core.ScanArgs; +import io.lettuce.core.ScoredValue; +import io.lettuce.core.ScriptOutputType; +import io.lettuce.core.SetArgs; +import io.lettuce.core.SortArgs; +import io.lettuce.core.TransactionResult; import io.lettuce.core.cluster.models.partitions.Partitions; import io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResult; @@ -34,19 +68,30 @@ import org.springframework.data.geo.Metric; import org.springframework.data.geo.Metrics; import org.springframework.data.geo.Point; -import org.springframework.data.redis.connection.*; +import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldGet; import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldIncrBy; import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldSet; import org.springframework.data.redis.connection.BitFieldSubCommands.BitFieldSubCommand; import org.springframework.data.redis.connection.Limit; +import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.Flag; import org.springframework.data.redis.connection.RedisClusterNode.LinkState; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; +import org.springframework.data.redis.connection.RedisConfiguration; import org.springframework.data.redis.connection.RedisListCommands.Direction; import org.springframework.data.redis.connection.RedisListCommands.Position; +import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisNode.NodeType; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisSentinelConfiguration; +import org.springframework.data.redis.connection.RedisServer; +import org.springframework.data.redis.connection.RedisServerCommands; +import org.springframework.data.redis.connection.RedisSocketConfiguration; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.RedisStringCommands.SetOption; +import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.connection.SortParameters; import org.springframework.data.redis.connection.SortParameters.Order; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.convert.StringToRedisClientInfoConverter; @@ -61,7 +106,7 @@ import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; import org.springframework.data.redis.domain.geo.RadiusShape; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -99,10 +144,9 @@ public abstract class LettuceConverters extends Converters { NEGATIVE_INFINITY_BYTES = toBytes("-inf"); } - public static Point geoCoordinatesToPoint(@Nullable GeoCoordinates geoCoordinate) { + public static @Nullable Point geoCoordinatesToPoint(@Nullable GeoCoordinates geoCoordinate) { - return geoCoordinate != null - ? new Point(geoCoordinate.getX().doubleValue(), geoCoordinate.getY().doubleValue()) + return geoCoordinate != null ? new Point(geoCoordinate.getX().doubleValue(), geoCoordinate.getY().doubleValue()) : null; } @@ -139,15 +183,18 @@ public static Converter longToBooleanConverter() { return Converters::toBoolean; } - public static Long toLong(@Nullable Date source) { + @Contract("null -> null;!null -> !null") + public static @Nullable Long toLong(@Nullable Date source) { return source != null ? source.getTime() : null; } - public static Set toBytesSet(@Nullable List source) { + @Contract("null -> null;!null -> !null") + public static @Nullable Set toBytesSet(@Nullable List source) { return source != null ? new LinkedHashSet<>(source) : null; } - public static List toBytesList(KeyValue source) { + @Contract("null -> null;!null -> !null") + public static @Nullable List toBytesList(@Nullable KeyValue source) { if (source == null) { return null; @@ -161,23 +208,16 @@ public static List toBytesList(KeyValue source) { return list; } - public static List toBytesList(Collection source) { - - if (source instanceof List) { - return (List) source; - } - - return source != null ? new ArrayList<>(source) : null; - } - + @Contract("null -> null;!null -> !null") + @SuppressWarnings("NullAway") public static Tuple toTuple(@Nullable ScoredValue source) { - return source != null && source.hasValue() - ? new DefaultTuple(source.getValue(), Double.valueOf(source.getScore())) + return source != null && source.hasValue() ? new DefaultTuple(source.getValue(), Double.valueOf(source.getScore())) : null; } - public static String toString(@Nullable byte[] source) { + @Contract("null -> null") + public static @Nullable String toString(byte @Nullable [] source) { if (source == null || Arrays.equals(source, new byte[0])) { return null; @@ -294,7 +334,7 @@ public static Range toRange(org.springframework.data.domain.Range rang * * @since 2.2 */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({ "rawtypes", "unchecked", "NullAway" }) public static Range toRange(org.springframework.data.domain.Range range, boolean convertNumberToBytes) { Range.Boundary upper = RangeConverter.convertBound(range.getUpperBound(), convertNumberToBytes, null, @@ -311,7 +351,7 @@ public static Range toRange(org.springframework.data.domain.Range rang * * @since 2.0 */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({ "rawtypes", "unchecked", "NullAway" }) public static Range toRevRange(org.springframework.data.domain.Range range) { Range.Boundary upper = RangeConverter.convertBound(range.getUpperBound(), false, null, @@ -383,7 +423,9 @@ public static RedisURI sentinelConfigurationToRedisURI(RedisSentinelConfiguratio password.toOptional().ifPresent(builder::withPassword); } - builder.withSentinelMasterId(sentinelConfiguration.getMaster().getName()); + if (sentinelConfiguration.getMaster() != null && sentinelConfiguration.getMaster().getName() != null) { + builder.withSentinelMasterId(sentinelConfiguration.getMaster().getName()); + } return builder.build(); } @@ -471,7 +513,8 @@ private static void applyAuthentication(RedisURI redisURI, RedisConfiguration.Wi } } - public static byte[] toBytes(@Nullable String source) { + @Contract("null -> null;!null -> !null") + public static byte @Nullable [] toBytes(@Nullable String source) { return source != null ? source.getBytes() : null; } @@ -521,6 +564,10 @@ public static RedisClusterNode toRedisClusterNode(io.lettuce.core.cluster.models private static Set parseFlags(@Nullable Set source) { + if(source == null) { + return Collections.emptySet(); + } + Set flags = new LinkedHashSet<>(source != null ? source.size() : 8, 1); for (NodeFlag flag : source) { @@ -616,6 +663,7 @@ static GetExArgs toGetExArgs(@Nullable Expiration expiration) { : args.ex(expiration.getConverted(TimeUnit.SECONDS)); } + @SuppressWarnings("NullAway") static Converter, Long> toTimeConverter(TimeUnit timeUnit) { return source -> { @@ -635,8 +683,8 @@ static Converter, Long> toTimeConverter(TimeUnit timeUnit) { */ public static GeoArgs.Unit toGeoArgsUnit(Metric metric) { - Metric metricToUse = metric == null - || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric; + Metric metricToUse = metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS + : metric; return ObjectUtils.caseInsensitiveValueOf(GeoArgs.Unit.values(), metricToUse.getAbbreviation()); } @@ -655,6 +703,7 @@ public static GeoArgs toGeoArgs(GeoRadiusCommandArgs args) { * * @since 2.6 */ + @SuppressWarnings("NullAway") public static GeoArgs toGeoArgs(GeoCommandArgs args) { GeoArgs geoArgs = new GeoArgs(); @@ -688,9 +737,12 @@ public static GeoArgs toGeoArgs(GeoCommandArgs args) { * * @since 2.1 */ - public static BitFieldArgs toBitFieldArgs(BitFieldSubCommands subCommands) { + public static BitFieldArgs toBitFieldArgs(@Nullable BitFieldSubCommands subCommands) { BitFieldArgs args = new BitFieldArgs(); + if(subCommands == null) { + return args; + } for (BitFieldSubCommand subCommand : subCommands) { @@ -716,7 +768,7 @@ public static BitFieldArgs toBitFieldArgs(BitFieldSubCommands subCommands) { case SAT -> BitFieldArgs.OverflowType.SAT; case FAIL -> BitFieldArgs.OverflowType.FAIL; case WRAP -> BitFieldArgs.OverflowType.WRAP; - }; + }; args = args.overflow(type); } @@ -766,6 +818,7 @@ static ScanArgs toScanArgs(@Nullable ScanOptions options) { * * @since 1.8 */ + @SuppressWarnings("NullAway") public static Converter, GeoResults>> bytesSetToGeoResultsConverter() { return source -> { @@ -888,7 +941,7 @@ static GeoSearch.GeoRef toGeoRef(GeoReference reference) { throw new IllegalArgumentException("Cannot convert %s to Lettuce GeoRef".formatted(reference)); } - static FlushMode toFlushMode(@Nullable RedisServerCommands.FlushOption option) { + static FlushMode toFlushMode(RedisServerCommands.@Nullable FlushOption option) { if (option == null) { return FlushMode.SYNC; @@ -897,7 +950,7 @@ static FlushMode toFlushMode(@Nullable RedisServerCommands.FlushOption option) { return switch (option) { case ASYNC -> FlushMode.ASYNC; case SYNC -> FlushMode.SYNC; - }; + }; } /** @@ -909,8 +962,8 @@ enum GeoResultsConverterFactory { INSTANCE; Converter>, GeoResults>> forMetric(Metric metric) { - return new GeoResultsConverter(metric == null - || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric); + return new GeoResultsConverter( + metric == null || ObjectUtils.nullSafeEquals(Metrics.NEUTRAL, metric) ? DistanceUnit.METERS : metric); } private static class GeoResultsConverter @@ -950,6 +1003,7 @@ Converter, GeoResult>> forMetric(Metric me return new GeoResultConverter(metric); } + @SuppressWarnings("NullAway") private static class GeoResultConverter implements Converter, GeoResult>> { private final Metric metric; diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceExceptionConverter.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceExceptionConverter.java index 773f0a7522..7e19594513 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceExceptionConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceExceptionConverter.java @@ -25,6 +25,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.DataAccessException; import org.springframework.dao.QueryTimeoutException; @@ -42,7 +43,7 @@ public class LettuceExceptionConverter implements Converter CompletableFuture failed(Throwable throwable) { * @throws CompletionException thrown if the future is completed with a checked exception. * @return the future result if completed normally. */ - @Nullable + static T join(CompletionStage future) throws RuntimeException, CompletionException { Assert.notNull(future, "CompletableFuture must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceGeoCommands.java index 0cad933193..887e932fad 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceGeoCommands.java @@ -27,6 +27,9 @@ import java.util.Map.Entry; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -36,7 +39,6 @@ import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -44,16 +46,17 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceGeoCommands implements RedisGeoCommands { private final LettuceConnection connection; - LettuceGeoCommands(LettuceConnection connection) { + LettuceGeoCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Long geoAdd(byte[] key, Point point, byte[] member) { + public Long geoAdd(byte @NonNull [] key, @NonNull Point point, byte @NonNull [] member) { Assert.notNull(key, "Key must not be null"); Assert.notNull(point, "Point must not be null"); @@ -63,7 +66,7 @@ public Long geoAdd(byte[] key, Point point, byte[] member) { } @Override - public Long geoAdd(byte[] key, Map memberCoordinateMap) { + public Long geoAdd(byte @NonNull [] key, @NonNull Map memberCoordinateMap) { Assert.notNull(key, "Key must not be null"); Assert.notNull(memberCoordinateMap, "MemberCoordinateMap must not be null"); @@ -80,7 +83,7 @@ public Long geoAdd(byte[] key, Map memberCoordinateMap) { } @Override - public Long geoAdd(byte[] key, Iterable> locations) { + public Long geoAdd(byte @NonNull [] key, @NonNull Iterable<@NonNull GeoLocation> locations) { Assert.notNull(key, "Key must not be null"); Assert.notNull(locations, "Locations must not be null"); @@ -96,18 +99,18 @@ public Long geoAdd(byte[] key, Iterable> locations) { return geoAdd(key, values); } - @Nullable - private Long geoAdd(byte[] key, Collection values) { + private @Nullable Long geoAdd(byte @NonNull [] key, @NonNull Collection<@NonNull Object> values) { return connection.invoke().just(it -> it.geoadd(key, values.toArray())); } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2) { return geoDist(key, member1, member2, DistanceUnit.METERS); } @Override - public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metric) { + public Distance geoDist(byte @NonNull [] key, byte @NonNull [] member1, byte @NonNull [] member2, + @NonNull Metric metric) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member1, "Member1 must not be null"); @@ -122,7 +125,7 @@ public Distance geoDist(byte[] key, byte[] member1, byte[] member2, Metric metri } @Override - public List geoHash(byte[] key, byte[]... members) { + public List geoHash(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -133,7 +136,7 @@ public List geoHash(byte[] key, byte[]... members) { } @Override - public List geoPos(byte[] key, byte[]... members) { + public List geoPos(byte @NonNull [] key, byte @NonNull [] @NonNull... members) { Assert.notNull(key, "Key must not be null"); Assert.notNull(members, "Members must not be null"); @@ -144,7 +147,7 @@ public List geoPos(byte[] key, byte[]... members) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -159,7 +162,8 @@ public GeoResults> geoRadius(byte[] key, Circle within) { } @Override - public GeoResults> geoRadius(byte[] key, Circle within, GeoRadiusCommandArgs args) { + public GeoResults> geoRadius(byte @NonNull [] key, @NonNull Circle within, + @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(within, "Within must not be null"); @@ -176,12 +180,14 @@ public GeoResults> geoRadius(byte[] key, Circle within, GeoR } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, double radius) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + double radius) { return geoRadiusByMember(key, member, new Distance(radius, DistanceUnit.METERS)); } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -196,8 +202,8 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public GeoResults> geoRadiusByMember(byte[] key, byte[] member, Distance radius, - GeoRadiusCommandArgs args) { + public GeoResults> geoRadiusByMember(byte @NonNull [] key, byte @NonNull [] member, + @NonNull Distance radius, @NonNull GeoRadiusCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(member, "Member must not be null"); @@ -215,13 +221,13 @@ public GeoResults> geoRadiusByMember(byte[] key, byte[] memb } @Override - public Long geoRemove(byte[] key, byte[]... values) { + public Long geoRemove(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { return connection.zSetCommands().zRem(key, values); } @Override - public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchCommandArgs args) { + public GeoResults> geoSearch(byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(reference, "Reference must not be null"); @@ -237,8 +243,8 @@ public GeoResults> geoSearch(byte[] key, GeoReference reference, GeoShape predicate, - GeoSearchStoreCommandArgs args) { + public Long geoSearchStore(byte @NonNull [] destKey, byte @NonNull [] key, @NonNull GeoReference reference, + @NonNull GeoShape predicate, @NonNull GeoSearchStoreCommandArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(reference, "Reference must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java index 278671704b..54e7c99e07 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java @@ -28,6 +28,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.connection.RedisHashCommands; @@ -37,7 +40,6 @@ import org.springframework.data.redis.core.KeyBoundCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -47,6 +49,7 @@ * @author Tihomir Mateev * @since 2.0 */ +@NullUnmarked class LettuceHashCommands implements RedisHashCommands { private final LettuceConnection connection; @@ -56,7 +59,7 @@ class LettuceHashCommands implements RedisHashCommands { } @Override - public Boolean hSet(byte[] key, byte[] field, byte[] value) { + public Boolean hSet(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -66,7 +69,7 @@ public Boolean hSet(byte[] key, byte[] field, byte[] value) { } @Override - public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { + public Boolean hSetNX(byte @NonNull [] key, byte @NonNull [] field, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -76,7 +79,7 @@ public Boolean hSetNX(byte[] key, byte[] field, byte[] value) { } @Override - public Long hDel(byte[] key, byte[]... fields) { + public Long hDel(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { Assert.notNull(key, "Key must not be null"); Assert.notNull(fields, "Fields must not be null"); @@ -85,7 +88,7 @@ public Long hDel(byte[] key, byte[]... fields) { } @Override - public Boolean hExists(byte[] key, byte[] field) { + public Boolean hExists(byte @NonNull [] key, byte @NonNull [] field) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Fields must not be null"); @@ -94,7 +97,7 @@ public Boolean hExists(byte[] key, byte[] field) { } @Override - public byte[] hGet(byte[] key, byte[] field) { + public byte[] hGet(byte @NonNull [] key, byte @NonNull [] field) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -103,16 +106,15 @@ public byte[] hGet(byte[] key, byte[] field) { } @Override - public Map hGetAll(byte[] key) { + public Map hGetAll(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(RedisHashAsyncCommands::hgetall, key); } - @Nullable @Override - public byte[] hRandField(byte[] key) { + public byte @Nullable [] hRandField(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -121,7 +123,7 @@ public byte[] hRandField(byte[] key) { @Nullable @Override - public Entry hRandFieldWithValues(byte[] key) { + public Entry hRandFieldWithValues(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -131,7 +133,7 @@ public Entry hRandFieldWithValues(byte[] key) { @Nullable @Override - public List hRandField(byte[] key, long count) { + public List hRandField(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -140,7 +142,7 @@ public List hRandField(byte[] key, long count) { @Nullable @Override - public List> hRandFieldWithValues(byte[] key, long count) { + public List> hRandFieldWithValues(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -149,7 +151,7 @@ public List> hRandFieldWithValues(byte[] key, long count) } @Override - public Long hIncrBy(byte[] key, byte[] field, long delta) { + public Long hIncrBy(byte @NonNull [] key, byte @NonNull [] field, long delta) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -158,7 +160,7 @@ public Long hIncrBy(byte[] key, byte[] field, long delta) { } @Override - public Double hIncrBy(byte[] key, byte[] field, double delta) { + public Double hIncrBy(byte @NonNull [] key, byte @NonNull [] field, double delta) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -167,7 +169,7 @@ public Double hIncrBy(byte[] key, byte[] field, double delta) { } @Override - public Set hKeys(byte[] key) { + public Set hKeys(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -175,7 +177,7 @@ public Set hKeys(byte[] key) { } @Override - public Long hLen(byte[] key) { + public Long hLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -183,7 +185,7 @@ public Long hLen(byte[] key) { } @Override - public List hMGet(byte[] key, byte[]... fields) { + public List hMGet(byte @NonNull [] key, byte @NonNull []... fields) { Assert.notNull(key, "Key must not be null"); Assert.notNull(fields, "Fields must not be null"); @@ -193,7 +195,7 @@ public List hMGet(byte[] key, byte[]... fields) { } @Override - public void hMSet(byte[] key, Map hashes) { + public void hMSet(byte @NonNull [] key, Map hashes) { Assert.notNull(key, "Key must not be null"); Assert.notNull(hashes, "Hashes must not be null"); @@ -202,7 +204,7 @@ public void hMSet(byte[] key, Map hashes) { } @Override - public List hVals(byte[] key) { + public List hVals(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -210,53 +212,56 @@ public List hVals(byte[] key) { } @Override - public Cursor> hScan(byte[] key, ScanOptions options) { + public Cursor> hScan(byte @NonNull [] key, @NonNull ScanOptions options) { return hScan(key, CursorId.initial(), options); } @Override - public List hExpire(byte[] key, long seconds, ExpirationOptions.Condition condition, byte[]... fields) { + public List hExpire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::hexpire, key, seconds, getExpireArgs(condition), fields) .toList(); } @Override - public List hpExpire(byte[] key, long millis, ExpirationOptions.Condition condition, byte[]... fields) { + public List hpExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::hpexpire, key, millis, getExpireArgs(condition), fields) .toList(); } @Override - public List hExpireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition, byte[]... fields) { + public List hExpireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition, + byte @NonNull [] @NonNull... fields) { return connection.invoke() .fromMany(RedisHashAsyncCommands::hexpireat, key, unixTime, getExpireArgs(condition), fields).toList(); } @Override - public List hpExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition, - byte[]... fields) { + public List hpExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition, byte @NonNull [] @NonNull... fields) { return connection.invoke() .fromMany(RedisHashAsyncCommands::hpexpireat, key, unixTimeInMillis, getExpireArgs(condition), fields).toList(); } @Override - public List hPersist(byte[] key, byte[]... fields) { + public List hPersist(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::hpersist, key, fields).toList(); } @Override - public List hTtl(byte[] key, byte[]... fields) { + public List hTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::httl, key, fields).toList(); } @Override - public List hTtl(byte[] key, TimeUnit timeUnit, byte[]... fields) { + public List hTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit, byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::httl, key, fields) .toList(Converters.secondsToTimeUnit(timeUnit)); } @Override - public List hpTtl(byte[] key, byte[]... fields) { + public List hpTtl(byte @NonNull [] key, byte @NonNull [] @NonNull... fields) { return connection.invoke().fromMany(RedisHashAsyncCommands::hpttl, key, fields).toList(); } @@ -267,14 +272,16 @@ public List hpTtl(byte[] key, byte[]... fields) { * @return * @since 1.4 */ - public Cursor> hScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor> hScan(byte @NonNull [] key, @NonNull CursorId cursorId, + @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); return new KeyBoundCursor>(key, cursorId, options) { @Override - protected ScanIteration> doScan(byte[] key, CursorId cursorId, ScanOptions options) { + protected ScanIteration> doScan(byte @NonNull [] key, @NonNull CursorId cursorId, + @NonNull ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { throw new InvalidDataAccessApiUsageException("'HSCAN' cannot be called in pipeline / transaction mode"); @@ -301,7 +308,7 @@ protected void doClose() { @Nullable @Override - public Long hStrLen(byte[] key, byte[] field) { + public Long hStrLen(byte @NonNull [] key, byte @NonNull [] field) { Assert.notNull(key, "Key must not be null"); Assert.notNull(field, "Field must not be null"); @@ -309,8 +316,7 @@ public Long hStrLen(byte[] key, byte[] field) { return connection.invoke().just(RedisHashAsyncCommands::hstrlen, key, field); } - @Nullable - private static Entry toEntry(KeyValue value) { + private @Nullable static Entry toEntry(KeyValue value) { return value.hasValue() ? Converters.entryOf(value.getKey(), value.getValue()) : null; } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHyperLogLogCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHyperLogLogCommands.java index d62e3b9d5e..04bc7dbf4a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHyperLogLogCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHyperLogLogCommands.java @@ -17,6 +17,8 @@ import io.lettuce.core.api.async.RedisHLLAsyncCommands; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisHyperLogLogCommands; import org.springframework.util.Assert; @@ -25,16 +27,17 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceHyperLogLogCommands implements RedisHyperLogLogCommands { private final LettuceConnection connection; - LettuceHyperLogLogCommands(LettuceConnection connection) { + LettuceHyperLogLogCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Long pfAdd(byte[] key, byte[]... values) { + public Long pfAdd(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notEmpty(values, "PFADD requires at least one non 'null' value."); Assert.noNullElements(values, "Values for PFADD must not contain 'null'"); @@ -43,7 +46,7 @@ public Long pfAdd(byte[] key, byte[]... values) { } @Override - public Long pfCount(byte[]... keys) { + public Long pfCount(byte @NonNull [] @NonNull... keys) { Assert.notEmpty(keys, "PFCOUNT requires at least one non 'null' key."); Assert.noNullElements(keys, "Keys for PFCOUNT must not contain 'null'"); @@ -52,7 +55,7 @@ public Long pfCount(byte[]... keys) { } @Override - public void pfMerge(byte[] destinationKey, byte[]... sourceKeys) { + public void pfMerge(byte @NonNull [] destinationKey, byte @NonNull [] @NonNull... sourceKeys) { Assert.notNull(destinationKey, "Destination key must not be null"); Assert.notNull(sourceKeys, "Source keys must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceInvoker.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceInvoker.java index 451593fc19..918655b42f 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceInvoker.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceInvoker.java @@ -26,9 +26,9 @@ import java.util.Set; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.convert.Converters; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -72,8 +72,7 @@ class LettuceInvoker { * * @param function must not be {@literal null}. */ - @Nullable - R just(ConnectionFunction0 function) { + @Nullable R just(ConnectionFunction0<@Nullable R> function) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -86,8 +85,7 @@ R just(ConnectionFunction0 function) { * @param function must not be {@literal null}. * @param t1 first argument. */ - @Nullable - R just(ConnectionFunction1 function, T1 t1) { + @Nullable R just(ConnectionFunction1 function, T1 t1) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -101,8 +99,7 @@ R just(ConnectionFunction1 function, T1 t1) { * @param t1 first argument. * @param t2 second argument. */ - @Nullable - R just(ConnectionFunction2 function, T1 t1, T2 t2) { + @Nullable R just(ConnectionFunction2 function, T1 t1, T2 t2) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -117,8 +114,7 @@ R just(ConnectionFunction2 function, T1 t1, T2 t2) { * @param t2 second argument. * @param t3 third argument. */ - @Nullable - R just(ConnectionFunction3 function, T1 t1, T2 t2, T3 t3) { + @Nullable R just(ConnectionFunction3 function, T1 t1, T2 t2, T3 t3) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -134,8 +130,8 @@ R just(ConnectionFunction3 function, T1 t1, T2 t2 * @param t3 third argument. * @param t4 fourth argument. */ - @Nullable - R just(ConnectionFunction4 function, T1 t1, T2 t2, T3 t3, T4 t4) { + @Nullable R just(ConnectionFunction4 function, T1 t1, T2 t2, T3 t3, + T4 t4) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -152,9 +148,8 @@ R just(ConnectionFunction4 function, T1 t * @param t4 fourth argument. * @param t5 fifth argument. */ - @Nullable - R just(ConnectionFunction5 function, T1 t1, T2 t2, T3 t3, T4 t4, - T5 t5) { + @Nullable R just(ConnectionFunction5 function, T1 t1, T2 t2, + T3 t3, T4 t4, T5 t5) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -167,7 +162,7 @@ R just(ConnectionFunction5 functi * * @param function must not be {@literal null}. */ - SingleInvocationSpec from(ConnectionFunction0 function) { + SingleInvocationSpec<@Nullable R> from(ConnectionFunction0<@Nullable R> function) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -181,7 +176,7 @@ SingleInvocationSpec from(ConnectionFunction0 function) { * @param function must not be {@literal null}. * @param t1 first argument. */ - SingleInvocationSpec from(ConnectionFunction1 function, T1 t1) { + SingleInvocationSpec<@Nullable R> from(ConnectionFunction1 function, T1 t1) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -196,7 +191,7 @@ SingleInvocationSpec from(ConnectionFunction1 function, T1 t1) * @param t1 first argument. * @param t2 second argument. */ - SingleInvocationSpec from(ConnectionFunction2 function, T1 t1, T2 t2) { + SingleInvocationSpec<@Nullable R> from(ConnectionFunction2 function, T1 t1, T2 t2) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -212,7 +207,8 @@ SingleInvocationSpec from(ConnectionFunction2 function * @param t2 second argument. * @param t3 third argument. */ - SingleInvocationSpec from(ConnectionFunction3 function, T1 t1, T2 t2, T3 t3) { + SingleInvocationSpec<@Nullable R> from(ConnectionFunction3 function, T1 t1, + T2 t2, T3 t3) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -229,8 +225,8 @@ SingleInvocationSpec from(ConnectionFunction3 * @param t3 third argument. * @param t4 fourth argument. */ - SingleInvocationSpec from(ConnectionFunction4 function, T1 t1, T2 t2, T3 t3, - T4 t4) { + SingleInvocationSpec<@Nullable R> from(ConnectionFunction4 function, + T1 t1, T2 t2, T3 t3, T4 t4) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -248,8 +244,8 @@ SingleInvocationSpec from(ConnectionFunction4 SingleInvocationSpec from(ConnectionFunction5 function, T1 t1, - T2 t2, T3 t3, T4 t4, T5 t5) { + SingleInvocationSpec<@Nullable R> from( + ConnectionFunction5 function, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -262,7 +258,7 @@ SingleInvocationSpec from(ConnectionFunction5, E> ManyInvocationSpec fromMany(ConnectionFunction0 function) { + , E> ManyInvocationSpec<@Nullable E> fromMany(ConnectionFunction0 function) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -276,7 +272,8 @@ , E> ManyInvocationSpec fromMany(ConnectionFunction0< * @param function must not be {@literal null}. * @param t1 first argument. */ - , E, T1> ManyInvocationSpec fromMany(ConnectionFunction1 function, T1 t1) { + , E, T1> ManyInvocationSpec<@Nullable E> fromMany( + ConnectionFunction1 function, T1 t1) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -291,8 +288,8 @@ , E, T1> ManyInvocationSpec fromMany(ConnectionFuncti * @param t1 first argument. * @param t2 second argument. */ - , E, T1, T2> ManyInvocationSpec fromMany(ConnectionFunction2 function, T1 t1, - T2 t2) { + , E, T1, T2> ManyInvocationSpec<@Nullable E> fromMany( + ConnectionFunction2 function, T1 t1, T2 t2) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -308,8 +305,8 @@ , E, T1, T2> ManyInvocationSpec fromMany(ConnectionFu * @param t2 second argument. * @param t3 third argument. */ - , E, T1, T2, T3> ManyInvocationSpec fromMany(ConnectionFunction3 function, - T1 t1, T2 t2, T3 t3) { + , E, T1, T2, T3> ManyInvocationSpec<@Nullable E> fromMany( + ConnectionFunction3 function, T1 t1, T2 t2, T3 t3) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -326,8 +323,8 @@ , E, T1, T2, T3> ManyInvocationSpec fromMany(Connecti * @param t3 third argument. * @param t4 fourth argument. */ - , E, T1, T2, T3, T4> ManyInvocationSpec fromMany( - ConnectionFunction4 function, T1 t1, T2 t2, T3 t3, T4 t4) { + , E, T1, T2, T3, T4> ManyInvocationSpec<@Nullable E> fromMany( + ConnectionFunction4 function, T1 t1, T2 t2, T3 t3, T4 t4) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -345,8 +342,8 @@ , E, T1, T2, T3, T4> ManyInvocationSpec fromMany( * @param t4 fourth argument. * @param t5 fifth argument. */ - , E, T1, T2, T3, T4, T5> ManyInvocationSpec fromMany( - ConnectionFunction5 function, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { + , E, T1, T2, T3, T4, T5> ManyInvocationSpec<@Nullable E> fromMany( + ConnectionFunction5 function, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { Assert.notNull(function, "ConnectionFunction must not be null"); @@ -368,8 +365,7 @@ interface SingleInvocationSpec { * @param target type. * @return the converted result, can be {@literal null}. */ - @Nullable - T get(Converter converter); + @Nullable T get(Converter converter); /** * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying @@ -380,8 +376,7 @@ interface SingleInvocationSpec { * @param target type. * @return the converted result, can be {@literal null}. */ - @Nullable - default T orElse(Converter converter, @Nullable T nullDefault) { + default @Nullable T orElse(Converter converter, @Nullable T nullDefault) { return getOrElse(converter, () -> nullDefault); } @@ -394,12 +389,11 @@ default T orElse(Converter converter, @Nullable T nullDefault) { * @param target type. * @return the converted result, can be {@literal null}. */ - @Nullable - T getOrElse(Converter converter, Supplier nullDefault); + @Nullable T getOrElse(Converter converter, Supplier<@Nullable T> nullDefault); } /** - * Represents an element in the invocation pipleline for methods returning {@link Collection}-like results allowing + * Represents an element in the invocation pipeline for methods returning {@link Collection}-like results allowing * consuming the result by applying a {@link Converter}. * * @param @@ -411,7 +405,7 @@ interface ManyInvocationSpec { * * @return the result as {@link List}. */ - default List toList() { + default List<@Nullable S> toList() { return toList(Converters.identityConverter()); } @@ -423,14 +417,14 @@ default List toList() { * @param target type. * @return the converted {@link List}. */ - List toList(Converter converter); + List<@Nullable T> toList(Converter converter); /** * Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result. * * @return the result as {@link Set}. */ - default Set toSet() { + default Set<@Nullable S> toSet() { return toSet(Converters.identityConverter()); } @@ -442,7 +436,7 @@ default Set toSet() { * @param target type. * @return the converted {@link Set}. */ - Set toSet(Converter converter); + Set<@Nullable T> toSet(Converter converter); } /** @@ -582,16 +576,15 @@ public DefaultSingleInvocationSpec(Supplier> parent, Synchronizer } @Override - public T get(Converter converter) { + public @Nullable T get(Converter converter) { Assert.notNull(converter, "Converter must not be null"); return synchronizer.invoke(parent, converter, () -> null); } - @Nullable @Override - public T getOrElse(Converter converter, Supplier nullDefault) { + public @Nullable T getOrElse(Converter converter, Supplier<@Nullable T> nullDefault) { Assert.notNull(converter, "Converter must not be null"); @@ -611,7 +604,8 @@ public DefaultManyInvocationSpec(Supplier>> } @Override - public List toList(Converter converter) { + @SuppressWarnings("NullAway") + public List<@Nullable T> toList(Converter converter) { Assert.notNull(converter, "Converter must not be null"); @@ -631,8 +625,8 @@ public List toList(Converter converter) { }, Collections::emptyList); } - @Override - public Set toSet(Converter converter) { + @SuppressWarnings("NullAway") + public Set<@Nullable T> toSet(Converter converter) { Assert.notNull(converter, "Converter must not be null"); @@ -659,23 +653,21 @@ public Set toSet(Converter converter) { @FunctionalInterface interface Synchronizer { - @Nullable @SuppressWarnings({ "unchecked", "rawtypes" }) - default T invoke(Supplier> futureSupplier) { + default @Nullable T invoke(Supplier> futureSupplier) { return (T) doInvoke((Supplier) futureSupplier, Converters.identityConverter(), () -> null); } - @Nullable @SuppressWarnings({ "unchecked", "rawtypes" }) - default T invoke(Supplier> futureSupplier, Converter converter, - Supplier nullDefault) { + default @Nullable T invoke(Supplier> futureSupplier, Converter converter, + Supplier<@Nullable T> nullDefault) { return (T) doInvoke((Supplier) futureSupplier, (Converter) converter, (Supplier) nullDefault); } @Nullable - Object doInvoke(Supplier> futureSupplier, Converter converter, - Supplier nullDefault); + Object doInvoke(Supplier> futureSupplier, Converter converter, + Supplier<@Nullable Object> nullDefault); } } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java index 78d4e7006e..6228c9485a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java @@ -30,6 +30,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.ExpirationOptions; @@ -40,7 +43,6 @@ import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -50,16 +52,17 @@ * @author ihaohong * @since 2.0 */ +@NullUnmarked class LettuceKeyCommands implements RedisKeyCommands { private final LettuceConnection connection; - LettuceKeyCommands(LettuceConnection connection) { + LettuceKeyCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { + public Boolean copy(byte @NonNull [] sourceKey, byte @NonNull [] targetKey, boolean replace) { Assert.notNull(sourceKey, "source key must not be null"); Assert.notNull(targetKey, "target key must not be null"); @@ -69,16 +72,15 @@ public Boolean copy(byte[] sourceKey, byte[] targetKey, boolean replace) { } @Override - public Boolean exists(byte[] key) { + public Boolean exists(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(RedisKeyAsyncCommands::exists, key).get(LettuceConverters.longToBooleanConverter()); } - @Nullable @Override - public Long exists(byte[]... keys) { + public Long exists(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -87,7 +89,7 @@ public Long exists(byte[]... keys) { } @Override - public Long del(byte[]... keys) { + public Long del(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -95,9 +97,8 @@ public Long del(byte[]... keys) { return connection.invoke().just(RedisKeyAsyncCommands::del, keys); } - @Override - public Long unlink(byte[]... keys) { + public Long unlink(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -105,7 +106,7 @@ public Long unlink(byte[]... keys) { } @Override - public DataType type(byte[] key) { + public DataType type(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -113,7 +114,7 @@ public DataType type(byte[] key) { } @Override - public Long touch(byte[]... keys) { + public Long touch(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); @@ -121,7 +122,7 @@ public Long touch(byte[]... keys) { } @Override - public Set keys(byte[] pattern) { + public Set keys(byte @NonNull [] pattern) { Assert.notNull(pattern, "Pattern must not be null"); @@ -132,12 +133,12 @@ public Set keys(byte[] pattern) { * @since 1.4 * @return */ - public Cursor scan() { + public Cursor scan() { return scan(ScanOptions.NONE); } @Override - public Cursor scan(ScanOptions options) { + public Cursor scan(@Nullable ScanOptions options) { return doScan(options != null ? options : ScanOptions.NONE); } @@ -146,12 +147,13 @@ public Cursor scan(ScanOptions options) { * @param options * @return */ - private Cursor doScan(ScanOptions options) { + private Cursor doScan(@NonNull ScanOptions options) { return new LettuceScanCursor(options) { @Override - protected LettuceScanIteration doScan(ScanCursor cursor, ScanOptions options) { + protected LettuceScanIteration doScan(@NonNull ScanCursor cursor, + @NonNull ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { throw new InvalidDataAccessApiUsageException("'SCAN' cannot be called in pipeline / transaction mode"); @@ -178,7 +180,7 @@ public byte[] randomKey() { } @Override - public void rename(byte[] oldKey, byte[] newKey) { + public void rename(byte @NonNull [] oldKey, byte @NonNull [] newKey) { Assert.notNull(oldKey, "Old key must not be null"); Assert.notNull(newKey, "New key must not be null"); @@ -187,7 +189,7 @@ public void rename(byte[] oldKey, byte[] newKey) { } @Override - public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { + public Boolean renameNX(byte @NonNull [] sourceKey, byte @NonNull [] targetKey) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(targetKey, "Target key must not be null"); @@ -196,7 +198,7 @@ public Boolean renameNX(byte[] sourceKey, byte[] targetKey) { } @Override - public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition condition) { + public Boolean expire(byte @NonNull [] key, long seconds, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -204,7 +206,7 @@ public Boolean expire(byte[] key, long seconds, ExpirationOptions.Condition cond } @Override - public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition condition) { + public Boolean pExpire(byte @NonNull [] key, long millis, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -212,7 +214,7 @@ public Boolean pExpire(byte[] key, long millis, ExpirationOptions.Condition cond } @Override - public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition condition) { + public Boolean expireAt(byte @NonNull [] key, long unixTime, ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -220,7 +222,8 @@ public Boolean expireAt(byte[] key, long unixTime, ExpirationOptions.Condition c } @Override - public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Condition condition) { + public Boolean pExpireAt(byte @NonNull [] key, long unixTimeInMillis, + ExpirationOptions.@NonNull Condition condition) { Assert.notNull(key, "Key must not be null"); @@ -228,7 +231,7 @@ public Boolean pExpireAt(byte[] key, long unixTimeInMillis, ExpirationOptions.Co } @Override - public Boolean persist(byte[] key) { + public Boolean persist(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -236,7 +239,7 @@ public Boolean persist(byte[] key) { } @Override - public Boolean move(byte[] key, int dbIndex) { + public Boolean move(byte @NonNull [] key, int dbIndex) { Assert.notNull(key, "Key must not be null"); @@ -244,7 +247,7 @@ public Boolean move(byte[] key, int dbIndex) { } @Override - public Long ttl(byte[] key) { + public Long ttl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -252,7 +255,7 @@ public Long ttl(byte[] key) { } @Override - public Long ttl(byte[] key, TimeUnit timeUnit) { + public Long ttl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -260,7 +263,7 @@ public Long ttl(byte[] key, TimeUnit timeUnit) { } @Override - public Long pTtl(byte[] key) { + public Long pTtl(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -268,7 +271,7 @@ public Long pTtl(byte[] key) { } @Override - public Long pTtl(byte[] key, TimeUnit timeUnit) { + public Long pTtl(byte @NonNull [] key, @NonNull TimeUnit timeUnit) { Assert.notNull(key, "Key must not be null"); @@ -276,7 +279,7 @@ public Long pTtl(byte[] key, TimeUnit timeUnit) { } @Override - public List sort(byte[] key, SortParameters params) { + public List sort(byte @NonNull [] key, @NonNull SortParameters params) { Assert.notNull(key, "Key must not be null"); @@ -286,7 +289,7 @@ public List sort(byte[] key, SortParameters params) { } @Override - public Long sort(byte[] key, SortParameters params, byte[] sortKey) { + public Long sort(byte @NonNull [] key, @NonNull SortParameters params, byte @NonNull [] sortKey) { Assert.notNull(key, "Key must not be null"); @@ -296,7 +299,7 @@ public Long sort(byte[] key, SortParameters params, byte[] sortKey) { } @Override - public byte[] dump(byte[] key) { + public byte[] dump(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -304,7 +307,7 @@ public byte[] dump(byte[] key) { } @Override - public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolean replace) { + public void restore(byte @NonNull [] key, long ttlInMillis, byte @NonNull [] serializedValue, boolean replace) { Assert.notNull(key, "Key must not be null"); Assert.notNull(serializedValue, "Serialized value must not be null"); @@ -316,7 +319,7 @@ public void restore(byte[] key, long ttlInMillis, byte[] serializedValue, boolea @Nullable @Override - public ValueEncoding encodingOf(byte[] key) { + public ValueEncoding encodingOf(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -326,7 +329,7 @@ public ValueEncoding encodingOf(byte[] key) { @Nullable @Override - public Duration idletime(byte[] key) { + public Duration idletime(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -335,14 +338,14 @@ public Duration idletime(byte[] key) { @Nullable @Override - public Long refcount(byte[] key) { + public Long refcount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(RedisKeyAsyncCommands::objectRefcount, key); } - private static ExpireArgs getExpireArgs(ExpirationOptions.Condition condition) { + private static ExpireArgs getExpireArgs(ExpirationOptions.@NonNull Condition condition) { return new ExpireArgs() { @Override diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java index 4f930633f2..0630380c55 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceListCommands.java @@ -23,8 +23,10 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisListCommands; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -33,16 +35,17 @@ * @author dengliming * @since 2.0 */ +@NullUnmarked class LettuceListCommands implements RedisListCommands { private final LettuceConnection connection; - LettuceListCommands(LettuceConnection connection) { + LettuceListCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Long rPush(byte[] key, byte[]... values) { + public Long rPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); @@ -50,7 +53,8 @@ public Long rPush(byte[] key, byte[]... values) { } @Override - public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Nullable Integer count) { + public List lPos(byte @NonNull [] key, byte @NonNull [] element, @Nullable Integer rank, + @Nullable Integer count) { Assert.notNull(key, "Key must not be null"); Assert.notNull(element, "Element must not be null"); @@ -69,7 +73,7 @@ public List lPos(byte[] key, byte[] element, @Nullable Integer rank, @Null } @Override - public Long lPush(byte[] key, byte[]... values) { + public Long lPush(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -79,7 +83,7 @@ public Long lPush(byte[] key, byte[]... values) { } @Override - public Long rPushX(byte[] key, byte[] value) { + public Long rPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -88,7 +92,7 @@ public Long rPushX(byte[] key, byte[] value) { } @Override - public Long lPushX(byte[] key, byte[] value) { + public Long lPushX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -97,7 +101,7 @@ public Long lPushX(byte[] key, byte[] value) { } @Override - public Long lLen(byte[] key) { + public Long lLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -105,7 +109,7 @@ public Long lLen(byte[] key) { } @Override - public List lRange(byte[] key, long start, long end) { + public List lRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -113,7 +117,7 @@ public List lRange(byte[] key, long start, long end) { } @Override - public void lTrim(byte[] key, long start, long end) { + public void lTrim(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -121,7 +125,7 @@ public void lTrim(byte[] key, long start, long end) { } @Override - public byte[] lIndex(byte[] key, long index) { + public byte[] lIndex(byte @NonNull [] key, long index) { Assert.notNull(key, "Key must not be null"); @@ -129,7 +133,7 @@ public byte[] lIndex(byte[] key, long index) { } @Override - public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { + public Long lInsert(byte @NonNull [] key, @NonNull Position where, byte @NonNull [] pivot, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); @@ -138,7 +142,8 @@ public Long lInsert(byte[] key, Position where, byte[] pivot, byte[] value) { } @Override - public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to) { + public byte[] lMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -151,7 +156,8 @@ public byte[] lMove(byte[] sourceKey, byte[] destinationKey, Direction from, Dir } @Override - public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Direction to, double timeout) { + public byte[] bLMove(byte @NonNull [] sourceKey, byte @NonNull [] destinationKey, @NonNull Direction from, + @NonNull Direction to, double timeout) { Assert.notNull(sourceKey, "Source key must not be null"); Assert.notNull(destinationKey, "Destination key must not be null"); @@ -163,7 +169,7 @@ public byte[] bLMove(byte[] sourceKey, byte[] destinationKey, Direction from, Di } @Override - public void lSet(byte[] key, long index, byte[] value) { + public void lSet(byte @NonNull [] key, long index, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -172,7 +178,7 @@ public void lSet(byte[] key, long index, byte[] value) { } @Override - public Long lRem(byte[] key, long count, byte[] value) { + public Long lRem(byte @NonNull [] key, long count, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -181,7 +187,7 @@ public Long lRem(byte[] key, long count, byte[] value) { } @Override - public byte[] lPop(byte[] key) { + public byte[] lPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -189,7 +195,7 @@ public byte[] lPop(byte[] key) { } @Override - public List lPop(byte[] key, long count) { + public List lPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -197,7 +203,7 @@ public List lPop(byte[] key, long count) { } @Override - public byte[] rPop(byte[] key) { + public byte[] rPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -205,7 +211,7 @@ public byte[] rPop(byte[] key) { } @Override - public List rPop(byte[] key, long count) { + public List rPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -213,7 +219,7 @@ public List rPop(byte[] key, long count) { } @Override - public List bLPop(int timeout, byte[]... keys) { + public List bLPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -223,7 +229,7 @@ public List bLPop(int timeout, byte[]... keys) { } @Override - public List bRPop(int timeout, byte[]... keys) { + public List bRPop(int timeout, byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Key must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -233,7 +239,7 @@ public List bRPop(int timeout, byte[]... keys) { } @Override - public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { + public byte[] rPopLPush(byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -242,7 +248,7 @@ public byte[] rPopLPush(byte[] srcKey, byte[] dstKey) { } @Override - public byte[] bRPopLPush(int timeout, byte[] srcKey, byte[] dstKey) { + public byte[] bRPopLPush(int timeout, byte @NonNull [] srcKey, byte @NonNull [] dstKey) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterSetCommands.java index 85d6feb3c1..151f528928 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterSetCommands.java @@ -82,11 +82,12 @@ public Flux> sUnionStore(Publisher { - Mono result = values.getOutput().collectList().flatMap(it -> { + Flux output = values.getOutput(); + Mono result = output != null ? output.collectList().flatMap(it -> { ByteBuffer[] members = it.toArray(new ByteBuffer[0]); return cmd.sadd(command.getKey(), members); - }); + }) : Mono.empty(); return result.map(value -> new NumericResponse<>(command, value)); }); @@ -142,11 +143,12 @@ public Flux> sInterStore(Publisher { - Mono result = values.getOutput().collectList().flatMap(it -> { + Flux output = values.getOutput(); + Mono result = output != null ? output.collectList().flatMap(it -> { ByteBuffer[] members = it.toArray(new ByteBuffer[0]); return cmd.sadd(command.getKey(), members); - }); + }) : Mono.empty(); return result.map(value -> new NumericResponse<>(command, value)); }); @@ -204,11 +206,12 @@ public Flux> sDiffStore(Publisher { - Mono result = values.getOutput().collectList().flatMap(it -> { + Flux output = values.getOutput(); + Mono result = output != null ? output.collectList().flatMap(it -> { ByteBuffer[] members = it.toArray(new ByteBuffer[0]); return cmd.sadd(command.getKey(), members); - }); + }) : Mono.empty(); return result.map(value -> new NumericResponse<>(command, value)); }); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveGeoCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveGeoCommands.java index 9425570f4a..e7d9b25021 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveGeoCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveGeoCommands.java @@ -228,6 +228,7 @@ public Flux> geoSearchStore(Publish })); } + @SuppressWarnings("NullAway") private Converter, GeoResult>> converter(Metric metric) { return (source) -> { diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveRedisConnection.java index 6905356065..8bce61b9ea 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveRedisConnection.java @@ -24,6 +24,7 @@ import io.lettuce.core.cluster.api.reactive.RedisClusterReactiveCommands; import io.lettuce.core.codec.RedisCodec; import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; +import org.jspecify.annotations.NullUnmarked; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -31,11 +32,11 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.data.redis.connection.*; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -43,6 +44,7 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceReactiveRedisConnection implements ReactiveRedisConnection { static final RedisCodec CODEC = ByteBufferCodec.INSTANCE; diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStreamCommands.java index 1f45c373cd..37b331a9e5 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStreamCommands.java @@ -89,6 +89,7 @@ public Flux> xAck(Publisher> xAdd(Publisher commands) { return connection.execute(cmd -> Flux.from(commands).concatMap(command -> { @@ -182,6 +183,7 @@ public Flux> xGroup(Publisher> xPen } @Override + @SuppressWarnings("NullAway") public Flux> xPending( Publisher commands) { return connection.execute(cmd -> Flux.from(commands).concatMap(command -> { @@ -324,12 +327,14 @@ public Flux>> xInfoGroups(Publish } @Override + @SuppressWarnings("NullAway") public Flux>> xInfoConsumers(Publisher commands) { return connection.execute(cmd -> Flux.from(commands).map(command -> { Assert.notNull(command.getKey(), "Key must not be null"); - + Assert.notNull(command.getGroupName(), "Command.getGroupName() must not be null"); + ByteBuffer groupName = ByteUtils.getByteBuffer(command.getGroupName()); return new CommandResponse<>(command, cmd.xinfoConsumers(command.getKey(), groupName) .map(it -> new XInfoConsumer(command.getGroupName(), (List) it))); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSubscription.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSubscription.java index 9df426a53d..2014226542 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSubscription.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveSubscription.java @@ -31,10 +31,10 @@ import java.util.function.Supplier; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ReactiveSubscription; import org.springframework.data.redis.connection.SubscriptionListener; import org.springframework.data.redis.connection.util.ByteArrayWrapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -229,7 +229,7 @@ Set getTargets() { * @param message type. * @return */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "NullAway" }) Flux receive(Supplier> connectFunction) { Flux fastPath = flux.get(); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommands.java index 415d76bfe2..4b24d0319e 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveZSetCommands.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse; @@ -43,7 +44,6 @@ import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.core.TimeoutUtils; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -392,6 +392,7 @@ public Flux>> zPop(Publisher>> bZPop(Publisher commands) { return this.connection.execute(reactiveCommands -> Flux.from(commands).map(command -> { diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceResult.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceResult.java index d3e2f779a1..1c8702a340 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceResult.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceResult.java @@ -19,9 +19,9 @@ import java.util.concurrent.Future; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.FutureResult; -import org.springframework.lang.Nullable; /** * Lettuce specific {@link FutureResult} implementation.
diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java index b3b467533c..3c0f02b96f 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java @@ -17,10 +17,10 @@ import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.ScanCursor; import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; -import org.springframework.lang.Nullable; /** * Lettuce-specific {@link ScanCursor} extension that maintains the cursor state that is required for stateful-scanning @@ -34,7 +34,7 @@ */ abstract class LettuceScanCursor extends ScanCursor { - private @Nullable io.lettuce.core.ScanCursor state; + private io.lettuce.core.@Nullable ScanCursor state; /** * Creates a new {@link LettuceScanCursor} given {@link ScanOptions}. diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java index 52ec10e0ed..f68eb0511b 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java @@ -20,6 +20,8 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.core.convert.converter.Converter; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisScriptingCommands; @@ -30,11 +32,12 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceScriptingCommands implements RedisScriptingCommands { private final LettuceConnection connection; - LettuceScriptingCommands(LettuceConnection connection) { + LettuceScriptingCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @@ -54,7 +57,7 @@ public void scriptKill() { } @Override - public String scriptLoad(byte[] script) { + public String scriptLoad(byte @NonNull [] script) { Assert.notNull(script, "Script must not be null"); @@ -62,7 +65,7 @@ public String scriptLoad(byte[] script) { } @Override - public List scriptExists(String... scriptSha1) { + public List scriptExists(@NonNull String @NonNull... scriptSha1) { Assert.notNull(scriptSha1, "Script digests must not be null"); Assert.noNullElements(scriptSha1, "Script digests must not contain null elements"); @@ -71,7 +74,8 @@ public List scriptExists(String... scriptSha1) { } @Override - public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T eval(byte @NonNull [] script, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(script, "Script must not be null"); @@ -86,7 +90,8 @@ public T eval(byte[] script, ReturnType returnType, int numKeys, byte[]... k } @Override - public T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(@NonNull String scriptSha1, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(scriptSha1, "Script digest must not be null"); @@ -100,7 +105,8 @@ public T evalSha(String scriptSha1, ReturnType returnType, int numKeys, byte } @Override - public T evalSha(byte[] scriptSha1, ReturnType returnType, int numKeys, byte[]... keysAndArgs) { + public T evalSha(byte @NonNull [] scriptSha1, @NonNull ReturnType returnType, int numKeys, + byte @NonNull [] @NonNull... keysAndArgs) { Assert.notNull(scriptSha1, "Script digest must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelConnection.java index 1abd08e60e..05faa6ec45 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSentinelConnection.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.ExceptionTranslationStrategy; import org.springframework.data.redis.FallbackExceptionTranslationStrategy; import org.springframework.data.redis.connection.NamedNode; @@ -41,6 +42,7 @@ * @author Mark Paluch * @since 1.5 */ +@NullUnmarked public class LettuceSentinelConnection implements RedisSentinelConnection { private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new FallbackExceptionTranslationStrategy( @@ -55,7 +57,12 @@ public class LettuceSentinelConnection implements RedisSentinelConnection { * @param sentinel The sentinel to connect to. */ public LettuceSentinelConnection(RedisNode sentinel) { - this(sentinel.getHost(), sentinel.getPort()); + + Assert.notNull(sentinel.getHost(), "Sentinel.getHost() must not be null"); + Assert.notNull(sentinel.getPort(), "Sentinel.getPort() must not be null"); + + this.provider = new DedicatedClientConnectionProvider(sentinel.getHost(), sentinel.getPort()); + this.init(); } /** diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java index 1b9124e138..c0903c9a33 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java @@ -26,10 +26,12 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.core.types.RedisClientInfo; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -37,11 +39,12 @@ * @author Dennis Neufeld * @since 2.0 */ +@NullUnmarked class LettuceServerCommands implements RedisServerCommands { private final LettuceConnection connection; - LettuceServerCommands(LettuceConnection connection) { + LettuceServerCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @@ -76,7 +79,7 @@ public void flushDb() { } @Override - public void flushDb(FlushOption option) { + public void flushDb(@NonNull FlushOption option) { connection.invokeStatus().just(RedisServerAsyncCommands::flushdb, LettuceConverters.toFlushMode(option)); } @@ -86,7 +89,7 @@ public void flushAll() { } @Override - public void flushAll(FlushOption option) { + public void flushAll(@NonNull FlushOption option) { connection.invokeStatus().just(RedisServerAsyncCommands::flushall, LettuceConverters.toFlushMode(option)); } @@ -96,7 +99,7 @@ public Properties info() { } @Override - public Properties info(String section) { + public Properties info(@NonNull String section) { Assert.hasText(section, "Section must not be null or empty"); @@ -114,7 +117,7 @@ public void shutdown() { } @Override - public void shutdown(ShutdownOption option) { + public void shutdown(@Nullable ShutdownOption option) { if (option == null) { shutdown(); @@ -132,7 +135,7 @@ public void shutdown(ShutdownOption option) { } @Override - public Properties getConfig(String pattern) { + public Properties getConfig(@NonNull String pattern) { Assert.hasText(pattern, "Pattern must not be null or empty"); @@ -141,7 +144,7 @@ public Properties getConfig(String pattern) { } @Override - public void setConfig(String param, String value) { + public void setConfig(@NonNull String param, @NonNull String value) { Assert.hasText(param, "Parameter must not be null or empty"); Assert.notNull(value, "Value must not be null"); @@ -160,7 +163,7 @@ public void rewriteConfig() { } @Override - public Long time(TimeUnit timeUnit) { + public Long time(@NonNull TimeUnit timeUnit) { Assert.notNull(timeUnit, "TimeUnit must not be null"); @@ -168,7 +171,7 @@ public Long time(TimeUnit timeUnit) { } @Override - public void killClient(String host, int port) { + public void killClient(@NonNull String host, int port) { Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'"); @@ -178,7 +181,7 @@ public void killClient(String host, int port) { } @Override - public void setClientName(byte[] name) { + public void setClientName(byte @NonNull [] name) { Assert.notNull(name, "Name must not be null"); @@ -191,13 +194,13 @@ public String getClientName() { } @Override - public List getClientList() { + public List<@NonNull RedisClientInfo> getClientList() { return connection.invoke().from(RedisServerAsyncCommands::clientList) .get(LettuceConverters.stringToRedisClientListConverter()); } @Override - public void replicaOf(String host, int port) { + public void replicaOf(@NonNull String host, int port) { Assert.hasText(host, "Host must not be null for 'REPLICAOF' command"); @@ -210,12 +213,13 @@ public void replicaOfNoOne() { } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option) { migrate(key, target, dbIndex, option, Long.MAX_VALUE); } @Override - public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable MigrateOption option, long timeout) { + public void migrate(byte @NonNull [] key, @NonNull RedisNode target, int dbIndex, @Nullable MigrateOption option, + long timeout) { Assert.notNull(key, "Key must not be null"); Assert.notNull(target, "Target node must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java index cb165702ff..170592600b 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java @@ -24,6 +24,9 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisSetCommands; import org.springframework.data.redis.core.Cursor; @@ -38,16 +41,17 @@ * @author Mark Paluch * @since 2.0 */ +@NullUnmarked class LettuceSetCommands implements RedisSetCommands { private final LettuceConnection connection; - LettuceSetCommands(LettuceConnection connection) { + LettuceSetCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Long sAdd(byte[] key, byte[]... values) { + public Long sAdd(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -57,7 +61,7 @@ public Long sAdd(byte[] key, byte[]... values) { } @Override - public Long sCard(byte[] key) { + public Long sCard(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -65,7 +69,7 @@ public Long sCard(byte[] key) { } @Override - public Set sDiff(byte[]... keys) { + public Set sDiff(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -74,7 +78,7 @@ public Set sDiff(byte[]... keys) { } @Override - public Long sDiffStore(byte[] destKey, byte[]... keys) { + public Long sDiffStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -84,7 +88,7 @@ public Long sDiffStore(byte[] destKey, byte[]... keys) { } @Override - public Set sInter(byte[]... keys) { + public Set sInter(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -93,7 +97,7 @@ public Set sInter(byte[]... keys) { } @Override - public Long sInterStore(byte[] destKey, byte[]... keys) { + public Long sInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -103,7 +107,7 @@ public Long sInterStore(byte[] destKey, byte[]... keys) { } @Override - public Boolean sIsMember(byte[] key, byte[] value) { + public Boolean sIsMember(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -112,7 +116,7 @@ public Boolean sIsMember(byte[] key, byte[] value) { } @Override - public List sMIsMember(byte[] key, byte[]... values) { + public List<@NonNull Boolean> sMIsMember(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -122,7 +126,7 @@ public List sMIsMember(byte[] key, byte[]... values) { } @Override - public Set sMembers(byte[] key) { + public Set sMembers(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -130,7 +134,7 @@ public Set sMembers(byte[] key) { } @Override - public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { + public Boolean sMove(byte @NonNull [] srcKey, byte @NonNull [] destKey, byte @NonNull [] value) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(destKey, "Destination key must not be null"); @@ -140,7 +144,7 @@ public Boolean sMove(byte[] srcKey, byte[] destKey, byte[] value) { } @Override - public byte[] sPop(byte[] key) { + public byte[] sPop(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -148,7 +152,7 @@ public byte[] sPop(byte[] key) { } @Override - public List sPop(byte[] key, long count) { + public List sPop(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -156,7 +160,7 @@ public List sPop(byte[] key, long count) { } @Override - public byte[] sRandMember(byte[] key) { + public byte[] sRandMember(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -164,7 +168,7 @@ public byte[] sRandMember(byte[] key) { } @Override - public List sRandMember(byte[] key, long count) { + public List sRandMember(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -172,7 +176,7 @@ public List sRandMember(byte[] key, long count) { } @Override - public Long sRem(byte[] key, byte[]... values) { + public Long sRem(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -182,7 +186,7 @@ public Long sRem(byte[] key, byte[]... values) { } @Override - public Set sUnion(byte[]... keys) { + public Set sUnion(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -191,7 +195,7 @@ public Set sUnion(byte[]... keys) { } @Override - public Long sUnionStore(byte[] destKey, byte[]... keys) { + public Long sUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... keys) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(keys, "Source keys must not be null"); @@ -201,8 +205,8 @@ public Long sUnionStore(byte[] destKey, byte[]... keys) { } @Override - public Cursor sScan(byte[] key, ScanOptions options) { - return sScan(key, CursorId.initial(), options); + public Cursor sScan(byte @NonNull [] key, @Nullable ScanOptions options) { + return sScan(key, CursorId.initial(), options != null ? options : ScanOptions.NONE); } /** @@ -212,14 +216,14 @@ public Cursor sScan(byte[] key, ScanOptions options) { * @return * @since 1.4 */ - public Cursor sScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor sScan(byte @NonNull [] key, @NonNull CursorId cursorId, @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); return new KeyBoundCursor(key, cursorId, options) { @Override - protected ScanIteration doScan(byte[] key, CursorId cursorId, ScanOptions options) { + protected ScanIteration doScan(byte @NonNull [] key, CursorId cursorId, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { throw new InvalidDataAccessApiUsageException("'SSCAN' cannot be called in pipeline / transaction mode"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStreamCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStreamCommands.java index ad5c2281c2..c80610b58d 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStreamCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStreamCommands.java @@ -27,6 +27,8 @@ import java.util.Objects; import java.util.function.Function; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.RedisStreamCommands; @@ -52,16 +54,17 @@ * @author Mark John Moreno * @since 2.2 */ +@NullUnmarked class LettuceStreamCommands implements RedisStreamCommands { private final LettuceConnection connection; - LettuceStreamCommands(LettuceConnection connection) { + LettuceStreamCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Long xAck(byte[] key, String group, RecordId... recordIds) { + public Long xAck(byte @NonNull [] key, @NonNull String group, @NonNull RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.hasText(group, "Group name must not be null or empty"); @@ -73,7 +76,8 @@ public Long xAck(byte[] key, String group, RecordId... recordIds) { } @Override - public RecordId xAdd(MapRecord record, XAddOptions options) { + public RecordId xAdd(@NonNull MapRecord record, + @NonNull XAddOptions options) { Assert.notNull(record.getStream(), "Stream must not be null"); Assert.notNull(record, "Record must not be null"); @@ -94,7 +98,8 @@ public RecordId xAdd(MapRecord record, XAddOptions optio } @Override - public List xClaimJustId(byte[] key, String group, String newOwner, XClaimOptions options) { + public List<@NonNull RecordId> xClaimJustId(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options) { String[] ids = options.getIdsAsStringArray(); io.lettuce.core.Consumer from = io.lettuce.core.Consumer.from(LettuceConverters.toBytes(group), @@ -106,7 +111,8 @@ public List xClaimJustId(byte[] key, String group, String newOwner, XC } @Override - public List xClaim(byte[] key, String group, String newOwner, XClaimOptions options) { + public List<@NonNull ByteRecord> xClaim(byte @NonNull [] key, @NonNull String group, @NonNull String newOwner, + @NonNull XClaimOptions options) { String[] ids = options.getIdsAsStringArray(); io.lettuce.core.Consumer from = io.lettuce.core.Consumer.from(LettuceConverters.toBytes(group), @@ -118,7 +124,7 @@ public List xClaim(byte[] key, String group, String newOwner, XClaim } @Override - public Long xDel(byte[] key, RecordId... recordIds) { + public Long xDel(byte @NonNull [] key, @NonNull RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.notNull(recordIds, "recordIds must not be null"); @@ -127,12 +133,13 @@ public Long xDel(byte[] key, RecordId... recordIds) { } @Override - public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset) { + public String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset) { return xGroupCreate(key, groupName, readOffset, false); } @Override - public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, boolean mkSteam) { + public String xGroupCreate(byte @NonNull [] key, @NonNull String groupName, @NonNull ReadOffset readOffset, + boolean mkSteam) { Assert.notNull(key, "Key must not be null"); Assert.hasText(groupName, "Group name must not be null or empty"); @@ -145,7 +152,7 @@ public String xGroupCreate(byte[] key, String groupName, ReadOffset readOffset, } @Override - public Boolean xGroupDelConsumer(byte[] key, Consumer consumer) { + public Boolean xGroupDelConsumer(byte @NonNull [] key, @NonNull Consumer consumer) { Assert.notNull(key, "Key must not be null"); Assert.notNull(consumer, "Consumer must not be null"); @@ -157,7 +164,7 @@ public Boolean xGroupDelConsumer(byte[] key, Consumer consumer) { } @Override - public Boolean xGroupDestroy(byte[] key, String groupName) { + public Boolean xGroupDestroy(byte @NonNull [] key, @NonNull String groupName) { Assert.notNull(key, "Key must not be null"); Assert.hasText(groupName, "Group name must not be null or empty"); @@ -166,7 +173,7 @@ public Boolean xGroupDestroy(byte[] key, String groupName) { } @Override - public XInfoStream xInfo(byte[] key) { + public XInfoStream xInfo(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -174,7 +181,7 @@ public XInfoStream xInfo(byte[] key) { } @Override - public XInfoGroups xInfoGroups(byte[] key) { + public XInfoGroups xInfoGroups(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -182,7 +189,7 @@ public XInfoGroups xInfoGroups(byte[] key) { } @Override - public XInfoConsumers xInfoConsumers(byte[] key, String groupName) { + public XInfoConsumers xInfoConsumers(byte @NonNull [] key, @NonNull String groupName) { Assert.notNull(key, "Key must not be null"); Assert.notNull(groupName, "GroupName must not be null"); @@ -192,7 +199,7 @@ public XInfoConsumers xInfoConsumers(byte[] key, String groupName) { } @Override - public Long xLen(byte[] key) { + public Long xLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -200,7 +207,7 @@ public Long xLen(byte[] key) { } @Override - public PendingMessagesSummary xPending(byte[] key, String groupName) { + public PendingMessagesSummary xPending(byte @NonNull [] key, @NonNull String groupName) { byte[] group = LettuceConverters.toBytes(groupName); @@ -209,7 +216,7 @@ public PendingMessagesSummary xPending(byte[] key, String groupName) { } @Override - public PendingMessages xPending(byte[] key, String groupName, XPendingOptions options) { + public PendingMessages xPending(byte @NonNull [] key, @NonNull String groupName, @NonNull XPendingOptions options) { byte[] group = LettuceConverters.toBytes(groupName); io.lettuce.core.Range range = RangeConverter.toRangeWithDefault(options.getRange(), "-", "+", @@ -230,7 +237,7 @@ public PendingMessages xPending(byte[] key, String groupName, XPendingOptions op } @Override - public List xRange(byte[] key, Range range, Limit limit) { + public List<@NonNull ByteRecord> xRange(byte @NonNull [] key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -244,7 +251,8 @@ public List xRange(byte[] key, Range range, Limit limit) { } @Override - public List xRead(StreamReadOptions readOptions, StreamOffset... streams) { + public List<@NonNull ByteRecord> xRead(@NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { Assert.notNull(readOptions, "StreamReadOptions must not be null"); Assert.notNull(streams, "StreamOffsets must not be null"); @@ -264,8 +272,8 @@ public List xRead(StreamReadOptions readOptions, StreamOffset xReadGroup(Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams) { + public List<@NonNull ByteRecord> xReadGroup(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { Assert.notNull(consumer, "Consumer must not be null"); Assert.notNull(readOptions, "StreamReadOptions must not be null"); @@ -287,7 +295,7 @@ public List xReadGroup(Consumer consumer, StreamReadOptions readOpti } @Override - public List xRevRange(byte[] key, Range range, Limit limit) { + public List<@NonNull ByteRecord> xRevRange(byte @NonNull [] key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -296,18 +304,17 @@ public List xRevRange(byte[] key, Range range, Limit limit) io.lettuce.core.Range lettuceRange = RangeConverter.toRange(range, Function.identity()); io.lettuce.core.Limit lettuceLimit = LettuceConverters.toLimit(limit); - return connection.invoke() - .fromMany(RedisStreamAsyncCommands::xrevrange, key, lettuceRange, lettuceLimit) + return connection.invoke().fromMany(RedisStreamAsyncCommands::xrevrange, key, lettuceRange, lettuceLimit) .toList(StreamConverters.byteRecordConverter()); } @Override - public Long xTrim(byte[] key, long count) { + public Long xTrim(byte @NonNull [] key, long count) { return xTrim(key, count, false); } @Override - public Long xTrim(byte[] key, long count, boolean approximateTrimming) { + public Long xTrim(byte @NonNull [] key, long count, boolean approximateTrimming) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(RedisStreamAsyncCommands::xtrim, key, approximateTrimming, count); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java index 5dad73a71e..87ab4b3e83 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java @@ -21,12 +21,14 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.RedisStringCommands; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -39,34 +41,33 @@ * @author Marcin Grzejszczak * @since 2.0 */ +@NullUnmarked class LettuceStringCommands implements RedisStringCommands { private final LettuceConnection connection; - LettuceStringCommands(LettuceConnection connection) { + LettuceStringCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public byte[] get(byte[] key) { + public byte[] get(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(RedisStringAsyncCommands::get, key); } - @Nullable @Override - public byte[] getDel(byte[] key) { + public byte[] getDel(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().just(RedisStringAsyncCommands::getdel, key); } - @Nullable @Override - public byte[] getEx(byte[] key, Expiration expiration) { + public byte[] getEx(byte @NonNull [] key, @NonNull Expiration expiration) { Assert.notNull(key, "Key must not be null"); Assert.notNull(expiration, "Expiration must not be null"); @@ -75,7 +76,7 @@ public byte[] getEx(byte[] key, Expiration expiration) { } @Override - public byte[] getSet(byte[] key, byte[] value) { + public byte[] getSet(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -84,7 +85,7 @@ public byte[] getSet(byte[] key, byte[] value) { } @Override - public List mGet(byte[]... keys) { + public List mGet(byte @NonNull [] @NonNull... keys) { Assert.notNull(keys, "Keys must not be null"); Assert.noNullElements(keys, "Keys must not contain null elements"); @@ -94,7 +95,7 @@ public List mGet(byte[]... keys) { } @Override - public Boolean set(byte[] key, byte[] value) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -104,7 +105,8 @@ public Boolean set(byte[] key, byte[] value) { } @Override - public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public Boolean set(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -117,20 +119,20 @@ public Boolean set(byte[] key, byte[] value, Expiration expiration, SetOption op } @Override - @Nullable - public byte[] setGet(byte[] key, byte[] value, Expiration expiration, SetOption option) { + public byte @Nullable [] setGet(byte @NonNull [] key, byte @NonNull [] value, @NonNull Expiration expiration, + @NonNull SetOption option) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); Assert.notNull(expiration, "Expiration must not be null"); Assert.notNull(option, "Option must not be null"); - return connection.invoke() - .just(RedisStringAsyncCommands::setGet, key, value, LettuceConverters.toSetArgs(expiration, option)); + return connection.invoke().just(RedisStringAsyncCommands::setGet, key, value, + LettuceConverters.toSetArgs(expiration, option)); } @Override - public Boolean setNX(byte[] key, byte[] value) { + public Boolean setNX(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -139,7 +141,7 @@ public Boolean setNX(byte[] key, byte[] value) { } @Override - public Boolean setEx(byte[] key, long seconds, byte[] value) { + public Boolean setEx(byte @NonNull [] key, long seconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -149,7 +151,7 @@ public Boolean setEx(byte[] key, long seconds, byte[] value) { } @Override - public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { + public Boolean pSetEx(byte @NonNull [] key, long milliseconds, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -159,7 +161,7 @@ public Boolean pSetEx(byte[] key, long milliseconds, byte[] value) { } @Override - public Boolean mSet(Map tuples) { + public Boolean mSet(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -167,7 +169,7 @@ public Boolean mSet(Map tuples) { } @Override - public Boolean mSetNX(Map tuples) { + public Boolean mSetNX(@NonNull Map tuples) { Assert.notNull(tuples, "Tuples must not be null"); @@ -175,7 +177,7 @@ public Boolean mSetNX(Map tuples) { } @Override - public Long incr(byte[] key) { + public Long incr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -183,7 +185,7 @@ public Long incr(byte[] key) { } @Override - public Long incrBy(byte[] key, long value) { + public Long incrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -191,7 +193,7 @@ public Long incrBy(byte[] key, long value) { } @Override - public Double incrBy(byte[] key, double value) { + public Double incrBy(byte @NonNull [] key, double value) { Assert.notNull(key, "Key must not be null"); @@ -199,7 +201,7 @@ public Double incrBy(byte[] key, double value) { } @Override - public Long decr(byte[] key) { + public Long decr(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -207,7 +209,7 @@ public Long decr(byte[] key) { } @Override - public Long decrBy(byte[] key, long value) { + public Long decrBy(byte @NonNull [] key, long value) { Assert.notNull(key, "Key must not be null"); @@ -215,7 +217,7 @@ public Long decrBy(byte[] key, long value) { } @Override - public Long append(byte[] key, byte[] value) { + public Long append(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -224,7 +226,7 @@ public Long append(byte[] key, byte[] value) { } @Override - public byte[] getRange(byte[] key, long start, long end) { + public byte[] getRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -232,7 +234,7 @@ public byte[] getRange(byte[] key, long start, long end) { } @Override - public void setRange(byte[] key, byte[] value, long offset) { + public void setRange(byte @NonNull [] key, byte @NonNull [] value, long offset) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -241,7 +243,7 @@ public void setRange(byte[] key, byte[] value, long offset) { } @Override - public Boolean getBit(byte[] key, long offset) { + public Boolean getBit(byte @NonNull [] key, long offset) { Assert.notNull(key, "Key must not be null"); @@ -250,7 +252,7 @@ public Boolean getBit(byte[] key, long offset) { } @Override - public Boolean setBit(byte[] key, long offset, boolean value) { + public Boolean setBit(byte @NonNull [] key, long offset, boolean value) { Assert.notNull(key, "Key must not be null"); @@ -259,7 +261,7 @@ public Boolean setBit(byte[] key, long offset, boolean value) { } @Override - public Long bitCount(byte[] key) { + public Long bitCount(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -267,7 +269,7 @@ public Long bitCount(byte[] key) { } @Override - public Long bitCount(byte[] key, long start, long end) { + public Long bitCount(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -275,7 +277,7 @@ public Long bitCount(byte[] key, long start, long end) { } @Override - public List bitField(byte[] key, BitFieldSubCommands subCommands) { + public List bitField(byte @NonNull [] key, @NonNull BitFieldSubCommands subCommands) { Assert.notNull(key, "Key must not be null"); Assert.notNull(subCommands, "Command must not be null"); @@ -286,7 +288,7 @@ public List bitField(byte[] key, BitFieldSubCommands subCommands) { } @Override - public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { + public Long bitOp(@NonNull BitOperation op, byte @NonNull [] destination, byte @NonNull [] @NonNull... keys) { Assert.notNull(op, "BitOperation must not be null"); Assert.notNull(destination, "Destination key must not be null"); @@ -295,23 +297,21 @@ public Long bitOp(BitOperation op, byte[] destination, byte[]... keys) { throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); } - return connection.invoke().just(it -> - switch (op) { - case AND -> it.bitopAnd(destination, keys); - case OR -> it.bitopOr(destination, keys); - case XOR -> it.bitopXor(destination, keys); - case NOT -> { - if (keys.length != 1) { - throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); - } - yield it.bitopNot(destination, keys[0]); + return connection.invoke().just(it -> switch (op) { + case AND -> it.bitopAnd(destination, keys); + case OR -> it.bitopOr(destination, keys); + case XOR -> it.bitopXor(destination, keys); + case NOT -> { + if (keys.length != 1) { + throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); } - }); + yield it.bitopNot(destination, keys[0]); + } + }); } - @Nullable @Override - public Long bitPos(byte[] key, boolean bit, Range range) { + public Long bitPos(byte @NonNull [] key, boolean bit, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null Use Range.unbounded() instead"); @@ -330,7 +330,7 @@ public Long bitPos(byte[] key, boolean bit, Range range) { } @Override - public Long strLen(byte[] key) { + public Long strLen(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java index aeb16f6e56..e777f2e46a 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java @@ -27,6 +27,9 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag; @@ -40,7 +43,6 @@ import org.springframework.data.redis.core.ScanIteration; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.TimeoutUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -53,16 +55,17 @@ * @author John Blum * @since 2.0 */ +@NullUnmarked class LettuceZSetCommands implements RedisZSetCommands { private final LettuceConnection connection; - LettuceZSetCommands(LettuceConnection connection) { + LettuceZSetCommands(@NonNull LettuceConnection connection) { this.connection = connection; } @Override - public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { + public Boolean zAdd(byte @NonNull [] key, double score, byte @NonNull [] value, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -73,7 +76,7 @@ public Boolean zAdd(byte[] key, double score, byte[] value, ZAddArgs args) { } @Override - public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { + public Long zAdd(byte @NonNull [] key, @NonNull Set<@NonNull Tuple> tuples, @NonNull ZAddArgs args) { Assert.notNull(key, "Key must not be null"); Assert.notNull(tuples, "Tuples must not be null"); @@ -83,7 +86,7 @@ public Long zAdd(byte[] key, Set tuples, ZAddArgs args) { } @Override - public Long zRem(byte[] key, byte[]... values) { + public Long zRem(byte @NonNull [] key, byte @NonNull [] @NonNull... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -93,7 +96,7 @@ public Long zRem(byte[] key, byte[]... values) { } @Override - public Double zIncrBy(byte[] key, double increment, byte[] value) { + public Double zIncrBy(byte @NonNull [] key, double increment, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -102,7 +105,7 @@ public Double zIncrBy(byte[] key, double increment, byte[] value) { } @Override - public byte[] zRandMember(byte[] key) { + public byte[] zRandMember(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -110,7 +113,7 @@ public byte[] zRandMember(byte[] key) { } @Override - public List zRandMember(byte[] key, long count) { + public List zRandMember(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -118,7 +121,7 @@ public List zRandMember(byte[] key, long count) { } @Override - public Tuple zRandMemberWithScore(byte[] key) { + public Tuple zRandMemberWithScore(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -127,7 +130,7 @@ public Tuple zRandMemberWithScore(byte[] key) { } @Override - public List zRandMemberWithScore(byte[] key, long count) { + public List<@NonNull Tuple> zRandMemberWithScore(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -136,7 +139,7 @@ public List zRandMemberWithScore(byte[] key, long count) { } @Override - public Long zRank(byte[] key, byte[] value) { + public Long zRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -145,7 +148,7 @@ public Long zRank(byte[] key, byte[] value) { } @Override - public Long zRevRank(byte[] key, byte[] value) { + public Long zRevRank(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); @@ -153,7 +156,7 @@ public Long zRevRank(byte[] key, byte[] value) { } @Override - public Set zRange(byte[] key, long start, long end) { + public Set zRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -161,7 +164,7 @@ public Set zRange(byte[] key, long start, long end) { } @Override - public Set zRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -170,8 +173,9 @@ public Set zRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set<@NonNull Tuple> zRangeByScoreWithScores(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null"); @@ -189,7 +193,7 @@ public Set zRangeByScoreWithScores(byte[] key, org.springframework.data.d } @Override - public Set zRevRange(byte[] key, long start, long end) { + public Set zRevRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -198,7 +202,7 @@ public Set zRevRange(byte[] key, long start, long end) { } @Override - public Set zRevRangeWithScores(byte[] key, long start, long end) { + public Set<@NonNull Tuple> zRevRangeWithScores(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -207,8 +211,9 @@ public Set zRevRangeWithScores(byte[] key, long start, long end) { } @Override - public Set zRevRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREVRANGEBYSCORE must not be null"); @@ -226,7 +231,7 @@ public Set zRevRangeByScore(byte[] key, org.springframework.data.domain. } @Override - public Set zRevRangeByScoreWithScores(byte[] key, + public Set<@NonNull Tuple> zRevRangeByScoreWithScores(byte @NonNull [] key, org.springframework.data.domain.Range range, org.springframework.data.redis.connection.Limit limit) { @@ -246,7 +251,7 @@ public Set zRevRangeByScoreWithScores(byte[] key, } @Override - public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); @@ -254,7 +259,7 @@ public Long zCount(byte[] key, org.springframework.data.domain.Range range) { + public Long zLexCount(byte @NonNull [] key, org.springframework.data.domain.@NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -263,18 +268,16 @@ public Long zLexCount(byte[] key, org.springframework.data.domain.Range LettuceConverters.toRange(range, true)); } - @Nullable @Override - public Tuple zPopMin(byte[] key) { + public Tuple zPopMin(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(RedisSortedSetAsyncCommands::zpopmin, key).get(LettuceConverters::toTuple); } - @Nullable @Override - public Set zPopMin(byte[] key, long count) { + public Set zPopMin(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -282,9 +285,8 @@ public Set zPopMin(byte[] key, long count) { .toSet(LettuceConverters::toTuple); } - @Nullable @Override - public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMin(byte @NonNull [] key, long timeout, TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -301,18 +303,16 @@ public Tuple bZPopMin(byte[] key, long timeout, TimeUnit unit) { .get(it -> it.map(LettuceConverters::toTuple).getValueOrElse(null)); } - @Nullable @Override - public Tuple zPopMax(byte[] key) { + public Tuple zPopMax(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); return connection.invoke().from(RedisSortedSetAsyncCommands::zpopmax, key).get(LettuceConverters::toTuple); } - @Nullable @Override - public Set zPopMax(byte[] key, long count) { + public Set<@NonNull Tuple> zPopMax(byte @NonNull [] key, long count) { Assert.notNull(key, "Key must not be null"); @@ -320,9 +320,8 @@ public Set zPopMax(byte[] key, long count) { .toSet(LettuceConverters::toTuple); } - @Nullable @Override - public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { + public Tuple bZPopMax(byte @NonNull [] key, long timeout, TimeUnit unit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(unit, "TimeUnit must not be null"); @@ -340,7 +339,7 @@ public Tuple bZPopMax(byte[] key, long timeout, TimeUnit unit) { } @Override - public Long zCard(byte[] key) { + public Long zCard(byte @NonNull [] key) { Assert.notNull(key, "Key must not be null"); @@ -348,7 +347,7 @@ public Long zCard(byte[] key) { } @Override - public Double zScore(byte[] key, byte[] value) { + public Double zScore(byte @NonNull [] key, byte @NonNull [] value) { Assert.notNull(key, "Key must not be null"); Assert.notNull(value, "Value must not be null"); @@ -357,7 +356,7 @@ public Double zScore(byte[] key, byte[] value) { } @Override - public List zMScore(byte[] key, byte[][] values) { + public List zMScore(byte @NonNull [] key, byte[][] values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Value must not be null"); @@ -366,7 +365,7 @@ public List zMScore(byte[] key, byte[][] values) { } @Override - public Long zRemRange(byte[] key, long start, long end) { + public Long zRemRange(byte @NonNull [] key, long start, long end) { Assert.notNull(key, "Key must not be null"); @@ -374,7 +373,7 @@ public Long zRemRange(byte[] key, long start, long end) { } @Override - public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByLex(byte @NonNull [] key, org.springframework.data.domain.Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX"); @@ -384,7 +383,7 @@ public Long zRemRangeByLex(byte[] key, org.springframework.data.domain.Range range) { + public Long zRemRangeByScore(byte @NonNull [] key, org.springframework.data.domain.Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZREMRANGEBYSCORE must not be null"); @@ -394,7 +393,7 @@ public Long zRemRangeByScore(byte[] key, org.springframework.data.domain.Range zDiff(byte[]... sets) { + public Set zDiff(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -402,7 +401,7 @@ public Set zDiff(byte[]... sets) { } @Override - public Set zDiffWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zDiffWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -411,7 +410,7 @@ public Set zDiffWithScores(byte[]... sets) { } @Override - public Long zDiffStore(byte[] destKey, byte[]... sets) { + public Long zDiffStore(byte[] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -420,7 +419,7 @@ public Long zDiffStore(byte[] destKey, byte[]... sets) { } @Override - public Set zInter(byte[]... sets) { + public Set zInter(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -428,7 +427,7 @@ public Set zInter(byte[]... sets) { } @Override - public Set zInterWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -437,7 +436,8 @@ public Set zInterWithScores(byte[]... sets) { } @Override - public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zInterWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -451,7 +451,8 @@ public Set zInterWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -465,7 +466,7 @@ public Long zInterStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Long zInterStore(byte[] destKey, byte[]... sets) { + public Long zInterStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -475,7 +476,7 @@ public Long zInterStore(byte[] destKey, byte[]... sets) { } @Override - public Set zUnion(byte[]... sets) { + public Set zUnion(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -483,7 +484,7 @@ public Set zUnion(byte[]... sets) { } @Override - public Set zUnionWithScores(byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); @@ -492,7 +493,8 @@ public Set zUnionWithScores(byte[]... sets) { } @Override - public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]... sets) { + public Set<@NonNull Tuple> zUnionWithScores(@NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(sets, "Sets must not be null"); Assert.noNullElements(sets, "Source sets must not contain null elements"); @@ -506,7 +508,8 @@ public Set zUnionWithScores(Aggregate aggregate, Weights weights, byte[]. } @Override - public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, @NonNull Aggregate aggregate, @NonNull Weights weights, + byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -520,7 +523,7 @@ public Long zUnionStore(byte[] destKey, Aggregate aggregate, Weights weights, by } @Override - public Long zUnionStore(byte[] destKey, byte[]... sets) { + public Long zUnionStore(byte @NonNull [] destKey, byte @NonNull [] @NonNull... sets) { Assert.notNull(destKey, "Destination key must not be null"); Assert.notNull(sets, "Source sets must not be null"); @@ -530,21 +533,21 @@ public Long zUnionStore(byte[] destKey, byte[]... sets) { } @Override - public Cursor zScan(byte[] key, ScanOptions options) { - return zScan(key, CursorId.initial(), options); + public Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @Nullable ScanOptions options) { + return zScan(key, CursorId.initial(), options != null ? options : ScanOptions.NONE); } /** * @since 1.4 */ - public Cursor zScan(byte[] key, CursorId cursorId, ScanOptions options) { + public Cursor<@NonNull Tuple> zScan(byte @NonNull [] key, @NonNull CursorId cursorId, @NonNull ScanOptions options) { Assert.notNull(key, "Key must not be null"); return new KeyBoundCursor(key, cursorId, options) { @Override - protected ScanIteration doScan(byte[] key, CursorId cursorId, ScanOptions options) { + protected ScanIteration doScan(byte @NonNull [] key, CursorId cursorId, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { throw new InvalidDataAccessApiUsageException("'ZSCAN' cannot be called in pipeline / transaction mode"); @@ -572,7 +575,7 @@ protected void doClose() { } @Override - public Set zRangeByScore(byte[] key, String min, String max) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max) { Assert.notNull(key, "Key must not be null"); @@ -580,7 +583,8 @@ public Set zRangeByScore(byte[] key, String min, String max) { } @Override - public Set zRangeByScore(byte[] key, String min, String max, long offset, long count) { + public Set zRangeByScore(byte @NonNull [] key, @Nullable String min, @Nullable String max, + long offset, long count) { Assert.notNull(key, "Key must not be null"); @@ -589,8 +593,9 @@ public Set zRangeByScore(byte[] key, String min, String max, long offset } @Override - public Set zRangeByScore(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByScore(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null"); @@ -606,8 +611,9 @@ public Set zRangeByScore(byte[] key, org.springframework.data.domain.Ran } @Override - public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for ZRANGEBYLEX must not be null"); @@ -623,8 +629,9 @@ public Set zRangeByLex(byte[] key, org.springframework.data.domain.Range } @Override - public Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Set zRevRangeByLex(byte @NonNull [] key, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range for must not be null"); @@ -640,8 +647,9 @@ public Set zRevRangeByLex(byte[] key, org.springframework.data.domain.Ra } @Override - public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -653,8 +661,9 @@ public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.d } @Override - public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByLex(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -666,9 +675,9 @@ public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframewor } @Override - public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); @@ -680,9 +689,9 @@ public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, } @Override - public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, - org.springframework.data.domain.Range range, - org.springframework.data.redis.connection.Limit limit) { + public Long zRangeStoreRevByScore(byte @NonNull [] dstKey, byte @NonNull [] srcKey, + org.springframework.data.domain.@NonNull Range range, + org.springframework.data.redis.connection.@NonNull Limit limit) { Assert.notNull(dstKey, "Destination key must not be null"); Assert.notNull(srcKey, "Source key must not be null"); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/RangeConverter.java b/src/main/java/org/springframework/data/redis/connection/lettuce/RangeConverter.java index 9210d2d908..f197310e96 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/RangeConverter.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/RangeConverter.java @@ -21,8 +21,8 @@ import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range.Bound; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -87,7 +87,7 @@ private static Boundary upperBoundArgOf(org.springframework.data.domain.R } static Boundary convertBound(org.springframework.data.domain.Range.Bound source, boolean convertNumberToBytes, - Object defaultValue, Function stringEncoder) { + @Nullable Object defaultValue, Function stringEncoder) { if (!source.isBounded()) { return Boundary.unbounded(); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/RedisCredentialsProviderFactory.java b/src/main/java/org/springframework/data/redis/connection/lettuce/RedisCredentialsProviderFactory.java index b29341b22b..c0c999c346 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/RedisCredentialsProviderFactory.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/RedisCredentialsProviderFactory.java @@ -17,11 +17,12 @@ import io.lettuce.core.RedisCredentials; import io.lettuce.core.RedisCredentialsProvider; + +import org.jspecify.annotations.Nullable; import reactor.core.publisher.Mono; import org.springframework.data.redis.connection.RedisConfiguration; import org.springframework.data.redis.connection.RedisSentinelConfiguration; -import org.springframework.lang.Nullable; /** * Factory interface to create {@link RedisCredentialsProvider} from a {@link RedisConfiguration}. Credentials can be @@ -44,8 +45,7 @@ public interface RedisCredentialsProviderFactory { * @param redisConfiguration the {@link RedisConfiguration} object. * @return a {@link RedisCredentialsProvider} that emits {@link RedisCredentials} for data node authentication. */ - @Nullable - default RedisCredentialsProvider createCredentialsProvider(RedisConfiguration redisConfiguration) { + default @Nullable RedisCredentialsProvider createCredentialsProvider(RedisConfiguration redisConfiguration) { if (redisConfiguration instanceof RedisConfiguration.WithAuthentication && ((RedisConfiguration.WithAuthentication) redisConfiguration).getPassword().isPresent()) { @@ -87,8 +87,7 @@ enum AbsentRedisCredentials implements RedisCredentials { ANONYMOUS; @Override - @Nullable - public String getUsername() { + public @Nullable String getUsername() { return null; } @@ -98,8 +97,7 @@ public boolean hasUsername() { } @Override - @Nullable - public char[] getPassword() { + public char @Nullable[] getPassword() { return null; } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/StandaloneConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/StandaloneConnectionProvider.java index e812b4946b..e3caf1a2c6 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/StandaloneConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/StandaloneConnectionProvider.java @@ -34,9 +34,9 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.beans.DirectFieldAccessor; import org.springframework.data.redis.connection.lettuce.LettuceConnectionProvider.TargetAware; -import org.springframework.lang.Nullable; /** * {@link LettuceConnectionProvider} implementation for a standalone Redis setup. @@ -81,6 +81,7 @@ class StandaloneConnectionProvider implements LettuceConnectionProvider, TargetA AtomicReference uriFieldReference = new AtomicReference<>(); @Override + @SuppressWarnings("NullAway") public RedisURI get() { RedisURI uri = uriFieldReference.get(); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java index 562c2eef31..cf06eb40d3 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java @@ -29,7 +29,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * {@link LettuceConnectionProvider} implementation for a static Master/Replica connection suitable for eg. AWS diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/aot/LettuceRuntimeHints.java b/src/main/java/org/springframework/data/redis/connection/lettuce/aot/LettuceRuntimeHints.java index 337b000195..703ad64724 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/aot/LettuceRuntimeHints.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/aot/LettuceRuntimeHints.java @@ -15,11 +15,11 @@ */ package org.springframework.data.redis.connection.lettuce.aot; +import org.jspecify.annotations.Nullable; import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.aot.hint.TypeReference; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/package-info.java b/src/main/java/org/springframework/data/redis/connection/lettuce/package-info.java index 6a8dd8d256..cedc904ead 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/package-info.java @@ -1,6 +1,5 @@ /** * Connection package for Lettuce Redis client. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection.lettuce; diff --git a/src/main/java/org/springframework/data/redis/connection/package-info.java b/src/main/java/org/springframework/data/redis/connection/package-info.java index e8ea570a95..ac6bff9d8f 100644 --- a/src/main/java/org/springframework/data/redis/connection/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/package-info.java @@ -3,7 +3,6 @@ *

* Performs exception translation between the underlying library exceptions to Spring's DAO hierarchy. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection; diff --git a/src/main/java/org/springframework/data/redis/connection/stream/ByteBufferRecord.java b/src/main/java/org/springframework/data/redis/connection/stream/ByteBufferRecord.java index 488ad046fc..2c459462f1 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/ByteBufferRecord.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/ByteBufferRecord.java @@ -20,10 +20,10 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; /** * A {@link Record} within the stream backed by a collection of binary {@literal field/value} pairs. @@ -65,6 +65,7 @@ default MapRecord deserialize(@Nullable RedisSerializer serializ * @param valueSerializer can be {@literal null} if the values suite already the target format. * @return new {@link MapRecord} holding the deserialized values. */ + @SuppressWarnings("NullAway") default MapRecord deserialize(@Nullable RedisSerializer streamSerializer, @Nullable RedisSerializer fieldSerializer, @Nullable RedisSerializer valueSerializer) { @@ -94,7 +95,7 @@ static ByteBufferRecord of(MapRecord source) * @param mapper must not be {@literal null}. * @return new instance of {@link ByteRecord}. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes", "NullAway" }) default ObjectRecord toObjectRecord( HashMapper mapper) { diff --git a/src/main/java/org/springframework/data/redis/connection/stream/ByteRecord.java b/src/main/java/org/springframework/data/redis/connection/stream/ByteRecord.java index 25d625ae6d..93d38d31b3 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/ByteRecord.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/ByteRecord.java @@ -18,8 +18,8 @@ import java.util.Collections; import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; /** * A {@link Record} within the stream backed by a collection of binary {@literal field/value} pairs. @@ -61,6 +61,7 @@ default MapRecord deserialize(@Nullable RedisSerializer serializ * @param valueSerializer can be {@literal null} if the values suite already the target format. * @return new {@link MapRecord} holding the deserialized values. */ + @SuppressWarnings("NullAway") default MapRecord deserialize(@Nullable RedisSerializer streamSerializer, @Nullable RedisSerializer fieldSerializer, @Nullable RedisSerializer valueSerializer) { diff --git a/src/main/java/org/springframework/data/redis/connection/stream/Consumer.java b/src/main/java/org/springframework/data/redis/connection/stream/Consumer.java index b5c05e1e03..ee5216ec35 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/Consumer.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/Consumer.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection.stream; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/stream/MapRecord.java b/src/main/java/org/springframework/data/redis/connection/stream/MapRecord.java index baf61286b6..066436ab0a 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/MapRecord.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/MapRecord.java @@ -21,10 +21,10 @@ import java.util.Map.Entry; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.stream.StreamRecords.MapBackedRecord; import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -113,6 +113,7 @@ default ByteRecord serialize(@Nullable RedisSerializer serializer) { * @param valueSerializer can be {@literal null} if the values are binary. * @return new {@link ByteRecord} holding the serialized values. */ + @SuppressWarnings("NullAway") default ByteRecord serialize(@Nullable RedisSerializer streamSerializer, @Nullable RedisSerializer fieldSerializer, @Nullable RedisSerializer valueSerializer) { @@ -134,7 +135,7 @@ default ByteRecord serialize(@Nullable RedisSerializer streamSerializ * @param type of the value backing the {@link ObjectRecord}. * @return new instance of {@link ObjectRecord}. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes", "NullAway" }) default ObjectRecord toObjectRecord(HashMapper mapper) { return Record. of((OV) mapper.fromHash((Map) getValue())).withId(getId()).withStreamKey(getRequiredStream()); } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/ObjectRecord.java b/src/main/java/org/springframework/data/redis/connection/stream/ObjectRecord.java index 7cb685dfb9..1d8f9765c4 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/ObjectRecord.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/ObjectRecord.java @@ -59,6 +59,7 @@ static ObjectRecord create(S stream, V value) { * @param the value type of the resulting {@link MapRecord}. * @return new instance of {@link MapRecord}. */ + @SuppressWarnings("NullAway") default MapRecord toMapRecord(HashMapper mapper) { return Record. of(mapper.toHash(getValue())).withId(getId()).withStreamKey(getStream()); } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/ReadOffset.java b/src/main/java/org/springframework/data/redis/connection/stream/ReadOffset.java index 0e9563d5ce..9d4cc7028f 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/ReadOffset.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/ReadOffset.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection.stream; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/stream/Record.java b/src/main/java/org/springframework/data/redis/connection/stream/Record.java index 9ad9a8cd6f..f558312995 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/Record.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/Record.java @@ -17,7 +17,7 @@ import java.util.Map; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/connection/stream/RecordId.java b/src/main/java/org/springframework/data/redis/connection/stream/RecordId.java index 6e79c38cc7..88533b459e 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/RecordId.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/RecordId.java @@ -15,7 +15,8 @@ */ package org.springframework.data.redis.connection.stream; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; @@ -42,12 +43,12 @@ public class RecordId { @Override public Long getSequence() { - return null; + return Long.MIN_VALUE; } @Override public Long getTimestamp() { - return null; + return Long.MIN_VALUE; } @Override @@ -114,8 +115,7 @@ public static RecordId autoGenerate() { * * @return millisecondsTime of the {@literal entry-id}. Can be {@literal null}. */ - @Nullable - public Long getTimestamp() { + public @Nullable Long getTimestamp() { return value(0); } @@ -124,8 +124,7 @@ public Long getTimestamp() { * * @return sequenceNumber of the {@literal entry-id}. Can be {@literal null}. */ - @Nullable - public Long getSequence() { + public @Nullable Long getSequence() { return value(1); } @@ -149,6 +148,7 @@ public String toString() { return raw; } + @SuppressWarnings("NullAway") private Long value(int index) { return NumberUtils.parseNumber(StringUtils.split(raw, DELIMITER)[index], Long.class); } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/StreamInfo.java b/src/main/java/org/springframework/data/redis/connection/stream/StreamInfo.java index 4a657a03f5..1d2f734185 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/StreamInfo.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/StreamInfo.java @@ -26,9 +26,9 @@ import java.util.function.Function; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -181,7 +181,7 @@ public String lastGeneratedId() { * * @return */ - public String firstEntryId() { + public @Nullable String firstEntryId() { return getAndMap("first-entry", Map.class, it -> it.keySet().iterator().next().toString()); } @@ -190,7 +190,7 @@ public String firstEntryId() { * * @return */ - public Map getFirstEntry() { + public @Nullable Map getFirstEntry() { return getAndMap("first-entry", Map.class, Collections::unmodifiableMap); } @@ -199,7 +199,7 @@ public Map getFirstEntry() { * * @return */ - public String lastEntryId() { + public @Nullable String lastEntryId() { return getAndMap("last-entry", Map.class, it -> it.keySet().iterator().next().toString()); } @@ -208,7 +208,7 @@ public String lastEntryId() { * * @return */ - public Map getLastEntry() { + public @Nullable Map getLastEntry() { return getAndMap("last-entry", Map.class, Collections::unmodifiableMap); } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/StreamOffset.java b/src/main/java/org/springframework/data/redis/connection/stream/StreamOffset.java index df44bc663a..01722c74e0 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/StreamOffset.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/StreamOffset.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.connection.stream; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -84,6 +84,7 @@ public static StreamOffset fromStart(K stream) { public static StreamOffset from(Record reference) { Assert.notNull(reference, "Reference record must not be null"); + Assert.notNull(reference.getStream(), "Reference.getStream() must not be null"); return create(reference.getStream(), ReadOffset.from(reference.getId())); } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/StreamReadOptions.java b/src/main/java/org/springframework/data/redis/connection/stream/StreamReadOptions.java index 4729e38a41..e68629f689 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/StreamReadOptions.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/StreamReadOptions.java @@ -17,7 +17,7 @@ import java.time.Duration; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -109,13 +109,11 @@ public boolean isBlocking() { return getBlock() != null && getBlock() >= 0; } - @Nullable - public Long getBlock() { + public @Nullable Long getBlock() { return block; } - @Nullable - public Long getCount() { + public @Nullable Long getCount() { return count; } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/StreamRecords.java b/src/main/java/org/springframework/data/redis/connection/stream/StreamRecords.java index 499119a1be..5c5524de46 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/StreamRecords.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/StreamRecords.java @@ -20,8 +20,8 @@ import java.util.Map; import java.util.Map.Entry; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -109,7 +109,7 @@ private StreamRecords() {} public static class RecordBuilder { private RecordId id; - private S stream; + private @Nullable S stream; RecordBuilder(@Nullable S stream, RecordId recordId) { @@ -321,7 +321,7 @@ public int hashCode() { */ static class ByteMapBackedRecord extends MapBackedRecord implements ByteRecord { - ByteMapBackedRecord(@Nullable byte[] stream, RecordId recordId, Map map) { + ByteMapBackedRecord(byte @Nullable[] stream, RecordId recordId, Map map) { super(stream, recordId, map); } @@ -342,7 +342,7 @@ public ByteMapBackedRecord withId(RecordId id) { static class ByteBufferMapBackedRecord extends MapBackedRecord implements ByteBufferRecord { - ByteBufferMapBackedRecord(@Nullable ByteBuffer stream, @Nullable RecordId recordId, + ByteBufferMapBackedRecord(@Nullable ByteBuffer stream, RecordId recordId, Map map) { super(stream, recordId, map); } @@ -363,7 +363,7 @@ public ByteBufferMapBackedRecord withId(RecordId id) { */ static class StringMapBackedRecord extends MapBackedRecord implements StringRecord { - StringMapBackedRecord(@Nullable String stream, @Nullable RecordId recordId, Map stringStringMap) { + StringMapBackedRecord(@Nullable String stream, RecordId recordId, Map stringStringMap) { super(stream, recordId, stringStringMap); } @@ -403,7 +403,7 @@ public S getStream() { return stream; } - @Nullable + @Override public RecordId getId() { return recordId; diff --git a/src/main/java/org/springframework/data/redis/connection/stream/StreamSerialization.java b/src/main/java/org/springframework/data/redis/connection/stream/StreamSerialization.java index 8849fc9813..698d8bb759 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/StreamSerialization.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/StreamSerialization.java @@ -17,9 +17,10 @@ import java.nio.ByteBuffer; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; /** * Utility methods for stream serialization. @@ -37,8 +38,8 @@ class StreamSerialization { * @param value the value to serialize. * @return the serialized (binary) representation of {@code value}. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - static byte[] serialize(@Nullable RedisSerializer serializer, Object value) { + @SuppressWarnings({ "unchecked", "rawtypes", "NullAway" }) + static byte@Nullable[] serialize(@Nullable RedisSerializer serializer, Object value) { return canSerialize(serializer, value) ? ((RedisSerializer) serializer).serialize(value) : (byte[]) value; } @@ -46,7 +47,7 @@ static byte[] serialize(@Nullable RedisSerializer serializer, Object value) { * Deserialize the {@code value using the optional {@link RedisSerializer}. If no conversion is possible, return * {@code value}. @param serializer @param value @param @return */ - static T deserialize(@Nullable RedisSerializer serializer, ByteBuffer value) { + static @Nullable T deserialize(@Nullable RedisSerializer serializer, ByteBuffer value) { return deserialize(serializer, ByteUtils.getBytes(value)); } @@ -54,7 +55,7 @@ static T deserialize(@Nullable RedisSerializer serializer, Byte * Deserialize the {@code value using the optional {@link RedisSerializer}. If no conversion is possible, return * {@code value}. @param serializer @param value @param @return */ - static T deserialize(@Nullable RedisSerializer serializer, byte[] value) { + static @Nullable T deserialize(@Nullable RedisSerializer serializer, byte[] value) { return serializer != null ? serializer.deserialize(value) : (T) value; } diff --git a/src/main/java/org/springframework/data/redis/connection/stream/package-info.java b/src/main/java/org/springframework/data/redis/connection/stream/package-info.java index 07d5dd4ecd..faf0a81c61 100644 --- a/src/main/java/org/springframework/data/redis/connection/stream/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/stream/package-info.java @@ -1,6 +1,5 @@ /** * Data structures and interfaces to interact with Redis Streams. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection.stream; diff --git a/src/main/java/org/springframework/data/redis/connection/util/AbstractSubscription.java b/src/main/java/org/springframework/data/redis/connection/util/AbstractSubscription.java index 8ffb356306..c791a54e08 100644 --- a/src/main/java/org/springframework/data/redis/connection/util/AbstractSubscription.java +++ b/src/main/java/org/springframework/data/redis/connection/util/AbstractSubscription.java @@ -19,10 +19,10 @@ import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.RedisInvalidSubscriptionException; import org.springframework.data.redis.connection.Subscription; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -53,7 +53,7 @@ protected AbstractSubscription(MessageListener listener) { * @param channels can be {@literal null}. * @param patterns can be {@literal null}. */ - protected AbstractSubscription(MessageListener listener, @Nullable byte[][] channels, @Nullable byte[][] patterns) { + protected AbstractSubscription(MessageListener listener, byte @Nullable[][] channels, byte @Nullable[][] patterns) { Assert.notNull(listener, "MessageListener must not be null"); @@ -175,7 +175,7 @@ public void unsubscribe() { } @Override - public void pUnsubscribe(@Nullable byte[]... patts) { + public void pUnsubscribe(byte @Nullable[]... patts) { if (!isAlive()) { return; } @@ -203,7 +203,7 @@ public void pUnsubscribe(@Nullable byte[]... patts) { } @Override - public void unsubscribe(@Nullable byte[]... chans) { + public void unsubscribe(byte @Nullable[]... chans) { if (!isAlive()) { return; } @@ -255,7 +255,7 @@ private static Collection clone(Collection col) { return list; } - private static void add(Collection col, @Nullable byte[]... bytes) { + private static void add(Collection col, byte @Nullable[]... bytes) { if (!ObjectUtils.isEmpty(bytes)) { for (byte[] bs : bytes) { col.add(new ByteArrayWrapper(bs)); @@ -263,7 +263,7 @@ private static void add(Collection col, @Nullable byte[]... by } } - private static void remove(Collection col, @Nullable byte[]... bytes) { + private static void remove(Collection col, byte @Nullable[]... bytes) { if (!ObjectUtils.isEmpty(bytes)) { for (byte[] bs : bytes) { col.remove(new ByteArrayWrapper(bs)); diff --git a/src/main/java/org/springframework/data/redis/connection/util/ByteArrayWrapper.java b/src/main/java/org/springframework/data/redis/connection/util/ByteArrayWrapper.java index 883bc003c8..c738680784 100644 --- a/src/main/java/org/springframework/data/redis/connection/util/ByteArrayWrapper.java +++ b/src/main/java/org/springframework/data/redis/connection/util/ByteArrayWrapper.java @@ -18,8 +18,8 @@ import java.nio.ByteBuffer; import java.util.Arrays; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; /** * Simple wrapper class used for wrapping arrays so they can be used as keys inside maps. diff --git a/src/main/java/org/springframework/data/redis/connection/util/DecodeUtils.java b/src/main/java/org/springframework/data/redis/connection/util/DecodeUtils.java index 42e7bd43a6..0e1ce14072 100644 --- a/src/main/java/org/springframework/data/redis/connection/util/DecodeUtils.java +++ b/src/main/java/org/springframework/data/redis/connection/util/DecodeUtils.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Simple class containing various decoding utilities. @@ -47,8 +47,8 @@ public static String[] decodeMultiple(byte[]... bytes) { return result; } - @Nullable - public static byte[] encode(@Nullable String string) { + + public static byte @Nullable[] encode(@Nullable String string) { return (string == null ? null : Base64.getEncoder().encode(string.getBytes())); } diff --git a/src/main/java/org/springframework/data/redis/connection/util/package-info.java b/src/main/java/org/springframework/data/redis/connection/util/package-info.java index b655016f04..2b21f13d92 100644 --- a/src/main/java/org/springframework/data/redis/connection/util/package-info.java +++ b/src/main/java/org/springframework/data/redis/connection/util/package-info.java @@ -1,7 +1,6 @@ /** * Internal utility package for encoding/decoding Strings to byte[] (using Base64) library. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.connection.util; diff --git a/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java b/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java index 00637153eb..b97358d5a6 100644 --- a/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java +++ b/src/main/java/org/springframework/data/redis/connection/zset/DefaultTuple.java @@ -17,7 +17,7 @@ import java.util.Arrays; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Default implementation for {@link Tuple} interface. diff --git a/src/main/java/org/springframework/data/redis/connection/zset/Weights.java b/src/main/java/org/springframework/data/redis/connection/zset/Weights.java index 754c48f230..6d799a033d 100644 --- a/src/main/java/org/springframework/data/redis/connection/zset/Weights.java +++ b/src/main/java/org/springframework/data/redis/connection/zset/Weights.java @@ -24,7 +24,7 @@ import java.util.stream.DoubleStream; import java.util.stream.IntStream; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/connection/zset/package-info.java b/src/main/java/org/springframework/data/redis/connection/zset/package-info.java new file mode 100644 index 0000000000..5f38aa9cb0 --- /dev/null +++ b/src/main/java/org/springframework/data/redis/connection/zset/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package org.springframework.data.redis.connection.zset; diff --git a/src/main/java/org/springframework/data/redis/core/AbstractOperations.java b/src/main/java/org/springframework/data/redis/core/AbstractOperations.java index c730e2d74b..380607b3e9 100644 --- a/src/main/java/org/springframework/data/redis/core/AbstractOperations.java +++ b/src/main/java/org/springframework/data/redis/core/AbstractOperations.java @@ -25,6 +25,9 @@ import java.util.Set; import java.util.function.BiFunction; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.GeoResults; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; @@ -34,7 +37,6 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -48,6 +50,7 @@ * @author Mark Paluch * @author Denis Zavedeev */ +@NullUnmarked abstract class AbstractOperations { // utility methods for the template internal methods @@ -58,13 +61,12 @@ public ValueDeserializingRedisCallback(Object key) { this.key = key; } - public final V doInRedis(RedisConnection connection) { + public final V doInRedis(@NonNull RedisConnection connection) { byte[] result = inRedis(rawKey(key), connection); return deserializeValue(result); } - @Nullable - protected abstract byte[] inRedis(byte[] rawKey, RedisConnection connection); + protected abstract byte @Nullable [] inRedis(byte[] rawKey, RedisConnection connection); } private class FunctionalValueDeserializingRedisCallback extends ValueDeserializingRedisCallback { @@ -76,15 +78,14 @@ public FunctionalValueDeserializingRedisCallback(Object key, BiFunction template; - AbstractOperations(RedisTemplate template) { + AbstractOperations(@NonNull RedisTemplate template) { this.template = template; } @@ -112,17 +113,16 @@ RedisSerializer stringSerializer() { return template.getStringSerializer(); } - @Nullable - T execute(RedisCallback callback) { + T execute(@NonNull RedisCallback callback) { return template.execute(callback, true); } - public RedisOperations getOperations() { + public @NonNull RedisOperations getOperations() { return template; } @SuppressWarnings("unchecked") - byte[] rawKey(Object key) { + byte[] rawKey(@NonNull Object key) { Assert.notNull(key, "non null key required"); @@ -244,8 +244,7 @@ Set deserializeValues(Set rawValues) { return SerializationUtils.deserialize(rawValues, valueSerializer()); } - @Nullable - Set> deserializeTupleValues(@Nullable Set rawValues) { + Set> deserializeTupleValues(Set rawValues) { if (rawValues == null) { return null; } @@ -268,8 +267,7 @@ List> deserializeTupleValues(List rawValues) { } @SuppressWarnings({ "unchecked", "rawtypes" }) - @Nullable - TypedTuple deserializeTuple(@Nullable Tuple tuple) { + TypedTuple deserializeTuple(Tuple tuple) { if (tuple == null) { return null; } @@ -331,7 +329,7 @@ List deserializeHashValues(List rawValues) { } @SuppressWarnings("unchecked") - Map deserializeHashMap(@Nullable Map entries) { + Map deserializeHashMap(Map entries) { // connection in pipeline/multi mode if (entries == null) { @@ -407,8 +405,7 @@ HV deserializeHashValue(byte[] value) { * @return converted or {@literal null}. * @since 1.8 */ - @Nullable - GeoResults> deserializeGeoResults(@Nullable GeoResults> source) { + GeoResults> deserializeGeoResults(GeoResults> source) { if (source == null) { return null; diff --git a/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java b/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java index d11a387f80..08103aa7f9 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundGeoOperations.java @@ -15,11 +15,16 @@ */ package org.springframework.data.redis.core; -import static org.springframework.data.redis.connection.RedisGeoCommands.*; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchCommandArgs; +import static org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs; import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; @@ -28,7 +33,6 @@ import org.springframework.data.redis.domain.geo.BoundingBox; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; /** * {@link GeoOperations} bound to a certain key. @@ -38,6 +42,7 @@ * @author Mark Paluch * @since 1.8 */ +@NullUnmarked public interface BoundGeoOperations extends BoundKeyOperations { /** @@ -49,8 +54,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(Point point, M member); + Long add(@NonNull Point point, @NonNull M member); /** * Add {@link GeoLocation} to {@literal key}. @@ -60,8 +64,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(GeoLocation location); + Long add(@NonNull GeoLocation location); /** * Add {@link Map} of member / {@link Point} pairs to {@literal key}. @@ -71,8 +74,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(Map memberCoordinateMap); + Long add(@NonNull Map<@NonNull M, @NonNull Point> memberCoordinateMap); /** * Add {@link GeoLocation}s to {@literal key} @@ -82,8 +84,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(Iterable> locations); + Long add(@NonNull Iterable<@NonNull GeoLocation> locations); /** * Get the {@link Distance} between {@literal member1} and {@literal member2}. @@ -94,8 +95,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEODIST */ - @Nullable - Distance distance(M member1, M member2); + Distance distance(@NonNull M member1, @NonNull M member2); /** * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. @@ -107,8 +107,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEODIST */ - @Nullable - Distance distance(M member1, M member2, Metric metric); + Distance distance(@NonNull M member1, @NonNull M member2, @NonNull Metric metric); /** * Get Geohash representation of the position for one or more {@literal member}s. @@ -118,8 +117,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOHASH */ - @Nullable - List hash(M... members); + List hash(@NonNull M @NonNull... members); /** * Get the {@link Point} representation of positions for one or more {@literal member}s. @@ -129,9 +127,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEOPOS */ - @Nullable - List position(M... members); - + List position(@NonNull M @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -141,8 +137,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> radius(Circle within); + GeoResults> radius(@NonNull Circle within); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. @@ -153,8 +148,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> radius(Circle within, GeoRadiusCommandArgs args); + GeoResults> radius(@NonNull Circle within, @NonNull GeoRadiusCommandArgs args); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -166,8 +160,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(M member, double radius); + GeoResults> radius(@NonNull M member, double radius); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -179,8 +172,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(M member, Distance distance); + GeoResults> radius(@NonNull M member, @NonNull Distance distance); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -193,8 +185,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(M member, Distance distance, GeoRadiusCommandArgs args); + GeoResults> radius(@NonNull M member, @NonNull Distance distance, @NonNull GeoRadiusCommandArgs args); /** * Remove the {@literal member}s. @@ -203,8 +194,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @return Number of elements removed. {@literal null} when used in pipeline / transaction. * @since 2.0 */ - @Nullable - Long remove(M... members); + Long remove(@NonNull M @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -214,8 +204,7 @@ public interface BoundGeoOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(Circle within) { + default GeoResults> search(@NonNull Circle within) { return search(GeoReference.fromCircle(within), GeoShape.byRadius(within.getRadius()), GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -230,8 +219,7 @@ default GeoResults> search(Circle within) { * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(GeoReference reference, Distance radius) { + default GeoResults> search(@NonNull GeoReference reference, @NonNull Distance radius) { return search(reference, radius, GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -246,9 +234,8 @@ default GeoResults> search(GeoReference reference, Distance ra * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(GeoReference reference, Distance radius, - GeoSearchCommandArgs args) { + default GeoResults> search(@NonNull GeoReference reference, @NonNull Distance radius, + @NonNull GeoSearchCommandArgs args) { return search(reference, GeoShape.byRadius(radius), args); } @@ -262,8 +249,7 @@ default GeoResults> search(GeoReference reference, Distance ra * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(GeoReference reference, BoundingBox boundingBox) { + default GeoResults> search(@NonNull GeoReference reference, @NonNull BoundingBox boundingBox) { return search(reference, boundingBox, GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -278,9 +264,8 @@ default GeoResults> search(GeoReference reference, BoundingBox * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(GeoReference reference, BoundingBox boundingBox, - GeoSearchCommandArgs args) { + default GeoResults> search(@NonNull GeoReference reference, @NonNull BoundingBox boundingBox, + @NonNull GeoSearchCommandArgs args) { return search(reference, GeoShape.byBox(boundingBox), args); } @@ -295,9 +280,8 @@ default GeoResults> search(GeoReference reference, BoundingBox * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - GeoResults> search(GeoReference reference, GeoShape geoPredicate, - GeoSearchCommandArgs args); + GeoResults> search(@NonNull GeoReference reference, @NonNull GeoShape geoPredicate, + @NonNull GeoSearchCommandArgs args); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} and store results at {@code destKey}. @@ -307,8 +291,7 @@ GeoResults> search(GeoReference reference, GeoShape geoPredica * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K destKey, Circle within) { + default Long searchAndStore(@NonNull K destKey, @NonNull Circle within) { return searchAndStore(destKey, GeoReference.fromCircle(within), GeoShape.byRadius(within.getRadius()), GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -323,8 +306,7 @@ default Long searchAndStore(K destKey, Circle within) { * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K destKey, GeoReference reference, Distance radius) { + default Long searchAndStore(@NonNull K destKey, @NonNull GeoReference reference, @NonNull Distance radius) { return searchAndStore(destKey, reference, radius, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -339,9 +321,8 @@ default Long searchAndStore(K destKey, GeoReference reference, Distance radiu * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K destKey, GeoReference reference, Distance radius, - GeoSearchStoreCommandArgs args) { + default Long searchAndStore(@NonNull K destKey, @NonNull GeoReference reference, @NonNull Distance radius, + @NonNull GeoSearchStoreCommandArgs args) { return searchAndStore(destKey, reference, GeoShape.byRadius(radius), args); } @@ -355,8 +336,8 @@ default Long searchAndStore(K destKey, GeoReference reference, Distance radiu * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K destKey, GeoReference reference, BoundingBox boundingBox) { + default Long searchAndStore(@NonNull K destKey, @NonNull GeoReference reference, + @NonNull BoundingBox boundingBox) { return searchAndStore(destKey, reference, boundingBox, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -371,8 +352,7 @@ default Long searchAndStore(K destKey, GeoReference reference, BoundingBox bo * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K destKey, GeoReference reference, BoundingBox boundingBox, + default Long searchAndStore(@NonNull K destKey, @NonNull GeoReference reference, @NonNull BoundingBox boundingBox, GeoSearchStoreCommandArgs args) { return searchAndStore(destKey, reference, GeoShape.byBox(boundingBox), args); } @@ -388,8 +368,7 @@ default Long searchAndStore(K destKey, GeoReference reference, BoundingBox bo * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - Long searchAndStore(K destKey, GeoReference reference, GeoShape geoPredicate, - GeoSearchStoreCommandArgs args); + Long searchAndStore(@NonNull K destKey, @NonNull GeoReference reference, @NonNull GeoShape geoPredicate, + @NonNull GeoSearchStoreCommandArgs args); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundHashFieldExpirationOperations.java b/src/main/java/org/springframework/data/redis/core/BoundHashFieldExpirationOperations.java index 8546445af4..0eebd058a3 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundHashFieldExpirationOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundHashFieldExpirationOperations.java @@ -19,10 +19,10 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; /** * Hash Field Expiration operations bound to a certain hash key and set of hash fields. diff --git a/src/main/java/org/springframework/data/redis/core/BoundHashOperations.java b/src/main/java/org/springframework/data/redis/core/BoundHashOperations.java index 0355588ea4..76ccca9451 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundHashOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundHashOperations.java @@ -21,7 +21,8 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * Hash operations bound to a certain key. @@ -32,6 +33,7 @@ * @author Mark Paluch * @author Tihomir Mateev */ +@NullUnmarked public interface BoundHashOperations extends BoundKeyOperations { /** @@ -40,8 +42,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param keys must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Long delete(Object... keys); + Long delete(@NonNull Object @NonNull... keys); /** * Determine if given hash {@code key} exists at the bound key. @@ -49,8 +50,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param key must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean hasKey(Object key); + Boolean hasKey(@NonNull Object key); /** * Get value for given {@code key} from the hash at the bound key. @@ -58,8 +58,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param member must not be {@literal null}. * @return {@literal null} when member does not exist or when used in pipeline / transaction. */ - @Nullable - HV get(Object member); + HV get(@NonNull Object member); /** * Get values for given {@code keys} from the hash at the bound key. Values are in the order of the requested keys @@ -68,8 +67,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param keys must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - List multiGet(Collection keys); + List multiGet(@NonNull Collection<@NonNull HK> keys); /** * Increment {@code value} of a hash {@code key} by the given {@code delta} at the bound key. @@ -78,8 +76,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param delta * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Long increment(HK key, long delta); + Long increment(@NonNull HK key, long delta); /** * Increment {@code value} of a hash {@code key} by the given {@code delta} at the bound key. @@ -88,8 +85,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param delta * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Double increment(HK key, double delta); + Double increment(@NonNull HK key, double delta); /** * Return a random key from the hash stored at the bound key. @@ -98,7 +94,6 @@ public interface BoundHashOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable HK randomKey(); /** @@ -108,8 +103,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map.Entry randomEntry(); + Map.Entry<@NonNull HK, HV> randomEntry(); /** * Return a random keys from the hash stored at the bound key. If the provided {@code count} argument is positive, @@ -122,8 +116,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List randomKeys(long count); + List<@NonNull HK> randomKeys(long count); /** * Return a random entry from the hash stored at the bound key. @@ -133,16 +126,14 @@ public interface BoundHashOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map randomEntries(long count); + Map<@NonNull HK, HV> randomEntries(long count); /** * Get key set (fields) of hash at the bound key. * * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Set keys(); + Set<@NonNull HK> keys(); /** * Returns the length of the value associated with {@code hashKey}. If the {@code hashKey} do not exist, {@code 0} is @@ -152,15 +143,13 @@ public interface BoundHashOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @since 2.1 */ - @Nullable - Long lengthOfValue(HK hashKey); + Long lengthOfValue(@NonNull HK hashKey); /** * Get size of hash at the bound key. * * @return {@literal null} when used in pipeline / transaction. */ - @Nullable Long size(); /** @@ -168,7 +157,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * * @param m must not be {@literal null}. */ - void putAll(Map m); + void putAll(Map m); /** * Set the {@code value} of a hash {@code key} at the bound key. @@ -176,7 +165,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param key must not be {@literal null}. * @param value */ - void put(HK key, HV value); + void put(@NonNull HK key, HV value); /** * Set the {@code value} of a hash {@code key} only if {@code key} does not exist. @@ -185,15 +174,13 @@ public interface BoundHashOperations extends BoundKeyOperations { * @param value * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean putIfAbsent(HK key, HV value); + Boolean putIfAbsent(@NonNull HK key, HV value); /** * Get entry set (values) of hash at the bound key. * * @return {@literal null} when used in pipeline / transaction. */ - @Nullable List values(); /** @@ -201,8 +188,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Map entries(); + Map<@NonNull HK, HV> entries(); /** * Use a {@link Cursor} to iterate over entries in hash at the bound key.
@@ -213,7 +199,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * try-with-resources clause). * @since 1.4 */ - Cursor> scan(ScanOptions options); + Cursor> scan(@NonNull ScanOptions options); /** * Returns a bound operations object to perform operations on the hash field expiration for all hash fields at the @@ -223,6 +209,7 @@ public interface BoundHashOperations extends BoundKeyOperations { * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ + @NonNull default BoundHashFieldExpirationOperations hashExpiration() { return new DefaultBoundHashFieldExpirationOperations<>(getOperations().opsForHash(), getKey(), this::keys); } @@ -235,7 +222,8 @@ default BoundHashFieldExpirationOperations hashExpiration() { * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundHashFieldExpirationOperations hashExpiration(HK... hashFields) { + @NonNull + default BoundHashFieldExpirationOperations hashExpiration(@NonNull HK @NonNull... hashFields) { return hashExpiration(Arrays.asList(hashFields)); } @@ -247,13 +235,15 @@ default BoundHashFieldExpirationOperations hashExpiration(HK... hashFields) * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundHashFieldExpirationOperations hashExpiration(Collection hashFields) { + @NonNull + default BoundHashFieldExpirationOperations hashExpiration(@NonNull Collection<@NonNull HK> hashFields) { return new DefaultBoundHashFieldExpirationOperations<>(getOperations().opsForHash(), getKey(), () -> hashFields); } /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundKeyExpirationOperations.java b/src/main/java/org/springframework/data/redis/core/BoundKeyExpirationOperations.java index b50431b209..1b67edd4c4 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundKeyExpirationOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundKeyExpirationOperations.java @@ -19,10 +19,11 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; /** * Key Expiration operations bound to a key. @@ -30,6 +31,7 @@ * @author Mark Paluch * @since 3.5 */ +@NullUnmarked public interface BoundKeyExpirationOperations { /** @@ -38,7 +40,7 @@ public interface BoundKeyExpirationOperations { * @param expiration the expiration definition. * @return changes to the key. {@literal null} when used in pipeline / transaction. */ - default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { + default ExpireChanges.ExpiryChangeState expire(@NonNull Expiration expiration) { return expire(expiration, ExpirationOptions.none()); } @@ -49,8 +51,7 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @param options expiration options. * @return changes to the key. {@literal null} when used in pipeline / transaction. */ - @Nullable - ExpireChanges.ExpiryChangeState expire(Expiration expiration, ExpirationOptions options); + ExpireChanges.ExpiryChangeState expire(@NonNull Expiration expiration, @NonNull ExpirationOptions options); /** * Set time to live for the bound key. @@ -61,8 +62,7 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @see Redis Documentation: EXPIRE * @since 3.5 */ - @Nullable - ExpireChanges.ExpiryChangeState expire(Duration timeout); + ExpireChanges.ExpiryChangeState expire(@NonNull Duration timeout); /** * Set the expiration for the bound key as a {@literal date} timestamp. @@ -73,8 +73,7 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @see Redis Documentation: EXPIRE * @since 3.5 */ - @Nullable - ExpireChanges.ExpiryChangeState expireAt(Instant expireAt); + ExpireChanges.ExpiryChangeState expireAt(@NonNull Instant expireAt); /** * Remove the expiration from the bound key. @@ -83,7 +82,6 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @see Redis Documentation: PERSIST * @since 3.5 */ - @Nullable ExpireChanges.ExpiryChangeState persist(); /** @@ -93,7 +91,6 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @see Redis Documentation: TTL * @since 3.5 */ - @Nullable Expirations.TimeToLive getTimeToLive(); /** @@ -105,7 +102,6 @@ default ExpireChanges.ExpiryChangeState expire(Expiration expiration) { * @see Redis Documentation: TTL * @since 3.5 */ - @Nullable - Expirations.TimeToLive getTimeToLive(TimeUnit timeUnit); + Expirations.TimeToLive getTimeToLive(@NonNull TimeUnit timeUnit); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundKeyOperations.java b/src/main/java/org/springframework/data/redis/core/BoundKeyOperations.java index bb8b438a75..b29ca3668b 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundKeyOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundKeyOperations.java @@ -20,8 +20,8 @@ import java.util.Date; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -78,8 +78,7 @@ default BoundKeyExpirationOperations expiration() { * @throws IllegalArgumentException if the timeout is {@literal null}. * @since 2.3 */ - @Nullable - default Boolean expire(Duration timeout) { + default @Nullable Boolean expire(Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -114,8 +113,7 @@ default Boolean expire(Duration timeout) { * @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}. * @since 2.3 */ - @Nullable - default Boolean expireAt(Instant expireAt) { + default @Nullable Boolean expireAt(Instant expireAt) { Assert.notNull(expireAt, "ExpireAt must not be null"); diff --git a/src/main/java/org/springframework/data/redis/core/BoundListOperations.java b/src/main/java/org/springframework/data/redis/core/BoundListOperations.java index 481ee8e674..6113b69bbc 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundListOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundListOperations.java @@ -19,8 +19,9 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisListCommands.Direction; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -29,6 +30,7 @@ * @author Costin Leau * @author Mark Paluch */ +@NullUnmarked public interface BoundListOperations extends BoundKeyOperations { /** @@ -39,7 +41,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LRANGE */ - @Nullable List range(long start, long end); /** @@ -57,7 +58,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LLEN */ - @Nullable Long size(); /** @@ -67,7 +67,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable Long leftPush(V value); /** @@ -77,7 +76,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable Long leftPushAll(V... values); /** @@ -87,7 +85,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSHX */ - @Nullable Long leftPushIfPresent(V value); /** @@ -97,8 +94,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable - Long leftPush(V pivot, V value); + Long leftPush(@NonNull V pivot, V value); /** * Append {@code value} to the bound key. @@ -107,7 +103,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable Long rightPush(V value); /** @@ -117,8 +112,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable - Long rightPushAll(V... values); + Long rightPushAll(V @NonNull... values); /** * Append {@code values} to the bound key only if the list exists. @@ -127,7 +121,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSHX */ - @Nullable Long rightPushIfPresent(V value); /** @@ -137,8 +130,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable - Long rightPush(V pivot, V value); + Long rightPush(@NonNull V pivot, V value); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -152,8 +144,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: LMOVE */ - @Nullable - V move(Direction from, K destinationKey, Direction to); + V move(@NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -170,8 +161,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: BLMOVE */ - @Nullable - V move(Direction from, K destinationKey, Direction to, Duration timeout); + V move(@NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to, @NonNull Duration timeout); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -189,8 +179,8 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: BLMOVE */ - @Nullable - V move(Direction from, K destinationKey, Direction to, long timeout, TimeUnit unit); + V move(@NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to, long timeout, + @NonNull TimeUnit unit); /** * Set the {@code value} list element at {@code index}. @@ -209,7 +199,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LREM */ - @Nullable Long remove(long count, Object value); /** @@ -218,7 +207,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @since 3.4 */ - @Nullable V getFirst(); /** @@ -227,7 +215,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @since 3.4 */ - @Nullable V getLast(); /** @@ -237,7 +224,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LINDEX */ - @Nullable V index(long index); /** @@ -249,7 +235,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.4 * @see Redis Documentation: LPOS */ - @Nullable Long indexOf(V value); /** @@ -261,7 +246,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.4 * @see Redis Documentation: LPOS */ - @Nullable Long lastIndexOf(V value); /** @@ -270,7 +254,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPOP */ - @Nullable V leftPop(); /** @@ -281,7 +264,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @see Redis Documentation: LPOP * @since 2.6 */ - @Nullable List leftPop(long count); /** @@ -293,8 +275,7 @@ public interface BoundListOperations extends BoundKeyOperations { * @return {@literal null} when timeout reached or used in pipeline / transaction. * @see Redis Documentation: BLPOP */ - @Nullable - V leftPop(long timeout, TimeUnit unit); + V leftPop(long timeout, @NonNull TimeUnit unit); /** * Removes and returns first element from lists stored at the bound key .
@@ -306,7 +287,6 @@ public interface BoundListOperations extends BoundKeyOperations { * @since 2.3 * @see Redis Documentation: BLPOP */ - @Nullable default V leftPop(Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -321,7 +301,6 @@ default V leftPop(Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPOP */ - @Nullable V rightPop(); /** @@ -332,7 +311,6 @@ default V leftPop(Duration timeout) { * @see Redis Documentation: RPOP * @since 2.6 */ - @Nullable List rightPop(long count); /** @@ -344,8 +322,7 @@ default V leftPop(Duration timeout) { * @return {@literal null} when timeout reached or used in pipeline / transaction. * @see Redis Documentation: BRPOP */ - @Nullable - V rightPop(long timeout, TimeUnit unit); + V rightPop(long timeout, @NonNull TimeUnit unit); /** * Removes and returns last element from lists stored at the bound key.
@@ -357,8 +334,7 @@ default V leftPop(Duration timeout) { * @since 2.3 * @see Redis Documentation: BRPOP */ - @Nullable - default V rightPop(Duration timeout) { + default V rightPop(@NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -366,5 +342,6 @@ default V rightPop(Duration timeout) { return rightPop(TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS); } + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundOperationsProxyFactory.java b/src/main/java/org/springframework/data/redis/core/BoundOperationsProxyFactory.java index 2c4bfc5f49..e98b9ac872 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundOperationsProxyFactory.java +++ b/src/main/java/org/springframework/data/redis/core/BoundOperationsProxyFactory.java @@ -24,13 +24,12 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; - +import org.jspecify.annotations.Nullable; import org.springframework.aop.framework.ProxyFactory; import org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.stream.ReadOffset; import org.springframework.data.redis.connection.stream.StreamOffset; -import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; /** @@ -133,6 +132,7 @@ public BoundOperationsMethodInterceptor(Object key, RedisOperations operat } @Override + @SuppressWarnings("NullAway") public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); @@ -150,8 +150,7 @@ public Object invoke(MethodInvocation invocation) throws Throwable { }; } - @Nullable - private Object doInvoke(MethodInvocation invocation, Method method, Object target, boolean considerKeyArgument) { + private @Nullable Object doInvoke(MethodInvocation invocation, Method method, Object target, boolean considerKeyArgument) { Method backingMethod = lookupRequiredMethod(method, target.getClass(), considerKeyArgument); diff --git a/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java b/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java index 424b210b67..13e6fddaff 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundSetOperations.java @@ -20,7 +20,8 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * Set operations bound to a certain key. @@ -28,6 +29,7 @@ * @author Costin Leau * @author Mark Paluch */ +@NullUnmarked public interface BoundSetOperations extends BoundKeyOperations { /** @@ -37,8 +39,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SADD */ - @Nullable - Long add(V... values); + Long add(V @NonNull... values); /** * Remove given {@code values} from set at the bound key and return the number of removed elements. @@ -47,8 +48,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SREM */ - @Nullable - Long remove(Object... values); + Long remove(Object @NonNull... values); /** * Remove and return a random member from set at the bound key. @@ -56,7 +56,6 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SPOP */ - @Nullable V pop(); /** @@ -67,8 +66,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMOVE */ - @Nullable - Boolean move(K destKey, V value); + Boolean move(@NonNull K destKey, @NonNull V value); /** * Get size of set at the bound key. @@ -76,7 +74,6 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SCARD */ - @Nullable Long size(); /** @@ -86,8 +83,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SISMEMBER */ - @Nullable - Boolean isMember(Object o); + Boolean isMember(@NonNull Object o); /** * Check if set at at the bound key contains one or more {@code values}. @@ -97,8 +93,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: SMISMEMBER */ - @Nullable - Map isMember(Object... objects); + Map isMember(Object @NonNull... objects); /** * Returns the members intersecting all given sets at the bound key and {@code key}. @@ -107,8 +102,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTER */ - @Nullable - Set intersect(K key); + Set<@NonNull V> intersect(@NonNull K key); /** * Returns the members intersecting all given sets at the bound key and {@code keys}. @@ -117,8 +111,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTER */ - @Nullable - Set intersect(Collection keys); + Set<@NonNull V> intersect(@NonNull Collection<@NonNull K> keys); /** * Intersect all given sets at the bound key and {@code key} and store result in {@code destKey}. @@ -127,7 +120,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @param destKey must not be {@literal null}. * @see Redis Documentation: SINTERSTORE */ - void intersectAndStore(K key, K destKey); + void intersectAndStore(@NonNull K key, @NonNull K destKey); /** * Intersect all given sets at the bound key and {@code keys} and store result in {@code destKey}. @@ -136,7 +129,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @param destKey must not be {@literal null}. * @see Redis Documentation: SINTERSTORE */ - void intersectAndStore(Collection keys, K destKey); + void intersectAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey); /** * Union all sets at given {@code key} and {@code key}. @@ -145,8 +138,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNION */ - @Nullable - Set union(K key); + Set<@NonNull V> union(@NonNull K key); /** * Union all sets at given {@code keys} and {@code keys}. @@ -155,8 +147,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNION */ - @Nullable - Set union(Collection keys); + Set<@NonNull V> union(@NonNull Collection<@NonNull K> keys); /** * Union all sets at given the bound key and {@code key} and store result in {@code destKey}. @@ -165,7 +156,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @param destKey must not be {@literal null}. * @see Redis Documentation: SUNIONSTORE */ - void unionAndStore(K key, K destKey); + void unionAndStore(@NonNull K key, @NonNull K destKey); /** * Union all sets at given the bound key and {@code keys} and store result in {@code destKey}. @@ -174,7 +165,7 @@ public interface BoundSetOperations extends BoundKeyOperations { * @param destKey must not be {@literal null}. * @see Redis Documentation: SUNIONSTORE */ - void unionAndStore(Collection keys, K destKey); + void unionAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey); /** * Diff all sets for given the bound key and {@code key}. @@ -184,9 +175,8 @@ public interface BoundSetOperations extends BoundKeyOperations { * @see Redis Documentation: SDIFF * @deprecated since 3.0, use {@link #difference(Object)} instead to follow a consistent method naming scheme. */ - @Nullable @Deprecated(since = "3.0") - default Set diff(K key) { + default Set<@NonNull V> diff(@NonNull K key) { return difference(key); } @@ -198,8 +188,7 @@ default Set diff(K key) { * @since 3.0 * @see Redis Documentation: SDIFF */ - @Nullable - Set difference(K key); + Set<@NonNull V> difference(@NonNull K key); /** * Diff all sets for given the bound key and {@code keys}. @@ -209,9 +198,8 @@ default Set diff(K key) { * @see Redis Documentation: SDIFF * @deprecated since 3.0, use {@link #difference(Collection)} instead to follow a consistent method naming scheme. */ - @Nullable @Deprecated(since = "3.0") - default Set diff(Collection keys) { + default Set<@NonNull V> diff(@NonNull Collection<@NonNull K> keys) { return difference(keys); } @@ -223,8 +211,7 @@ default Set diff(Collection keys) { * @since 3.0 * @see Redis Documentation: SDIFF */ - @Nullable - Set difference(Collection keys); + Set<@NonNull V> difference(@NonNull Collection<@NonNull K> keys); /** * Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}. @@ -236,7 +223,7 @@ default Set diff(Collection keys) { * scheme.. */ @Deprecated - default void diffAndStore(K keys, K destKey) { + default void diffAndStore(@NonNull K keys, @NonNull K destKey) { differenceAndStore(keys, destKey); } @@ -248,7 +235,7 @@ default void diffAndStore(K keys, K destKey) { * @since 3.0 * @see Redis Documentation: SDIFFSTORE */ - void differenceAndStore(K keys, K destKey); + void differenceAndStore(@NonNull K keys, @NonNull K destKey); /** * Diff all sets for given the bound key and {@code keys} and store result in {@code destKey}. @@ -260,7 +247,7 @@ default void diffAndStore(K keys, K destKey) { * naming scheme. */ @Deprecated - default void diffAndStore(Collection keys, K destKey) { + default void diffAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey) { differenceAndStore(keys, destKey); } @@ -272,7 +259,7 @@ default void diffAndStore(Collection keys, K destKey) { * @since 3.0 * @see Redis Documentation: SDIFFSTORE */ - void differenceAndStore(Collection keys, K destKey); + void differenceAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey); /** * Get all elements of set at the bound key. @@ -280,8 +267,7 @@ default void diffAndStore(Collection keys, K destKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMEMBERS */ - @Nullable - Set members(); + Set<@NonNull V> members(); /** * Get random element from set at the bound key. @@ -289,7 +275,6 @@ default void diffAndStore(Collection keys, K destKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SRANDMEMBER */ - @Nullable V randomMember(); /** @@ -299,8 +284,7 @@ default void diffAndStore(Collection keys, K destKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - Set distinctRandomMembers(long count); + Set<@NonNull V> distinctRandomMembers(long count); /** * Get {@code count} random elements from set at the bound key. @@ -309,8 +293,7 @@ default void diffAndStore(Collection keys, K destKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - List randomMembers(long count); + List<@NonNull V> randomMembers(long count); /** * Use a {@link Cursor} to iterate over entries in set at {@code key}.
@@ -321,12 +304,12 @@ default void diffAndStore(Collection keys, K destKey) { * try-with-resources clause). * @since 1.4 */ - @Nullable - Cursor scan(ScanOptions options); + Cursor<@NonNull V> scan(@NonNull ScanOptions options); /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundStreamOperations.java b/src/main/java/org/springframework/data/redis/core/BoundStreamOperations.java index d3add2dad7..46f23598cf 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundStreamOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundStreamOperations.java @@ -18,6 +18,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.RedisStreamCommands.XAddOptions; @@ -26,7 +28,6 @@ import org.springframework.data.redis.connection.stream.ReadOffset; import org.springframework.data.redis.connection.stream.RecordId; import org.springframework.data.redis.connection.stream.StreamReadOptions; -import org.springframework.lang.Nullable; /** * Redis stream specific operations bound to a certain key. @@ -36,6 +37,7 @@ * @author Dengliming * @since 2.2 */ +@NullUnmarked public interface BoundStreamOperations { /** @@ -46,8 +48,7 @@ public interface BoundStreamOperations { * @return length of acknowledged records. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - @Nullable - Long acknowledge(String group, String... recordIds); + Long acknowledge(@NonNull String group, @NonNull String @NonNull... recordIds); /** * Append a record to the stream {@code key}. @@ -56,8 +57,7 @@ public interface BoundStreamOperations { * @return the record Id. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XADD */ - @Nullable - RecordId add(Map body); + RecordId add(@NonNull Map<@NonNull HK, HV> body); /** * Append a record to the stream {@code key} with the specified options. @@ -68,8 +68,7 @@ public interface BoundStreamOperations { * @see Redis Documentation: XADD * @since 3.4 */ - @Nullable - RecordId add(Map content, XAddOptions xAddOptions); + RecordId add(@NonNull Map<@NonNull HK, HV> content, @NonNull XAddOptions xAddOptions); /** * Removes the specified entries from the stream. Returns the number of items deleted, that may be different from the @@ -79,8 +78,7 @@ public interface BoundStreamOperations { * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XDEL */ - @Nullable - Long delete(String... recordIds); + Long delete(@NonNull String @NonNull... recordIds); /** * Create a consumer group. @@ -89,8 +87,7 @@ public interface BoundStreamOperations { * @param group name of the consumer group. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - String createGroup(ReadOffset readOffset, String group); + String createGroup(@NonNull ReadOffset readOffset, @NonNull String group); /** * Delete a consumer from a consumer group. @@ -98,8 +95,7 @@ public interface BoundStreamOperations { * @param consumer consumer identified by group name and consumer key. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean deleteConsumer(Consumer consumer); + Boolean deleteConsumer(@NonNull Consumer consumer); /** * Destroy a consumer group. @@ -107,8 +103,7 @@ public interface BoundStreamOperations { * @param group name of the consumer group. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean destroyGroup(String group); + Boolean destroyGroup(@NonNull String group); /** * Get the length of a stream. @@ -116,7 +111,6 @@ public interface BoundStreamOperations { * @return length of the stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XLEN */ - @Nullable Long size(); /** @@ -126,8 +120,7 @@ public interface BoundStreamOperations { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - default List> range(Range range) { + default List<@NonNull MapRecord> range(@NonNull Range range) { return range(range, Limit.unlimited()); } @@ -139,8 +132,7 @@ default List> range(Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - List> range(Range range, Limit limit); + List<@NonNull MapRecord> range(@NonNull Range range, @NonNull Limit limit); /** * Read records from {@link ReadOffset}. @@ -149,8 +141,7 @@ default List> range(Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - default List> read(ReadOffset readOffset) { + default List<@NonNull MapRecord> read(@NonNull ReadOffset readOffset) { return read(StreamReadOptions.empty(), readOffset); } @@ -162,8 +153,7 @@ default List> read(ReadOffset readOffset) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - List> read(StreamReadOptions readOptions, ReadOffset readOffset); + List<@NonNull MapRecord> read(@NonNull StreamReadOptions readOptions, @NonNull ReadOffset readOffset); /** * Read records starting from {@link ReadOffset}. using a consumer group. @@ -173,8 +163,7 @@ default List> read(ReadOffset readOffset) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - default List> read(Consumer consumer, ReadOffset readOffset) { + default List<@NonNull MapRecord> read(@NonNull Consumer consumer, @NonNull ReadOffset readOffset) { return read(consumer, StreamReadOptions.empty(), readOffset); } @@ -187,8 +176,8 @@ default List> read(Consumer consumer, ReadOffset readOffset * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - List> read(Consumer consumer, StreamReadOptions readOptions, ReadOffset readOffset); + List<@NonNull MapRecord> read(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull ReadOffset readOffset); /** * Read records from a stream within a specific {@link Range} in reverse order. @@ -197,8 +186,7 @@ default List> read(Consumer consumer, ReadOffset readOffset * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - default List> reverseRange(Range range) { + default List<@NonNull MapRecord> reverseRange(@NonNull Range range) { return reverseRange(range, Limit.unlimited()); } @@ -210,8 +198,7 @@ default List> reverseRange(Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - List> reverseRange(Range range, Limit limit); + List<@NonNull MapRecord> reverseRange(@NonNull Range range, @NonNull Limit limit); /** * Trims the stream to {@code count} elements. @@ -220,7 +207,6 @@ default List> reverseRange(Range range) { * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XTRIM */ - @Nullable Long trim(long count); /** @@ -232,6 +218,5 @@ default List> reverseRange(Range range) { * @since 2.4 * @see Redis Documentation: XTRIM */ - @Nullable Long trim(long count, boolean approximateTrimming); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java b/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java index 429b053ff4..f5d98b9d54 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundValueOperations.java @@ -18,7 +18,8 @@ import java.time.Duration; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.util.Assert; /** @@ -30,6 +31,7 @@ * @author Christoph Strobl * @author Marcin Grzejszczak */ +@NullUnmarked public interface BoundValueOperations extends BoundKeyOperations { /** @@ -38,7 +40,7 @@ public interface BoundValueOperations extends BoundKeyOperations { * @param value must not be {@literal null}. * @see Redis Documentation: SET */ - void set(V value); + void set(@NonNull V value); /** * Set the {@code value} and expiration {@code timeout} for the bound key. @@ -48,7 +50,7 @@ public interface BoundValueOperations extends BoundKeyOperations { * @param unit must not be {@literal null}. * @see Redis Documentation: SETEX */ - void set(V value, long timeout, TimeUnit unit); + void set(@NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set the {@code value} and expiration {@code timeout} for the bound key. Return the old string stored at key, or @@ -62,7 +64,7 @@ public interface BoundValueOperations extends BoundKeyOperations { * @see Redis Documentation: SET * @since 3.5 */ - V setGet(V value, long timeout, TimeUnit unit); + V setGet(@NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set the {@code value} and expiration {@code timeout} for the bound key. Return the old string stored at key, or @@ -75,7 +77,7 @@ public interface BoundValueOperations extends BoundKeyOperations { * @see Redis Documentation: SET * @since 3.5 */ - V setGet(V value, Duration duration); + V setGet(@NonNull V value, @NonNull Duration duration); /** * Set the {@code value} and expiration {@code timeout} for the bound key. @@ -86,7 +88,7 @@ public interface BoundValueOperations extends BoundKeyOperations { * @see Redis Documentation: SETEX * @since 2.1 */ - default void set(V value, Duration timeout) { + default void set(@NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -104,8 +106,7 @@ default void set(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SETNX */ - @Nullable - Boolean setIfAbsent(V value); + Boolean setIfAbsent(@NonNull V value); /** * Set the bound key to hold the string {@code value} and expiration {@code timeout} if the bound key is absent. @@ -117,8 +118,7 @@ default void set(V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: SET */ - @Nullable - Boolean setIfAbsent(V value, long timeout, TimeUnit unit); + Boolean setIfAbsent(@NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set bound key to hold the string {@code value} and expiration {@code timeout} if the bound key is absent. @@ -130,8 +130,7 @@ default void set(V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - default Boolean setIfAbsent(V value, Duration timeout) { + default Boolean setIfAbsent(@NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -151,8 +150,7 @@ default Boolean setIfAbsent(V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - Boolean setIfPresent(V value); + Boolean setIfPresent(@NonNull V value); /** * Set the bound key to hold the string {@code value} and expiration {@code timeout} if the bound key is present. @@ -165,8 +163,7 @@ default Boolean setIfAbsent(V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - Boolean setIfPresent(V value, long timeout, TimeUnit unit); + Boolean setIfPresent(@NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set the bound key to hold the string {@code value} and expiration {@code timeout} if the bound key is present. @@ -178,8 +175,7 @@ default Boolean setIfAbsent(V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - default Boolean setIfPresent(V value, Duration timeout) { + default Boolean setIfPresent(@NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -196,7 +192,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: GET */ - @Nullable V get(); /** @@ -206,7 +201,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @see Redis Documentation: GETDEL * @since 2.6 */ - @Nullable V getAndDelete(); /** @@ -218,8 +212,7 @@ default Boolean setIfPresent(V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - V getAndExpire(long timeout, TimeUnit unit); + V getAndExpire(long timeout, @NonNull TimeUnit unit); /** * Return the value at the bound key and expire the key by applying {@code timeout}. @@ -229,8 +222,7 @@ default Boolean setIfPresent(V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - V getAndExpire(Duration timeout); + V getAndExpire(@NonNull Duration timeout); /** * Return the value at the bound key and persist the key. This operation removes any TTL that is associated with the @@ -240,7 +232,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable V getAndPersist(); /** @@ -249,8 +240,7 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GETSET */ - @Nullable - V getAndSet(V value); + V getAndSet(@NonNull V value); /** * Increment an integer value stored as string value under the bound key by one. @@ -259,7 +249,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: INCR */ - @Nullable Long increment(); /** @@ -269,7 +258,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBY */ - @Nullable Long increment(long delta); /** @@ -279,7 +267,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBYFLOAT */ - @Nullable Double increment(double delta); /** @@ -289,7 +276,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: DECR */ - @Nullable Long decrement(); /** @@ -300,7 +286,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: DECRBY */ - @Nullable Long decrement(long delta); /** @@ -310,8 +295,7 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: APPEND */ - @Nullable - Integer append(String value); + Integer append(@NonNull String value); /** * Get a substring of value of the bound key between {@code begin} and {@code end}. @@ -321,7 +305,6 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GETRANGE */ - @Nullable String get(long start, long end); /** @@ -331,7 +314,7 @@ default Boolean setIfPresent(V value, Duration timeout) { * @param offset * @see Redis Documentation: SETRANGE */ - void set(V value, long offset); + void set(@NonNull V value, long offset); /** * Get the length of the value stored at the bound key. @@ -339,11 +322,11 @@ default Boolean setIfPresent(V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: STRLEN */ - @Nullable Long size(); /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/BoundZSetOperations.java b/src/main/java/org/springframework/data/redis/core/BoundZSetOperations.java index 160d0836ad..f8d3ec6711 100644 --- a/src/main/java/org/springframework/data/redis/core/BoundZSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/BoundZSetOperations.java @@ -22,13 +22,14 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.zset.Aggregate; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -40,6 +41,7 @@ * @author Wongoo (望哥) * @author Andrey Shlykov */ +@NullUnmarked public interface BoundZSetOperations extends BoundKeyOperations { /** @@ -50,8 +52,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - Boolean add(V value, double score); + Boolean add(@NonNull V value, double score); /** * Add {@code value} to a sorted set at the bound key if it does not already exists. @@ -62,8 +63,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.5 * @see Redis Documentation: ZADD NX */ - @Nullable - Boolean addIfAbsent(V value, double score); + Boolean addIfAbsent(@NonNull V value, double score); /** * Add {@code tuples} to a sorted set at the bound key, or update its {@code score} if it already exists. @@ -72,8 +72,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - Long add(Set> tuples); + Long add(Set<@NonNull TypedTuple> tuples); /** * Add {@code tuples} to a sorted set at the bound key if it does not already exists. @@ -83,8 +82,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.5 * @see Redis Documentation: ZADD NX */ - @Nullable - Long addIfAbsent(Set> tuples); + Long addIfAbsent(Set<@NonNull TypedTuple> tuples); /** * Remove {@code values} from sorted set. Return number of removed elements. @@ -93,8 +91,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREM */ - @Nullable - Long remove(Object... values); + Long remove(@NonNull Object @NonNull... values); /** * Increment the score of element with {@code value} in sorted set by {@code increment}. @@ -104,8 +101,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINCRBY */ - @Nullable - Double incrementScore(V value, double delta); + Double incrementScore(@NonNull V value, double delta); /** * Get random element from set at the bound key. @@ -125,7 +121,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable Set distinctRandomMembers(long count); /** @@ -137,7 +132,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable List randomMembers(long count); /** @@ -158,8 +152,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - Set> distinctRandomMembersWithScore(long count); + Set<@NonNull TypedTuple> distinctRandomMembersWithScore(long count); /** * Get {@code count} random elements with their score from set at the bound key. @@ -170,8 +163,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List> randomMembersWithScore(long count); + List<@NonNull TypedTuple> randomMembersWithScore(long count); /** * Determine the index of element with {@code value} in a sorted set. @@ -180,8 +172,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANK */ - @Nullable - Long rank(Object o); + Long rank(@NonNull Object o); /** * Determine the index of element with {@code value} in a sorted set when scored high to low. @@ -190,8 +181,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANK */ - @Nullable - Long reverseRank(Object o); + Long reverseRank(@NonNull Object o); /** * Get elements between {@code start} and {@code end} from sorted set. @@ -201,7 +191,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGE */ - @Nullable Set range(long start, long end); /** @@ -212,8 +201,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGE */ - @Nullable - Set> rangeWithScores(long start, long end); + Set<@NonNull TypedTuple> rangeWithScores(long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -223,7 +211,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable Set rangeByScore(double min, double max); /** @@ -234,8 +221,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set> rangeByScoreWithScores(double min, double max); + Set<@NonNull TypedTuple> rangeByScoreWithScores(double min, double max); /** * Get elements in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -245,7 +231,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable Set reverseRange(long start, long end); /** @@ -256,8 +241,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - Set> reverseRangeWithScores(long start, long end); + Set<@NonNull TypedTuple> reverseRangeWithScores(long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set ordered from high to low. @@ -267,7 +251,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable Set reverseRangeByScore(double min, double max); /** @@ -279,8 +262,7 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set> reverseRangeByScoreWithScores(double min, double max); + Set<@NonNull TypedTuple> reverseRangeByScoreWithScores(double min, double max); /** * Count number of elements within sorted set with scores between {@code min} and {@code max}. @@ -290,7 +272,6 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCOUNT */ - @Nullable Long count(double min, double max); /** @@ -303,9 +284,8 @@ public interface BoundZSetOperations extends BoundKeyOperations { * @see Redis Documentation: ZLEXCOUNT * @deprecated since 3.0. Please use {@link #lexCount(Range)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return lexCount(range.toRange()); } @@ -318,8 +298,7 @@ default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommand * @since 3.0 * @see Redis Documentation: ZLEXCOUNT */ - @Nullable - Long lexCount(Range range); + Long lexCount(@NonNull Range range); /** * Remove and return the value with its score having the lowest score from sorted set at the bound key. @@ -328,7 +307,6 @@ default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommand * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable TypedTuple popMin(); /** @@ -339,8 +317,7 @@ default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommand * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Set> popMin(long count); + Set<@NonNull TypedTuple> popMin(long count); /** * Remove and return the value with its score having the lowest score from sorted set at the bound key. Blocks @@ -352,8 +329,7 @@ default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommand * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - TypedTuple popMin(long timeout, TimeUnit unit); + TypedTuple popMin(long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the lowest score from sorted set at the bound key. Blocks @@ -365,8 +341,7 @@ default Long lexCount(org.springframework.data.redis.connection.RedisZSetCommand * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - default TypedTuple popMin(Duration timeout) { + default TypedTuple popMin(@NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -381,7 +356,6 @@ default TypedTuple popMin(Duration timeout) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable TypedTuple popMax(); /** @@ -392,8 +366,7 @@ default TypedTuple popMin(Duration timeout) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - Set> popMax(long count); + Set<@NonNull TypedTuple> popMax(long count); /** * Remove and return the value with its score having the highest score from sorted set at the bound key. Blocks @@ -405,8 +378,7 @@ default TypedTuple popMin(Duration timeout) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - TypedTuple popMax(long timeout, TimeUnit unit); + TypedTuple popMax(long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the highest score from sorted set at the bound key. Blocks @@ -418,8 +390,7 @@ default TypedTuple popMin(Duration timeout) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - default TypedTuple popMax(Duration timeout) { + default TypedTuple popMax(@NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -434,7 +405,6 @@ default TypedTuple popMax(Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCARD */ - @Nullable Long size(); /** @@ -444,7 +414,6 @@ default TypedTuple popMax(Duration timeout) { * @since 1.3 * @see Redis Documentation: ZCARD */ - @Nullable Long zCard(); /** @@ -454,8 +423,7 @@ default TypedTuple popMax(Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZSCORE */ - @Nullable - Double score(Object o); + Double score(@NonNull Object o); /** * Get the scores of elements with {@code values} from sorted set with key the bound key. @@ -465,8 +433,7 @@ default TypedTuple popMax(Duration timeout) { * @see Redis Documentation: ZMSCORE * @since 2.6 */ - @Nullable - List score(Object... o); + List score(@NonNull Object @NonNull... o); /** * Remove elements in range between {@code start} and {@code end} from sorted set with the bound key. @@ -476,7 +443,6 @@ default TypedTuple popMax(Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYRANK */ - @Nullable Long removeRange(long start, long end); /** @@ -488,9 +454,8 @@ default TypedTuple popMax(Duration timeout) { * @see Redis Documentation: ZREMRANGEBYLEX * @deprecated since 3.0. Please use {@link #removeRangeByLex(Range)}. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return removeRangeByLex(range.toRange()); } @@ -502,8 +467,7 @@ default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSe * @since 3.0 * @see Redis Documentation: ZREMRANGEBYLEX */ - @Nullable - Long removeRangeByLex(Range range); + Long removeRangeByLex(@NonNull Range range); /** * Remove elements with scores between {@code min} and {@code max} from sorted set with the bound key. @@ -513,7 +477,6 @@ default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSe * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYSCORE */ - @Nullable Long removeRangeByScore(double min, double max); /** @@ -527,8 +490,8 @@ default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSe * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Long unionAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, @NonNull Aggregate aggregate, + @NonNull Weights weights); /** * Diff sorted {@code sets}. @@ -538,8 +501,7 @@ default Long removeRangeByLex(org.springframework.data.redis.connection.RedisZSe * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - default Set difference(K otherKey) { + default Set difference(@NonNull K otherKey) { return difference(Collections.singleton(otherKey)); } @@ -551,8 +513,7 @@ default Set difference(K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set difference(Collection otherKeys); + Set difference(@NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets}. @@ -562,8 +523,7 @@ default Set difference(K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - default Set> differenceWithScores(K otherKey) { + default Set<@NonNull TypedTuple> differenceWithScores(@NonNull K otherKey) { return differenceWithScores(Collections.singleton(otherKey)); } @@ -575,8 +535,7 @@ default Set> differenceWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set> differenceWithScores(Collection otherKeys); + Set<@NonNull TypedTuple> differenceWithScores(@NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets} and store result in destination {@code destKey}. @@ -587,8 +546,7 @@ default Set> differenceWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - @Nullable - default Long differenceAndStore(K otherKey, K destKey) { + default Long differenceAndStore(@NonNull K otherKey, @NonNull K destKey) { return differenceAndStore(Collections.singleton(otherKey), destKey); } @@ -601,8 +559,7 @@ default Long differenceAndStore(K otherKey, K destKey) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - @Nullable - Long differenceAndStore(Collection otherKeys, K destKey); + Long differenceAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted {@code sets}. @@ -612,8 +569,7 @@ default Long differenceAndStore(K otherKey, K destKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set intersect(K otherKey) { + default Set intersect(@NonNull K otherKey) { return intersect(Collections.singleton(otherKey)); } @@ -625,8 +581,7 @@ default Set intersect(K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set intersect(Collection otherKeys); + Set intersect(@NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted {@code sets}. @@ -636,8 +591,7 @@ default Set intersect(K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set> intersectWithScores(K otherKey) { + default Set<@NonNull TypedTuple> intersectWithScores(@NonNull K otherKey) { return intersectWithScores(Collections.singleton(otherKey)); } @@ -649,8 +603,7 @@ default Set> intersectWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set> intersectWithScores(Collection otherKeys); + Set<@NonNull TypedTuple> intersectWithScores(@NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted {@code sets}. @@ -662,8 +615,8 @@ default Set> intersectWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set> intersectWithScores(Collection otherKeys, Aggregate aggregate, Weights weights); + Set<@NonNull TypedTuple> intersectWithScores(@NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Intersect sorted sets at the bound key and {@code otherKey} and store result in destination {@code destKey}. @@ -673,8 +626,7 @@ default Set> intersectWithScores(K otherKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(K otherKey, K destKey); + Long intersectAndStore(@NonNull K otherKey, @NonNull K destKey); /** * Intersect sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -684,8 +636,7 @@ default Set> intersectWithScores(K otherKey) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(Collection otherKeys, K destKey); + Long intersectAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -697,8 +648,7 @@ default Set> intersectWithScores(K otherKey) { * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(Collection otherKeys, K destKey, Aggregate aggregate); + Long intersectAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, @NonNull Aggregate aggregate); /** * Intersect sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -711,8 +661,8 @@ default Set> intersectWithScores(K otherKey) { * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Long intersectAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, @NonNull Aggregate aggregate, + @NonNull Weights weights); /** * Union sorted {@code sets}. @@ -722,8 +672,7 @@ default Set> intersectWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set union(K otherKey) { + default Set union(@NonNull K otherKey) { return union(Collections.singleton(otherKey)); } @@ -735,8 +684,7 @@ default Set union(K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set union(Collection otherKeys); + Set union(@NonNull Collection<@NonNull K> otherKeys); /** * Union sorted {@code sets}. @@ -746,8 +694,7 @@ default Set union(K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set> unionWithScores(K otherKey) { + default Set<@NonNull TypedTuple> unionWithScores(@NonNull K otherKey) { return unionWithScores(Collections.singleton(otherKey)); } @@ -759,8 +706,7 @@ default Set> unionWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set> unionWithScores(Collection otherKeys); + Set<@NonNull TypedTuple> unionWithScores(@NonNull Collection<@NonNull K> otherKeys); /** * Union sorted sets at the bound key and {@code otherKeys}. @@ -771,8 +717,8 @@ default Set> unionWithScores(K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set> unionWithScores(Collection otherKeys, Aggregate aggregate) { + default Set<@NonNull TypedTuple> unionWithScores(@NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate) { return unionWithScores(otherKeys, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -786,8 +732,8 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set> unionWithScores(Collection otherKeys, Aggregate aggregate, Weights weights); + Set<@NonNull TypedTuple> unionWithScores(@NonNull Collection<@NonNull K> otherKeys, @NonNull Aggregate aggregate, + @NonNull Weights weights); /** * Union sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -797,8 +743,7 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(K otherKey, K destKey); + Long unionAndStore(@NonNull K otherKey, @NonNull K destKey); /** * Union sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -808,8 +753,7 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(Collection otherKeys, K destKey); + Long unionAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Union sorted sets at the bound key and {@code otherKeys} and store result in destination {@code destKey}. @@ -821,8 +765,7 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(Collection otherKeys, K destKey, Aggregate aggregate); + Long unionAndStore(@NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, @NonNull Aggregate aggregate); /** * Use a {@link Cursor} to iterate over entries in zset at the bound key.
@@ -833,7 +776,7 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * try-with-resources clause). * @since 1.4 */ - Cursor> scan(ScanOptions options); + Cursor<@NonNull TypedTuple> scan(@NonNull ScanOptions options); /** * Get all elements with lexicographical ordering with a value between @@ -846,9 +789,8 @@ default Set> unionWithScores(Collection otherKeys, Aggregate ag * @see Redis Documentation: ZRANGEBYLEX * @deprecated since 3.0. Please use {@link #rangeByLex(Range)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return rangeByLex(range.toRange()); } @@ -861,8 +803,7 @@ default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCom * @since 3.0 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - default Set rangeByLex(Range range) { + default Set rangeByLex(@NonNull Range range) { return rangeByLex(range, Limit.unlimited()); } @@ -879,9 +820,9 @@ default Set rangeByLex(Range range) { * @see Redis Documentation: ZRANGEBYLEX * @deprecated since 3.0. Please use {@link #rangeByLex(Range, Limit)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range, Limit limit) { + default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range, + @NonNull Limit limit) { return rangeByLex(range.toRange(), limit); } @@ -896,8 +837,7 @@ default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCom * @since 3.0 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - Set rangeByLex(Range range, Limit limit); + Set rangeByLex(Range range, @NonNull Limit limit); /** * Get all elements with reverse lexicographical ordering from {@literal ZSET} with a value between @@ -910,9 +850,8 @@ default Set rangeByLex(org.springframework.data.redis.connection.RedisZSetCom * @see Redis Documentation: ZREVRANGEBYLEX * @deprecated since 3.0. Please use {@link #reverseRangeByLex(Range)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Set reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return reverseRangeByLex(range); } @@ -925,8 +864,7 @@ default Set reverseRangeByLex(org.springframework.data.redis.connection.Redis * @since 3.0 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - default Set reverseRangeByLex(Range range) { + default Set reverseRangeByLex(@NonNull Range range) { return reverseRangeByLex(range, Limit.unlimited()); } @@ -943,10 +881,9 @@ default Set reverseRangeByLex(Range range) { * @see Redis Documentation: ZREVRANGEBYLEX * @deprecated since 3.0. Please use {@link #reverseRangeByLex(Range, Limit)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range, - Limit limit) { + default Set reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range, + @NonNull Limit limit) { return reverseRangeByLex(range.toRange(), limit); } @@ -961,8 +898,7 @@ default Set reverseRangeByLex(org.springframework.data.redis.connection.Redis * @since 3.0 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - Set reverseRangeByLex(Range range, Limit limit); + Set reverseRangeByLex(@NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at the bound key with a @@ -975,8 +911,7 @@ default Set reverseRangeByLex(org.springframework.data.redis.connection.Redis * @see #rangeByLex(Range) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long rangeAndStoreByLex(K dstKey, Range range) { + default Long rangeAndStoreByLex(@NonNull K dstKey, @NonNull Range range) { return rangeAndStoreByLex(dstKey, range, Limit.unlimited()); } @@ -993,8 +928,7 @@ default Long rangeAndStoreByLex(K dstKey, Range range) { * @see #rangeByLex(Range, Limit) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long rangeAndStoreByLex(K dstKey, Range range, Limit limit); + Long rangeAndStoreByLex(@NonNull K dstKey, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at the bound key @@ -1007,8 +941,7 @@ default Long rangeAndStoreByLex(K dstKey, Range range) { * @see #reverseRangeByLex(Range) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long reverseRangeAndStoreByLex(K dstKey, Range range) { + default Long reverseRangeAndStoreByLex(@NonNull K dstKey, @NonNull Range range) { return reverseRangeAndStoreByLex(dstKey, range, Limit.unlimited()); } @@ -1025,8 +958,7 @@ default Long reverseRangeAndStoreByLex(K dstKey, Range range) { * @see #reverseRangeByLex(Range, Limit) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long reverseRangeAndStoreByLex(K dstKey, Range range, Limit limit); + Long reverseRangeAndStoreByLex(@NonNull K dstKey, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at the bound key with a score @@ -1039,8 +971,7 @@ default Long reverseRangeAndStoreByLex(K dstKey, Range range) { * @see #rangeByScore(double, double) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long rangeAndStoreByScore(K dstKey, Range range) { + default Long rangeAndStoreByScore(@NonNull K dstKey, @NonNull Range range) { return rangeAndStoreByScore(dstKey, range, Limit.unlimited()); } @@ -1057,8 +988,7 @@ default Long rangeAndStoreByScore(K dstKey, Range range) { * @see #rangeByScore(double, double) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long rangeAndStoreByScore(K dstKey, Range range, Limit limit); + Long rangeAndStoreByScore(@NonNull K dstKey, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at the bound key with a @@ -1071,8 +1001,7 @@ default Long rangeAndStoreByScore(K dstKey, Range range) { * @see #reverseRangeByScore(double, double) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long reverseRangeAndStoreByScore(K dstKey, Range range) { + default Long reverseRangeAndStoreByScore(@NonNull K dstKey, @NonNull Range range) { return reverseRangeAndStoreByScore(dstKey, range, Limit.unlimited()); } @@ -1088,11 +1017,11 @@ default Long reverseRangeAndStoreByScore(K dstKey, Range range * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long reverseRangeAndStoreByScore(K dstKey, Range range, Limit limit); + Long reverseRangeAndStoreByScore(@NonNull K dstKey, @NonNull Range range, @NonNull Limit limit); /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/CloseSuppressingInvocationHandler.java b/src/main/java/org/springframework/data/redis/core/CloseSuppressingInvocationHandler.java index 1f85f9d389..274e5139b4 100644 --- a/src/main/java/org/springframework/data/redis/core/CloseSuppressingInvocationHandler.java +++ b/src/main/java/org/springframework/data/redis/core/CloseSuppressingInvocationHandler.java @@ -19,8 +19,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.lang.Nullable; /** * Invocation handler that suppresses close calls on {@link RedisConnection}. @@ -42,8 +42,7 @@ public CloseSuppressingInvocationHandler(Object target) { } @Override - @Nullable - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals(EQUALS)) { // Only consider equal when proxies are identical. diff --git a/src/main/java/org/springframework/data/redis/core/ClusterOperations.java b/src/main/java/org/springframework/data/redis/core/ClusterOperations.java index f96c8c0d39..a30d085928 100644 --- a/src/main/java/org/springframework/data/redis/core/ClusterOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ClusterOperations.java @@ -18,6 +18,8 @@ import java.util.Collection; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisClusterCommands; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; @@ -26,15 +28,16 @@ /** * Redis operations for cluster specific operations. A {@link RedisClusterNode} can be obtained from - * {@link RedisClusterCommands#clusterGetNodes() a connection} or it can be - * constructed using either {@link RedisClusterNode#getHost() host} and {@link RedisClusterNode#getPort()} or the - * {@link RedisClusterNode#getId() node Id}. + * {@link RedisClusterCommands#clusterGetNodes() a connection} or it can be constructed using either + * {@link RedisClusterNode#getHost() host} and {@link RedisClusterNode#getPort()} or the {@link RedisClusterNode#getId() + * node Id}. * * @author Christoph Strobl * @author Mark Paluch * @author Dennis Neufeld * @since 1.7 */ +@NullUnmarked public interface ClusterOperations { /** @@ -45,7 +48,7 @@ public interface ClusterOperations { * @return never {@literal null}. * @see RedisConnection#keys(byte[]) */ - Set keys(RedisClusterNode node, K pattern); + Set<@NonNull K> keys(@NonNull RedisClusterNode node, @NonNull K pattern); /** * Ping the given node; @@ -54,7 +57,7 @@ public interface ClusterOperations { * @return * @see RedisConnection#ping() */ - String ping(RedisClusterNode node); + String ping(@NonNull RedisClusterNode node); /** * Get a random key from the range served by the given node. @@ -63,7 +66,7 @@ public interface ClusterOperations { * @return * @see RedisConnection#randomKey() */ - K randomKey(RedisClusterNode node); + K randomKey(@NonNull RedisClusterNode node); /** * Add slots to given node; @@ -71,7 +74,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @param slots must not be {@literal null}. */ - void addSlots(RedisClusterNode node, int... slots); + void addSlots(@NonNull RedisClusterNode node, int... slots); /** * Add slots in {@link SlotRange} to given node. @@ -79,7 +82,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @param range must not be {@literal null}. */ - void addSlots(RedisClusterNode node, SlotRange range); + void addSlots(@NonNull RedisClusterNode node, @NonNull SlotRange range); /** * Start an {@literal Append Only File} rewrite process on given node. @@ -87,7 +90,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @see RedisConnection#bgReWriteAof() */ - void bgReWriteAof(RedisClusterNode node); + void bgReWriteAof(@NonNull RedisClusterNode node); /** * Start background saving of db on given node. @@ -95,21 +98,21 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @see RedisConnection#bgSave() */ - void bgSave(RedisClusterNode node); + void bgSave(@NonNull RedisClusterNode node); /** * Add the node to cluster. * * @param node must not be {@literal null}. */ - void meet(RedisClusterNode node); + void meet(@NonNull RedisClusterNode node); /** * Remove the node from the cluster. * * @param node must not be {@literal null}. */ - void forget(RedisClusterNode node); + void forget(@NonNull RedisClusterNode node); /** * Flush db on node. @@ -117,7 +120,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @see RedisConnection#flushDb() */ - void flushDb(RedisClusterNode node); + void flushDb(@NonNull RedisClusterNode node); /** * Flush db on node using the specified {@link FlushOption}. @@ -127,13 +130,13 @@ public interface ClusterOperations { * @see RedisConnection#flushDb(FlushOption) * @since 2.7 */ - void flushDb(RedisClusterNode node, FlushOption option); + void flushDb(@NonNull RedisClusterNode node, @NonNull FlushOption option); /** * @param node must not be {@literal null}. * @return */ - Collection getReplicas(RedisClusterNode node); + Collection<@NonNull RedisClusterNode> getReplicas(@NonNull RedisClusterNode node); /** * Synchronous save current db snapshot on server. @@ -141,7 +144,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @see RedisConnection#save() */ - void save(RedisClusterNode node); + void save(@NonNull RedisClusterNode node); /** * Shutdown given node. @@ -149,7 +152,7 @@ public interface ClusterOperations { * @param node must not be {@literal null}. * @see RedisConnection#shutdown() */ - void shutdown(RedisClusterNode node); + void shutdown(@NonNull RedisClusterNode node); /** * Move slot assignment from one source to target node and copy keys associated with the slot. @@ -158,5 +161,5 @@ public interface ClusterOperations { * @param slot * @param target must not be {@literal null}. */ - void reshard(RedisClusterNode source, int slot, RedisClusterNode target); + void reshard(@NonNull RedisClusterNode source, int slot, @NonNull RedisClusterNode target); } diff --git a/src/main/java/org/springframework/data/redis/core/ConvertingCursor.java b/src/main/java/org/springframework/data/redis/core/ConvertingCursor.java index b0d5e1e5fd..b581557ad6 100644 --- a/src/main/java/org/springframework/data/redis/core/ConvertingCursor.java +++ b/src/main/java/org/springframework/data/redis/core/ConvertingCursor.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -53,8 +53,7 @@ public boolean hasNext() { } @Override - @Nullable - public T next() { + public @Nullable T next() { return converter.convert(delegate.next()); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultBoundHashFieldExpirationOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultBoundHashFieldExpirationOperations.java index fdb45c57bc..f8735a9687 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultBoundHashFieldExpirationOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultBoundHashFieldExpirationOperations.java @@ -21,10 +21,10 @@ import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/core/DefaultBoundKeyExpirationOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultBoundKeyExpirationOperations.java index 9ff186cd3e..8c84ca01a0 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultBoundKeyExpirationOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultBoundKeyExpirationOperations.java @@ -19,10 +19,10 @@ import java.time.Instant; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; /** * Default {@link BoundKeyExpirationOperations} implementation. @@ -40,45 +40,45 @@ public DefaultBoundKeyExpirationOperations(RedisOperations operations, K k this.key = key; } - @Nullable + @Override - public ExpireChanges.ExpiryChangeState expire(Expiration expiration, ExpirationOptions options) { + public ExpireChanges.@Nullable ExpiryChangeState expire(Expiration expiration, ExpirationOptions options) { return operations.expire(key, expiration, options); } - @Nullable + @Override - public ExpireChanges.ExpiryChangeState expire(Duration timeout) { + public ExpireChanges.@Nullable ExpiryChangeState expire(Duration timeout) { Boolean expire = operations.expire(key, timeout); return toExpiryChangeState(expire); } - @Nullable + @Override - public ExpireChanges.ExpiryChangeState expireAt(Instant expireAt) { + public ExpireChanges.@Nullable ExpiryChangeState expireAt(Instant expireAt) { return toExpiryChangeState(operations.expireAt(key, expireAt)); } - @Nullable + @Override - public ExpireChanges.ExpiryChangeState persist() { + public ExpireChanges.@Nullable ExpiryChangeState persist() { return toExpiryChangeState(operations.persist(key)); } - @Nullable + @Override - public Expirations.TimeToLive getTimeToLive() { + public Expirations.@Nullable TimeToLive getTimeToLive() { Long expire = operations.getExpire(key); return expire == null ? null : Expirations.TimeToLive.of(expire, TimeUnit.SECONDS); } - @Nullable + @Override - public Expirations.TimeToLive getTimeToLive(TimeUnit timeUnit) { + public Expirations.@Nullable TimeToLive getTimeToLive(TimeUnit timeUnit) { Long expire = operations.getExpire(key, timeUnit); @@ -86,8 +86,8 @@ public Expirations.TimeToLive getTimeToLive(TimeUnit timeUnit) { } - @Nullable - private static ExpireChanges.ExpiryChangeState toExpiryChangeState(@Nullable Boolean result) { + + private static ExpireChanges.@Nullable ExpiryChangeState toExpiryChangeState(@Nullable Boolean result) { if (result == null) { return null; diff --git a/src/main/java/org/springframework/data/redis/core/DefaultClusterOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultClusterOperations.java index 7215430082..a26fadfe3b 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultClusterOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultClusterOperations.java @@ -19,13 +19,14 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisClusterCommands.AddSlots; import org.springframework.data.redis.connection.RedisClusterConnection; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; import org.springframework.data.redis.connection.RedisServerCommands.FlushOption; import org.springframework.data.redis.connection.RedisServerCommands.MigrateOption; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -37,6 +38,7 @@ * @param * @param */ +@NullUnmarked class DefaultClusterOperations extends AbstractOperations implements ClusterOperations { private final RedisTemplate template; @@ -46,14 +48,14 @@ class DefaultClusterOperations extends AbstractOperations implements * * @param template must not be {@literal null}. */ - DefaultClusterOperations(RedisTemplate template) { + DefaultClusterOperations(@NonNull RedisTemplate template) { super(template); this.template = template; } @Override - public Set keys(RedisClusterNode node, K pattern) { + public Set keys(@NonNull RedisClusterNode node, @NonNull K pattern) { Assert.notNull(node, "ClusterNode must not be null"); @@ -61,7 +63,7 @@ public Set keys(RedisClusterNode node, K pattern) { } @Override - public K randomKey(RedisClusterNode node) { + public K randomKey(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -69,7 +71,7 @@ public K randomKey(RedisClusterNode node) { } @Override - public String ping(RedisClusterNode node) { + public String ping(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -77,7 +79,7 @@ public String ping(RedisClusterNode node) { } @Override - public void addSlots(RedisClusterNode node, int... slots) { + public void addSlots(@NonNull RedisClusterNode node, int... slots) { Assert.notNull(node, "ClusterNode must not be null"); @@ -88,7 +90,7 @@ public void addSlots(RedisClusterNode node, int... slots) { } @Override - public void addSlots(RedisClusterNode node, SlotRange range) { + public void addSlots(@NonNull RedisClusterNode node, @NonNull SlotRange range) { Assert.notNull(node, "ClusterNode must not be null"); Assert.notNull(range, "Range must not be null"); @@ -97,7 +99,7 @@ public void addSlots(RedisClusterNode node, SlotRange range) { } @Override - public void bgReWriteAof(RedisClusterNode node) { + public void bgReWriteAof(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -108,7 +110,7 @@ public void bgReWriteAof(RedisClusterNode node) { } @Override - public void bgSave(RedisClusterNode node) { + public void bgSave(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -119,7 +121,7 @@ public void bgSave(RedisClusterNode node) { } @Override - public void meet(RedisClusterNode node) { + public void meet(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -130,7 +132,7 @@ public void meet(RedisClusterNode node) { } @Override - public void forget(RedisClusterNode node) { + public void forget(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -141,7 +143,7 @@ public void forget(RedisClusterNode node) { } @Override - public void flushDb(RedisClusterNode node) { + public void flushDb(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -152,7 +154,7 @@ public void flushDb(RedisClusterNode node) { } @Override - public void flushDb(RedisClusterNode node, FlushOption option) { + public void flushDb(@NonNull RedisClusterNode node, @NonNull FlushOption option) { Assert.notNull(node, "ClusterNode must not be null"); @@ -163,7 +165,7 @@ public void flushDb(RedisClusterNode node, FlushOption option) { } @Override - public Collection getReplicas(final RedisClusterNode node) { + public Collection getReplicas(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -171,7 +173,7 @@ public Collection getReplicas(final RedisClusterNode node) { } @Override - public void save(RedisClusterNode node) { + public void save(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -182,7 +184,7 @@ public void save(RedisClusterNode node) { } @Override - public void shutdown(RedisClusterNode node) { + public void shutdown(@NonNull RedisClusterNode node) { Assert.notNull(node, "ClusterNode must not be null"); @@ -193,7 +195,7 @@ public void shutdown(RedisClusterNode node) { } @Override - public void reshard(RedisClusterNode source, int slot, RedisClusterNode target) { + public void reshard(@NonNull RedisClusterNode source, int slot, @NonNull RedisClusterNode target) { Assert.notNull(source, "Source node must not be null"); Assert.notNull(target, "Target node must not be null"); @@ -218,8 +220,7 @@ public void reshard(RedisClusterNode source, int slot, RedisClusterNode target) * @param callback must not be {@literal null}. * @return execution result. Can be {@literal null}. */ - @Nullable - T doInCluster(RedisClusterCallback callback) { + T doInCluster(@NonNull RedisClusterCallback callback) { Assert.notNull(callback, "ClusterCallback must not be null"); diff --git a/src/main/java/org/springframework/data/redis/core/DefaultHashOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultHashOperations.java index ccdfbee704..6712257b05 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultHashOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultHashOperations.java @@ -26,13 +26,15 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; import org.springframework.data.redis.core.types.Expirations.Timeouts; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -43,16 +45,17 @@ * @author Ninad Divadkar * @author Tihomir Mateev */ +@NullUnmarked class DefaultHashOperations extends AbstractOperations implements HashOperations { @SuppressWarnings("unchecked") - DefaultHashOperations(RedisTemplate template) { + DefaultHashOperations(@NonNull RedisTemplate template) { super((RedisTemplate) template); } @Override @SuppressWarnings("unchecked") - public HV get(K key, Object hashKey) { + public HV get(@NonNull K key, @NonNull Object hashKey) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -62,7 +65,7 @@ public HV get(K key, Object hashKey) { } @Override - public Boolean hasKey(K key, Object hashKey) { + public Boolean hasKey(@NonNull K key, @NonNull Object hashKey) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -70,7 +73,7 @@ public Boolean hasKey(K key, Object hashKey) { } @Override - public Long increment(K key, HK hashKey, long delta) { + public Long increment(@NonNull K key, @NonNull HK hashKey, long delta) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -78,7 +81,7 @@ public Long increment(K key, HK hashKey, long delta) { } @Override - public Double increment(K key, HK hashKey, double delta) { + public Double increment(@NonNull K key, @NonNull HK hashKey, double delta) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -87,15 +90,14 @@ public Double increment(K key, HK hashKey, double delta) { @Nullable @Override - public HK randomKey(K key) { + public HK randomKey(@NonNull K key) { byte[] rawKey = rawKey(key); return deserializeHashKey(execute(connection -> connection.hRandField(rawKey))); } - @Nullable @Override - public Entry randomEntry(K key) { + public Entry<@NonNull HK, HV> randomEntry(@NonNull K key) { byte[] rawKey = rawKey(key); Entry rawEntry = execute(connection -> connection.hRandFieldWithValues(rawKey)); @@ -103,18 +105,16 @@ public Entry randomEntry(K key) { : Converters.entryOf(deserializeHashKey(rawEntry.getKey()), deserializeHashValue(rawEntry.getValue())); } - @Nullable @Override - public List randomKeys(K key, long count) { + public List<@NonNull HK> randomKeys(@NonNull K key, long count) { byte[] rawKey = rawKey(key); List rawValues = execute(connection -> connection.hRandField(rawKey, count)); return deserializeHashKeys(rawValues); } - @Nullable @Override - public Map randomEntries(K key, long count) { + public Map<@NonNull HK, HV> randomEntries(@NonNull K key, long count) { Assert.isTrue(count > 0, "Count must not be negative"); byte[] rawKey = rawKey(key); @@ -130,7 +130,7 @@ public Map randomEntries(K key, long count) { } @Override - public Set keys(K key) { + public Set<@NonNull HK> keys(@NonNull K key) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.hKeys(rawKey)); @@ -139,15 +139,14 @@ public Set keys(K key) { } @Override - public Long size(K key) { + public Long size(@NonNull K key) { byte[] rawKey = rawKey(key); return execute(connection -> connection.hLen(rawKey)); } - @Nullable @Override - public Long lengthOfValue(K key, HK hashKey) { + public Long lengthOfValue(@NonNull K key, @NonNull HK hashKey) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -155,7 +154,7 @@ public Long lengthOfValue(K key, HK hashKey) { } @Override - public void putAll(K key, Map m) { + public void putAll(@NonNull K key, @NonNull Map m) { if (m.isEmpty()) { return; @@ -176,7 +175,7 @@ public void putAll(K key, Map m) { } @Override - public List multiGet(K key, Collection fields) { + public List multiGet(@NonNull K key, @NonNull Collection<@NonNull HK> fields) { if (fields.isEmpty()) { return Collections.emptyList(); @@ -186,7 +185,8 @@ public List multiGet(K key, Collection fields) { byte[][] rawHashKeys = new byte[fields.size()][]; int counter = 0; - for (HK hashKey : fields) { + for (@NonNull + HK hashKey : fields) { rawHashKeys[counter++] = rawHashKey(hashKey); } @@ -196,7 +196,7 @@ public List multiGet(K key, Collection fields) { } @Override - public void put(K key, HK hashKey, HV value) { + public void put(@NonNull K key, @NonNull HK hashKey, HV value) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -209,7 +209,7 @@ public void put(K key, HK hashKey, HV value) { } @Override - public Boolean putIfAbsent(K key, HK hashKey, HV value) { + public Boolean putIfAbsent(@NonNull K key, @NonNull HK hashKey, HV value) { byte[] rawKey = rawKey(key); byte[] rawHashKey = rawHashKey(hashKey); @@ -219,13 +219,13 @@ public Boolean putIfAbsent(K key, HK hashKey, HV value) { } @Override - public ExpireChanges expire(K key, Duration duration, Collection hashKeys) { + public ExpireChanges<@NonNull HK> expire(@NonNull K key, @NonNull Duration duration, + @NonNull Collection<@NonNull HK> hashKeys) { List orderedKeys = List.copyOf(hashKeys); byte[] rawKey = rawKey(key); byte[][] rawHashKeys = rawHashKeys(orderedKeys.toArray()); - boolean hasMillis = TimeoutUtils.hasMillis(duration); List raw = execute(connection -> TimeoutUtils.hasMillis(duration) ? connection.hashCommands().hpExpire(rawKey, duration.toMillis(), rawHashKeys) @@ -235,7 +235,8 @@ public ExpireChanges expire(K key, Duration duration, Collection hashKey } @Override - public ExpireChanges expireAt(K key, Instant instant, Collection hashKeys) { + public ExpireChanges<@NonNull HK> expireAt(@NonNull K key, @NonNull Instant instant, + @NonNull Collection<@NonNull HK> hashKeys) { List orderedKeys = List.copyOf(hashKeys); @@ -251,7 +252,8 @@ public ExpireChanges expireAt(K key, Instant instant, Collection hashKey } @Override - public ExpireChanges expire(K key, Expiration expiration, ExpirationOptions options, Collection hashKeys) { + public ExpireChanges<@NonNull HK> expire(@NonNull K key, @NonNull Expiration expiration, + @NonNull ExpirationOptions options, @NonNull Collection<@NonNull HK> hashKeys) { List orderedKeys = List.copyOf(hashKeys); byte[] rawKey = rawKey(key); @@ -263,7 +265,7 @@ public ExpireChanges expire(K key, Expiration expiration, ExpirationOptions } @Override - public ExpireChanges persist(K key, Collection hashKeys) { + public ExpireChanges<@NonNull HK> persist(@NonNull K key, @NonNull Collection<@NonNull HK> hashKeys) { List orderedKeys = List.copyOf(hashKeys); byte[] rawKey = rawKey(key); @@ -275,9 +277,10 @@ public ExpireChanges persist(K key, Collection hashKeys) { } @Override - public Expirations getTimeToLive(K key, TimeUnit timeUnit, Collection hashKeys) { + public Expirations<@NonNull HK> getTimeToLive(@NonNull K key, @NonNull TimeUnit timeUnit, + @NonNull Collection<@NonNull HK> hashKeys) { - if(timeUnit.compareTo(TimeUnit.MILLISECONDS) < 0) { + if (timeUnit.compareTo(TimeUnit.MILLISECONDS) < 0) { throw new IllegalArgumentException("%s precision is not supported must be >= MILLISECONDS".formatted(timeUnit)); } @@ -299,7 +302,7 @@ public Expirations getTimeToLive(K key, TimeUnit timeUnit, Collection ha } @Override - public List values(K key) { + public List values(@NonNull K key) { byte[] rawKey = rawKey(key); List rawValues = execute(connection -> connection.hVals(rawKey)); @@ -308,7 +311,7 @@ public List values(K key) { } @Override - public Long delete(K key, Object... hashKeys) { + public Long delete(@NonNull K key, @NonNull Object @NonNull... hashKeys) { byte[] rawKey = rawKey(key); byte[][] rawHashKeys = rawHashKeys(hashKeys); @@ -317,7 +320,7 @@ public Long delete(K key, Object... hashKeys) { } @Override - public Map entries(K key) { + public Map<@NonNull HK, HV> entries(@NonNull K key) { byte[] rawKey = rawKey(key); Map entries = execute(connection -> connection.hGetAll(rawKey)); @@ -326,11 +329,12 @@ public Map entries(K key) { } @Override - public Cursor> scan(K key, ScanOptions options) { + public Cursor> scan(@NonNull K key, @Nullable ScanOptions options) { byte[] rawKey = rawKey(key); - return template.executeWithStickyConnection( - (RedisCallback>>) connection -> new ConvertingCursor<>(connection.hScan(rawKey, options), + return template + .executeWithStickyConnection((RedisCallback>>) connection -> new ConvertingCursor<>( + connection.hScan(rawKey, options != null ? options : ScanOptions.NONE), new Converter, Entry>() { @Override diff --git a/src/main/java/org/springframework/data/redis/core/DefaultListOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultListOperations.java index ce0268869c..6884a01b9a 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultListOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultListOperations.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisListCommands.Direction; import org.springframework.data.redis.connection.RedisListCommands.Position; @@ -33,14 +35,15 @@ * @author Christoph Strobl * @author dengliming */ +@NullUnmarked class DefaultListOperations extends AbstractOperations implements ListOperations { - DefaultListOperations(RedisTemplate template) { + DefaultListOperations(@NonNull RedisTemplate template) { super(template); } @Override - public V index(K key, long index) { + public V index(@NonNull K key, long index) { return execute(new ValueDeserializingRedisCallback(key) { @@ -52,7 +55,7 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public Long indexOf(K key, V value) { + public Long indexOf(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -60,7 +63,7 @@ public Long indexOf(K key, V value) { } @Override - public Long lastIndexOf(K key, V value) { + public Long lastIndexOf(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -72,7 +75,7 @@ public Long lastIndexOf(K key, V value) { } @Override - public V leftPop(K key) { + public V leftPop(@NonNull K key) { return execute(new ValueDeserializingRedisCallback(key) { @@ -84,13 +87,13 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public List leftPop(K key, long count) { + public List leftPop(@NonNull K key, long count) { byte[] rawKey = rawKey(key); return execute(connection -> deserializeValues(connection.lPop(rawKey, count))); } @Override - public V leftPop(K key, long timeout, TimeUnit unit) { + public V leftPop(@NonNull K key, long timeout, @NonNull TimeUnit unit) { int tm = (int) TimeoutUtils.toSeconds(timeout, unit); return execute(new ValueDeserializingRedisCallback(key) { @@ -104,7 +107,7 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public Long leftPush(K key, V value) { + public Long leftPush(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -112,7 +115,7 @@ public Long leftPush(K key, V value) { } @Override - public Long leftPushAll(K key, V... values) { + public Long leftPushAll(@NonNull K key, V @NonNull... values) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(values); @@ -120,7 +123,7 @@ public Long leftPushAll(K key, V... values) { } @Override - public Long leftPushAll(K key, Collection values) { + public Long leftPushAll(@NonNull K key, @NonNull Collection values) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(values); @@ -129,7 +132,7 @@ public Long leftPushAll(K key, Collection values) { } @Override - public Long leftPushIfPresent(K key, V value) { + public Long leftPushIfPresent(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -137,7 +140,7 @@ public Long leftPushIfPresent(K key, V value) { } @Override - public Long leftPush(K key, V pivot, V value) { + public Long leftPush(@NonNull K key, @NonNull V pivot, V value) { byte[] rawKey = rawKey(key); byte[] rawPivot = rawValue(pivot); @@ -146,21 +149,21 @@ public Long leftPush(K key, V pivot, V value) { } @Override - public Long size(K key) { + public Long size(@NonNull K key) { byte[] rawKey = rawKey(key); return execute(connection -> connection.lLen(rawKey)); } @Override - public List range(K key, long start, long end) { + public List range(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); return execute(connection -> deserializeValues(connection.lRange(rawKey, start, end))); } @Override - public Long remove(K key, long count, Object value) { + public Long remove(@NonNull K key, long count, Object value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -168,7 +171,7 @@ public Long remove(K key, long count, Object value) { } @Override - public V rightPop(K key) { + public V rightPop(@NonNull K key) { return execute(new ValueDeserializingRedisCallback(key) { @@ -180,13 +183,13 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public List rightPop(K key, long count) { + public List rightPop(@NonNull K key, long count) { byte[] rawKey = rawKey(key); return execute(connection -> deserializeValues(connection.rPop(rawKey, count))); } @Override - public V rightPop(K key, long timeout, TimeUnit unit) { + public V rightPop(@NonNull K key, long timeout, @NonNull TimeUnit unit) { int tm = (int) TimeoutUtils.toSeconds(timeout, unit); @@ -201,7 +204,7 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public Long rightPush(K key, V value) { + public Long rightPush(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -209,7 +212,7 @@ public Long rightPush(K key, V value) { } @Override - public Long rightPushAll(K key, V... values) { + public Long rightPushAll(@NonNull K key, V @NonNull... values) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(values); @@ -217,7 +220,7 @@ public Long rightPushAll(K key, V... values) { } @Override - public Long rightPushAll(K key, Collection values) { + public Long rightPushAll(@NonNull K key, @NonNull Collection values) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(values); @@ -225,7 +228,7 @@ public Long rightPushAll(K key, Collection values) { } @Override - public Long rightPushIfPresent(K key, V value) { + public Long rightPushIfPresent(@NonNull K key, V value) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -233,7 +236,7 @@ public Long rightPushIfPresent(K key, V value) { } @Override - public Long rightPush(K key, V pivot, V value) { + public Long rightPush(@NonNull K key, @NonNull V pivot, V value) { byte[] rawKey = rawKey(key); byte[] rawPivot = rawValue(pivot); @@ -242,7 +245,7 @@ public Long rightPush(K key, V pivot, V value) { } @Override - public V rightPopAndLeftPush(K sourceKey, K destinationKey) { + public V rightPopAndLeftPush(@NonNull K sourceKey, @NonNull K destinationKey) { byte[] rawDestKey = rawKey(destinationKey); return execute(new ValueDeserializingRedisCallback(sourceKey) { @@ -255,7 +258,7 @@ protected byte[] inRedis(byte[] rawSourceKey, RedisConnection connection) { } @Override - public V rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit) { + public V rightPopAndLeftPush(@NonNull K sourceKey, @NonNull K destinationKey, long timeout, @NonNull TimeUnit unit) { int tm = (int) TimeoutUtils.toSeconds(timeout, unit); byte[] rawDestKey = rawKey(destinationKey); @@ -269,7 +272,7 @@ protected byte[] inRedis(byte[] rawSourceKey, RedisConnection connection) { } @Override - public V move(K sourceKey, Direction from, K destinationKey, Direction to) { + public V move(@NonNull K sourceKey, @NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to) { byte[] rawDestKey = rawKey(destinationKey); return execute(new ValueDeserializingRedisCallback(sourceKey) { @@ -282,7 +285,8 @@ protected byte[] inRedis(byte[] rawSourceKey, RedisConnection connection) { } @Override - public V move(K sourceKey, Direction from, K destinationKey, Direction to, long timeout, TimeUnit unit) { + public V move(@NonNull K sourceKey, @NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to, + long timeout, @NonNull TimeUnit unit) { byte[] rawDestKey = rawKey(destinationKey); return execute(new ValueDeserializingRedisCallback(sourceKey) { @@ -295,7 +299,7 @@ protected byte[] inRedis(byte[] rawSourceKey, RedisConnection connection) { } @Override - public void set(K key, long index, V value) { + public void set(@NonNull K key, long index, V value) { byte[] rawValue = rawValue(value); execute(new ValueDeserializingRedisCallback(key) { @@ -309,7 +313,7 @@ protected byte[] inRedis(byte[] rawKey, RedisConnection connection) { } @Override - public void trim(K key, long start, long end) { + public void trim(@NonNull K key, long start, long end) { execute(new ValueDeserializingRedisCallback(key) { diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveGeoOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveGeoOperations.java index 6e92f6a749..c618629dca 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveGeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveGeoOperations.java @@ -25,6 +25,7 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -39,7 +40,6 @@ import org.springframework.data.redis.domain.geo.GeoReference.GeoMemberReference; import org.springframework.data.redis.domain.geo.GeoShape; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -325,11 +325,11 @@ private ByteBuffer rawValue(V value) { return serializationContext.getValueSerializationPair().write(value); } - @Nullable - private V readValue(ByteBuffer buffer) { + private @Nullable V readValue(ByteBuffer buffer) { return serializationContext.getValueSerializationPair().read(buffer); } + @SuppressWarnings("NullAway") private GeoResult> readGeoResult(GeoResult> source) { return new GeoResult<>(new GeoLocation<>(readValue(source.getContent().getName()), source.getContent().getPoint()), diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveHashOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveHashOperations.java index 282f229913..e569e87497 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveHashOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveHashOperations.java @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ExpirationOptions; @@ -39,7 +40,6 @@ import org.springframework.data.redis.core.types.Expirations; import org.springframework.data.redis.core.types.Expirations.Timeouts; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -353,8 +353,7 @@ private ByteBuffer rawHashValue(HV key) { } @SuppressWarnings("unchecked") - @Nullable - private HK readHashKey(ByteBuffer value) { + private @Nullable HK readHashKey(ByteBuffer value) { return (HK) serializationContext.getHashKeySerializationPair().read(value); } @@ -370,8 +369,7 @@ private HK readRequiredHashKey(ByteBuffer buffer) { } @SuppressWarnings("unchecked") - @Nullable - private HV readHashValue(@Nullable ByteBuffer value) { + private @Nullable HV readHashValue(@Nullable ByteBuffer value) { return value != null ? (HV) serializationContext.getHashValueSerializationPair().read(value) : null; } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveListOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveListOperations.java index 1a26f750a7..cb1401f822 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveListOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveListOperations.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.core; +import org.springframework.lang.Contract; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -26,6 +27,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ReactiveListCommands; @@ -33,7 +35,6 @@ import org.springframework.data.redis.connection.ReactiveListCommands.LPosCommand; import org.springframework.data.redis.connection.RedisListCommands.Position; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -251,6 +252,7 @@ public Flux leftPop(K key, long count) { } @Override + @SuppressWarnings("NullAway") public Mono leftPop(K key, Duration timeout) { Assert.notNull(key, "Key must not be null"); @@ -278,6 +280,7 @@ public Flux rightPop(K key, long count) { } @Override + @SuppressWarnings("NullAway") public Mono rightPop(K key, Duration timeout) { Assert.notNull(key, "Key must not be null"); @@ -344,8 +347,8 @@ private ByteBuffer rawValue(V value) { return serializationContext.getValueSerializationPair().write(value); } - @Nullable - private V readValue(ByteBuffer buffer) { + @Contract("!null -> !null") + private @Nullable V readValue(ByteBuffer buffer) { return serializationContext.getValueSerializationPair().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveSetOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveSetOperations.java index 4294bca879..33ad054e3b 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveSetOperations.java @@ -27,11 +27,11 @@ import java.util.Map; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ReactiveSetCommands; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -418,8 +418,7 @@ private ByteBuffer rawValue(V value) { return serializationContext.getValueSerializationPair().write(value); } - @Nullable - private V readValue(ByteBuffer buffer) { + private @Nullable V readValue(ByteBuffer buffer) { return serializationContext.getValueSerializationPair().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveStreamOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveStreamOperations.java index f7365adba5..b87d0b1a0b 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveStreamOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveStreamOperations.java @@ -26,14 +26,15 @@ import java.util.Map.Entry; import java.util.function.Function; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.reactivestreams.Publisher; - import org.springframework.core.convert.ConversionService; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.ReactiveStreamCommands; -import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.RedisStreamCommands.XAddOptions; +import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.connection.stream.ByteBufferRecord; import org.springframework.data.redis.connection.stream.Consumer; @@ -50,7 +51,6 @@ import org.springframework.data.redis.connection.stream.StreamReadOptions; import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -64,29 +64,31 @@ * @author jinkshower * @since 2.2 */ +@NullUnmarked class DefaultReactiveStreamOperations implements ReactiveStreamOperations { private final ReactiveRedisTemplate template; private final RedisSerializationContext serializationContext; private final StreamObjectMapper objectMapper; - DefaultReactiveStreamOperations(ReactiveRedisTemplate template, - RedisSerializationContext serializationContext, - @Nullable HashMapper hashMapper) { + DefaultReactiveStreamOperations(@NonNull ReactiveRedisTemplate template, + @NonNull RedisSerializationContext serializationContext, + @NonNull HashMapper hashMapper) { this.template = template; this.serializationContext = serializationContext; this.objectMapper = new StreamObjectMapper(hashMapper) { @Override - protected HashMapper doGetHashMapper(ConversionService conversionService, Class targetType) { + protected HashMapper doGetHashMapper(@NonNull ConversionService conversionService, + @NonNull Class targetType) { if (objectMapper.isSimpleType(targetType) || ClassUtils.isAssignable(ByteBuffer.class, targetType)) { return new HashMapper<>() { @Override - public Map toHash(Object object) { + public Map toHash(@NonNull Object object) { Object key = "payload"; Object value = object; @@ -102,7 +104,7 @@ public Map toHash(Object object) { } @Override - public Object fromHash(Map hash) { + public Object fromHash(@NonNull Map hash) { Object value = hash.values().iterator().next(); @@ -127,7 +129,7 @@ public Object fromHash(Map hash) { } @Override - public Mono acknowledge(K key, String group, RecordId... recordIds) { + public Mono acknowledge(@NonNull K key, @NonNull String group, RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.hasText(group, "Group must not be null or empty"); @@ -138,7 +140,7 @@ public Mono acknowledge(K key, String group, RecordId... recordIds) { } @Override - public Mono add(Record record) { + public Mono add(@NonNull Record record) { Assert.notNull(record.getStream(), "Key must not be null"); Assert.notNull(record.getValue(), "Body must not be null"); @@ -149,7 +151,7 @@ public Mono add(Record record) { } @Override - public Mono add(Record record, XAddOptions xAddOptions) { + public Mono add(@NonNull Record record, @NonNull XAddOptions xAddOptions) { Assert.notNull(record.getStream(), "Key must not be null"); Assert.notNull(record.getValue(), "Body must not be null"); @@ -161,14 +163,15 @@ public Mono add(Record record, XAddOptions xAddOptions) { } @Override - public Flux> claim(K key, String consumerGroup, String newOwner, XClaimOptions xClaimOptions) { + public Flux> claim(@NonNull K key, @NonNull String consumerGroup, @NonNull String newOwner, + @NonNull XClaimOptions xClaimOptions) { return createFlux(streamCommands -> streamCommands.xClaim(rawKey(key), consumerGroup, newOwner, xClaimOptions) .map(this::deserializeRecord)); } @Override - public Mono delete(K key, RecordId... recordIds) { + public Mono delete(@NonNull K key, RecordId @NonNull... recordIds) { Assert.notNull(key, "Key must not be null"); Assert.notNull(recordIds, "MessageIds must not be null"); @@ -177,7 +180,7 @@ public Mono delete(K key, RecordId... recordIds) { } @Override - public Mono createGroup(K key, ReadOffset readOffset, String group) { + public Mono createGroup(@NonNull K key, @NonNull ReadOffset readOffset, @NonNull String group) { Assert.notNull(key, "Key must not be null"); Assert.notNull(readOffset, "ReadOffset must not be null"); @@ -187,7 +190,7 @@ public Mono createGroup(K key, ReadOffset readOffset, String group) { } @Override - public Mono deleteConsumer(K key, Consumer consumer) { + public Mono deleteConsumer(@NonNull K key, @NonNull Consumer consumer) { Assert.notNull(key, "Key must not be null"); Assert.notNull(consumer, "Consumer must not be null"); @@ -196,7 +199,7 @@ public Mono deleteConsumer(K key, Consumer consumer) { } @Override - public Mono destroyGroup(K key, String group) { + public Mono destroyGroup(@NonNull K key, @NonNull String group) { Assert.notNull(key, "Key must not be null"); Assert.notNull(group, "Group must not be null"); @@ -205,7 +208,7 @@ public Mono destroyGroup(K key, String group) { } @Override - public Flux consumers(K key, String group) { + public Flux consumers(@NonNull K key, @NonNull String group) { Assert.notNull(key, "Key must not be null"); Assert.notNull(group, "Group must not be null"); @@ -214,7 +217,7 @@ public Flux consumers(K key, String group) { } @Override - public Mono info(K key) { + public Mono info(@NonNull K key) { Assert.notNull(key, "Key must not be null"); @@ -222,7 +225,7 @@ public Mono info(K key) { } @Override - public Flux groups(K key) { + public Flux groups(@NonNull K key) { Assert.notNull(key, "Key must not be null"); @@ -230,7 +233,7 @@ public Flux groups(K key) { } @Override - public Mono pending(K key, String group, Range range, long count) { + public Mono pending(@NonNull K key, @NonNull String group, @NonNull Range range, long count) { ByteBuffer rawKey = rawKey(key); @@ -238,7 +241,8 @@ public Mono pending(K key, String group, Range range, long c } @Override - public Mono pending(K key, Consumer consumer, Range range, long count) { + public Mono pending(@NonNull K key, @NonNull Consumer consumer, @NonNull Range range, + long count) { ByteBuffer rawKey = rawKey(key); @@ -246,7 +250,7 @@ public Mono pending(K key, Consumer consumer, Range range, l } @Override - public Mono pending(K key, String group) { + public Mono pending(@NonNull K key, @NonNull String group) { ByteBuffer rawKey = rawKey(key); @@ -254,7 +258,7 @@ public Mono pending(K key, String group) { } @Override - public Mono size(K key) { + public Mono size(@NonNull K key) { Assert.notNull(key, "Key must not be null"); @@ -262,19 +266,18 @@ public Mono size(K key) { } @Override - public Flux> range(K key, Range range, Limit limit) { + public Flux> range(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); Assert.notNull(limit, "Limit must not be null"); - return createFlux(streamCommands -> - streamCommands.xRange(rawKey(key), range, limit).map(this::deserializeRecord)); + return createFlux(streamCommands -> streamCommands.xRange(rawKey(key), range, limit).map(this::deserializeRecord)); } @Override @SuppressWarnings("unchecked") - public Flux> read(StreamReadOptions readOptions, StreamOffset... streams) { + public Flux> read(@NonNull StreamReadOptions readOptions, StreamOffset @NonNull... streams) { Assert.notNull(readOptions, "StreamReadOptions must not be null"); Assert.notNull(streams, "Streams must not be null"); @@ -289,8 +292,8 @@ public Flux> read(StreamReadOptions readOptions, StreamOffs @Override @SuppressWarnings("unchecked") - public Flux> read(Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams) { + public Flux> read(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + StreamOffset @NonNull... streams) { Assert.notNull(consumer, "Consumer must not be null"); Assert.notNull(readOptions, "StreamReadOptions must not be null"); @@ -305,30 +308,30 @@ public Flux> read(Consumer consumer, StreamReadOptions read } @Override - public Flux> reverseRange(K key, Range range, Limit limit) { + public Flux> reverseRange(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); Assert.notNull(limit, "Limit must not be null"); - return createFlux(streamCommands -> - streamCommands.xRevRange(rawKey(key), range, limit).map(this::deserializeRecord)); + return createFlux( + streamCommands -> streamCommands.xRevRange(rawKey(key), range, limit).map(this::deserializeRecord)); } @Override - public Mono trim(K key, long count) { + public Mono trim(@NonNull K key, long count) { return trim(key, count, false); } @Override - public Mono trim(K key, long count, boolean approximateTrimming) { + public Mono trim(@NonNull K key, long count, boolean approximateTrimming) { Assert.notNull(key, "Key must not be null"); return createMono(streamCommands -> streamCommands.xTrim(rawKey(key), count, approximateTrimming)); } @Override - public HashMapper getHashMapper(Class targetType) { + public HashMapper getHashMapper(@NonNull Class targetType) { return objectMapper.getHashMapper(targetType); } @@ -361,8 +364,7 @@ private ByteBuffer rawHashKey(HK key) { try { return serializationContext.getHashKeySerializationPair().write(key); - } catch (IllegalStateException ignore) { - } + } catch (IllegalStateException ignore) {} return ByteBuffer.wrap(objectMapper.getConversionService().convert(key, byte[].class)); } @@ -371,8 +373,7 @@ private ByteBuffer rawValue(HV value) { try { return serializationContext.getHashValueSerializationPair().write(value); - } catch (IllegalStateException ignore) { - } + } catch (IllegalStateException ignore) {} return ByteBuffer.wrap(objectMapper.getConversionService().convert(value, byte[].class)); } @@ -392,7 +393,7 @@ private HV deserializeHashValue(ByteBuffer buffer) { } @Override - public MapRecord deserializeRecord(ByteBufferRecord record) { + public MapRecord deserializeRecord(@NonNull ByteBufferRecord record) { return record.map(it -> it.mapEntries(this::deserializeRecordFields).withStreamKey(readKey(record.getStream()))); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java index 8cf8d54985..57a06bb660 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveValueOperations.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.BitFieldSubCommands; @@ -35,7 +36,6 @@ import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -342,8 +342,7 @@ private ByteBuffer rawValue(V value) { return serializationContext.getValueSerializationPair().write(value); } - @Nullable - private V readValue(ByteBuffer buffer) { + private @Nullable V readValue(ByteBuffer buffer) { return serializationContext.getValueSerializationPair().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultReactiveZSetOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultReactiveZSetOperations.java index 65ae76a139..191e1d082b 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultReactiveZSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultReactiveZSetOperations.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -26,6 +28,7 @@ import java.util.List; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -39,7 +42,6 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -50,12 +52,13 @@ * @author Andrey Shlykov * @since 2.0 */ +@NullUnmarked class DefaultReactiveZSetOperations implements ReactiveZSetOperations { private final ReactiveRedisTemplate template; private final RedisSerializationContext serializationContext; - public DefaultReactiveZSetOperations(ReactiveRedisTemplate template, + public DefaultReactiveZSetOperations( @NonNull ReactiveRedisTemplate template, RedisSerializationContext serializationContext) { this.template = template; @@ -63,7 +66,7 @@ public DefaultReactiveZSetOperations(ReactiveRedisTemplate template, } @Override - public Mono add(K key, V value, double score) { + public Mono add( @NonNull K key, @NonNull V value, double score) { Assert.notNull(key, "Key must not be null"); @@ -71,7 +74,7 @@ public Mono add(K key, V value, double score) { } @Override - public Mono addAll(K key, Collection> tuples) { + public Mono addAll( @NonNull K key, @NonNull Collection> tuples) { Assert.notNull(key, "Key must not be null"); Assert.notNull(tuples, "Key must not be null"); @@ -84,7 +87,7 @@ public Mono addAll(K key, Collection> tuples) { @Override @SuppressWarnings("unchecked") - public Mono remove(K key, Object... values) { + public Mono remove( @NonNull K key, @NonNull Object @NonNull ... values) { Assert.notNull(key, "Key must not be null"); Assert.notNull(values, "Values must not be null"); @@ -100,7 +103,7 @@ public Mono remove(K key, Object... values) { } @Override - public Mono incrementScore(K key, V value, double delta) { + public Mono incrementScore( @NonNull K key, @NonNull V value, double delta) { Assert.notNull(key, "Key must not be null"); @@ -108,7 +111,7 @@ public Mono incrementScore(K key, V value, double delta) { } @Override - public Mono randomMember(K key) { + public Mono randomMember( @NonNull K key) { Assert.notNull(key, "Key must not be null"); @@ -116,7 +119,7 @@ public Mono randomMember(K key) { } @Override - public Flux distinctRandomMembers(K key, long count) { + public Flux distinctRandomMembers( @NonNull K key, long count) { Assert.notNull(key, "Key must not be null"); Assert.isTrue(count > 0, "Negative count not supported; Use randomMembers to allow duplicate elements"); @@ -125,7 +128,7 @@ public Flux distinctRandomMembers(K key, long count) { } @Override - public Flux randomMembers(K key, long count) { + public Flux randomMembers( @NonNull K key, long count) { Assert.notNull(key, "Key must not be null"); Assert.isTrue(count > 0, "Use a positive number for count; This method is already allowing duplicate elements"); @@ -134,7 +137,7 @@ public Flux randomMembers(K key, long count) { } @Override - public Mono> randomMemberWithScore(K key) { + public Mono> randomMemberWithScore( @NonNull K key) { Assert.notNull(key, "Key must not be null"); @@ -142,7 +145,7 @@ public Mono> randomMemberWithScore(K key) { } @Override - public Flux> distinctRandomMembersWithScore(K key, long count) { + public Flux> distinctRandomMembersWithScore( @NonNull K key, long count) { Assert.notNull(key, "Key must not be null"); Assert.isTrue(count > 0, "Negative count not supported; Use randomMembers to allow duplicate elements"); @@ -151,7 +154,7 @@ public Flux> distinctRandomMembersWithScore(K key, long count) { } @Override - public Flux> randomMembersWithScore(K key, long count) { + public Flux> randomMembersWithScore( @NonNull K key, long count) { Assert.notNull(key, "Key must not be null"); Assert.isTrue(count > 0, "Use a positive number for count; This method is already allowing duplicate elements"); @@ -161,7 +164,7 @@ public Flux> randomMembersWithScore(K key, long count) { @Override @SuppressWarnings("unchecked") - public Mono rank(K key, Object o) { + public Mono rank( @NonNull K key, @NonNull Object o) { Assert.notNull(key, "Key must not be null"); @@ -170,7 +173,7 @@ public Mono rank(K key, Object o) { @Override @SuppressWarnings("unchecked") - public Mono reverseRank(K key, Object o) { + public Mono reverseRank( @NonNull K key, @NonNull Object o) { Assert.notNull(key, "Key must not be null"); @@ -178,7 +181,7 @@ public Mono reverseRank(K key, Object o) { } @Override - public Flux range(K key, Range range) { + public Flux range( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -187,7 +190,7 @@ public Flux range(K key, Range range) { } @Override - public Flux> rangeWithScores(K key, Range range) { + public Flux> rangeWithScores( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -196,7 +199,7 @@ public Flux> rangeWithScores(K key, Range range) { } @Override - public Flux rangeByScore(K key, Range range) { + public Flux rangeByScore( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -205,7 +208,7 @@ public Flux rangeByScore(K key, Range range) { } @Override - public Flux> rangeByScoreWithScores(K key, Range range) { + public Flux> rangeByScoreWithScores( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -215,7 +218,7 @@ public Flux> rangeByScoreWithScores(K key, Range range) { } @Override - public Flux rangeByScore(K key, Range range, Limit limit) { + public Flux rangeByScore( @NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -225,7 +228,7 @@ public Flux rangeByScore(K key, Range range, Limit limit) { } @Override - public Flux> rangeByScoreWithScores(K key, Range range, Limit limit) { + public Flux> rangeByScoreWithScores( @NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -236,7 +239,7 @@ public Flux> rangeByScoreWithScores(K key, Range range, Li } @Override - public Flux reverseRange(K key, Range range) { + public Flux reverseRange( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -245,7 +248,7 @@ public Flux reverseRange(K key, Range range) { } @Override - public Flux> reverseRangeWithScores(K key, Range range) { + public Flux> reverseRangeWithScores( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -255,7 +258,7 @@ public Flux> reverseRangeWithScores(K key, Range range) { } @Override - public Flux reverseRangeByScore(K key, Range range) { + public Flux reverseRangeByScore( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -265,7 +268,7 @@ public Flux reverseRangeByScore(K key, Range range) { } @Override - public Flux> reverseRangeByScoreWithScores(K key, Range range) { + public Flux> reverseRangeByScoreWithScores( @NonNull K key, @NonNull Range range) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -275,7 +278,7 @@ public Flux> reverseRangeByScoreWithScores(K key, Range ra } @Override - public Flux reverseRangeByScore(K key, Range range, Limit limit) { + public Flux reverseRangeByScore( @NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -285,7 +288,7 @@ public Flux reverseRangeByScore(K key, Range range, Limit limit) { } @Override - public Flux> reverseRangeByScoreWithScores(K key, Range range, Limit limit) { + public Flux> reverseRangeByScoreWithScores( @NonNull K key, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(key, "Key must not be null"); Assert.notNull(range, "Range must not be null"); @@ -296,7 +299,7 @@ public Flux> reverseRangeByScoreWithScores(K key, Range ra } @Override - public Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit) { + public Mono rangeAndStoreByLex( @NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -307,7 +310,7 @@ public Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range, Li } @Override - public Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit) { + public Mono reverseRangeAndStoreByLex( @NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -319,7 +322,7 @@ public Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range ra } @Override - public Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit) { + public Mono rangeAndStoreByScore( @NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -331,7 +334,7 @@ public Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range, } @Override - public Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit) { + public Mono reverseRangeAndStoreByScore( @NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, @NonNull Limit limit) { Assert.notNull(srcKey, "Source key must not be null"); Assert.notNull(dstKey, "Destination key must not be null"); @@ -343,13 +346,13 @@ public Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range } @Override - public Flux> scan(K key, ScanOptions options) { + public Flux> scan( @NonNull K key, @Nullable ScanOptions options) { Assert.notNull(key, "Key must not be null"); Assert.notNull(options, "ScanOptions must not be null"); return createFlux(zSetCommands -> - zSetCommands.zScan(rawKey(key), options).map(this::readTypedTuple)); + zSetCommands.zScan(rawKey(key), options ).map(this::readTypedTuple)); } @Override @@ -738,8 +741,7 @@ private ByteBuffer rawValue(V value) { return serializationContext.getValueSerializationPair().write(value); } - @Nullable - private V readValue(ByteBuffer buffer) { + private @Nullable V readValue(ByteBuffer buffer) { return serializationContext.getValueSerializationPair().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultStreamOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultStreamOperations.java index 3cb27d1dcd..1127f80cc9 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultStreamOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultStreamOperations.java @@ -22,6 +22,9 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; @@ -44,7 +47,6 @@ import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.support.collections.CollectionUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -58,13 +60,14 @@ * @author jinkshower * @since 2.2 */ +@NullUnmarked class DefaultStreamOperations extends AbstractOperations implements StreamOperations { private final StreamObjectMapper objectMapper; @SuppressWarnings("unchecked") - DefaultStreamOperations(RedisTemplate template, - @Nullable HashMapper mapper) { + DefaultStreamOperations(@NonNull RedisTemplate template, + @NonNull HashMapper mapper) { super((RedisTemplate) template); @@ -118,16 +121,15 @@ public Object fromHash(Map hash) { } @Override - public Long acknowledge(K key, String group, String... recordIds) { + public Long acknowledge(@NonNull K key, @NonNull String group, @NonNull String @NonNull... recordIds) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xAck(rawKey, group, recordIds)); } - @Nullable @Override @SuppressWarnings("unchecked") - public RecordId add(Record record) { + public RecordId add(@NonNull Record record) { Assert.notNull(record, "Record must not be null"); @@ -138,10 +140,9 @@ public RecordId add(Record record) { return execute(connection -> connection.xAdd(binaryRecord)); } - @Nullable @Override @SuppressWarnings("unchecked") - public RecordId add(Record record, XAddOptions options) { + public RecordId add(@NonNull Record record, @NonNull XAddOptions options) { Assert.notNull(record, "Record must not be null"); Assert.notNull(options, "XAddOptions must not be null"); @@ -154,7 +155,8 @@ public RecordId add(Record record, XAddOptions options) { } @Override - public List> claim(K key, String consumerGroup, String newOwner, XClaimOptions xClaimOptions) { + public List> claim(@NonNull K key, @NonNull String consumerGroup, @NonNull String newOwner, + @NonNull XClaimOptions xClaimOptions) { return CollectionUtils.nullSafeList(execute(new RecordDeserializingRedisCallback() { @@ -167,84 +169,84 @@ List inRedis(RedisConnection connection) { } @Override - public Long delete(K key, RecordId... recordIds) { + public Long delete(@NonNull K key, @NonNull RecordId @NonNull... recordIds) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xDel(rawKey, recordIds)); } @Override - public String createGroup(K key, ReadOffset readOffset, String group) { + public String createGroup(@NonNull K key, @NonNull ReadOffset readOffset, @NonNull String group) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xGroupCreate(rawKey, group, readOffset, true)); } @Override - public Boolean deleteConsumer(K key, Consumer consumer) { + public Boolean deleteConsumer(@NonNull K key, @NonNull Consumer consumer) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xGroupDelConsumer(rawKey, consumer)); } @Override - public Boolean destroyGroup(K key, String group) { + public Boolean destroyGroup(@NonNull K key, @NonNull String group) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xGroupDestroy(rawKey, group)); } @Override - public XInfoStream info(K key) { + public XInfoStream info(@NonNull K key) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xInfo(rawKey)); } @Override - public XInfoConsumers consumers(K key, String group) { + public XInfoConsumers consumers(@NonNull K key, @NonNull String group) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xInfoConsumers(rawKey, group)); } @Override - public XInfoGroups groups(K key) { + public XInfoGroups groups(@NonNull K key) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xInfoGroups(rawKey)); } @Override - public PendingMessages pending(K key, String group, Range range, long count) { + public PendingMessages pending(@NonNull K key, @NonNull String group, @NonNull Range range, long count) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xPending(rawKey, group, range, count)); } @Override - public PendingMessages pending(K key, Consumer consumer, Range range, long count) { + public PendingMessages pending(@NonNull K key, @NonNull Consumer consumer, @NonNull Range range, long count) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xPending(rawKey, consumer, range, count)); } @Override - public PendingMessagesSummary pending(K key, String group) { + public PendingMessagesSummary pending(@NonNull K key, @NonNull String group) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xPending(rawKey, group)); } @Override - public Long size(K key) { + public Long size(@NonNull K key) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xLen(rawKey)); } @Override - public List> range(K key, Range range, Limit limit) { + public List> range(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { return execute(new RecordDeserializingRedisCallback() { @@ -257,7 +259,8 @@ List inRedis(RedisConnection connection) { } @Override - public List> read(StreamReadOptions readOptions, StreamOffset... streams) { + public List> read(@NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { return execute(new RecordDeserializingRedisCallback() { @@ -270,7 +273,8 @@ List inRedis(RedisConnection connection) { } @Override - public List> read(Consumer consumer, StreamReadOptions readOptions, StreamOffset... streams) { + public List> read(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { return execute(new RecordDeserializingRedisCallback() { @@ -283,7 +287,7 @@ List inRedis(RedisConnection connection) { } @Override - public List> reverseRange(K key, Range range, Limit limit) { + public List> reverseRange(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { return execute(new RecordDeserializingRedisCallback() { @@ -296,25 +300,26 @@ List inRedis(RedisConnection connection) { } @Override - public Long trim(K key, long count) { + public Long trim(@NonNull K key, long count) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xTrim(rawKey, count)); } @Override - public Long trim(K key, long count, boolean approximateTrimming) { + public Long trim(@NonNull K key, long count, boolean approximateTrimming) { byte[] rawKey = rawKey(key); return execute(connection -> connection.xTrim(rawKey, count, approximateTrimming)); } @Override - public HashMapper getHashMapper(Class targetType) { + public HashMapper getHashMapper(@NonNull Class targetType) { return objectMapper.getHashMapper(targetType); } @Override - public MapRecord deserializeRecord(ByteRecord record) { + @SuppressWarnings("unchecked") + public MapRecord deserializeRecord(@NonNull ByteRecord record) { return record.deserialize(keySerializer(), hashKeySerializer(), hashValueSerializer()); } @@ -342,13 +347,12 @@ private StreamOffset[] rawStreamOffsets(StreamOffset[] streams) { return Arrays.stream(streams) // .map(it -> StreamOffset.create(rawKey(it.getKey()), it.getOffset())) // - .toArray(it -> new StreamOffset[it]); + .toArray(StreamOffset[]::new); } abstract class RecordDeserializingRedisCallback implements RedisCallback>> { - @SuppressWarnings("unchecked") - public final List> doInRedis(RedisConnection connection) { + public final List> doInRedis(@NonNull RedisConnection connection) { List raw = inRedis(connection); if (raw == null) { @@ -363,7 +367,6 @@ public final List> doInRedis(RedisConnection connection) { return result; } - @Nullable abstract List inRedis(RedisConnection connection); } } diff --git a/src/main/java/org/springframework/data/redis/core/DefaultTypedTuple.java b/src/main/java/org/springframework/data/redis/core/DefaultTypedTuple.java index 3ae83af6c5..1cd77b3abc 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultTypedTuple.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultTypedTuple.java @@ -17,8 +17,8 @@ import java.util.Arrays; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; -import org.springframework.lang.Nullable; /** * Default implementation of TypedTuple. @@ -41,13 +41,11 @@ public DefaultTypedTuple(@Nullable V value, @Nullable Double score) { this.value = value; } - @Nullable - public Double getScore() { + public @Nullable Double getScore() { return score; } - @Nullable - public V getValue() { + public @Nullable V getValue() { return value; } @@ -84,7 +82,7 @@ public boolean equals(@Nullable Object obj) { return true; } - public int compareTo(Double o) { + public int compareTo(@Nullable Double o) { double thisScore = (score == null ? 0.0 : score); double otherScore = (o == null ? 0.0 : o); @@ -93,7 +91,7 @@ public int compareTo(Double o) { } @Override - public int compareTo(TypedTuple o) { + public int compareTo(@Nullable TypedTuple o) { if (o == null) { return compareTo(Double.valueOf(0)); diff --git a/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java index 357dda961f..5911597f99 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultValueOperations.java @@ -23,12 +23,12 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.DefaultedRedisConnection; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisStringCommands.SetOption; import org.springframework.data.redis.core.types.Expiration; -import org.springframework.lang.Nullable; /** * Default implementation of {@link ValueOperations}. diff --git a/src/main/java/org/springframework/data/redis/core/DefaultZSetOperations.java b/src/main/java/org/springframework/data/redis/core/DefaultZSetOperations.java index 030974bf8c..fc920e28d7 100644 --- a/src/main/java/org/springframework/data/redis/core/DefaultZSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/DefaultZSetOperations.java @@ -22,13 +22,15 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs; import org.springframework.data.redis.connection.zset.Aggregate; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -44,14 +46,15 @@ * @author Shyngys Sapraliyev * @author John Blum */ +@NullUnmarked class DefaultZSetOperations extends AbstractOperations implements ZSetOperations { - DefaultZSetOperations(RedisTemplate template) { + DefaultZSetOperations(@NonNull RedisTemplate template) { super(template); } @Override - public Boolean add(K key, V value, double score) { + public Boolean add(@NonNull K key, @NonNull V value, double score) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -60,7 +63,7 @@ public Boolean add(K key, V value, double score) { } @Override - public Boolean addIfAbsent(K key, V value, double score) { + public Boolean addIfAbsent(@NonNull K key, @NonNull V value, double score) { return add(key, value, score, ZAddArgs.ifNotExists()); } @@ -71,8 +74,7 @@ public Boolean addIfAbsent(K key, V value, double score) { * @return can be {@literal null}. * @since 2.5 */ - @Nullable - protected Boolean add(K key, V value, double score, ZAddArgs args) { + protected Boolean add(@NonNull K key, @NonNull V value, double score, @NonNull ZAddArgs args) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -81,7 +83,7 @@ protected Boolean add(K key, V value, double score, ZAddArgs args) { } @Override - public Long add(K key, Set> tuples) { + public Long add(@NonNull K key, @NonNull Set<@NonNull TypedTuple> tuples) { byte[] rawKey = rawKey(key); Set rawValues = rawTupleValues(tuples); @@ -90,7 +92,7 @@ public Long add(K key, Set> tuples) { } @Override - public Long addIfAbsent(K key, Set> tuples) { + public Long addIfAbsent(@NonNull K key, @NonNull Set<@NonNull TypedTuple> tuples) { return add(key, tuples, ZAddArgs.ifNotExists()); } @@ -101,8 +103,7 @@ public Long addIfAbsent(K key, Set> tuples) { * @return can be {@literal null}. * @since 2.5 */ - @Nullable - protected Long add(K key, Set> tuples, ZAddArgs args) { + protected Long add(@NonNull K key, @NonNull Set<@NonNull TypedTuple> tuples, @NonNull ZAddArgs args) { byte[] rawKey = rawKey(key); Set rawValues = rawTupleValues(tuples); @@ -111,7 +112,7 @@ protected Long add(K key, Set> tuples, ZAddArgs args) { } @Override - public Double incrementScore(K key, V value, double delta) { + public Double incrementScore(@NonNull K key, @NonNull V value, double delta) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(value); @@ -120,7 +121,7 @@ public Double incrementScore(K key, V value, double delta) { } @Override - public V randomMember(K key) { + public V randomMember(@NonNull K key) { byte[] rawKey = rawKey(key); @@ -128,7 +129,7 @@ public V randomMember(K key) { } @Override - public Set distinctRandomMembers(K key, long count) { + public Set distinctRandomMembers(@NonNull K key, long count) { Assert.isTrue(count > 0, "Negative count not supported; Use randomMembers to allow duplicate elements"); @@ -139,7 +140,7 @@ public Set distinctRandomMembers(K key, long count) { } @Override - public List randomMembers(K key, long count) { + public List randomMembers(@NonNull K key, long count) { Assert.isTrue(count > 0, "Use a positive number for count; This method is already allowing duplicate elements"); @@ -150,7 +151,7 @@ public List randomMembers(K key, long count) { } @Override - public TypedTuple randomMemberWithScore(K key) { + public TypedTuple randomMemberWithScore(@NonNull K key) { byte[] rawKey = rawKey(key); @@ -158,7 +159,7 @@ public TypedTuple randomMemberWithScore(K key) { } @Override - public Set> distinctRandomMembersWithScore(K key, long count) { + public Set> distinctRandomMembersWithScore(@NonNull K key, long count) { Assert.isTrue(count > 0, "Negative count not supported; Use randomMembers to allow duplicate elements"); @@ -169,7 +170,7 @@ public Set> distinctRandomMembersWithScore(K key, long count) { } @Override - public List> randomMembersWithScore(K key, long count) { + public List> randomMembersWithScore(@NonNull K key, long count) { Assert.isTrue(count > 0, "Use a positive number for count; This method is already allowing duplicate elements"); @@ -180,7 +181,7 @@ public List> randomMembersWithScore(K key, long count) { } @Override - public Set range(K key, long start, long end) { + public Set range(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRange(rawKey, start, end)); @@ -189,7 +190,7 @@ public Set range(K key, long start, long end) { } @Override - public Set reverseRange(K key, long start, long end) { + public Set reverseRange(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRange(rawKey, start, end)); @@ -198,7 +199,7 @@ public Set reverseRange(K key, long start, long end) { } @Override - public Set> rangeWithScores(K key, long start, long end) { + public Set> rangeWithScores(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeWithScores(rawKey, start, end)); @@ -207,7 +208,7 @@ public Set> rangeWithScores(K key, long start, long end) { } @Override - public Set> reverseRangeWithScores(K key, long start, long end) { + public Set> reverseRangeWithScores(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRangeWithScores(rawKey, start, end)); @@ -216,7 +217,7 @@ public Set> reverseRangeWithScores(K key, long start, long end) { } @Override - public Set rangeByLex(K key, Range range, Limit limit) { + public Set rangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeByLex(rawKey, serialize(range), limit)); @@ -225,7 +226,7 @@ public Set rangeByLex(K key, Range range, Limit limit) { } @Override - public Set reverseRangeByLex(K key, Range range, Limit limit) { + public Set reverseRangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRangeByLex(rawKey, serialize(range), limit)); @@ -234,7 +235,8 @@ public Set reverseRangeByLex(K key, Range range, Limit limit) { } @Override - public Long rangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit) { + public Long rangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit) { byte[] rawDstKey = rawKey(dstKey); byte[] rawSrcKey = rawKey(srcKey); @@ -243,7 +245,8 @@ public Long rangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit li } @Override - public Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit) { + public Long reverseRangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit) { byte[] rawDstKey = rawKey(dstKey); byte[] rawSrcKey = rawKey(srcKey); @@ -252,7 +255,8 @@ public Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range, L } @Override - public Long rangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit) { + public Long rangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit) { byte[] rawDstKey = rawKey(dstKey); byte[] rawSrcKey = rawKey(srcKey); @@ -261,7 +265,8 @@ public Long rangeAndStoreByScore(K srcKey, K dstKey, Range ran } @Override - public Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit) { + public Long reverseRangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit) { byte[] rawDstKey = rawKey(dstKey); byte[] rawSrcKey = rawKey(srcKey); @@ -270,7 +275,7 @@ public Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range rangeByScore(K key, double min, double max) { + public Set rangeByScore(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeByScore(rawKey, min, max)); @@ -279,7 +284,7 @@ public Set rangeByScore(K key, double min, double max) { } @Override - public Set rangeByScore(K key, double min, double max, long offset, long count) { + public Set rangeByScore(@NonNull K key, double min, double max, long offset, long count) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeByScore(rawKey, min, max, offset, count)); @@ -288,7 +293,7 @@ public Set rangeByScore(K key, double min, double max, long offset, long coun } @Override - public Set reverseRangeByScore(K key, double min, double max) { + public Set reverseRangeByScore(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRangeByScore(rawKey, min, max)); @@ -297,7 +302,7 @@ public Set reverseRangeByScore(K key, double min, double max) { } @Override - public Set reverseRangeByScore(K key, double min, double max, long offset, long count) { + public Set reverseRangeByScore(@NonNull K key, double min, double max, long offset, long count) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRangeByScore(rawKey, min, max, offset, count)); @@ -306,7 +311,7 @@ public Set reverseRangeByScore(K key, double min, double max, long offset, lo } @Override - public Set> rangeByScoreWithScores(K key, double min, double max) { + public Set> rangeByScoreWithScores(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeByScoreWithScores(rawKey, min, max)); @@ -315,7 +320,7 @@ public Set> rangeByScoreWithScores(K key, double min, double max) } @Override - public Set> rangeByScoreWithScores(K key, double min, double max, long offset, long count) { + public Set> rangeByScoreWithScores(@NonNull K key, double min, double max, long offset, long count) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRangeByScoreWithScores(rawKey, min, max, offset, count)); @@ -324,7 +329,7 @@ public Set> rangeByScoreWithScores(K key, double min, double max, } @Override - public Set> reverseRangeByScoreWithScores(K key, double min, double max) { + public Set> reverseRangeByScoreWithScores(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); Set rawValues = execute(connection -> connection.zRevRangeByScoreWithScores(rawKey, min, max)); @@ -333,17 +338,18 @@ public Set> reverseRangeByScoreWithScores(K key, double min, doubl } @Override - public Set> reverseRangeByScoreWithScores(K key, double min, double max, long offset, long count) { + public Set> reverseRangeByScoreWithScores(@NonNull K key, double min, double max, long offset, + long count) { byte[] rawKey = rawKey(key); - Set rawValues = execute(connection -> - connection.zRevRangeByScoreWithScores(rawKey, min, max, offset, count)); + Set rawValues = execute( + connection -> connection.zRevRangeByScoreWithScores(rawKey, min, max, offset, count)); return deserializeTupleValues(rawValues); } @Override - public Long rank(K key, Object o) { + public Long rank(@NonNull K key, @NonNull Object o) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(o); @@ -355,7 +361,7 @@ public Long rank(K key, Object o) { } @Override - public Long reverseRank(K key, Object o) { + public Long reverseRank(@NonNull K key, @NonNull Object o) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(o); @@ -367,7 +373,7 @@ public Long reverseRank(K key, Object o) { } @Override - public Long remove(K key, Object... values) { + public Long remove(@NonNull K key, @NonNull Object @NonNull... values) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(values); @@ -376,7 +382,7 @@ public Long remove(K key, Object... values) { } @Override - public Long removeRange(K key, long start, long end) { + public Long removeRange(@NonNull K key, long start, long end) { byte[] rawKey = rawKey(key); @@ -384,7 +390,7 @@ public Long removeRange(K key, long start, long end) { } @Override - public Long removeRangeByLex(K key, Range range) { + public Long removeRangeByLex(@NonNull K key, @NonNull Range range) { byte[] rawKey = rawKey(key); @@ -392,7 +398,7 @@ public Long removeRangeByLex(K key, Range range) { } @Override - public Long removeRangeByScore(K key, double min, double max) { + public Long removeRangeByScore(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); @@ -400,7 +406,7 @@ public Long removeRangeByScore(K key, double min, double max) { } @Override - public Double score(K key, Object o) { + public Double score(@NonNull K key, Object o) { byte[] rawKey = rawKey(key); byte[] rawValue = rawValue(o); @@ -409,7 +415,7 @@ public Double score(K key, Object o) { } @Override - public List score(K key, Object... o) { + public List score(@NonNull K key, Object... o) { byte[] rawKey = rawKey(key); byte[][] rawValues = rawValues(o); @@ -418,7 +424,7 @@ public List score(K key, Object... o) { } @Override - public Long count(K key, double min, double max) { + public Long count(@NonNull K key, double min, double max) { byte[] rawKey = rawKey(key); @@ -426,7 +432,7 @@ public Long count(K key, double min, double max) { } @Override - public Long lexCount(K key, Range range) { + public Long lexCount(@NonNull K key, @NonNull Range range) { byte[] rawKey = rawKey(key); @@ -435,7 +441,7 @@ public Long lexCount(K key, Range range) { @Nullable @Override - public TypedTuple popMin(K key) { + public TypedTuple popMin(@NonNull K key) { byte[] rawKey = rawKey(key); @@ -444,7 +450,7 @@ public TypedTuple popMin(K key) { @Nullable @Override - public Set> popMin(K key, long count) { + public Set> popMin(@NonNull K key, long count) { byte[] rawKey = rawKey(key); Set result = execute(connection -> connection.zPopMin(rawKey, count)); @@ -454,7 +460,7 @@ public Set> popMin(K key, long count) { @Nullable @Override - public TypedTuple popMin(K key, long timeout, TimeUnit unit) { + public TypedTuple popMin(@NonNull K key, long timeout, @NonNull TimeUnit unit) { byte[] rawKey = rawKey(key); @@ -463,7 +469,7 @@ public TypedTuple popMin(K key, long timeout, TimeUnit unit) { @Nullable @Override - public TypedTuple popMax(K key) { + public TypedTuple popMax(@NonNull K key) { byte[] rawKey = rawKey(key); @@ -472,7 +478,7 @@ public TypedTuple popMax(K key) { @Nullable @Override - public Set> popMax(K key, long count) { + public Set> popMax(@NonNull K key, long count) { byte[] rawKey = rawKey(key); Set result = execute(connection -> connection.zPopMax(rawKey, count)); @@ -482,7 +488,7 @@ public Set> popMax(K key, long count) { @Nullable @Override - public TypedTuple popMax(K key, long timeout, TimeUnit unit) { + public TypedTuple popMax(@NonNull K key, long timeout, @NonNull TimeUnit unit) { byte[] rawKey = rawKey(key); @@ -490,12 +496,12 @@ public TypedTuple popMax(K key, long timeout, TimeUnit unit) { } @Override - public Long size(K key) { + public Long size(@NonNull K key) { return zCard(key); } @Override - public Long zCard(K key) { + public Long zCard(@NonNull K key) { byte[] rawKey = rawKey(key); @@ -503,7 +509,7 @@ public Long zCard(K key) { } @Override - public Set difference(K key, Collection otherKeys) { + public Set difference(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(connection -> connection.zDiff(rawKeys)); @@ -512,7 +518,7 @@ public Set difference(K key, Collection otherKeys) { } @Override - public Set> differenceWithScores(K key, Collection otherKeys) { + public Set> differenceWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set result = execute(connection -> connection.zDiffWithScores(rawKeys)); @@ -521,7 +527,7 @@ public Set> differenceWithScores(K key, Collection otherKeys) { } @Override - public Long differenceAndStore(K key, Collection otherKeys, K destKey) { + public Long differenceAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey) { byte[][] rawKeys = rawKeys(key, otherKeys); byte[] rawDestKey = rawKey(destKey); @@ -530,7 +536,7 @@ public Long differenceAndStore(K key, Collection otherKeys, K destKey) { } @Override - public Set intersect(K key, Collection otherKeys) { + public Set intersect(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(connection -> connection.zInter(rawKeys)); @@ -539,7 +545,7 @@ public Set intersect(K key, Collection otherKeys) { } @Override - public Set> intersectWithScores(K key, Collection otherKeys) { + public Set> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set result = execute(connection -> connection.zInterWithScores(rawKeys)); @@ -548,7 +554,8 @@ public Set> intersectWithScores(K key, Collection otherKeys) { } @Override - public Set> intersectWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights) { + public Set> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights) { byte[][] rawKeys = rawKeys(key, otherKeys); Set result = execute(connection -> connection.zInterWithScores(aggregate, weights, rawKeys)); @@ -557,12 +564,12 @@ public Set> intersectWithScores(K key, Collection otherKeys, Ag } @Override - public Long intersectAndStore(K key, K otherKey, K destKey) { + public Long intersectAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey) { return intersectAndStore(key, Collections.singleton(otherKey), destKey); } @Override - public Long intersectAndStore(K key, Collection otherKeys, K destKey) { + public Long intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey) { byte[][] rawKeys = rawKeys(key, otherKeys); byte[] rawDestKey = rawKey(destKey); @@ -571,7 +578,8 @@ public Long intersectAndStore(K key, Collection otherKeys, K destKey) { } @Override - public Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights) { + public Long intersectAndStore(@NonNull K key, Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights) { byte[][] rawKeys = rawKeys(key, otherKeys); byte[] rawDestKey = rawKey(destKey); @@ -580,7 +588,7 @@ public Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggrega } @Override - public Set union(K key, Collection otherKeys) { + public Set union(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set rawValues = execute(connection -> connection.zUnion(rawKeys)); @@ -589,7 +597,7 @@ public Set union(K key, Collection otherKeys) { } @Override - public Set> unionWithScores(K key, Collection otherKeys) { + public Set> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys) { byte[][] rawKeys = rawKeys(key, otherKeys); Set result = execute(connection -> connection.zUnionWithScores(rawKeys)); @@ -598,7 +606,8 @@ public Set> unionWithScores(K key, Collection otherKeys) { } @Override - public Set> unionWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights) { + public Set> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights) { byte[][] rawKeys = rawKeys(key, otherKeys); Set result = execute(connection -> connection.zUnionWithScores(aggregate, weights, rawKeys)); @@ -607,12 +616,12 @@ public Set> unionWithScores(K key, Collection otherKeys, Aggreg } @Override - public Long unionAndStore(K key, K otherKey, K destKey) { + public Long unionAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey) { return unionAndStore(key, Collections.singleton(otherKey), destKey); } @Override - public Long unionAndStore(K key, Collection otherKeys, K destKey) { + public Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey) { byte[][] rawKeys = rawKeys(key, otherKeys); byte[] rawDestKey = rawKey(destKey); @@ -621,7 +630,8 @@ public Long unionAndStore(K key, Collection otherKeys, K destKey) { } @Override - public Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights) { + public Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights) { byte[][] rawKeys = rawKeys(key, otherKeys); byte[] rawDestKey = rawKey(destKey); @@ -630,7 +640,7 @@ public Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate a } @Override - public Cursor> scan(K key, ScanOptions options) { + public Cursor> scan(@NonNull K key, @Nullable ScanOptions options) { byte[] rawKey = rawKey(key); Cursor cursor = template.executeWithStickyConnection(connection -> connection.zScan(rawKey, options)); @@ -638,14 +648,14 @@ public Cursor> scan(K key, ScanOptions options) { return new ConvertingCursor<>(cursor, this::deserializeTuple); } - public Set rangeByScore(K key, String min, String max) { + public Set rangeByScore(@NonNull K key, String min, String max) { byte[] rawKey = rawKey(key); return execute(connection -> connection.zRangeByScore(rawKey, min, max)); } - public Set rangeByScore(K key, String min, String max, long offset, long count) { + public Set rangeByScore(@NonNull K key, String min, String max, long offset, long count) { byte[] rawKey = rawKey(key); diff --git a/src/main/java/org/springframework/data/redis/core/ExpireChanges.java b/src/main/java/org/springframework/data/redis/core/ExpireChanges.java index 10bef1e2d2..a96b85d83e 100644 --- a/src/main/java/org/springframework/data/redis/core/ExpireChanges.java +++ b/src/main/java/org/springframework/data/redis/core/ExpireChanges.java @@ -24,6 +24,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -84,7 +85,7 @@ public List stateChanges() { * @return the status change for the given {@literal key}, or {@literal null} if {@link ExpiryChangeState} does not * contain an entry for it. */ - public ExpiryChangeState stateOf(K key) { + public @Nullable ExpiryChangeState stateOf(K key) { return changes.get(key); } diff --git a/src/main/java/org/springframework/data/redis/core/GeoOperations.java b/src/main/java/org/springframework/data/redis/core/GeoOperations.java index 6b20c07789..90806c84c3 100644 --- a/src/main/java/org/springframework/data/redis/core/GeoOperations.java +++ b/src/main/java/org/springframework/data/redis/core/GeoOperations.java @@ -18,6 +18,8 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; @@ -30,7 +32,6 @@ import org.springframework.data.redis.domain.geo.BoundingBox; import org.springframework.data.redis.domain.geo.GeoReference; import org.springframework.data.redis.domain.geo.GeoShape; -import org.springframework.lang.Nullable; /** * Redis operations for geo commands. @@ -41,6 +42,7 @@ * @see Redis Documentation: Geo Commands * @since 1.8 */ +@NullUnmarked public interface GeoOperations { /** @@ -53,8 +55,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(K key, Point point, M member); + Long add(@NonNull K key, @NonNull Point point, @NonNull M member); /** * Add {@link GeoLocation} to {@literal key}. @@ -65,8 +66,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(K key, GeoLocation location); + Long add(@NonNull K key, @NonNull GeoLocation location); /** * Add {@link Map} of member / {@link Point} pairs to {@literal key}. @@ -77,8 +77,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(K key, Map memberCoordinateMap); + Long add(@NonNull K key, @NonNull Map<@NonNull M, @NonNull Point> memberCoordinateMap); /** * Add {@link GeoLocation}s to {@literal key} @@ -89,8 +88,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOADD */ - @Nullable - Long add(K key, Iterable> locations); + Long add(@NonNull K key, @NonNull Iterable<@NonNull GeoLocation> locations); /** * Get the {@link Distance} between {@literal member1} and {@literal member2}. @@ -102,8 +100,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEODIST */ - @Nullable - Distance distance(K key, M member1, M member2); + Distance distance(@NonNull K key, @NonNull M member1, @NonNull M member2); /** * Get the {@link Distance} between {@literal member1} and {@literal member2} in the given {@link Metric}. @@ -116,8 +113,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEODIST */ - @Nullable - Distance distance(K key, M member1, M member2, Metric metric); + Distance distance(@NonNull K key, @NonNull M member1, @NonNull M member2, @NonNull Metric metric); /** * Get Geohash representation of the position for one or more {@literal member}s. @@ -128,8 +124,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOHASH */ - @Nullable - List hash(K key, M... members); + List hash(@NonNull K key, @NonNull M @NonNull... members); /** * Get the {@link Point} representation of positions for one or more {@literal member}s. @@ -140,8 +135,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEOPOS */ - @Nullable - List position(K key, M... members); + List position(@NonNull K key, @NonNull M @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -152,8 +146,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> radius(K key, Circle within); + GeoResults> radius(@NonNull K key, @NonNull Circle within); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} applying {@link GeoRadiusCommandArgs}. @@ -165,8 +158,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEORADIUS */ - @Nullable - GeoResults> radius(K key, Circle within, GeoRadiusCommandArgs args); + GeoResults> radius(@NonNull K key, @NonNull Circle within, @NonNull GeoRadiusCommandArgs args); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -179,8 +171,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(K key, M member, double radius); + GeoResults> radius(@NonNull K key, @NonNull M member, double radius); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -193,8 +184,7 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(K key, M member, Distance distance); + GeoResults> radius(@NonNull K key, @NonNull M member, @NonNull Distance distance); /** * Get the {@literal member}s within the circle defined by the {@literal members} coordinates and given @@ -208,8 +198,8 @@ public interface GeoOperations { * @since 2.0 * @see Redis Documentation: GEORADIUSBYMEMBER */ - @Nullable - GeoResults> radius(K key, M member, Distance distance, GeoRadiusCommandArgs args); + GeoResults> radius(@NonNull K key, @NonNull M member, @NonNull Distance distance, + @NonNull GeoRadiusCommandArgs args); /** * Remove the {@literal member}s. @@ -219,8 +209,7 @@ public interface GeoOperations { * @return Number of elements removed. {@literal null} when used in pipeline / transaction. * @since 2.0 */ - @Nullable - Long remove(K key, M... members); + Long remove(@NonNull K key, @NonNull M @NonNull... members); /** * Get the {@literal member}s within the boundaries of a given {@link Circle}. @@ -231,8 +220,7 @@ public interface GeoOperations { * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(K key, Circle within) { + default GeoResults> search(@NonNull K key, @NonNull Circle within) { return search(key, GeoReference.fromCircle(within), GeoShape.byRadius(within.getRadius()), GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -248,8 +236,8 @@ default GeoResults> search(K key, Circle within) { * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(K key, GeoReference reference, Distance radius) { + default GeoResults> search(@NonNull K key, @NonNull GeoReference reference, + @NonNull Distance radius) { return search(key, reference, radius, GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -265,9 +253,8 @@ default GeoResults> search(K key, GeoReference reference, Dist * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(K key, GeoReference reference, Distance radius, - GeoSearchCommandArgs args) { + default GeoResults> search(@NonNull K key, @NonNull GeoReference reference, + @NonNull Distance radius, @NonNull GeoSearchCommandArgs args) { return search(key, reference, GeoShape.byRadius(radius), args); } @@ -282,9 +269,8 @@ default GeoResults> search(K key, GeoReference reference, Dist * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(K key, GeoReference reference, - BoundingBox boundingBox) { + default GeoResults> search(@NonNull K key, @NonNull GeoReference reference, + @NonNull BoundingBox boundingBox) { return search(key, reference, boundingBox, GeoSearchCommandArgs.newGeoSearchArgs()); } @@ -300,9 +286,8 @@ default GeoResults> search(K key, GeoReference reference, * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - default GeoResults> search(K key, GeoReference reference, BoundingBox boundingBox, - GeoSearchCommandArgs args) { + default GeoResults> search(@NonNull K key, @NonNull GeoReference reference, + @NonNull BoundingBox boundingBox, @NonNull GeoSearchCommandArgs args) { return search(key, reference, GeoShape.byBox(boundingBox), args); } @@ -318,9 +303,8 @@ default GeoResults> search(K key, GeoReference reference, Boun * @since 2.6 * @see Redis Documentation: GEOSEARCH */ - @Nullable - GeoResults> search(K key, GeoReference reference, - GeoShape geoPredicate, GeoSearchCommandArgs args); + GeoResults> search(@NonNull K key, @NonNull GeoReference reference, @NonNull GeoShape geoPredicate, + @NonNull GeoSearchCommandArgs args); /** * Get the {@literal member}s within the boundaries of a given {@link Circle} and store results at {@code destKey}. @@ -331,8 +315,7 @@ GeoResults> search(K key, GeoReference reference, * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K key, K destKey, Circle within) { + default Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull Circle within) { return searchAndStore(key, destKey, GeoReference.fromCircle(within), GeoShape.byRadius(within.getRadius()), GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -348,8 +331,8 @@ default Long searchAndStore(K key, K destKey, Circle within) { * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K key, K destKey, GeoReference reference, Distance radius) { + default Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull GeoReference reference, + @NonNull Distance radius) { return searchAndStore(key, destKey, reference, radius, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -365,9 +348,8 @@ default Long searchAndStore(K key, K destKey, GeoReference reference, Distanc * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K key, K destKey, GeoReference reference, Distance radius, - GeoSearchStoreCommandArgs args) { + default Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull GeoReference reference, + @NonNull Distance radius, @NonNull GeoSearchStoreCommandArgs args) { return searchAndStore(key, destKey, reference, GeoShape.byRadius(radius), args); } @@ -382,8 +364,8 @@ default Long searchAndStore(K key, K destKey, GeoReference reference, Distanc * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K key, K destKey, GeoReference reference, BoundingBox boundingBox) { + default Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull GeoReference reference, + @NonNull BoundingBox boundingBox) { return searchAndStore(key, destKey, reference, boundingBox, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs()); } @@ -399,9 +381,8 @@ default Long searchAndStore(K key, K destKey, GeoReference reference, Boundin * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - default Long searchAndStore(K key, K destKey, GeoReference reference, BoundingBox boundingBox, - GeoSearchStoreCommandArgs args) { + default Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull GeoReference reference, + @NonNull BoundingBox boundingBox, @NonNull GeoSearchStoreCommandArgs args) { return searchAndStore(key, destKey, reference, GeoShape.byBox(boundingBox), args); } @@ -417,8 +398,7 @@ default Long searchAndStore(K key, K destKey, GeoReference reference, Boundin * @since 2.6 * @see Redis Documentation: GEOSEARCHSTORE */ - @Nullable - Long searchAndStore(K key, K destKey, GeoReference reference, GeoShape geoPredicate, - GeoSearchStoreCommandArgs args); + Long searchAndStore(@NonNull K key, @NonNull K destKey, @NonNull GeoReference reference, + @NonNull GeoShape geoPredicate, @NonNull GeoSearchStoreCommandArgs args); } diff --git a/src/main/java/org/springframework/data/redis/core/HashOperations.java b/src/main/java/org/springframework/data/redis/core/HashOperations.java index 1dc34db4c3..c2803df48c 100644 --- a/src/main/java/org/springframework/data/redis/core/HashOperations.java +++ b/src/main/java/org/springframework/data/redis/core/HashOperations.java @@ -24,10 +24,12 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; /** * Redis map specific operations working on a hash. @@ -37,6 +39,7 @@ * @author Ninad Divadkar * @author Tihomir Mateev */ +@NullUnmarked public interface HashOperations { /** @@ -46,7 +49,7 @@ public interface HashOperations { * @param hashKeys must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - Long delete(H key, Object... hashKeys); + Long delete(@NonNull H key, @NonNull Object @NonNull... hashKeys); /** * Determine if given hash {@code hashKey} exists. @@ -55,7 +58,7 @@ public interface HashOperations { * @param hashKey must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - Boolean hasKey(H key, Object hashKey); + Boolean hasKey(@NonNull H key, @NonNull Object hashKey); /** * Get value for given {@code hashKey} from hash at {@code key}. @@ -64,8 +67,7 @@ public interface HashOperations { * @param hashKey must not be {@literal null}. * @return {@literal null} when key or hashKey does not exist or used in pipeline / transaction. */ - @Nullable - HV get(H key, Object hashKey); + HV get(@NonNull H key, @NonNull Object hashKey); /** * Get values for given {@code hashKeys} from hash at {@code key}. Values are in the order of the requested keys @@ -75,7 +77,7 @@ public interface HashOperations { * @param hashKeys must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - List multiGet(H key, Collection hashKeys); + List multiGet(@NonNull H key, @NonNull Collection<@NonNull HK> hashKeys); /** * Increment {@code value} of a hash {@code hashKey} by the given {@code delta}. @@ -85,7 +87,7 @@ public interface HashOperations { * @param delta * @return {@literal null} when used in pipeline / transaction. */ - Long increment(H key, HK hashKey, long delta); + Long increment(@NonNull H key, @NonNull HK hashKey, long delta); /** * Increment {@code value} of a hash {@code hashKey} by the given {@code delta}. @@ -95,7 +97,7 @@ public interface HashOperations { * @param delta * @return {@literal null} when used in pipeline / transaction. */ - Double increment(H key, HK hashKey, double delta); + Double increment(@NonNull H key, @NonNull HK hashKey, double delta); /** * Return a random hash key from the hash stored at {@code key}. @@ -105,8 +107,7 @@ public interface HashOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - HK randomKey(H key); + HK randomKey(@NonNull H key); /** * Return a random entry from the hash stored at {@code key}. @@ -116,8 +117,7 @@ public interface HashOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map.Entry randomEntry(H key); + Map. Entry<@NonNull HK, HV> randomEntry(@NonNull H key); /** * Return random hash keys from the hash stored at {@code key}. If the provided {@code count} argument is positive, @@ -131,8 +131,7 @@ public interface HashOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - List randomKeys(H key, long count); + List<@NonNull HK> randomKeys(@NonNull H key, long count); /** * Return a random entries from the hash stored at {@code key}. @@ -143,8 +142,7 @@ public interface HashOperations { * @since 2.6 * @see Redis Documentation: HRANDFIELD */ - @Nullable - Map randomEntries(H key, long count); + Map<@NonNull HK, HV> randomEntries(@NonNull H key, long count); /** * Get key set (fields) of hash at {@code key}. @@ -152,7 +150,7 @@ public interface HashOperations { * @param key must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - Set keys(H key); + Set<@NonNull HK> keys(@NonNull H key); /** * Returns the length of the value associated with {@code hashKey}. If either the {@code key} or the {@code hashKey} @@ -163,8 +161,7 @@ public interface HashOperations { * @return {@literal null} when used in pipeline / transaction. * @since 2.1 */ - @Nullable - Long lengthOfValue(H key, HK hashKey); + Long lengthOfValue(@NonNull H key, @NonNull HK hashKey); /** * Get size of hash at {@code key}. @@ -172,7 +169,7 @@ public interface HashOperations { * @param key must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - Long size(H key); + Long size(@NonNull H key); /** * Set multiple hash fields to multiple values using data provided in {@code m}. @@ -180,7 +177,7 @@ public interface HashOperations { * @param key must not be {@literal null}. * @param m must not be {@literal null}. */ - void putAll(H key, Map m); + void putAll(@NonNull H key, @NonNull Map m); /** * Set the {@code value} of a hash {@code hashKey}. @@ -189,7 +186,7 @@ public interface HashOperations { * @param hashKey must not be {@literal null}. * @param value */ - void put(H key, HK hashKey, HV value); + void put(@NonNull H key, @NonNull HK hashKey, HV value); /** * Set the {@code value} of a hash {@code hashKey} only if {@code hashKey} does not exist. @@ -199,7 +196,7 @@ public interface HashOperations { * @param value * @return {@literal null} when used in pipeline / transaction. */ - Boolean putIfAbsent(H key, HK hashKey, HV value); + Boolean putIfAbsent(@NonNull H key, @NonNull HK hashKey, HV value); /** * Get entry set (values) of hash at {@code key}. @@ -207,7 +204,7 @@ public interface HashOperations { * @param key must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - List values(H key); + List values(@NonNull H key); /** * Get entire hash stored at {@code key}. @@ -215,19 +212,19 @@ public interface HashOperations { * @param key must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - Map entries(H key); + Map<@NonNull HK, HV> entries(@NonNull H key); /** * Use a {@link Cursor} to iterate over entries in hash at {@code key}.
* Important: Call {@link Cursor#close()} when done to avoid resource leaks. * * @param key must not be {@literal null}. - * @param options must not be {@literal null}. + * @param options can be {@literal null}. * @return the result cursor providing access to the scan result. Must be closed once fully processed (e.g. through a * try-with-resources clause). * @since 1.4 */ - Cursor> scan(H key, ScanOptions options); + Cursor> scan(@NonNull H key, @Nullable ScanOptions options); /** * Set time to live for given {@code hashKey} . @@ -240,8 +237,8 @@ public interface HashOperations { * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - ExpireChanges expire(H key, Duration timeout, Collection hashKeys); + ExpireChanges<@NonNull HK> expire(@NonNull H key, @NonNull Duration timeout, + @NonNull Collection<@NonNull HK> hashKeys); /** * Set the expiration for given {@code hashKeys} as a {@literal date} timestamp. @@ -254,8 +251,8 @@ public interface HashOperations { * @see Redis Documentation: HEXPIRE * @since 3.5 */ - @Nullable - ExpireChanges expireAt(H key, Instant expireAt, Collection hashKeys); + ExpireChanges<@NonNull HK> expireAt(@NonNull H key, @NonNull Instant expireAt, + @NonNull Collection<@NonNull HK> hashKeys); /** * Apply the expiration for given {@code hashKeys}. @@ -273,8 +270,8 @@ public interface HashOperations { * @see Redis Documentation: HPERSIST * @since 3.5 */ - @Nullable - ExpireChanges expire(H key, Expiration expiration, ExpirationOptions options, Collection hashKeys); + ExpireChanges<@NonNull HK> expire(@NonNull H key, @NonNull Expiration expiration, @NonNull ExpirationOptions options, + @NonNull Collection<@NonNull HK> hashKeys); /** * Remove the expiration from given {@code hashKeys} . @@ -285,8 +282,7 @@ public interface HashOperations { * @see Redis Documentation: HPERSIST * @since 3.5 */ - @Nullable - ExpireChanges persist(H key, Collection hashKeys); + ExpireChanges<@NonNull HK> persist(@NonNull H key, @NonNull Collection<@NonNull HK> hashKeys); /** * Get the time to live for {@code hashKeys} in seconds. @@ -297,8 +293,7 @@ public interface HashOperations { * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - default Expirations getTimeToLive(H key, Collection hashKeys) { + default Expirations<@NonNull HK> getTimeToLive(@NonNull H key, Collection<@NonNull HK> hashKeys) { return getTimeToLive(key, TimeUnit.SECONDS, hashKeys); } @@ -312,8 +307,8 @@ default Expirations getTimeToLive(H key, Collection hashKeys) { * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - Expirations getTimeToLive(H key, TimeUnit timeUnit, Collection hashKeys); + Expirations<@NonNull HK> getTimeToLive(@NonNull H key, @NonNull TimeUnit timeUnit, + @NonNull Collection<@NonNull HK> hashKeys); /** * Returns a bound operations object to perform operations on the hash field expiration for all hash fields at @@ -323,7 +318,8 @@ default Expirations getTimeToLive(H key, Collection hashKeys) { * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundHashFieldExpirationOperations expiration(H key) { + @NonNull + default BoundHashFieldExpirationOperations expiration(@NonNull H key) { return new DefaultBoundHashFieldExpirationOperations<>(this, key, () -> keys(key)); } @@ -335,7 +331,8 @@ default BoundHashFieldExpirationOperations expiration(H key) { * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundHashFieldExpirationOperations expiration(H key, HK... hashFields) { + @NonNull + default BoundHashFieldExpirationOperations expiration(@NonNull H key, @NonNull HK @NonNull... hashFields) { return expiration(key, Arrays.asList(hashFields)); } @@ -347,13 +344,16 @@ default BoundHashFieldExpirationOperations expiration(H key, HK... hashField * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundHashFieldExpirationOperations expiration(H key, Collection hashFields) { + @NonNull + default BoundHashFieldExpirationOperations expiration(@NonNull H key, + @NonNull Collection<@NonNull HK> hashFields) { return new DefaultBoundHashFieldExpirationOperations<>(this, key, () -> hashFields); } /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/HyperLogLogOperations.java b/src/main/java/org/springframework/data/redis/core/HyperLogLogOperations.java index 9adb6252f4..4876522a39 100644 --- a/src/main/java/org/springframework/data/redis/core/HyperLogLogOperations.java +++ b/src/main/java/org/springframework/data/redis/core/HyperLogLogOperations.java @@ -15,10 +15,14 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; + /** * @author Christoph Strobl * @since 1.5 */ +@NullUnmarked public interface HyperLogLogOperations { /** @@ -29,7 +33,7 @@ public interface HyperLogLogOperations { * @return 1 of at least one of the values was added to the key; 0 otherwise. {@literal null} when used in pipeline / * transaction. */ - Long add(K key, V... values); + Long add(@NonNull K key, @NonNull V @NonNull... values); /** * Gets the current number of elements within the {@literal key}. @@ -37,7 +41,7 @@ public interface HyperLogLogOperations { * @param keys must not be {@literal null} or {@literal empty}. * @return {@literal null} when used in pipeline / transaction. */ - Long size(K... keys); + Long size(@NonNull K @NonNull... keys); /** * Merges all values of given {@literal sourceKeys} into {@literal destination} key. @@ -46,13 +50,13 @@ public interface HyperLogLogOperations { * @param sourceKeys must not be {@literal null} or {@literal empty}. * @return {@literal null} when used in pipeline / transaction. */ - Long union(K destination, K... sourceKeys); + Long union(@NonNull K destination, @NonNull K @NonNull... sourceKeys); /** * Removes the given {@literal key}. * * @param key must not be {@literal null}. */ - void delete(K key); + void delete(@NonNull K key); } diff --git a/src/main/java/org/springframework/data/redis/core/IndexWriter.java b/src/main/java/org/springframework/data/redis/core/IndexWriter.java index 73e2a27347..958f78507e 100644 --- a/src/main/java/org/springframework/data/redis/core/IndexWriter.java +++ b/src/main/java/org/springframework/data/redis/core/IndexWriter.java @@ -17,6 +17,7 @@ import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisConnection; @@ -26,7 +27,6 @@ import org.springframework.data.redis.core.convert.RemoveIndexedData; import org.springframework.data.redis.core.convert.SimpleIndexedPropertyValue; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -278,6 +278,7 @@ private byte[] toBytes(Object... values) { return ByteUtils.concatAll(arrays); } + @SuppressWarnings("NullAway") private byte[] toBytes(@Nullable Object source) { if (source == null) { diff --git a/src/main/java/org/springframework/data/redis/core/KeyBoundCursor.java b/src/main/java/org/springframework/data/redis/core/KeyBoundCursor.java index a0c553509a..133b4ee3cf 100644 --- a/src/main/java/org/springframework/data/redis/core/KeyBoundCursor.java +++ b/src/main/java/org/springframework/data/redis/core/KeyBoundCursor.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * @author Christoph Strobl diff --git a/src/main/java/org/springframework/data/redis/core/KeyScanOptions.java b/src/main/java/org/springframework/data/redis/core/KeyScanOptions.java index 888157c525..971001929f 100644 --- a/src/main/java/org/springframework/data/redis/core/KeyScanOptions.java +++ b/src/main/java/org/springframework/data/redis/core/KeyScanOptions.java @@ -17,8 +17,8 @@ import java.util.StringJoiner; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; -import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -37,7 +37,7 @@ public class KeyScanOptions extends ScanOptions { private final @Nullable String type; - KeyScanOptions(@Nullable Long count, @Nullable String pattern, @Nullable byte[] bytePattern, + KeyScanOptions(@Nullable Long count, @Nullable String pattern, byte @Nullable[] bytePattern, @Nullable String type) { super(count, pattern, bytePattern); @@ -54,8 +54,7 @@ public static ScanOptionsBuilder scanOptions(DataType type) { return new ScanOptionsBuilder().type(type); } - @Nullable - public String getType() { + public @Nullable String getType() { return type; } diff --git a/src/main/java/org/springframework/data/redis/core/ListOperations.java b/src/main/java/org/springframework/data/redis/core/ListOperations.java index 8d08c61aa1..19b08ace89 100644 --- a/src/main/java/org/springframework/data/redis/core/ListOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ListOperations.java @@ -15,14 +15,16 @@ */ package org.springframework.data.redis.core; -import static org.springframework.data.redis.connection.RedisListCommands.*; +import static org.springframework.data.redis.connection.RedisListCommands.Direction; import java.time.Duration; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; import org.springframework.util.Assert; /** @@ -36,6 +38,7 @@ * @author dengliming * @author Lee Jaeheon */ +@NullUnmarked public interface ListOperations { /** @@ -47,8 +50,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LRANGE */ - @Nullable - List range(K key, long start, long end); + List range(@NonNull K key, long start, long end); /** * Trim list at {@code key} to elements between {@code start} and {@code end}. @@ -58,7 +60,7 @@ public interface ListOperations { * @param end * @see Redis Documentation: LTRIM */ - void trim(K key, long start, long end); + void trim(@NonNull K key, long start, long end); /** * Get the size of list stored at {@code key}. @@ -67,8 +69,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LLEN */ - @Nullable - Long size(K key); + Long size(@NonNull K key); /** * Prepend {@code value} to {@code key}. @@ -78,8 +79,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable - Long leftPush(K key, V value); + Long leftPush(@NonNull K key, V value); /** * Prepend {@code values} to {@code key}. @@ -89,8 +89,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSH */ - @Nullable - Long leftPushAll(K key, V... values); + Long leftPushAll(@NonNull K key, V @NonNull... values); /** * Prepend {@code values} to {@code key}. @@ -101,8 +100,7 @@ public interface ListOperations { * @since 1.5 * @see Redis Documentation: LPUSH */ - @Nullable - Long leftPushAll(K key, Collection values); + Long leftPushAll(@NonNull K key, @NonNull Collection values); /** * Prepend {@code values} to {@code key} only if the list exists. @@ -112,8 +110,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LPUSHX */ - @Nullable - Long leftPushIfPresent(K key, V value); + Long leftPushIfPresent(@NonNull K key, V value); /** * Insert {@code value} to {@code key} before {@code pivot}. @@ -124,8 +121,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LINSERT */ - @Nullable - Long leftPush(K key, V pivot, V value); + Long leftPush(@NonNull K key, @NonNull V pivot, V value); /** * Append {@code value} to {@code key}. @@ -135,8 +131,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable - Long rightPush(K key, V value); + Long rightPush(@NonNull K key, V value); /** * Append {@code values} to {@code key}. @@ -146,8 +141,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSH */ - @Nullable - Long rightPushAll(K key, V... values); + Long rightPushAll(@NonNull K key, V @NonNull... values); /** * Append {@code values} to {@code key}. @@ -158,8 +152,7 @@ public interface ListOperations { * @since 1.5 * @see Redis Documentation: RPUSH */ - @Nullable - Long rightPushAll(K key, Collection values); + Long rightPushAll(@NonNull K key, @NonNull Collection values); /** * Append {@code values} to {@code key} only if the list exists. @@ -169,8 +162,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RPUSHX */ - @Nullable - Long rightPushIfPresent(K key, V value); + Long rightPushIfPresent(@NonNull K key, V value); /** * Insert {@code value} to {@code key} after {@code pivot}. @@ -181,8 +173,7 @@ public interface ListOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LINSERT */ - @Nullable - Long rightPush(K key, V pivot, V value); + Long rightPush(@NonNull K key, @NonNull V pivot, V value); /** * Value object representing the {@code where from} part for the {@code LMOVE} command. @@ -191,6 +182,7 @@ public interface ListOperations { * @since 2.6 * @see Redis Documentation: LMOVE */ + @NullMarked class MoveFrom { final K key; @@ -218,6 +210,7 @@ public static MoveFrom fromTail(K key) { * @since 2.6 * @see Redis Documentation: LMOVE */ + @NullMarked class MoveTo { final K key; @@ -249,8 +242,7 @@ public static MoveTo toTail(K key) { * @since 2.6 * @see Redis Documentation: LMOVE */ - @Nullable - default V move(MoveFrom from, MoveTo to) { + default V move(@NonNull MoveFrom from, @NonNull MoveTo to) { Assert.notNull(from, "Move from must not be null"); Assert.notNull(to, "Move to must not be null"); @@ -271,8 +263,7 @@ default V move(MoveFrom from, MoveTo to) { * @since 2.6 * @see Redis Documentation: LMOVE */ - @Nullable - V move(K sourceKey, Direction from, K destinationKey, Direction to); + V move(@NonNull K sourceKey, @NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to); /** * Atomically returns and removes the first/last element (head/tail depending on the {@code from} argument) of the @@ -288,8 +279,7 @@ default V move(MoveFrom from, MoveTo to) { * @since 2.6 * @see Redis Documentation: BLMOVE */ - @Nullable - default V move(MoveFrom from, MoveTo to, Duration timeout) { + default V move(@NonNull MoveFrom from, @NonNull MoveTo to, @NonNull Duration timeout) { Assert.notNull(from, "Move from must not be null"); Assert.notNull(to, "Move to must not be null"); @@ -316,8 +306,8 @@ default V move(MoveFrom from, MoveTo to, Duration timeout) { * @since 2.6 * @see Redis Documentation: BLMOVE */ - @Nullable - default V move(K sourceKey, Direction from, K destinationKey, Direction to, Duration timeout) { + default V move(@NonNull K sourceKey, @NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to, + @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -343,8 +333,8 @@ default V move(K sourceKey, Direction from, K destinationKey, Direction to, Dura * @since 2.6 * @see Redis Documentation: BLMOVE */ - @Nullable - V move(K sourceKey, Direction from, K destinationKey, Direction to, long timeout, TimeUnit unit); + V move(@NonNull K sourceKey, @NonNull Direction from, @NonNull K destinationKey, @NonNull Direction to, long timeout, + @NonNull TimeUnit unit); /** * Set the {@code value} list element at {@code index}. @@ -354,7 +344,7 @@ default V move(K sourceKey, Direction from, K destinationKey, Direction to, Dura * @param value * @see Redis Documentation: LSET */ - void set(K key, long index, V value); + void set(@NonNull K key, long index, V value); /** * Removes the first {@code count} occurrences of {@code value} from the list stored at {@code key}. @@ -365,8 +355,7 @@ default V move(K sourceKey, Direction from, K destinationKey, Direction to, Dura * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LREM */ - @Nullable - Long remove(K key, long count, Object value); + Long remove(@NonNull K key, long count, Object value); /** * Returns the first element from the list at {@code key}. @@ -375,8 +364,7 @@ default V move(K sourceKey, Direction from, K destinationKey, Direction to, Dura * @return {@literal null} when used in pipeline / transaction. * @since 3.4 */ - @Nullable - default V getFirst(K key) { + default V getFirst(@NonNull K key) { return index(key, 0); } @@ -387,8 +375,7 @@ default V getFirst(K key) { * @return {@literal null} when used in pipeline / transaction. * @since 3.4 */ - @Nullable - default V getLast(K key) { + default V getLast(@NonNull K key) { return index(key, -1); } @@ -400,8 +387,7 @@ default V getLast(K key) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: LINDEX */ - @Nullable - V index(K key, long index); + V index(@NonNull K key, long index); /** * Returns the index of the first occurrence of the specified value in the list at at {@code key}.
@@ -413,8 +399,7 @@ default V getLast(K key) { * @since 2.4 * @see Redis Documentation: LPOS */ - @Nullable - Long indexOf(K key, V value); + Long indexOf(@NonNull K key, V value); /** * Returns the index of the last occurrence of the specified value in the list at at {@code key}.
@@ -426,8 +411,7 @@ default V getLast(K key) { * @since 2.4 * @see Redis Documentation: LPOS */ - @Nullable - Long lastIndexOf(K key, V value); + Long lastIndexOf(@NonNull K key, V value); /** * Removes and returns first element in list stored at {@code key}. @@ -436,8 +420,7 @@ default V getLast(K key) { * @return can be {@literal null}. * @see Redis Documentation: LPOP */ - @Nullable - V leftPop(K key); + V leftPop(@NonNull K key); /** * Removes and returns first {@code} elements in list stored at {@code key}. @@ -448,8 +431,7 @@ default V getLast(K key) { * @see Redis Documentation: LPOP * @since 2.6 */ - @Nullable - List leftPop(K key, long count); + List leftPop(@NonNull K key, long count); /** * Removes and returns first element from lists stored at {@code key} .
@@ -461,8 +443,7 @@ default V getLast(K key) { * @return can be {@literal null}. * @see Redis Documentation: BLPOP */ - @Nullable - V leftPop(K key, long timeout, TimeUnit unit); + V leftPop(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Removes and returns first element from lists stored at {@code key} .
@@ -475,8 +456,7 @@ default V getLast(K key) { * @since 2.3 * @see Redis Documentation: BLPOP */ - @Nullable - default V leftPop(K key, Duration timeout) { + default V leftPop(@NonNull K key, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -491,8 +471,7 @@ default V leftPop(K key, Duration timeout) { * @return can be {@literal null}. * @see Redis Documentation: RPOP */ - @Nullable - V rightPop(K key); + V rightPop(@NonNull K key); /** * Removes and returns last {@code} elements in list stored at {@code key}. @@ -503,8 +482,7 @@ default V leftPop(K key, Duration timeout) { * @see Redis Documentation: RPOP * @since 2.6 */ - @Nullable - List rightPop(K key, long count); + List rightPop(@NonNull K key, long count); /** * Removes and returns last element from lists stored at {@code key}.
@@ -516,8 +494,7 @@ default V leftPop(K key, Duration timeout) { * @return can be {@literal null}. * @see Redis Documentation: BRPOP */ - @Nullable - V rightPop(K key, long timeout, TimeUnit unit); + V rightPop(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Removes and returns last element from lists stored at {@code key}.
@@ -529,8 +506,7 @@ default V leftPop(K key, Duration timeout) { * @since 2.3 * @see Redis Documentation: BRPOP */ - @Nullable - default V rightPop(K key, Duration timeout) { + default V rightPop(@NonNull K key, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -546,8 +522,7 @@ default V rightPop(K key, Duration timeout) { * @return can be {@literal null}. * @see Redis Documentation: RPOPLPUSH */ - @Nullable - V rightPopAndLeftPush(K sourceKey, K destinationKey); + V rightPopAndLeftPush(@NonNull K sourceKey, @NonNull K destinationKey); /** * Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its @@ -561,8 +536,7 @@ default V rightPop(K key, Duration timeout) { * @return can be {@literal null}. * @see Redis Documentation: BRPOPLPUSH */ - @Nullable - V rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit); + V rightPopAndLeftPush(@NonNull K sourceKey, @NonNull K destinationKey, long timeout, @NonNull TimeUnit unit); /** * Remove the last element from list at {@code sourceKey}, append it to {@code destinationKey} and return its @@ -577,8 +551,7 @@ default V rightPop(K key, Duration timeout) { * @since 2.3 * @see Redis Documentation: BRPOPLPUSH */ - @Nullable - default V rightPopAndLeftPush(K sourceKey, K destinationKey, Duration timeout) { + default V rightPopAndLeftPush(@NonNull K sourceKey, @NonNull K destinationKey, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -586,5 +559,6 @@ default V rightPopAndLeftPush(K sourceKey, K destinationKey, Duration timeout) { return rightPopAndLeftPush(sourceKey, destinationKey, TimeoutUtils.toSeconds(timeout), TimeUnit.SECONDS); } + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/PartialUpdate.java b/src/main/java/org/springframework/data/redis/core/PartialUpdate.java index 400333efdc..b47a217765 100644 --- a/src/main/java/org/springframework/data/redis/core/PartialUpdate.java +++ b/src/main/java/org/springframework/data/redis/core/PartialUpdate.java @@ -19,7 +19,7 @@ import java.util.Collections; import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -98,8 +98,7 @@ public static PartialUpdate newPartialUpdate(Object id, Class targetTy /** * @return can be {@literal null}. */ - @Nullable - public T getValue() { + public @Nullable T getValue() { return value; } @@ -226,8 +225,7 @@ public String getPropertyPath() { * * @return can be {@literal null}. */ - @Nullable - public Object getValue() { + public @Nullable Object getValue() { return value; } } diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveHashOperations.java b/src/main/java/org/springframework/data/redis/core/ReactiveHashOperations.java index 4c8c0986d8..7d9e6c7776 100644 --- a/src/main/java/org/springframework/data/redis/core/ReactiveHashOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ReactiveHashOperations.java @@ -26,10 +26,10 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.Expirations; -import org.springframework.lang.Nullable; /** * Reactive Redis operations for Hash Commands. @@ -300,8 +300,7 @@ default Flux> scan(H key) { * @see Redis Documentation: HTTL * @since 3.5 */ - @Nullable - default Mono> getTimeToLive(H key, Collection hashKeys) { + default @Nullable Mono> getTimeToLive(H key, Collection hashKeys) { return getTimeToLive(key, TimeUnit.SECONDS, hashKeys); } diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveListOperations.java b/src/main/java/org/springframework/data/redis/core/ReactiveListOperations.java index a3a69bbd0f..89182ad266 100644 --- a/src/main/java/org/springframework/data/redis/core/ReactiveListOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ReactiveListOperations.java @@ -24,9 +24,9 @@ import java.time.Duration; import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.ListOperations.MoveFrom; import org.springframework.data.redis.core.ListOperations.MoveTo; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -284,8 +284,7 @@ default Mono move(MoveFrom from, MoveTo to, Duration timeout) { * @return * @since 3.4 */ - @Nullable - default Mono getFirst(K key) { + default @Nullable Mono getFirst(K key) { return index(key, 0); } @@ -296,8 +295,7 @@ default Mono getFirst(K key) { * @return * @since 3.4 */ - @Nullable - default Mono getLast(K key) { + default @Nullable Mono getLast(K key) { return index(key, -1); } diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveRedisTemplate.java b/src/main/java/org/springframework/data/redis/core/ReactiveRedisTemplate.java index 3741aa751d..0c25518329 100644 --- a/src/main/java/org/springframework/data/redis/core/ReactiveRedisTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/ReactiveRedisTemplate.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.DataType; @@ -48,7 +49,6 @@ import org.springframework.data.redis.serializer.RedisElementReader; import org.springframework.data.redis.serializer.RedisElementWriter; import org.springframework.data.redis.serializer.RedisSerializationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -710,8 +710,7 @@ private List rawKeys(Collection keys) { return rawKeys; } - @Nullable - private K readKey(ByteBuffer buffer) { + private @Nullable K readKey(ByteBuffer buffer) { return getSerializationContext().getKeySerializationPair().getReader().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveStreamOperations.java b/src/main/java/org/springframework/data/redis/core/ReactiveStreamOperations.java index 341eafe6b7..1abf9bb96b 100644 --- a/src/main/java/org/springframework/data/redis/core/ReactiveStreamOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ReactiveStreamOperations.java @@ -22,11 +22,13 @@ import java.util.Arrays; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.reactivestreams.Publisher; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; -import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.RedisStreamCommands.XAddOptions; +import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.stream.ByteBufferRecord; import org.springframework.data.redis.connection.stream.Consumer; import org.springframework.data.redis.connection.stream.MapRecord; @@ -44,7 +46,6 @@ import org.springframework.data.redis.connection.stream.StreamReadOptions; import org.springframework.data.redis.connection.stream.StreamRecords; import org.springframework.data.redis.hash.HashMapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -58,6 +59,7 @@ * @author jinkshower * @since 2.2 */ +@NullUnmarked public interface ReactiveStreamOperations extends HashMapperProvider { /** @@ -69,7 +71,7 @@ public interface ReactiveStreamOperations extends HashMapperProvider< * @return the {@link Mono} emitting the length of acknowledged records. * @see Redis Documentation: XACK */ - default Mono acknowledge(K key, String group, String... recordIds) { + default Mono acknowledge(@NonNull K key, @NonNull String group, @NonNull String @NonNull... recordIds) { return acknowledge(key, group, Arrays.stream(recordIds).map(RecordId::of).toArray(RecordId[]::new)); } @@ -82,7 +84,7 @@ default Mono acknowledge(K key, String group, String... recordIds) { * @return the {@link Mono} emitting the length of acknowledged records. * @see Redis Documentation: XACK */ - Mono acknowledge(K key, String group, RecordId... recordIds); + Mono acknowledge(@NonNull K key, @NonNull String group, @NonNull RecordId @NonNull... recordIds); /** * Acknowledge the given record as processed. @@ -92,7 +94,7 @@ default Mono acknowledge(K key, String group, String... recordIds) { * @return the {@link Mono} emitting the length of acknowledged records. * @see Redis Documentation: XACK */ - default Mono acknowledge(String group, Record record) { + default Mono acknowledge(@NonNull String group, @NonNull Record record) { return acknowledge(record.getRequiredStream(), group, record.getId()); } @@ -106,7 +108,8 @@ default Mono acknowledge(String group, Record record) { * @see Redis Documentation: XADD * @since 3.4 */ - default Mono add(K key, Map content, XAddOptions xAddOptions) { + default Mono add(@NonNull K key, @NonNull Map content, + @NonNull XAddOptions xAddOptions) { return add(StreamRecords.newRecord().in(key).ofMap(content), xAddOptions); } @@ -119,14 +122,15 @@ default Mono add(K key, Map content, XAddO * @see Redis Documentation: XADD * @since 3.4 */ - @SuppressWarnings("unchecked") - default Mono add(MapRecord record, XAddOptions xAddOptions) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + default Mono add(@NonNull MapRecord record, + @NonNull XAddOptions xAddOptions) { return add((Record) record, xAddOptions); } /** - * Append the record, backed by the given value, to the stream with the specified options. - * The value will be hashed and serialized. + * Append the record, backed by the given value, to the stream with the specified options. The value will be hashed + * and serialized. * * @param record must not be {@literal null}. * @param xAddOptions parameters for the {@literal XADD} call. Must not be {@literal null}. @@ -136,7 +140,7 @@ default Mono add(MapRecord record, XAdd * @see Redis Documentation: XADD * @since 3.4 */ - Mono add(Record record, XAddOptions xAddOptions); + Mono add(@NonNull Record record, @NonNull XAddOptions xAddOptions); /** * Append one or more records to the stream {@code key}. @@ -146,7 +150,8 @@ default Mono add(MapRecord record, XAdd * @return the record Ids. * @see Redis Documentation: XADD */ - default Flux add(K key, Publisher> bodyPublisher) { + default Flux add(@NonNull K key, + @NonNull Publisher> bodyPublisher) { return Flux.from(bodyPublisher).flatMap(it -> add(key, it)); } @@ -158,7 +163,7 @@ default Flux add(K key, PublisherRedis Documentation: XADD */ - default Mono add(K key, Map content) { + default Mono add(@NonNull K key, @NonNull Map content) { return add(StreamRecords.newRecord().in(key).ofMap(content)); } @@ -170,7 +175,7 @@ default Mono add(K key, Map content) { * @see Redis Documentation: XADD */ @SuppressWarnings("unchecked") - default Mono add(MapRecord record) { + default Mono add(@NonNull MapRecord record) { return add((Record) record); } @@ -182,14 +187,12 @@ default Mono add(MapRecord record) { * @see MapRecord * @see ObjectRecord */ - Mono add(Record record); + Mono add(@NonNull Record record); /** - * Changes the ownership of a pending message so that the new owner is the consumer specified as - * the command argument. - * - * The message is claimed only if its idle time (ms) is greater than the {@link Duration minimum idle time} - * specified when calling {@literal XCLAIM}. + * Changes the ownership of a pending message so that the new owner is the consumer specified as the command argument. + * The message is claimed only if its idle time (ms) is greater than the {@link Duration minimum idle time} specified + * when calling {@literal XCLAIM}. * * @param key {@link K key} to the steam. * @param consumerGroup {@link String name} of the consumer group. @@ -203,16 +206,14 @@ default Mono add(MapRecord record) { * @see #claim(Object, String, String, XClaimOptions) * @see reactor.core.publisher.Flux */ - default Flux> claim(K key, String consumerGroup, String newOwner, Duration minIdleTime, - RecordId... recordIds) { + default Flux> claim(@NonNull K key, @NonNull String consumerGroup, @NonNull String newOwner, + @NonNull Duration minIdleTime, @NonNull RecordId @NonNull... recordIds) { return claim(key, consumerGroup, newOwner, XClaimOptions.minIdle(minIdleTime).ids(recordIds)); } /** - * Changes the ownership of a pending message so that the new owner is the consumer specified as - * the command argument. - + * Changes the ownership of a pending message so that the new owner is the consumer specified as the command argument. * The message is claimed only if its idle time (ms) is greater than the given {@link Duration minimum idle time} * specified when calling {@literal XCLAIM}. * @@ -226,7 +227,8 @@ default Flux> claim(K key, String consumerGroup, String new * @see org.springframework.data.redis.connection.stream.MapRecord * @see reactor.core.publisher.Flux */ - Flux> claim(K key, String consumerGroup, String newOwner, XClaimOptions xClaimOptions); + Flux> claim(@NonNull K key, @NonNull String consumerGroup, @NonNull String newOwner, + @NonNull XClaimOptions xClaimOptions); /** * Removes the specified records from the stream. Returns the number of records deleted, that may be different from @@ -237,7 +239,7 @@ default Flux> claim(K key, String consumerGroup, String new * @return the {@link Mono} emitting the number of removed records. * @see Redis Documentation: XDEL */ - default Mono delete(K key, String... recordIds) { + default Mono delete(@NonNull K key, @NonNull String @NonNull... recordIds) { return delete(key, Arrays.stream(recordIds).map(RecordId::of).toArray(RecordId[]::new)); } @@ -247,7 +249,9 @@ default Mono delete(K key, String... recordIds) { * @param record must not be {@literal null}. * @return he {@link Mono} emitting the number of removed records. */ - default Mono delete(Record record) { + default Mono delete(@NonNull Record record) { + + Assert.notNull(record.getStream(), "Record.getStream() must not be null"); return delete(record.getStream(), record.getId()); } @@ -260,7 +264,7 @@ default Mono delete(Record record) { * @return the {@link Mono} emitting the number of removed records. * @see Redis Documentation: XDEL */ - Mono delete(K key, RecordId... recordIds); + Mono delete(@NonNull K key, @NonNull RecordId @NonNull... recordIds); /** * Create a consumer group at the {@link ReadOffset#latest() latest offset}. This command creates the stream if it @@ -271,7 +275,7 @@ default Mono delete(Record record) { * @return the {@link Mono} emitting {@literal OK} if successful.. {@literal null} when used in pipeline / * transaction. */ - default Mono createGroup(K key, String group) { + default Mono createGroup(@NonNull K key, @NonNull String group) { return createGroup(key, ReadOffset.latest(), group); } @@ -283,7 +287,7 @@ default Mono createGroup(K key, String group) { * @param group name of the consumer group. * @return the {@link Mono} emitting {@literal OK} if successful. */ - Mono createGroup(K key, ReadOffset readOffset, String group); + Mono createGroup(@NonNull K key, @NonNull ReadOffset readOffset, @NonNull String group); /** * Delete a consumer from a consumer group. @@ -292,7 +296,7 @@ default Mono createGroup(K key, String group) { * @param consumer consumer identified by group name and consumer key. * @return the {@link Mono} {@literal OK} if successful. {@literal null} when used in pipeline / transaction. */ - Mono deleteConsumer(K key, Consumer consumer); + Mono deleteConsumer(@NonNull K key, @NonNull Consumer consumer); /** * Destroy a consumer group. @@ -301,7 +305,7 @@ default Mono createGroup(K key, String group) { * @param group name of the consumer group. * @return the {@link Mono} {@literal OK} if successful. {@literal null} when used in pipeline / transaction. */ - Mono destroyGroup(K key, String group); + Mono destroyGroup(@NonNull K key, @NonNull String group); /** * Obtain information about every consumer in a specific {@literal consumer group} for the stream stored at the @@ -312,7 +316,7 @@ default Mono createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - Flux consumers(K key, String group); + Flux consumers(@NonNull K key, @NonNull String group); /** * Obtain information about {@literal consumer groups} associated with the stream stored at the specified @@ -322,7 +326,7 @@ default Mono createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - Flux groups(K key); + Flux groups(@NonNull K key); /** * Obtain general information about the stream stored at the specified {@literal key}. @@ -331,7 +335,7 @@ default Mono createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - Mono info(K key); + Mono info(@NonNull K key); /** * Obtain the {@link PendingMessagesSummary} for a given {@literal consumer group}. @@ -343,8 +347,7 @@ default Mono createGroup(K key, String group) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - Mono pending(K key, String group); + Mono pending(@NonNull K key, @NonNull String group); /** * Obtained detailed information about all pending messages for a given {@link Consumer}. @@ -355,7 +358,7 @@ default Mono createGroup(K key, String group) { * @see Redis Documentation: xpending * @since 2.3 */ - default Mono pending(K key, Consumer consumer) { + default Mono pending(@NonNull K key, @NonNull Consumer consumer) { return pending(key, consumer, Range.unbounded(), -1L); } @@ -372,7 +375,7 @@ default Mono pending(K key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - Mono pending(K key, String group, Range range, long count); + Mono pending(@NonNull K key, @NonNull String group, @NonNull Range range, long count); /** * Obtain detailed information about pending {@link PendingMessage messages} for a given {@link Range} and @@ -386,7 +389,7 @@ default Mono pending(K key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - Mono pending(K key, Consumer consumer, Range range, long count); + Mono pending(@NonNull K key, @NonNull Consumer consumer, @NonNull Range range, long count); /** * Get the length of a stream. @@ -395,7 +398,7 @@ default Mono pending(K key, Consumer consumer) { * @return the {@link Mono} emitting the length of the stream. * @see Redis Documentation: XLEN */ - Mono size(K key); + Mono size(@NonNull K key); /** * Read records from a stream within a specific {@link Range}. @@ -405,7 +408,7 @@ default Mono pending(K key, Consumer consumer) { * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XRANGE */ - default Flux> range(K key, Range range) { + default Flux> range(@NonNull K key, @NonNull Range range) { return range(key, range, Limit.unlimited()); } @@ -418,7 +421,7 @@ default Flux> range(K key, Range range) { * @return lthe {@link Flux} emitting records one by one. * @see Redis Documentation: XRANGE */ - Flux> range(K key, Range range, Limit limit); + Flux> range(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Read all records from a stream within a specific {@link Range}. @@ -429,7 +432,8 @@ default Flux> range(K key, Range range) { * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XRANGE */ - default Flux> range(Class targetType, K key, Range range) { + default Flux> range(@NonNull Class targetType, @NonNull K key, + @NonNull Range range) { return range(targetType, key, range, Limit.unlimited()); } @@ -443,7 +447,8 @@ default Flux> range(Class targetType, K key, RangeRedis Documentation: XRANGE */ - default Flux> range(Class targetType, K key, Range range, Limit limit) { + default Flux> range(@NonNull Class targetType, @NonNull K key, @NonNull Range range, + @NonNull Limit limit) { Assert.notNull(targetType, "Target type must not be null"); @@ -458,7 +463,7 @@ default Flux> range(Class targetType, K key, RangeRedis Documentation: XREAD */ @SuppressWarnings("unchecked") - default Flux> read(StreamOffset stream) { + default Flux> read(@NonNull StreamOffset stream) { Assert.notNull(stream, "StreamOffset must not be null"); @@ -474,7 +479,7 @@ default Flux> read(StreamOffset stream) { * @see Redis Documentation: XREAD */ @SuppressWarnings("unchecked") - default Flux> read(Class targetType, StreamOffset stream) { + default Flux> read(@NonNull Class targetType, @NonNull StreamOffset stream) { Assert.notNull(stream, "StreamOffset must not be null"); @@ -488,7 +493,7 @@ default Flux> read(Class targetType, StreamOffset s * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREAD */ - default Flux> read(StreamOffset... streams) { + default Flux> read(@NonNull StreamOffset... streams) { return read(StreamReadOptions.empty(), streams); } @@ -500,7 +505,7 @@ default Flux> read(StreamOffset... streams) { * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREAD */ - default Flux> read(Class targetType, StreamOffset... streams) { + default Flux> read(@NonNull Class targetType, @NonNull StreamOffset... streams) { return read(targetType, StreamReadOptions.empty(), streams); } @@ -512,7 +517,7 @@ default Flux> read(Class targetType, StreamOffset.. * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREAD */ - Flux> read(StreamReadOptions readOptions, StreamOffset... streams); + Flux> read(@NonNull StreamReadOptions readOptions, @NonNull StreamOffset @NonNull... streams); /** * Read records from one or more {@link StreamOffset}s as {@link ObjectRecord}. @@ -523,8 +528,8 @@ default Flux> read(Class targetType, StreamOffset.. * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREAD */ - default Flux> read(Class targetType, StreamReadOptions readOptions, - StreamOffset... streams) { + default Flux> read(@NonNull Class targetType, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset @NonNull... streams) { Assert.notNull(targetType, "Target type must not be null"); @@ -539,7 +544,7 @@ default Flux> read(Class targetType, StreamReadOptions * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREADGROUP */ - default Flux> read(Consumer consumer, StreamOffset... streams) { + default Flux> read(@NonNull Consumer consumer, @NonNull StreamOffset @NonNull... streams) { return read(consumer, StreamReadOptions.empty(), streams); } @@ -552,7 +557,8 @@ default Flux> read(Consumer consumer, StreamOffset... st * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREADGROUP */ - default Flux> read(Class targetType, Consumer consumer, StreamOffset... streams) { + default Flux> read(@NonNull Class targetType, @NonNull Consumer consumer, + @NonNull StreamOffset @NonNull... streams) { return read(targetType, consumer, StreamReadOptions.empty(), streams); } @@ -565,7 +571,8 @@ default Flux> read(Class targetType, Consumer consumer * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREADGROUP */ - Flux> read(Consumer consumer, StreamReadOptions readOptions, StreamOffset... streams); + Flux> read(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + @NonNull StreamOffset... streams); /** * Read records from one or more {@link StreamOffset}s using a consumer group as {@link ObjectRecord}. @@ -577,8 +584,8 @@ default Flux> read(Class targetType, Consumer consumer * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREADGROUP */ - default Flux> read(Class targetType, Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams) { + default Flux> read(@NonNull Class targetType, @NonNull Consumer consumer, + @NonNull StreamReadOptions readOptions, @NonNull StreamOffset @NonNull... streams) { Assert.notNull(targetType, "Target type must not be null"); @@ -593,7 +600,7 @@ default Flux> read(Class targetType, Consumer consumer * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREVRANGE */ - default Flux> reverseRange(K key, Range range) { + default Flux> reverseRange(@NonNull K key, @NonNull Range range) { return reverseRange(key, range, Limit.unlimited()); } @@ -606,7 +613,7 @@ default Flux> reverseRange(K key, Range range) { * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREVRANGE */ - Flux> reverseRange(K key, Range range, Limit limit); + Flux> reverseRange(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Read records from a stream within a specific {@link Range} in reverse order as {@link ObjectRecord}. @@ -617,7 +624,8 @@ default Flux> reverseRange(K key, Range range) { * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREVRANGE */ - default Flux> reverseRange(Class targetType, K key, Range range) { + default Flux> reverseRange(@NonNull Class targetType, @NonNull K key, + @NonNull Range range) { return reverseRange(targetType, key, range, Limit.unlimited()); } @@ -632,7 +640,8 @@ default Flux> reverseRange(Class targetType, K key, Ra * @return the {@link Flux} emitting records one by one. * @see Redis Documentation: XREVRANGE */ - default Flux> reverseRange(Class targetType, K key, Range range, Limit limit) { + default Flux> reverseRange(@NonNull Class targetType, @NonNull K key, + @NonNull Range range, @NonNull Limit limit) { Assert.notNull(targetType, "Target type must not be null"); @@ -647,7 +656,7 @@ default Flux> reverseRange(Class targetType, K key, Ra * @return number of removed entries. * @see Redis Documentation: XTRIM */ - Mono trim(K key, long count); + Mono trim(@NonNull K key, long count); /** * Trims the stream to {@code count} elements. @@ -659,7 +668,7 @@ default Flux> reverseRange(Class targetType, K key, Ra * @since 2.4 * @see Redis Documentation: XTRIM */ - Mono trim(K key, long count, boolean approximateTrimming); + Mono trim(@NonNull K key, long count, boolean approximateTrimming); /** * Get the {@link HashMapper} for a specific type. @@ -669,7 +678,7 @@ default Flux> reverseRange(Class targetType, K key, Ra * @return the {@link HashMapper} suitable for a given type; */ @Override - HashMapper getHashMapper(Class targetType); + HashMapper getHashMapper(@NonNull Class targetType); /** * Map records from {@link MapRecord} to {@link ObjectRecord}. @@ -679,7 +688,7 @@ default Flux> reverseRange(Class targetType, K key, Ra * @return the mapped {@link ObjectRecord}. * @since 2.x */ - default ObjectRecord map(MapRecord record, Class targetType) { + default ObjectRecord map(@NonNull MapRecord record, @NonNull Class targetType) { Assert.notNull(record, "Records must not be null"); Assert.notNull(targetType, "Target type must not be null"); @@ -694,5 +703,5 @@ default ObjectRecord map(MapRecord record, Class targetT * @return deserialized {@link MapRecord}. * @since 2.x */ - MapRecord deserializeRecord(ByteBufferRecord record); + MapRecord deserializeRecord(@NonNull ByteBufferRecord record); } diff --git a/src/main/java/org/springframework/data/redis/core/ReactiveZSetOperations.java b/src/main/java/org/springframework/data/redis/core/ReactiveZSetOperations.java index e98bfd5929..a8083ec252 100644 --- a/src/main/java/org/springframework/data/redis/core/ReactiveZSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ReactiveZSetOperations.java @@ -24,13 +24,15 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.zset.Aggregate; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; -import org.springframework.lang.Nullable; /** * Reactive Redis operations for Sorted (ZSet) Commands. @@ -46,6 +48,7 @@ * @see Redis Documentation: Sorted Set Commands * @since 2.0 */ +@NullUnmarked public interface ReactiveZSetOperations { /** @@ -57,7 +60,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZADD */ - Mono add(K key, V value, double score); + Mono add(@NonNull K key, @NonNull V value, double score); /** * Add {@code tuples} to a sorted set at {@code key}, or update their score if it already exists. @@ -67,7 +70,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZADD */ - Mono addAll(K key, Collection> tuples); + Mono addAll(@NonNull K key, @NonNull Collection> tuples); /** * Remove {@code values} from sorted set. Return number of removed elements. @@ -77,7 +80,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREM */ - Mono remove(K key, Object... values); + Mono remove(@NonNull K key, @NonNull Object @NonNull... values); /** * Increment the score of element with {@code value} in sorted set by {@code increment}. @@ -88,7 +91,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZINCRBY */ - Mono incrementScore(K key, V value, double delta); + Mono incrementScore(@NonNull K key, @NonNull V value, double delta); /** * Get random element from set at {@code key}. @@ -98,7 +101,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Mono randomMember(K key); + Mono randomMember(@NonNull K key); /** * Get {@code count} distinct random elements from set at {@code key}. @@ -110,7 +113,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Flux distinctRandomMembers(K key, long count); + Flux distinctRandomMembers(@NonNull K key, long count); /** * Get {@code count} random elements from set at {@code key}. @@ -122,7 +125,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Flux randomMembers(K key, long count); + Flux randomMembers(@NonNull K key, long count); /** * Get random element with its score from set at {@code key}. @@ -132,7 +135,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Mono> randomMemberWithScore(K key); + Mono> randomMemberWithScore(@NonNull K key); /** * Get {@code count} distinct random elements with their score from set at {@code key}. @@ -144,7 +147,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Flux> distinctRandomMembersWithScore(K key, long count); + Flux> distinctRandomMembersWithScore(@NonNull K key, long count); /** * Get {@code count} random elements with their score from set at {@code key}. @@ -156,7 +159,7 @@ public interface ReactiveZSetOperations { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - Flux> randomMembersWithScore(K key, long count); + Flux> randomMembersWithScore(@NonNull K key, long count); /** * Determine the index of element with {@code value} in a sorted set. @@ -166,7 +169,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANK */ - Mono rank(K key, Object o); + Mono rank(@NonNull K key, @NonNull Object o); /** * Determine the index of element with {@code value} in a sorted set when scored high to low. @@ -176,7 +179,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANK */ - Mono reverseRank(K key, Object o); + Mono reverseRank(@NonNull K key, @NonNull Object o); /** * Get elements between {@code start} and {@code end} from sorted set. @@ -186,7 +189,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGE */ - Flux range(K key, Range range); + Flux range(@NonNull K key, @NonNull Range range); /** * Get set of {@link Tuple}s between {@code start} and {@code end} from sorted set. @@ -196,7 +199,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGE */ - Flux> rangeWithScores(K key, Range range); + Flux> rangeWithScores(@NonNull K key, @NonNull Range range); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -206,7 +209,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGEBYSCORE */ - Flux rangeByScore(K key, Range range); + Flux rangeByScore(@NonNull K key, @NonNull Range range); /** * Get set of {@link Tuple}s where score is between {@code min} and {@code max} from sorted set. @@ -216,7 +219,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGEBYSCORE */ - Flux> rangeByScoreWithScores(K key, Range range); + Flux> rangeByScoreWithScores(@NonNull K key, @NonNull Range range); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -228,7 +231,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGEBYSCORE */ - Flux rangeByScore(K key, Range range, Limit limit); + Flux rangeByScore(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} where score is between {@code min} and @@ -240,7 +243,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZRANGEBYSCORE */ - Flux> rangeByScoreWithScores(K key, Range range, Limit limit); + Flux> rangeByScoreWithScores(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Get elements in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -250,7 +253,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGE */ - Flux reverseRange(K key, Range range); + Flux reverseRange(@NonNull K key, @NonNull Range range); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -260,7 +263,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGE */ - Flux> reverseRangeWithScores(K key, Range range); + Flux> reverseRangeWithScores(@NonNull K key, @NonNull Range range); /** * Get elements where score is between {@code min} and {@code max} from sorted set ordered from high to low. @@ -270,7 +273,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGEBYSCORE */ - Flux reverseRangeByScore(K key, Range range); + Flux reverseRangeByScore(@NonNull K key, @NonNull Range range); /** * Get set of {@link Tuple} where score is between {@code min} and {@code max} from sorted set ordered from high to @@ -281,7 +284,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGEBYSCORE */ - Flux> reverseRangeByScoreWithScores(K key, Range range); + Flux> reverseRangeByScoreWithScores(@NonNull K key, @NonNull Range range); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -293,7 +296,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGEBYSCORE */ - Flux reverseRangeByScore(K key, Range range, Limit limit); + Flux reverseRangeByScore(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Get set of {@link Tuple} in range from {@code start} to {@code end} where score is between {@code min} and @@ -305,7 +308,7 @@ public interface ReactiveZSetOperations { * @return * @see Redis Documentation: ZREVRANGEBYSCORE */ - Flux> reverseRangeByScoreWithScores(K key, Range range, Limit limit); + Flux> reverseRangeByScoreWithScores(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a @@ -318,7 +321,7 @@ public interface ReactiveZSetOperations { * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - default Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range) { + default Mono rangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return rangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited()); } @@ -335,7 +338,8 @@ default Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range) { * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit); + Mono rangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey} @@ -348,7 +352,7 @@ default Mono rangeAndStoreByLex(K srcKey, K dstKey, Range range) { * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - default Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range) { + default Mono reverseRangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return reverseRangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited()); } @@ -366,7 +370,8 @@ default Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range r * @see #reverseRangeByLex(Object, Range, Limit) * @see Redis Documentation: ZRANGESTORE */ - Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit); + Mono reverseRangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at {@code srcKey} with a score @@ -379,8 +384,8 @@ default Mono reverseRangeAndStoreByLex(K srcKey, K dstKey, Range r * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range) { + default @Nullable Mono rangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, + @NonNull Range range) { return rangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited()); } @@ -397,7 +402,8 @@ default Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range) * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit); + Mono rangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a @@ -410,7 +416,7 @@ default Mono rangeAndStoreByScore(K srcKey, K dstKey, Range range) * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - default Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range) { + default Mono reverseRangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return reverseRangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited()); } @@ -427,7 +433,8 @@ default Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range * @since 3.0 * @see Redis Documentation: ZRANGESTORE */ - Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit); + Mono reverseRangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Use a {@link Flux} to iterate over entries in the sorted set at {@code key}. The resulting {@link Flux} acts as a @@ -440,7 +447,7 @@ default Mono reverseRangeAndStoreByScore(K srcKey, K dstKey, Range * @see Redis Documentation: ZSCAN * @since 2.1 */ - default Flux> scan(K key) { + default Flux> scan(@NonNull K key) { return scan(key, ScanOptions.NONE); } @@ -457,7 +464,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZSCAN * @since 2.1 */ - Flux> scan(K key, ScanOptions options); + Flux> scan(@NonNull K key, @Nullable ScanOptions options); /** * Count number of elements within sorted set with scores between {@code min} and {@code max}. @@ -467,7 +474,7 @@ default Flux> scan(K key) { * @return * @see Redis Documentation: ZCOUNT */ - Mono count(K key, Range range); + Mono count(@NonNull K key, @NonNull Range range); /** * Count number of elements within sorted set with a value between {@link Range#getLowerBound()} and @@ -479,7 +486,7 @@ default Flux> scan(K key) { * @since 2.4 * @see Redis Documentation: ZLEXCOUNT */ - Mono lexCount(K key, Range range); + Mono lexCount(@NonNull K key, @NonNull Range range); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. @@ -489,7 +496,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - Mono> popMin(K key); + Mono> popMin(@NonNull K key); /** * Remove and return {@code count} values with their score having the lowest score from sorted set at {@code key}. @@ -500,7 +507,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - Flux> popMin(K key, long count); + Flux> popMin(@NonNull K key, long count); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. @@ -513,7 +520,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - Mono> popMin(K key, Duration timeout); + Mono> popMin(@NonNull K key, Duration timeout); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}. @@ -523,7 +530,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - Mono> popMax(K key); + Mono> popMax(@NonNull K key); /** * Remove and return {@code count} values with their score having the highest score from sorted set at {@code key}. @@ -534,7 +541,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - Flux> popMax(K key, long count); + Flux> popMax(@NonNull K key, long count); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}. @@ -547,7 +554,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - Mono> popMax(K key, Duration timeout); + Mono> popMax(@NonNull K key, @NonNull Duration timeout); /** * Returns the number of elements of the sorted set stored with given {@code key}. @@ -556,7 +563,7 @@ default Flux> scan(K key) { * @return * @see Redis Documentation: ZCARD */ - Mono size(K key); + Mono size(@NonNull K key); /** * Get the score of element with {@code value} from sorted set with key {@code key}. @@ -566,7 +573,7 @@ default Flux> scan(K key) { * @return * @see Redis Documentation: ZSCORE */ - Mono score(K key, Object o); + Mono score(@NonNull K key, @NonNull Object o); /** * Get the scores of elements with {@code values} from sorted set with key {@code key}. @@ -577,7 +584,7 @@ default Flux> scan(K key) { * @see Redis Documentation: ZMSCORE * @since 2.6 */ - Mono> score(K key, Object... o); + Mono> score(@NonNull K key, @NonNull Object @NonNull... o); /** * Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}. @@ -587,7 +594,7 @@ default Flux> scan(K key) { * @return * @see Redis Documentation: ZREMRANGEBYRANK */ - Mono removeRange(K key, Range range); + Mono removeRange(@NonNull K key, @NonNull Range range); /** * Remove elements in range from sorted set with {@code key}. @@ -598,7 +605,7 @@ default Flux> scan(K key) { * @since 2.5 * @see Redis Documentation: ZREMRANGEBYRANK */ - Mono removeRangeByLex(K key, Range range); + Mono removeRangeByLex(@NonNull K key, @NonNull Range range); /** * Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}. @@ -608,7 +615,7 @@ default Flux> scan(K key) { * @return * @see Redis Documentation: ZREMRANGEBYSCORE */ - Mono removeRangeByScore(K key, Range range); + Mono removeRangeByScore(@NonNull K key, @NonNull Range range); /** * Diff sorted {@code sets}. @@ -619,7 +626,7 @@ default Flux> scan(K key) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - default Flux difference(K key, K otherKey) { + default Flux difference(@NonNull K key, @NonNull K otherKey) { return difference(key, Collections.singleton(otherKey)); } @@ -632,7 +639,7 @@ default Flux difference(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - Flux difference(K key, Collection otherKeys); + Flux difference(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets}. @@ -643,7 +650,7 @@ default Flux difference(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - default Flux> differenceWithScores(K key, K otherKey) { + default Flux> differenceWithScores(@NonNull K key, @NonNull K otherKey) { return differenceWithScores(key, Collections.singleton(otherKey)); } @@ -656,7 +663,7 @@ default Flux> differenceWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - Flux> differenceWithScores(K key, Collection otherKeys); + Flux> differenceWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets} and store result in destination {@code destKey}. @@ -668,7 +675,7 @@ default Flux> differenceWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - default Mono differenceAndStore(K key, K otherKey, K destKey) { + default Mono differenceAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey) { return differenceAndStore(key, Collections.singleton(otherKey), destKey); } @@ -682,7 +689,7 @@ default Mono differenceAndStore(K key, K otherKey, K destKey) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - Mono differenceAndStore(K key, Collection otherKeys, K destKey); + Mono differenceAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted {@code sets}. @@ -693,7 +700,7 @@ default Mono differenceAndStore(K key, K otherKey, K destKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - default Flux intersect(K key, K otherKey) { + default Flux intersect(@NonNull K key, @NonNull K otherKey) { return intersect(key, Collections.singleton(otherKey)); } @@ -706,7 +713,7 @@ default Flux intersect(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - Flux intersect(K key, Collection otherKeys); + Flux intersect(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted {@code sets}. @@ -717,7 +724,7 @@ default Flux intersect(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - default Flux> intersectWithScores(K key, K otherKey) { + default Flux> intersectWithScores(@NonNull K key, @NonNull K otherKey) { return intersectWithScores(key, Collections.singleton(otherKey)); } @@ -730,7 +737,7 @@ default Flux> intersectWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - Flux> intersectWithScores(K key, Collection otherKeys); + Flux> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted sets at {@code key} and {@code otherKeys} . @@ -742,7 +749,8 @@ default Flux> intersectWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - default Flux> intersectWithScores(K key, Collection otherKeys, Aggregate aggregate) { + default Flux> intersectWithScores(@NonNull K key, @NonNull Collection otherKeys, + @NonNull Aggregate aggregate) { return intersectWithScores(key, otherKeys, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -757,7 +765,8 @@ default Flux> intersectWithScores(K key, Collection otherKeys, * @since 2.6 * @see Redis Documentation: ZINTER */ - Flux> intersectWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights); + Flux> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Intersect sorted sets at {@code key} and {@code otherKey} and store result in destination {@code destKey}. @@ -768,7 +777,7 @@ default Flux> intersectWithScores(K key, Collection otherKeys, * @return * @see Redis Documentation: ZINTERSTORE */ - default Mono intersectAndStore(K key, K otherKey, K destKey) { + default Mono intersectAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey) { return intersectAndStore(key, Collections.singleton(otherKey), destKey); } @@ -781,7 +790,7 @@ default Mono intersectAndStore(K key, K otherKey, K destKey) { * @return * @see Redis Documentation: ZINTERSTORE */ - Mono intersectAndStore(K key, Collection otherKeys, K destKey); + Mono intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -794,7 +803,8 @@ default Mono intersectAndStore(K key, K otherKey, K destKey) { * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - default Mono intersectAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate) { + default Mono intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate) { return intersectAndStore(key, otherKeys, destKey, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -810,7 +820,8 @@ default Mono intersectAndStore(K key, Collection otherKeys, K destKey, * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - Mono intersectAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Mono intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Union sorted {@code sets}. @@ -821,7 +832,7 @@ default Mono intersectAndStore(K key, Collection otherKeys, K destKey, * @since 2.6 * @see Redis Documentation: ZUNION */ - default Flux union(K key, K otherKey) { + default Flux union(@NonNull K key, @NonNull K otherKey) { return union(key, Collections.singleton(otherKey)); } @@ -834,7 +845,7 @@ default Flux union(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - Flux union(K key, Collection otherKeys); + Flux union(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Union sorted {@code sets}. @@ -845,7 +856,7 @@ default Flux union(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - default Flux> unionWithScores(K key, K otherKey) { + default Flux> unionWithScores(@NonNull K key, @NonNull K otherKey) { return unionWithScores(key, Collections.singleton(otherKey)); } @@ -858,7 +869,7 @@ default Flux> unionWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - Flux> unionWithScores(K key, Collection otherKeys); + Flux> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Union sorted sets at {@code key} and {@code otherKeys} . @@ -870,7 +881,8 @@ default Flux> unionWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - default Flux> unionWithScores(K key, Collection otherKeys, Aggregate aggregate) { + default Flux> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate) { return unionWithScores(key, otherKeys, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -885,7 +897,8 @@ default Flux> unionWithScores(K key, Collection otherKeys, Aggr * @since 2.6 * @see Redis Documentation: ZUNION */ - Flux> unionWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights); + Flux> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -896,7 +909,7 @@ default Flux> unionWithScores(K key, Collection otherKeys, Aggr * @return * @see Redis Documentation: ZUNIONSTORE */ - Mono unionAndStore(K key, K otherKey, K destKey); + Mono unionAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -907,7 +920,7 @@ default Flux> unionWithScores(K key, Collection otherKeys, Aggr * @return * @see Redis Documentation: ZUNIONSTORE */ - Mono unionAndStore(K key, Collection otherKeys, K destKey); + Mono unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -920,7 +933,8 @@ default Flux> unionWithScores(K key, Collection otherKeys, Aggr * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate) { + default Mono unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate) { return unionAndStore(key, otherKeys, destKey, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -936,7 +950,8 @@ default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggr * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Mono unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Get all elements with lexicographical ordering from {@literal ZSET} at {@code key} with a value between @@ -946,7 +961,7 @@ default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggr * @param range must not be {@literal null}. * @see Redis Documentation: ZRANGEBYLEX */ - Flux rangeByLex(K key, Range range); + Flux rangeByLex(@NonNull K key, @NonNull Range range); /** * Get all elements {@literal n} elements, where {@literal n = } {@link Limit#getCount()}, starting at @@ -959,7 +974,7 @@ default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggr * @return * @see Redis Documentation: ZRANGEBYLEX */ - Flux rangeByLex(K key, Range range, Limit limit); + Flux rangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Get all elements with reverse lexicographical ordering from {@literal ZSET} at {@code key} with a value between @@ -969,7 +984,7 @@ default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggr * @param range must not be {@literal null}. * @see Redis Documentation: ZREVRANGEBYLEX */ - Flux reverseRangeByLex(K key, Range range); + Flux reverseRangeByLex(@NonNull K key, @NonNull Range range); /** * Get all elements {@literal n} elements, where {@literal n = } {@link Limit#getCount()}, starting at @@ -982,13 +997,13 @@ default Mono unionAndStore(K key, Collection otherKeys, K destKey, Aggr * @return * @see Redis Documentation: ZREVRANGEBYLEX */ - Flux reverseRangeByLex(K key, Range range, Limit limit); + Flux reverseRangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Removes the given {@literal key}. * * @param key must not be {@literal null}. */ - Mono delete(K key); + Mono delete(@NonNull K key); } diff --git a/src/main/java/org/springframework/data/redis/core/RedisAccessor.java b/src/main/java/org/springframework/data/redis/core/RedisAccessor.java index 5753347654..6efbc26daf 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisAccessor.java +++ b/src/main/java/org/springframework/data/redis/core/RedisAccessor.java @@ -17,9 +17,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -46,8 +46,7 @@ public void afterPropertiesSet() { * @return the configured {@link RedisConnectionFactory}. Can be {@literal null}. * @see RedisConnectionFactory */ - @Nullable - public RedisConnectionFactory getConnectionFactory() { + public @Nullable RedisConnectionFactory getConnectionFactory() { return this.connectionFactory; } diff --git a/src/main/java/org/springframework/data/redis/core/RedisCallback.java b/src/main/java/org/springframework/data/redis/core/RedisCallback.java index 9ad8b41306..09a770306a 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisCallback.java +++ b/src/main/java/org/springframework/data/redis/core/RedisCallback.java @@ -15,9 +15,9 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.lang.Nullable; /** * Callback interface for Redis 'low level' code. To be used with {@link RedisTemplate} execution methods, often as diff --git a/src/main/java/org/springframework/data/redis/core/RedisClusterCallback.java b/src/main/java/org/springframework/data/redis/core/RedisClusterCallback.java index f13ea55dd9..34b1623a73 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisClusterCallback.java +++ b/src/main/java/org/springframework/data/redis/core/RedisClusterCallback.java @@ -15,9 +15,9 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisClusterConnection; -import org.springframework.lang.Nullable; /** * Callback interface for low level operations executed against a clustered Redis environment. diff --git a/src/main/java/org/springframework/data/redis/core/RedisCommand.java b/src/main/java/org/springframework/data/redis/core/RedisCommand.java index 1454fd33c2..abc9cbb54e 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisCommand.java +++ b/src/main/java/org/springframework/data/redis/core/RedisCommand.java @@ -20,7 +20,7 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java index 3e8193a15e..a4a786ce7e 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java +++ b/src/main/java/org/springframework/data/redis/core/RedisConnectionUtils.java @@ -22,12 +22,12 @@ import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.aop.RawTargetAccess; import org.springframework.aop.framework.ProxyFactory; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.lang.Nullable; import org.springframework.transaction.support.ResourceHolderSupport; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -463,11 +463,12 @@ private ConnectionSplittingInterceptor(RedisConnectionFactory factory, Method co } @Override - public Object invoke(MethodInvocation invocation) throws Throwable { + public @Nullable Object invoke(MethodInvocation invocation) throws Throwable { return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments()); } - public Object intercept(Object obj, Method method, Object[] args) throws Throwable { + @SuppressWarnings("NullAway") + public @Nullable Object intercept(@Nullable Object obj, Method method, Object[] args) throws Throwable { if (method.getName().equals("getTargetConnection")) { // Handle getTargetConnection method: return underlying RedisConnection. @@ -567,8 +568,7 @@ protected boolean hasConnection() { return this.connection != null; } - @Nullable - public RedisConnection getConnection() { + public @Nullable RedisConnection getConnection() { return this.connection; } diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyExpiredEvent.java b/src/main/java/org/springframework/data/redis/core/RedisKeyExpiredEvent.java index 3ebed4eb48..049dde5edd 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyExpiredEvent.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyExpiredEvent.java @@ -18,9 +18,9 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEvent; import org.springframework.data.redis.core.convert.MappingRedisConverter.BinaryKeyspaceIdentifier; -import org.springframework.lang.Nullable; /** * {@link RedisKeyExpiredEvent} is a Redis specific {@link ApplicationEvent} published when a particular key in Redis @@ -37,7 +37,7 @@ public class RedisKeyExpiredEvent extends RedisKeyspaceEvent { */ private static final Charset CHARSET = StandardCharsets.UTF_8; - private final BinaryKeyspaceIdentifier objectId; + private final @Nullable BinaryKeyspaceIdentifier objectId; private final @Nullable Object value; /** @@ -84,7 +84,7 @@ public RedisKeyExpiredEvent(@Nullable String channel, byte[] key, @Nullable Obje * * @return {@literal null} if it could not be determined. */ - public String getKeyspace() { + public @Nullable String getKeyspace() { return objectId != null ? new String(objectId.getKeyspace(), CHARSET) : null; } @@ -102,8 +102,7 @@ public byte[] getId() { * * @return {@literal null} if not present. */ - @Nullable - public Object getValue() { + public @Nullable Object getValue() { return value; } diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java index 4cff5b30f3..64712642c8 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java @@ -28,7 +28,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -64,7 +64,6 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.util.ByteUtils; import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -134,6 +133,11 @@ enum State { CREATED, STARTING, STARTED, STOPPING, STOPPED, DESTROYED; } + @SuppressWarnings("NullAway") + protected RedisKeyValueAdapter() { + // I'm here for the sole sake of CDI + } + /** * Creates new {@link RedisKeyValueAdapter} with default {@link RedisMappingContext} and default * {@link RedisCustomConversions}. @@ -163,7 +167,7 @@ public RedisKeyValueAdapter(RedisOperations redisOps, RedisMappingContext * @since 2.0 */ public RedisKeyValueAdapter(RedisOperations redisOps, RedisMappingContext mappingContext, - @Nullable org.springframework.data.convert.CustomConversions customConversions) { + org.springframework.data.convert.@Nullable CustomConversions customConversions) { super(new RedisQueryEngine()); @@ -197,12 +201,8 @@ public RedisKeyValueAdapter(RedisOperations redisOps, RedisConverter redis this.redisOps = redisOps; } - /** - * Default constructor. - */ - protected RedisKeyValueAdapter() {} - @Override + @SuppressWarnings("NullAway") public Object put(Object id, Object item, String keyspace) { RedisData rdo = item instanceof RedisData ? (RedisData) item : new RedisData(); @@ -305,12 +305,12 @@ public T get(Object id, String keyspace, Class type) { } @Override - public Object delete(Object id, String keyspace) { + public @Nullable Object delete(Object id, String keyspace) { return delete(id, keyspace, Object.class); } @Override - public T delete(Object id, String keyspace, Class type) { + public @Nullable T delete(Object id, String keyspace, Class type) { byte[] binId = toBytes(id); byte[] binKeyspace = toBytes(keyspace); @@ -415,6 +415,7 @@ public long count(String keyspace) { return count != null ? count : 0; } + @SuppressWarnings("NullAway") public void update(PartialUpdate update) { RedisPersistentEntity entity = this.converter.getMappingContext() @@ -552,8 +553,7 @@ private RedisUpdateObject fetchDeletePathsFromHashAndUpdateIndex(RedisUpdateObje * @param callback must not be {@literal null}. * @see RedisOperations#execute(RedisCallback) */ - @Nullable - public T execute(RedisCallback callback) { + public @Nullable T execute(RedisCallback callback) { return redisOps.execute(callback); } @@ -584,10 +584,12 @@ public byte[] createKey(String keyspace, String id) { /** * Convert given source to binary representation using the underlying {@link ConversionService}. */ - public byte[] toBytes(Object source) { + @SuppressWarnings("NullAway") + public byte [] toBytes(Object source) { return source instanceof byte[] bytes ? bytes : getConverter().getConversionService().convert(source, byte[].class); } + @SuppressWarnings("NullAway") private String toString(Object value) { return value instanceof String stringValue ? stringValue : getConverter().getConversionService().convert(value, String.class); @@ -596,8 +598,8 @@ private String toString(Object value) { /** * Read back and set {@link TimeToLive} for the property. */ - @Nullable - private T readBackTimeToLiveIfSet(@Nullable byte[] key, @Nullable T target) { + @SuppressWarnings("NullAway") + private @Nullable T readBackTimeToLiveIfSet(byte @Nullable [] key, @Nullable T target) { if (target == null || key == null) { return target; @@ -723,6 +725,7 @@ public void start() { if (isCreatedOrStopped(current)) { + Assert.state(messageListenerContainer != null, "MessageListenerContainer must not be null"); messageListenerContainer.start(); if (ObjectUtils.nullSafeEquals(EnableKeyspaceEvents.ON_STARTUP, this.enableKeyspaceEvents)) { @@ -754,7 +757,9 @@ public void stop() { } } - messageListenerContainer.stop(); + if (messageListenerContainer != null) { + messageListenerContainer.stop(); + } state.set(State.STOPPED); } } @@ -833,7 +838,8 @@ static class MappingExpirationListener extends KeyExpirationEventMessageListener } @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + @SuppressWarnings("NullAway") + public void onMessage(Message message, byte @Nullable [] pattern) { if (!isKeyExpirationMessage(message)) { return; @@ -863,8 +869,7 @@ private boolean isKeyExpirationMessage(Message message) { return BinaryKeyspaceIdentifier.isValid(message.getBody()); } - @Nullable - private Object readShadowCopyIfEnabled(byte[] key) { + private @Nullable Object readShadowCopyIfEnabled(byte[] key) { if (shadowCopy == ShadowCopy.OFF) { return null; @@ -872,8 +877,8 @@ private Object readShadowCopyIfEnabled(byte[] key) { return readShadowCopy(key); } - @Nullable - private Object readShadowCopy(byte[] key) { + @SuppressWarnings("NullAway") + private @Nullable Object readShadowCopy(byte[] key) { byte[] phantomKey = ByteUtils.concat(key, converter.getConversionService().convert(KeyspaceIdentifier.PHANTOM_SUFFIX, byte[].class)); diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java index 4e1454f533..526415b03f 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyValueTemplate.java @@ -89,6 +89,7 @@ public RedisMappingContext getMappingContext() { * @param type must not be {@literal null}. * @return empty list if not elements found. */ + @SuppressWarnings("NullAway") public List find(RedisCallback callback, Class type) { Assert.notNull(callback, "Callback must not be null"); diff --git a/src/main/java/org/springframework/data/redis/core/RedisKeyspaceEvent.java b/src/main/java/org/springframework/data/redis/core/RedisKeyspaceEvent.java index aff2138cb0..f559153e24 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisKeyspaceEvent.java +++ b/src/main/java/org/springframework/data/redis/core/RedisKeyspaceEvent.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEvent; -import org.springframework.lang.Nullable; /** * Redis specific {@link ApplicationEvent} published when a key expires in Redis. @@ -58,8 +58,7 @@ public byte[] getSource() { * @return can be {@literal null}. * @since 1.8 */ - @Nullable - public String getChannel() { + public @Nullable String getChannel() { return this.channel; } diff --git a/src/main/java/org/springframework/data/redis/core/RedisOperations.java b/src/main/java/org/springframework/data/redis/core/RedisOperations.java index 4ea682d900..b6d5658d65 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisOperations.java +++ b/src/main/java/org/springframework/data/redis/core/RedisOperations.java @@ -24,6 +24,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.ExpirationOptions; import org.springframework.data.redis.connection.RedisConnection; @@ -34,7 +36,6 @@ import org.springframework.data.redis.core.types.RedisClientInfo; import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -51,6 +52,7 @@ * @author Vedran Pavic * @author Marcin Grzejszczak */ +@NullUnmarked public interface RedisOperations { /** @@ -66,8 +68,7 @@ public interface RedisOperations { * @param action callback object that specifies the Redis action. Must not be {@literal null}. * @return result of the given {@link RedisCallback#doInRedis(RedisConnection)} invocation. */ - @Nullable - T execute(RedisCallback action); + T execute(@NonNull RedisCallback action); /** * Executes a Redis session. Allows multiple operations to be executed in the same session enabling 'transactional' @@ -77,8 +78,7 @@ public interface RedisOperations { * @param session session callback. Must not be {@literal null}. * @return result of the given {@link SessionCallback#execute(RedisOperations)} invocation. */ - @Nullable - T execute(SessionCallback session); + T execute(@NonNull SessionCallback session); /** * Executes the given action object on a pipelined connection, returning the results. Note that the callback @@ -90,7 +90,7 @@ public interface RedisOperations { * collected from {@link RedisConnection} calls, {@link RedisCallback#doInRedis(RedisConnection)} itself must * return {@literal null}. */ - List executePipelined(RedisCallback action); + List executePipelined(@NonNull RedisCallback action); /** * Executes the given action object on a pipelined connection, returning the results using a dedicated serializer. @@ -103,7 +103,7 @@ public interface RedisOperations { * collected from {@link RedisConnection} calls, {@link RedisCallback#doInRedis(RedisConnection)} itself must * return {@literal null}. */ - List executePipelined(RedisCallback action, RedisSerializer resultSerializer); + List executePipelined(@NonNull RedisCallback action, @NonNull RedisSerializer resultSerializer); /** * Executes the given Redis session on a pipelined connection. Allows transactions to be pipelined. Note that the @@ -114,7 +114,7 @@ public interface RedisOperations { * collected from {@link RedisOperations} calls, {@link SessionCallback#execute(RedisOperations)} itself must * return {@literal null}. */ - List executePipelined(SessionCallback session); + List executePipelined(@NonNull SessionCallback session); /** * Executes the given Redis session on a pipelined connection, returning the results using a dedicated serializer. @@ -127,7 +127,7 @@ public interface RedisOperations { * collected from {@link RedisOperations} calls, {@link SessionCallback#execute(RedisOperations)} itself must * return {@literal null}. */ - List executePipelined(SessionCallback session, RedisSerializer resultSerializer); + List executePipelined(@NonNull SessionCallback session, @NonNull RedisSerializer resultSerializer); /** * Executes the given {@link RedisScript} @@ -138,8 +138,7 @@ public interface RedisOperations { * @return The return value of the script or null if {@link RedisScript#getResultType()} is null, likely indicating a * throw-away status reply (i.e. "OK") */ - @Nullable - T execute(RedisScript script, List keys, Object... args); + T execute(@NonNull RedisScript script, @NonNull List<@NonNull K> keys, @NonNull Object @NonNull... args); /** * Executes the given {@link RedisScript}, using the provided {@link RedisSerializer}s to serialize the script @@ -153,9 +152,8 @@ public interface RedisOperations { * @return The return value of the script or null if {@link RedisScript#getResultType()} is null, likely indicating a * throw-away status reply (i.e. "OK") */ - @Nullable - T execute(RedisScript script, RedisSerializer argsSerializer, RedisSerializer resultSerializer, - List keys, Object... args); + T execute(@NonNull RedisScript script, @NonNull RedisSerializer argsSerializer, + @NonNull RedisSerializer resultSerializer, @NonNull List<@NonNull K> keys, @NonNull Object @NonNull... args); /** * Allocates and binds a new {@link RedisConnection} to the actual return type of the method. It is up to the caller @@ -165,8 +163,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return the {@link Object result} of the operation performed in the callback or {@literal null}. * @since 1.8 */ - @Nullable - T executeWithStickyConnection(RedisCallback callback); + T executeWithStickyConnection(@NonNull RedisCallback callback); // ------------------------------------------------------------------------- // Methods dealing with Redis Keys @@ -182,8 +179,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @see Redis Documentation: COPY * @since 2.6 */ - @Nullable - Boolean copy(K sourceKey, K targetKey, boolean replace); + Boolean copy(@NonNull K sourceKey, @NonNull K targetKey, boolean replace); /** * Determine if given {@code key} exists. @@ -192,8 +188,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal true} if key exists. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: EXISTS */ - @Nullable - Boolean hasKey(K key); + Boolean hasKey(@NonNull K key); /** * Count the number of {@code keys} that exist. @@ -204,8 +199,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @see Redis Documentation: EXISTS * @since 2.1 */ - @Nullable - Long countExistingKeys(Collection keys); + Long countExistingKeys(@NonNull Collection<@NonNull K> keys); /** * Delete given {@code key}. @@ -214,8 +208,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal true} if the key was removed. * @see Redis Documentation: DEL */ - @Nullable - Boolean delete(K key); + Boolean delete(@NonNull K key); /** * Delete given {@code keys}. @@ -224,8 +217,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return The number of keys that were removed. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DEL */ - @Nullable - Long delete(Collection keys); + Long delete(@NonNull Collection<@NonNull K> keys); /** * Unlink the {@code key} from the keyspace. Unlike with {@link #delete(Object)} the actual memory reclaiming here @@ -236,8 +228,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @see Redis Documentation: UNLINK * @since 2.1 */ - @Nullable - Boolean unlink(K key); + Boolean unlink(@NonNull K key); /** * Unlink the {@code keys} from the keyspace. Unlike with {@link #delete(Collection)} the actual memory reclaiming @@ -248,8 +239,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @see Redis Documentation: UNLINK * @since 2.1 */ - @Nullable - Long unlink(Collection keys); + Long unlink(@NonNull Collection<@NonNull K> keys); /** * Determine the type stored at {@code key}. @@ -258,8 +248,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: TYPE */ - @Nullable - DataType type(K key); + DataType type(@NonNull K key); /** * Find all keys matching the given {@code pattern}. @@ -268,8 +257,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: KEYS */ - @Nullable - Set keys(K pattern); + Set<@NonNull K> keys(@NonNull K pattern); /** * Use a {@link Cursor} to iterate over keys.
@@ -281,7 +269,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @since 2.7 * @see Redis Documentation: SCAN */ - Cursor scan(ScanOptions options); + Cursor<@NonNull K> scan(@NonNull ScanOptions options); /** * Return a random key from the keyspace. @@ -289,7 +277,6 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal null} no keys exist or when used in pipeline / transaction. * @see Redis Documentation: RANDOMKEY */ - @Nullable K randomKey(); /** @@ -299,7 +286,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @param newKey must not be {@literal null}. * @see Redis Documentation: RENAME */ - void rename(K oldKey, K newKey); + void rename(@NonNull K oldKey, @NonNull K newKey); /** * Rename key {@code oldKey} to {@code newKey} only if {@code newKey} does not exist. @@ -309,8 +296,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: RENAMENX */ - @Nullable - Boolean renameIfAbsent(K oldKey, K newKey); + Boolean renameIfAbsent(@NonNull K oldKey, @NonNull K newKey); /** * Set time to live for given {@code key}. @@ -320,8 +306,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @param unit must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean expire(K key, long timeout, TimeUnit unit); + Boolean expire(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Set time to live for given {@code key}. @@ -332,8 +317,7 @@ T execute(RedisScript script, RedisSerializer argsSerializer, RedisSer * @throws IllegalArgumentException if the timeout is {@literal null}. * @since 2.3 */ - @Nullable - default Boolean expire(K key, Duration timeout) { + default Boolean expire(@NonNull K key, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -348,8 +332,7 @@ default Boolean expire(K key, Duration timeout) { * @param date must not be {@literal null}. * @return {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean expireAt(K key, Date date); + Boolean expireAt(@NonNull K key, @NonNull Date date); /** * Set the expiration for given {@code key} as a {@literal date} timestamp. @@ -360,8 +343,7 @@ default Boolean expire(K key, Duration timeout) { * @throws IllegalArgumentException if the instant is {@literal null} or too large to represent as a {@code Date}. * @since 2.3 */ - @Nullable - default Boolean expireAt(K key, Instant expireAt) { + default Boolean expireAt(@NonNull K key, @NonNull Instant expireAt) { Assert.notNull(expireAt, "Timestamp must not be null"); @@ -383,8 +365,8 @@ default Boolean expireAt(K key, Instant expireAt) { * @see Redis Documentation: PERSIST * @since 3.5 */ - @Nullable - ExpireChanges.ExpiryChangeState expire(K key, Expiration expiration, ExpirationOptions options); + ExpireChanges.ExpiryChangeState expire(@NonNull K key, @NonNull Expiration expiration, + @NonNull ExpirationOptions options); /** * Returns a bound operations object to perform expiration operations on the bound key. @@ -392,7 +374,7 @@ default Boolean expireAt(K key, Instant expireAt) { * @return the bound operations object to perform operations on the hash field expiration. * @since 3.5 */ - default BoundKeyExpirationOperations expiration(K key) { + default @NonNull BoundKeyExpirationOperations expiration(@NonNull K key) { return new DefaultBoundKeyExpirationOperations<>(this, key); } @@ -403,8 +385,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @return {@code true} when persisted successfully or {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PERSIST */ - @Nullable - Boolean persist(K key); + Boolean persist(@NonNull K key); /** * Get the time to live for {@code key} in seconds. @@ -413,8 +394,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: TTL */ - @Nullable - Long getExpire(K key); + Long getExpire(@NonNull K key); /** * Get the time to live for {@code key} in and convert it to the given {@link TimeUnit}. @@ -424,8 +404,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @return {@literal null} when used in pipeline / transaction. * @since 1.8 */ - @Nullable - Long getExpire(K key, TimeUnit timeUnit); + Long getExpire(@NonNull K key, @NonNull TimeUnit timeUnit); /** * Move given {@code key} to database with {@code index}. @@ -435,8 +414,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MOVE */ - @Nullable - Boolean move(K key, int dbIndex); + Boolean move(@NonNull K key, int dbIndex); /** * Retrieve serialized version of the value stored at {@code key}. @@ -445,8 +423,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: DUMP */ - @Nullable - byte[] dump(K key); + byte[] dump(@NonNull K key); /** * Create {@code key} using the {@code serializedValue}, previously obtained using {@link #dump(Object)}. @@ -457,7 +434,7 @@ default BoundKeyExpirationOperations expiration(K key) { * @param unit must not be {@literal null}. * @see Redis Documentation: RESTORE */ - default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { + default void restore(@NonNull K key, byte @NonNull [] value, long timeToLive, @NonNull TimeUnit unit) { restore(key, value, timeToLive, unit, false); } @@ -472,7 +449,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @since 2.1 * @see Redis Documentation: RESTORE */ - void restore(K key, byte[] value, long timeToLive, TimeUnit unit, boolean replace); + void restore(@NonNull K key, byte @NonNull [] value, long timeToLive, @NonNull TimeUnit unit, boolean replace); /** * Sort the elements for {@code query}. @@ -481,8 +458,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return the results of sort. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - List sort(SortQuery query); + List sort(@NonNull SortQuery<@NonNull K> query); /** * Sort the elements for {@code query} applying {@link RedisSerializer}. @@ -491,8 +467,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return the deserialized results of sort. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - List sort(SortQuery query, RedisSerializer resultSerializer); + List sort(@NonNull SortQuery<@NonNull K> query, @NonNull RedisSerializer resultSerializer); /** * Sort the elements for {@code query} applying {@link BulkMapper}. @@ -501,8 +476,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return the deserialized results of sort. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - List sort(SortQuery query, BulkMapper bulkMapper); + List sort(@NonNull SortQuery<@NonNull K> query, @NonNull BulkMapper bulkMapper); /** * Sort the elements for {@code query} applying {@link BulkMapper} and {@link RedisSerializer}. @@ -511,8 +485,8 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return the deserialized results of sort. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - List sort(SortQuery query, BulkMapper bulkMapper, RedisSerializer resultSerializer); + List sort(SortQuery<@NonNull K> query, @NonNull BulkMapper bulkMapper, + @NonNull RedisSerializer resultSerializer); /** * Sort the elements for {@code query} and store result in {@code storeKey}. @@ -522,8 +496,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return number of values. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SORT */ - @Nullable - Long sort(SortQuery query, K storeKey); + Long sort(@NonNull SortQuery<@NonNull K> query, @NonNull K storeKey); // ------------------------------------------------------------------------- // Methods dealing with Redis Transactions @@ -535,7 +508,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key must not be {@literal null}. * @see Redis Documentation: WATCH */ - void watch(K key); + void watch(@NonNull K key); /** * Watch given {@code keys} for modifications during transaction started with {@link #multi()}. @@ -543,7 +516,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param keys must not be {@literal null}. * @see Redis Documentation: WATCH */ - void watch(Collection keys); + void watch(@NonNull Collection<@NonNull K> keys); /** * Flushes all the previously {@link #watch(Object)} keys. @@ -585,7 +558,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param valueSerializer The {@link RedisSerializer} to use for deserializing the results of transaction exec * @return The deserialized results of transaction exec */ - List exec(RedisSerializer valueSerializer); + List exec(@NonNull RedisSerializer valueSerializer); // ------------------------------------------------------------------------- // Methods dealing with Redis Server Commands @@ -597,8 +570,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return {@link List} of {@link RedisClientInfo} objects. * @since 1.3 */ - @Nullable - List getClientList(); + List<@NonNull RedisClientInfo> getClientList(); /** * Closes a given client connection identified by {@literal ip:port} given in {@code client}. @@ -607,7 +579,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param port of connection to close * @since 1.3 */ - void killClient(String host, int port); + void killClient(@NonNull String host, int port); /** * Change redis replication setting to new master. @@ -617,7 +589,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @since 1.3 * @see Redis Documentation: REPLICAOF */ - void replicaOf(String host, int port); + void replicaOf(@NonNull String host, int port); /** * Change server into master. @@ -635,8 +607,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return the number of clients that received the message. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: PUBLISH */ - @Nullable - Long convertAndSend(String destination, Object message); + Long convertAndSend(@NonNull String destination, @NonNull Object message); // ------------------------------------------------------------------------- // Methods to obtain specific operations interface objects. @@ -650,6 +621,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return never {@literal null}. * @since 1.7 */ + @NonNull ClusterOperations opsForCluster(); /** @@ -658,6 +630,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return never {@literal null}. * @since 1.8 */ + @NonNull GeoOperations opsForGeo(); /** @@ -667,7 +640,8 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return never {@literal null}. * @since 1.8 */ - BoundGeoOperations boundGeoOps(K key); + @NonNull + BoundGeoOperations boundGeoOps(@NonNull K key); /** * Returns the operations performed on hash values. @@ -676,7 +650,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param hash value type * @return hash operations */ - HashOperations opsForHash(); + @NonNull HashOperations opsForHash(); /** * Returns the operations performed on hash values bound to the given key. @@ -686,12 +660,13 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key Redis key * @return hash operations bound to the given key. */ - BoundHashOperations boundHashOps(K key); + @NonNull BoundHashOperations boundHashOps(@NonNull K key); /** * @return never {@literal null}. * @since 1.5 */ + @NonNull HyperLogLogOperations opsForHyperLogLog(); /** @@ -699,6 +674,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * * @return list operations */ + @NonNull ListOperations opsForList(); /** @@ -707,6 +683,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key Redis key * @return list operations bound to the given key */ + @NonNull BoundListOperations boundListOps(K key); /** @@ -714,6 +691,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * * @return set operations */ + @NonNull SetOperations opsForSet(); /** @@ -722,7 +700,8 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key Redis key * @return set operations bound to the given key */ - BoundSetOperations boundSetOps(K key); + @NonNull + BoundSetOperations boundSetOps(@NonNull K key); /** * Returns the operations performed on Streams. @@ -730,7 +709,7 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return stream operations. * @since 2.2 */ - StreamOperations opsForStream(); + @NonNull StreamOperations opsForStream(); /** * Returns the operations performed on Streams. @@ -739,7 +718,8 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return stream operations. * @since 2.2 */ - StreamOperations opsForStream(HashMapper hashMapper); + @NonNull StreamOperations opsForStream( + @NonNull HashMapper hashMapper); /** * Returns the operations performed on Streams bound to the given key. @@ -747,13 +727,14 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @return stream operations. * @since 2.2 */ - BoundStreamOperations boundStreamOps(K key); + @NonNull BoundStreamOperations boundStreamOps(@NonNull K key); /** * Returns the operations performed on simple values (or Strings in Redis terminology). * * @return value operations */ + @NonNull ValueOperations opsForValue(); /** @@ -762,13 +743,15 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key Redis key * @return value operations bound to the given key */ - BoundValueOperations boundValueOps(K key); + @NonNull + BoundValueOperations boundValueOps(@NonNull K key); /** * Returns the operations performed on zset values (also known as sorted sets). * * @return zset operations */ + @NonNull ZSetOperations opsForZSet(); /** @@ -777,26 +760,31 @@ default void restore(K key, byte[] value, long timeToLive, TimeUnit unit) { * @param key Redis key * @return zset operations bound to the given key. */ - BoundZSetOperations boundZSetOps(K key); + @NonNull + BoundZSetOperations boundZSetOps(@NonNull K key); /** * @return the key {@link RedisSerializer}. */ + @NonNull RedisSerializer getKeySerializer(); /** * @return the value {@link RedisSerializer}. */ + @NonNull RedisSerializer getValueSerializer(); /** * @return the hash key {@link RedisSerializer}. */ + @NonNull RedisSerializer getHashKeySerializer(); /** * @return the hash value {@link RedisSerializer}. */ + @NonNull RedisSerializer getHashValueSerializer(); } diff --git a/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java b/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java index 070e04d4ac..6453fe139e 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java +++ b/src/main/java/org/springframework/data/redis/core/RedisQueryEngine.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.data.geo.Circle; import org.springframework.data.geo.GeoResult; @@ -48,7 +49,6 @@ import org.springframework.data.redis.repository.query.RedisOperationChain.PathAndValue; import org.springframework.data.redis.util.ByteUtils; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; /** @@ -82,7 +82,7 @@ private RedisQueryEngine(CriteriaAccessor criteriaAccessor, @Override @SuppressWarnings("unchecked") - public List execute(RedisOperationChain criteria, Comparator sort, long offset, int rows, String keyspace, + public List execute(@Nullable RedisOperationChain criteria, @Nullable Comparator sort, long offset, int rows, String keyspace, Class type) { List result = doFind(criteria, offset, rows, keyspace, type); @@ -93,7 +93,8 @@ public List execute(RedisOperationChain criteria, Comparator sort, lon return result; } - private List doFind(RedisOperationChain criteria, long offset, int rows, String keyspace, Class type) { + @SuppressWarnings("NullAway") + private List doFind(@Nullable RedisOperationChain criteria, long offset, int rows, String keyspace, Class type) { if (criteria == null || (CollectionUtils.isEmpty(criteria.getOrSismember()) && CollectionUtils.isEmpty(criteria.getSismember())) @@ -146,6 +147,7 @@ private List doFind(RedisOperationChain criteria, long offset, int rows, return result; } + @SuppressWarnings("NullAway") private List findKeys(RedisOperationChain criteria, int rows, String keyspace, Class domainType, RedisConnection connection) { @@ -200,12 +202,13 @@ private List findKeys(RedisOperationChain criteria, int rows, String key } @Override - public List execute(RedisOperationChain criteria, Comparator sort, long offset, int rows, String keyspace) { + public List execute(@Nullable RedisOperationChain criteria, @Nullable Comparator sort, long offset, int rows, String keyspace) { return execute(criteria, sort, offset, rows, keyspace, Object.class); } @Override - public long count(RedisOperationChain criteria, String keyspace) { + @SuppressWarnings("NullAway") + public long count(@Nullable RedisOperationChain criteria, String keyspace) { if (criteria == null || criteria.isEmpty()) { return this.getRequiredAdapter().count(keyspace); @@ -227,6 +230,7 @@ public long count(RedisOperationChain criteria, String keyspace) { }); } + @SuppressWarnings("NullAway") private byte[][] keys(String prefix, Collection source) { ConversionService conversionService = getRequiredAdapter().getConverter().getConversionService(); @@ -243,6 +247,7 @@ private byte[][] keys(String prefix, Collection source) { return keys; } + @SuppressWarnings("NullAway") private byte[] geoKey(String prefix, NearPath source) { String path = GeoIndexedPropertyValue.geoIndexName(source.getPath()); @@ -257,7 +262,7 @@ private byte[] geoKey(String prefix, NearPath source) { static class RedisCriteriaAccessor implements CriteriaAccessor { @Override - public RedisOperationChain resolve(KeyValueQuery query) { + public @Nullable RedisOperationChain resolve(KeyValueQuery query) { return (RedisOperationChain) query.getCriteria(); } } diff --git a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java index c80f555ee0..411e34f1cb 100644 --- a/src/main/java/org/springframework/data/redis/core/RedisTemplate.java +++ b/src/main/java/org/springframework/data/redis/core/RedisTemplate.java @@ -29,6 +29,9 @@ import java.util.function.Consumer; import java.util.function.Function; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.RedisSystemException; @@ -55,7 +58,6 @@ import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationUtils; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -94,6 +96,7 @@ * @param the Redis value type against which the template works * @see StringRedisTemplate */ +@NullUnmarked public class RedisTemplate extends RedisAccessor implements RedisOperations, BeanClassLoaderAware { private boolean enableTransactionSupport = false; @@ -233,7 +236,7 @@ public void setEnableTransactionSupport(boolean enableTransactionSupport) { * @since 1.8 */ @Override - public void setBeanClassLoader(ClassLoader classLoader) { + public void setBeanClassLoader(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; } @@ -242,8 +245,7 @@ public void setBeanClassLoader(ClassLoader classLoader) { * * @return template default serializer. */ - @Nullable - public RedisSerializer getDefaultSerializer() { + public @Nullable RedisSerializer getDefaultSerializer() { return defaultSerializer; } @@ -254,7 +256,7 @@ public RedisSerializer getDefaultSerializer() { * * @param serializer default serializer to use. */ - public void setDefaultSerializer(RedisSerializer serializer) { + public void setDefaultSerializer(@Nullable RedisSerializer serializer) { this.defaultSerializer = serializer; } @@ -362,8 +364,7 @@ public void setScriptExecutor(ScriptExecutor scriptExecutor) { } @Override - @Nullable - public T execute(RedisCallback action) { + public @Nullable T execute(@NonNull RedisCallback action) { return execute(action, isExposeConnection()); } @@ -375,8 +376,7 @@ public T execute(RedisCallback action) { * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code * @return object returned by the action */ - @Nullable - public T execute(RedisCallback action, boolean exposeConnection) { + public @Nullable T execute(@NonNull RedisCallback action, boolean exposeConnection) { return execute(action, exposeConnection, false); } @@ -390,8 +390,7 @@ public T execute(RedisCallback action, boolean exposeConnection) { * @param pipeline whether to pipeline or not the connection for the execution * @return object returned by the action */ - @Nullable - public T execute(RedisCallback action, boolean exposeConnection, boolean pipeline) { + public @Nullable T execute(@NonNull RedisCallback action, boolean exposeConnection, boolean pipeline) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(action, "Callback object must not be null"); @@ -424,7 +423,7 @@ public T execute(RedisCallback action, boolean exposeConnection, boolean } @Override - public T execute(SessionCallback session) { + public T execute(@NonNull SessionCallback session) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(session, "Callback object must not be null"); @@ -440,12 +439,13 @@ public T execute(SessionCallback session) { } @Override - public List executePipelined(SessionCallback session) { + public List executePipelined(@NonNull SessionCallback session) { return executePipelined(session, valueSerializer); } @Override - public List executePipelined(SessionCallback session, @Nullable RedisSerializer resultSerializer) { + public List executePipelined(@NonNull SessionCallback session, + @Nullable RedisSerializer resultSerializer) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(session, "Callback object must not be null"); @@ -478,12 +478,13 @@ public List executePipelined(SessionCallback session, @Nullable Redis } @Override - public List executePipelined(RedisCallback action) { + public List executePipelined(@NonNull RedisCallback action) { return executePipelined(action, valueSerializer); } @Override - public List executePipelined(RedisCallback action, @Nullable RedisSerializer resultSerializer) { + public List executePipelined(@NonNull RedisCallback action, + @Nullable RedisSerializer resultSerializer) { return execute((RedisCallback>) connection -> { connection.openPipeline(); @@ -506,18 +507,19 @@ public List executePipelined(RedisCallback action, @Nullable RedisSer } @Override - public T execute(RedisScript script, List keys, Object... args) { + public T execute(@NonNull RedisScript script, @NonNull List<@NonNull K> keys, + @NonNull Object @NonNull... args) { return scriptExecutor.execute(script, keys, args); } @Override - public T execute(RedisScript script, RedisSerializer argsSerializer, RedisSerializer resultSerializer, - List keys, Object... args) { + public T execute(@NonNull RedisScript script, @NonNull RedisSerializer argsSerializer, + @NonNull RedisSerializer resultSerializer, @NonNull List<@NonNull K> keys, @NonNull Object @NonNull... args) { return scriptExecutor.execute(script, argsSerializer, resultSerializer, keys, args); } @Override - public T executeWithStickyConnection(RedisCallback callback) { + public T executeWithStickyConnection(@NonNull RedisCallback callback) { Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it"); Assert.notNull(callback, "Callback object must not be null"); @@ -552,8 +554,7 @@ protected RedisConnection preProcessConnection(RedisConnection connection, boole return connection; } - @Nullable - protected T postProcessResult(@Nullable T result, RedisConnection conn, boolean existingConnection) { + protected @Nullable T postProcessResult(@Nullable T result, RedisConnection conn, boolean existingConnection) { return result; } @@ -713,9 +714,8 @@ public Boolean expireAt(K key, final Date date) { }); } - @Nullable @Override - public ExpireChanges.ExpiryChangeState expire(K key, Expiration expiration, ExpirationOptions options) { + public ExpireChanges.@Nullable ExpiryChangeState expire(K key, Expiration expiration, ExpirationOptions options) { byte[] rawKey = rawKey(key); Boolean raw = doWithKeys(connection -> connection.applyExpiration(rawKey, expiration, options)); @@ -797,8 +797,7 @@ public void restore(K key, byte[] value, long timeToLive, TimeUnit unit, boolean }); } - @Nullable - private T doWithKeys(Function action) { + private @Nullable T doWithKeys(Function action) { return execute((RedisCallback) connection -> action.apply(connection.keyCommands()), true); } @@ -1117,8 +1116,7 @@ private K deserializeKey(byte[] value) { } @SuppressWarnings({ "unchecked", "rawtypes" }) - @Nullable - private List deserializeMixedResults(@Nullable List rawValues, + private @Nullable List deserializeMixedResults(@Nullable List rawValues, @Nullable RedisSerializer valueSerializer, @Nullable RedisSerializer hashKeySerializer, @Nullable RedisSerializer hashValueSerializer) { diff --git a/src/main/java/org/springframework/data/redis/core/ScanCursor.java b/src/main/java/org/springframework/data/redis/core/ScanCursor.java index 354e0cfcc9..965422e9a6 100644 --- a/src/main/java/org/springframework/data/redis/core/ScanCursor.java +++ b/src/main/java/org/springframework/data/redis/core/ScanCursor.java @@ -19,8 +19,9 @@ import java.util.Iterator; import java.util.NoSuchElementException; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; /** @@ -37,7 +38,7 @@ * @param * @since 1.4 */ -public abstract class ScanCursor implements Cursor { +public abstract class ScanCursor implements Cursor<@NonNull T> { private CursorState state; private CursorId id; diff --git a/src/main/java/org/springframework/data/redis/core/ScanIteration.java b/src/main/java/org/springframework/data/redis/core/ScanIteration.java index 3e0b5a5929..fc4947853d 100644 --- a/src/main/java/org/springframework/data/redis/core/ScanIteration.java +++ b/src/main/java/org/springframework/data/redis/core/ScanIteration.java @@ -22,7 +22,7 @@ import java.util.Collections; import java.util.Iterator; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * {@link ScanIteration} holds the values contained in Redis {@literal Multibulk reply} on exectuting {@literal SCAN} diff --git a/src/main/java/org/springframework/data/redis/core/ScanOptions.java b/src/main/java/org/springframework/data/redis/core/ScanOptions.java index b7520703f6..8a1cdaf53a 100644 --- a/src/main/java/org/springframework/data/redis/core/ScanOptions.java +++ b/src/main/java/org/springframework/data/redis/core/ScanOptions.java @@ -17,8 +17,8 @@ import java.util.StringJoiner; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -40,9 +40,9 @@ public class ScanOptions { private final @Nullable Long count; private final @Nullable String pattern; - private final @Nullable byte[] bytePattern; + private final byte @Nullable[] bytePattern; - ScanOptions(@Nullable Long count, @Nullable String pattern, @Nullable byte[] bytePattern) { + ScanOptions(@Nullable Long count, @Nullable String pattern, byte @Nullable[] bytePattern) { this.count = count; this.pattern = pattern; @@ -58,13 +58,11 @@ public static ScanOptionsBuilder scanOptions() { return new ScanOptionsBuilder(); } - @Nullable - public Long getCount() { + public @Nullable Long getCount() { return count; } - @Nullable - public String getPattern() { + public @Nullable String getPattern() { if (bytePattern != null && pattern == null) { return new String(bytePattern); @@ -73,8 +71,8 @@ public String getPattern() { return pattern; } - @Nullable - public byte[] getBytePattern() { + + public byte @Nullable[] getBytePattern() { if (bytePattern == null && pattern != null) { return pattern.getBytes(); @@ -112,7 +110,7 @@ public static class ScanOptionsBuilder { @Nullable Long count; @Nullable String pattern; - @Nullable byte[] bytePattern; + byte @Nullable[] bytePattern; @Nullable DataType type; ScanOptionsBuilder() {} diff --git a/src/main/java/org/springframework/data/redis/core/SessionCallback.java b/src/main/java/org/springframework/data/redis/core/SessionCallback.java index 42a53a068f..f119238c30 100644 --- a/src/main/java/org/springframework/data/redis/core/SessionCallback.java +++ b/src/main/java/org/springframework/data/redis/core/SessionCallback.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.core; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; -import org.springframework.lang.Nullable; /** * Callback executing all operations against a surrogate 'session' (basically against the same underlying Redis diff --git a/src/main/java/org/springframework/data/redis/core/SetOperations.java b/src/main/java/org/springframework/data/redis/core/SetOperations.java index b1eddb91da..9361a12472 100644 --- a/src/main/java/org/springframework/data/redis/core/SetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/SetOperations.java @@ -20,7 +20,8 @@ import java.util.Map; import java.util.Set; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; /** * Redis set specific operations. @@ -30,6 +31,7 @@ * @author Mark Paluch * @author Roman Bezpalko */ +@NullUnmarked public interface SetOperations { /** @@ -40,8 +42,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SADD */ - @Nullable - Long add(K key, V... values); + Long add(@NonNull K key, V@NonNull ... values); /** * Remove given {@code values} from set at {@code key} and return the number of removed elements. @@ -51,8 +52,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SREM */ - @Nullable - Long remove(K key, Object... values); + Long remove(@NonNull K key, Object@NonNull ... values); /** * Remove and return a random member from set at {@code key}. @@ -61,8 +61,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SPOP */ - @Nullable - V pop(K key); + V pop(@NonNull K key); /** * Remove and return {@code count} random members from set at {@code key}. @@ -73,8 +72,7 @@ public interface SetOperations { * @see Redis Documentation: SPOP * @since 2.0 */ - @Nullable - List pop(K key, long count); + List<@NonNull V> pop(@NonNull K key, long count); /** * Move {@code value} from {@code key} to {@code destKey} @@ -85,8 +83,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMOVE */ - @Nullable - Boolean move(K key, V value, K destKey); + Boolean move(@NonNull K key, V value, @NonNull K destKey); /** * Get size of set at {@code key}. @@ -95,8 +92,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SCARD */ - @Nullable - Long size(K key); + Long size(@NonNull K key); /** * Check if set at {@code key} contains {@code value}. @@ -106,8 +102,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SISMEMBER */ - @Nullable - Boolean isMember(K key, Object o); + Boolean isMember(@NonNull K key, Object o); /** * Check if set at {@code key} contains one or more {@code values}. @@ -118,8 +113,7 @@ public interface SetOperations { * @since 2.6 * @see Redis Documentation: SMISMEMBER */ - @Nullable - Map isMember(K key, Object... objects); + Map isMember(@NonNull K key, Object@NonNull ... objects); /** * Returns the members intersecting all given sets at {@code key} and {@code otherKey}. @@ -129,8 +123,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTER */ - @Nullable - Set intersect(K key, K otherKey); + Set<@NonNull V> intersect(@NonNull K key, @NonNull K otherKey); /** * Returns the members intersecting all given sets at {@code key} and {@code otherKeys}. @@ -140,8 +133,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTER */ - @Nullable - Set intersect(K key, Collection otherKeys); + Set<@NonNull V> intersect(@NonNull K key, @NonNull Collection otherKeys); /** * Returns the members intersecting all given sets at {@code keys}. @@ -151,8 +143,7 @@ public interface SetOperations { * @see Redis Documentation: SINTER * @since 2.2 */ - @Nullable - Set intersect(Collection keys); + Set<@NonNull V> intersect(@NonNull Collection keys); /** * Intersect all given sets at {@code key} and {@code otherKey} and store result in {@code destKey}. @@ -163,8 +154,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTERSTORE */ - @Nullable - Long intersectAndStore(K key, K otherKey, K destKey); + Long intersectAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Intersect all given sets at {@code key} and {@code otherKeys} and store result in {@code destKey}. @@ -175,8 +165,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SINTERSTORE */ - @Nullable - Long intersectAndStore(K key, Collection otherKeys, K destKey); + Long intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect all given sets at {@code keys} and store result in {@code destKey}. @@ -187,8 +176,7 @@ public interface SetOperations { * @see Redis Documentation: SINTERSTORE * @since 2.2 */ - @Nullable - Long intersectAndStore(Collection keys, K destKey); + Long intersectAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey); /** * Union all sets at given {@code keys} and {@code otherKey}. @@ -198,8 +186,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNION */ - @Nullable - Set union(K key, K otherKey); + Set<@NonNull V> union(@NonNull K key, @NonNull K otherKey); /** * Union all sets at given {@code keys} and {@code otherKeys}. @@ -209,8 +196,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNION */ - @Nullable - Set union(K key, Collection otherKeys); + Set<@NonNull V> union(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Union all sets at given {@code keys}. @@ -220,8 +206,7 @@ public interface SetOperations { * @see Redis Documentation: SUNION * @since 2.2 */ - @Nullable - Set union(Collection keys); + Set<@NonNull V> union(@NonNull Collection<@NonNull K> keys); /** * Union all sets at given {@code key} and {@code otherKey} and store result in {@code destKey}. @@ -232,8 +217,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNIONSTORE */ - @Nullable - Long unionAndStore(K key, K otherKey, K destKey); + Long unionAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Union all sets at given {@code key} and {@code otherKeys} and store result in {@code destKey}. @@ -244,8 +228,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SUNIONSTORE */ - @Nullable - Long unionAndStore(K key, Collection otherKeys, K destKey); + Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Union all sets at given {@code keys} and store result in {@code destKey}. @@ -256,8 +239,7 @@ public interface SetOperations { * @see Redis Documentation: SUNIONSTORE * @since 2.2 */ - @Nullable - Long unionAndStore(Collection keys, K destKey); + Long unionAndStore(@NonNull Collection<@NonNull K> keys, @NonNull K destKey); /** * Diff all sets for given {@code key} and {@code otherKey}. @@ -267,8 +249,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFF */ - @Nullable - Set difference(K key, K otherKey); + Set<@NonNull V> difference(@NonNull K key, @NonNull K otherKey); /** * Diff all sets for given {@code key} and {@code otherKeys}. @@ -278,8 +259,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFF */ - @Nullable - Set difference(K key, Collection otherKeys); + Set<@NonNull V> difference(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Diff all sets for given {@code keys}. @@ -289,8 +269,7 @@ public interface SetOperations { * @see Redis Documentation: SDIFF * @since 2.2 */ - @Nullable - Set difference(Collection keys); + Set<@NonNull V> difference(@NonNull Collection<@NonNull K> keys); /** * Diff all sets for given {@code key} and {@code otherKey} and store result in {@code destKey}. @@ -301,8 +280,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFFSTORE */ - @Nullable - Long differenceAndStore(K key, K otherKey, K destKey); + Long differenceAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Diff all sets for given {@code key} and {@code otherKeys} and store result in {@code destKey}. @@ -313,8 +291,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SDIFFSTORE */ - @Nullable - Long differenceAndStore(K key, Collection otherKeys, K destKey); + Long differenceAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Diff all sets for given {@code keys} and store result in {@code destKey}. @@ -325,8 +302,7 @@ public interface SetOperations { * @see Redis Documentation: SDIFFSTORE * @since 2.2 */ - @Nullable - Long differenceAndStore(Collection keys, K destKey); + Long differenceAndStore(@NonNull Collection<@NonNull K> keys,@NonNull K destKey); /** * Get all elements of set at {@code key}. @@ -335,8 +311,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SMEMBERS */ - @Nullable - Set members(K key); + Set<@NonNull V> members(@NonNull K key); /** * Get random element from set at {@code key}. @@ -345,7 +320,7 @@ public interface SetOperations { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SRANDMEMBER */ - V randomMember(K key); + V randomMember(@NonNull K key); /** * Get {@code count} distinct random elements from set at {@code key}. @@ -356,8 +331,7 @@ public interface SetOperations { * @throws IllegalArgumentException if count is negative. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - Set distinctRandomMembers(K key, long count); + Set<@NonNull V> distinctRandomMembers(@NonNull K key, long count); /** * Get {@code count} random elements from set at {@code key}. @@ -368,8 +342,7 @@ public interface SetOperations { * @throws IllegalArgumentException if count is negative. * @see Redis Documentation: SRANDMEMBER */ - @Nullable - List randomMembers(K key, long count); + List<@NonNull V> randomMembers(@NonNull K key, long count); /** * Use a {@link Cursor} to iterate over entries set at {@code key}.
@@ -381,7 +354,8 @@ public interface SetOperations { * try-with-resources clause). * @since 1.4 */ - Cursor scan(K key, ScanOptions options); + Cursor<@NonNull V> scan(@NonNull K key, @NonNull ScanOptions options); + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/StreamObjectMapper.java b/src/main/java/org/springframework/data/redis/core/StreamObjectMapper.java index 4b72930993..4664fce005 100644 --- a/src/main/java/org/springframework/data/redis/core/StreamObjectMapper.java +++ b/src/main/java/org/springframework/data/redis/core/StreamObjectMapper.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.redis.connection.stream.MapRecord; @@ -30,7 +31,6 @@ import org.springframework.data.redis.core.convert.RedisCustomConversions; import org.springframework.data.redis.hash.HashMapper; import org.springframework.data.redis.hash.ObjectHashMapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -65,7 +65,7 @@ class StreamObjectMapper { * * @param mapper the configured {@link HashMapper}. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes", "NullAway" }) StreamObjectMapper(HashMapper mapper) { Assert.notNull(mapper, "HashMapper must not be null"); @@ -103,7 +103,7 @@ public Object fromHash(Map hash) { * @param source the source value. * @return the converted {@link MapRecord}. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes", "NullAway" }) static MapRecord toMapRecord(HashMapperProvider provider, Record source) { if (source instanceof ObjectRecord entry) { diff --git a/src/main/java/org/springframework/data/redis/core/StreamOperations.java b/src/main/java/org/springframework/data/redis/core/StreamOperations.java index 59a0647f29..bcfb811934 100644 --- a/src/main/java/org/springframework/data/redis/core/StreamOperations.java +++ b/src/main/java/org/springframework/data/redis/core/StreamOperations.java @@ -22,10 +22,12 @@ import java.util.List; import java.util.Map; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; -import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.RedisStreamCommands.XAddOptions; +import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; import org.springframework.data.redis.connection.stream.ByteRecord; import org.springframework.data.redis.connection.stream.Consumer; import org.springframework.data.redis.connection.stream.MapRecord; @@ -43,7 +45,6 @@ import org.springframework.data.redis.connection.stream.StreamReadOptions; import org.springframework.data.redis.connection.stream.StreamRecords; import org.springframework.data.redis.hash.HashMapper; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -57,6 +58,7 @@ * @author jinkshower * @since 2.2 */ +@NullUnmarked public interface StreamOperations extends HashMapperProvider { /** @@ -68,8 +70,7 @@ public interface StreamOperations extends HashMapperProvider * @return length of acknowledged records. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - @Nullable - Long acknowledge(K key, String group, String... recordIds); + Long acknowledge(@NonNull K key, @NonNull String group, @NonNull String @NonNull... recordIds); /** * Acknowledge one or more records as processed. @@ -80,8 +81,7 @@ public interface StreamOperations extends HashMapperProvider * @return length of acknowledged records. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - @Nullable - default Long acknowledge(K key, String group, RecordId... recordIds) { + default Long acknowledge(@NonNull K key, @NonNull String group, @NonNull RecordId @NonNull... recordIds) { return acknowledge(key, group, Arrays.stream(recordIds).map(RecordId::getValue).toArray(String[]::new)); } @@ -93,7 +93,7 @@ default Long acknowledge(K key, String group, RecordId... recordIds) { * @return length of acknowledged records. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XACK */ - default Long acknowledge(String group, Record record) { + default Long acknowledge(@NonNull String group, @NonNull Record<@NonNull K, ?> record) { return acknowledge(record.getRequiredStream(), group, record.getId()); } @@ -107,9 +107,8 @@ default Long acknowledge(String group, Record record) { * @see Redis Documentation: XADD * @since 3.4 */ - @SuppressWarnings("unchecked") - @Nullable - default RecordId add(K key, Map content, XAddOptions xAddOptions) { + default RecordId add(@NonNull K key, @NonNull Map content, + @NonNull XAddOptions xAddOptions) { return add(StreamRecords.newRecord().in(key).ofMap(content), xAddOptions); } @@ -123,14 +122,13 @@ default RecordId add(K key, Map content, XAddOptions * @since 3.4 */ @SuppressWarnings("unchecked") - @Nullable - default RecordId add(MapRecord record, XAddOptions xAddOptions) { + default RecordId add(@NonNull MapRecord record, @NonNull XAddOptions xAddOptions) { return add((Record) record, xAddOptions); } /** - * Append the record, backed by the given value, to the stream with the specified options. - * The value will be hashed and serialized. + * Append the record, backed by the given value, to the stream with the specified options. The value will be hashed + * and serialized. * * @param record must not be {@literal null}. * @param xAddOptions parameters for the {@literal XADD} call. Must not be {@literal null}. @@ -141,8 +139,7 @@ default RecordId add(MapRecord record, XAddOption * @since 3.4 */ @SuppressWarnings("unchecked") - @Nullable - RecordId add(Record record, XAddOptions xAddOptions); + RecordId add(@NonNull Record record, @NonNull XAddOptions xAddOptions); /** * Append a record to the stream {@code key}. @@ -153,8 +150,7 @@ default RecordId add(MapRecord record, XAddOption * @see Redis Documentation: XADD */ @SuppressWarnings("unchecked") - @Nullable - default RecordId add(K key, Map content) { + default RecordId add(@NonNull K key, @NonNull Map content) { return add(StreamRecords.newRecord().in(key).ofMap(content)); } @@ -165,9 +161,8 @@ default RecordId add(K key, Map content) { * @return the record Id. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XADD */ - @Nullable @SuppressWarnings("unchecked") - default RecordId add(MapRecord record) { + default RecordId add(@NonNull MapRecord record) { return add((Record) record); } @@ -180,17 +175,14 @@ default RecordId add(MapRecord record) { * @see ObjectRecord */ @SuppressWarnings("unchecked") - @Nullable - RecordId add(Record record); + RecordId add(@NonNull Record record); /** - * Changes the ownership of a pending message so that the new owner is the consumer specified as - * the command argument. - * + * Changes the ownership of a pending message so that the new owner is the consumer specified as the command argument. * The message is claimed only if its idle time (ms) is greater than the given {@link Duration minimum idle time} * specified when calling {@literal XCLAIM}. * - * @param key {@link K key} to the steam. + * @param key {@link @NonNull K key} to the steam. * @param consumerGroup {@link String name} of the consumer group. * @param newOwner {@link String name} of the consumer claiming the message. * @param minIdleTime {@link Duration minimum idle time} required for a message to be claimed. @@ -201,20 +193,18 @@ default RecordId add(MapRecord record) { * @see org.springframework.data.redis.connection.stream.RecordId * @see #claim(Object, String, String, XClaimOptions) */ - default List> claim(K key, String consumerGroup, String newOwner, Duration minIdleTime, - RecordId... recordIds) { + default List<@NonNull MapRecord> claim(@NonNull K key, @NonNull String consumerGroup, + @NonNull String newOwner, @NonNull Duration minIdleTime, @NonNull RecordId @NonNull... recordIds) { return claim(key, consumerGroup, newOwner, XClaimOptions.minIdle(minIdleTime).ids(recordIds)); } /** - * Changes the ownership of a pending message so that the new owner is the consumer specified as - * the command argument. - * + * Changes the ownership of a pending message so that the new owner is the consumer specified as the command argument. * The message is claimed only if its idle time (ms) is greater than the given {@link Duration minimum idle time} * specified when calling {@literal XCLAIM}. * - * @param key {@link K key} to the steam. + * @param key {@link @NonNull K key} to the steam. * @param consumerGroup {@link String name} of the consumer group. * @param newOwner {@link String name} of the consumer claiming the message. * @param xClaimOptions additional parameters for the {@literal CLAIM} call. @@ -223,7 +213,8 @@ default List> claim(K key, String consumerGroup, String new * @see org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions * @see org.springframework.data.redis.connection.stream.MapRecord */ - List> claim(K key, String consumerGroup, String newOwner, XClaimOptions xClaimOptions); + List<@NonNull MapRecord> claim(@NonNull K key, @NonNull String consumerGroup, @NonNull String newOwner, + @NonNull XClaimOptions xClaimOptions); /** * Removes the specified records from the stream. Returns the number of records deleted, that may be different from @@ -234,8 +225,7 @@ default List> claim(K key, String consumerGroup, String new * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XDEL */ - @Nullable - default Long delete(K key, String... recordIds) { + default Long delete(@NonNull K key, @NonNull String @NonNull... recordIds) { return delete(key, Arrays.stream(recordIds).map(RecordId::of).toArray(RecordId[]::new)); } @@ -245,8 +235,7 @@ default Long delete(K key, String... recordIds) { * @param record must not be {@literal null}. * @return he {@link Mono} emitting the number of removed records. */ - @Nullable - default Long delete(Record record) { + default Long delete(@NonNull Record record) { return delete(record.getStream(), record.getId()); } @@ -259,8 +248,7 @@ default Long delete(Record record) { * @return the {@link Mono} emitting the number of removed records. * @see Redis Documentation: XDEL */ - @Nullable - Long delete(K key, RecordId... recordIds); + Long delete(@NonNull K key, @NonNull RecordId @NonNull... recordIds); /** * Create a consumer group at the {@link ReadOffset#latest() latest offset}. This command creates the stream if it @@ -270,7 +258,7 @@ default Long delete(Record record) { * @param group name of the consumer group. * @return {@literal OK} if successful. {@literal null} when used in pipeline / transaction. */ - default String createGroup(K key, String group) { + default String createGroup(@NonNull K key, @NonNull String group) { return createGroup(key, ReadOffset.latest(), group); } @@ -282,8 +270,7 @@ default String createGroup(K key, String group) { * @param group name of the consumer group. * @return {@literal OK} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - String createGroup(K key, ReadOffset readOffset, String group); + String createGroup(@NonNull K key, @NonNull ReadOffset readOffset, @NonNull String group); /** * Delete a consumer from a consumer group. @@ -292,8 +279,7 @@ default String createGroup(K key, String group) { * @param consumer consumer identified by group name and consumer key. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean deleteConsumer(K key, Consumer consumer); + Boolean deleteConsumer(@NonNull K key, @NonNull Consumer consumer); /** * Destroy a consumer group. @@ -302,8 +288,7 @@ default String createGroup(K key, String group) { * @param group name of the consumer group. * @return {@literal true} if successful. {@literal null} when used in pipeline / transaction. */ - @Nullable - Boolean destroyGroup(K key, String group); + Boolean destroyGroup(@NonNull K key, @NonNull String group); /** * Obtain information about every consumer in a specific {@literal consumer group} for the stream stored at the @@ -314,7 +299,7 @@ default String createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - XInfoConsumers consumers(K key, String group); + XInfoConsumers consumers(@NonNull K key, @NonNull String group); /** * Obtain information about {@literal consumer groups} associated with the stream stored at the specified @@ -324,7 +309,7 @@ default String createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - XInfoGroups groups(K key); + XInfoGroups groups(@NonNull K key); /** * Obtain general information about the stream stored at the specified {@literal key}. @@ -333,7 +318,7 @@ default String createGroup(K key, String group) { * @return {@literal null} when used in pipeline / transaction. * @since 2.3 */ - XInfoStream info(K key); + XInfoStream info(@NonNull K key); /** * Obtain the {@link PendingMessagesSummary} for a given {@literal consumer group}. @@ -345,8 +330,7 @@ default String createGroup(K key, String group) { * @see Redis Documentation: xpending * @since 2.3 */ - @Nullable - PendingMessagesSummary pending(K key, String group); + PendingMessagesSummary pending(@NonNull K key, @NonNull String group); /** * Obtained detailed information about all pending messages for a given {@link Consumer}. @@ -357,7 +341,7 @@ default String createGroup(K key, String group) { * @see Redis Documentation: xpending * @since 2.3 */ - default PendingMessages pending(K key, Consumer consumer) { + default PendingMessages pending(@NonNull K key, @NonNull Consumer consumer) { return pending(key, consumer, Range.unbounded(), -1L); } @@ -374,7 +358,7 @@ default PendingMessages pending(K key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - PendingMessages pending(K key, String group, Range range, long count); + PendingMessages pending(@NonNull K key, @NonNull String group, @NonNull Range range, long count); /** * Obtain detailed information about pending {@link PendingMessage messages} for a given {@link Range} and @@ -388,7 +372,7 @@ default PendingMessages pending(K key, Consumer consumer) { * @see Redis Documentation: xpending * @since 2.3 */ - PendingMessages pending(K key, Consumer consumer, Range range, long count); + PendingMessages pending(@NonNull K key, @NonNull Consumer consumer, @NonNull Range range, long count); /** * Get the length of a stream. @@ -397,8 +381,7 @@ default PendingMessages pending(K key, Consumer consumer) { * @return length of the stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XLEN */ - @Nullable - Long size(K key); + Long size(@NonNull K key); /** * Read records from a stream within a specific {@link Range}. @@ -408,8 +391,7 @@ default PendingMessages pending(K key, Consumer consumer) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - default List> range(K key, Range range) { + default List> range(@NonNull K key, @NonNull Range range) { return range(key, range, Limit.unlimited()); } @@ -422,8 +404,7 @@ default List> range(K key, Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - @Nullable - List> range(K key, Range range, Limit limit); + List> range(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Read all records from a stream within a specific {@link Range} as {@link ObjectRecord}. @@ -434,7 +415,8 @@ default List> range(K key, Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XRANGE */ - default List> range(Class targetType, K key, Range range) { + default List<@NonNull ObjectRecord> range(@NonNull Class targetType, @NonNull K key, + @NonNull Range range) { return range(targetType, key, range, Limit.unlimited()); } @@ -448,7 +430,8 @@ default List> range(Class targetType, K key, RangeRedis Documentation: XRANGE */ - default List> range(Class targetType, K key, Range range, Limit limit) { + default List<@NonNull ObjectRecord> range(@NonNull Class targetType, @NonNull K key, + @NonNull Range range, @NonNull Limit limit) { Assert.notNull(targetType, "Target type must not be null"); @@ -462,8 +445,7 @@ default List> range(Class targetType, K key, RangeRedis Documentation: XREAD */ - @Nullable - default List> read(StreamOffset... streams) { + default List<@NonNull MapRecord> read(StreamOffset<@NonNull K> @NonNull... streams) { return read(StreamReadOptions.empty(), streams); } @@ -475,7 +457,8 @@ default List> read(StreamOffset... streams) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - default List> read(Class targetType, StreamOffset... streams) { + default List<@NonNull ObjectRecord> read(@NonNull Class targetType, + StreamOffset<@NonNull K> @NonNull... streams) { return read(targetType, StreamReadOptions.empty(), streams); } @@ -487,8 +470,8 @@ default List> read(Class targetType, StreamOffset.. * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - List> read(StreamReadOptions readOptions, StreamOffset... streams); + List<@NonNull MapRecord> read(@NonNull StreamReadOptions readOptions, + StreamOffset<@NonNull K> @NonNull... streams); /** * Read records from one or more {@link StreamOffset}s as {@link ObjectRecord}. @@ -499,9 +482,8 @@ default List> read(Class targetType, StreamOffset.. * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREAD */ - @Nullable - default List> read(Class targetType, StreamReadOptions readOptions, - StreamOffset... streams) { + default List<@NonNull ObjectRecord> read(@NonNull Class targetType, + @NonNull StreamReadOptions readOptions, StreamOffset<@NonNull K> @NonNull... streams) { Assert.notNull(targetType, "Target type must not be null"); @@ -516,8 +498,8 @@ default List> read(Class targetType, StreamReadOptions * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - default List> read(Consumer consumer, StreamOffset... streams) { + default List<@NonNull MapRecord> read(@NonNull Consumer consumer, + StreamOffset<@NonNull K> @NonNull... streams) { return read(consumer, StreamReadOptions.empty(), streams); } @@ -530,8 +512,8 @@ default List> read(Consumer consumer, StreamOffset... st * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - default List> read(Class targetType, Consumer consumer, StreamOffset... streams) { + default List> read(@NonNull Class targetType, @NonNull Consumer consumer, + StreamOffset<@NonNull K> @NonNull... streams) { return read(targetType, consumer, StreamReadOptions.empty(), streams); } @@ -544,8 +526,8 @@ default List> read(Class targetType, Consumer consumer * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - List> read(Consumer consumer, StreamReadOptions readOptions, StreamOffset... streams); + List<@NonNull MapRecord> read(@NonNull Consumer consumer, @NonNull StreamReadOptions readOptions, + StreamOffset<@NonNull K> @NonNull... streams); /** * Read records from one or more {@link StreamOffset}s using a consumer group as {@link ObjectRecord}. @@ -557,9 +539,8 @@ default List> read(Class targetType, Consumer consumer * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREADGROUP */ - @Nullable - default List> read(Class targetType, Consumer consumer, StreamReadOptions readOptions, - StreamOffset... streams) { + default List> read(@NonNull Class targetType, @NonNull Consumer consumer, + @NonNull StreamReadOptions readOptions, StreamOffset<@NonNull K> @NonNull... streams) { Assert.notNull(targetType, "Target type must not be null"); @@ -574,8 +555,7 @@ default List> read(Class targetType, Consumer consumer * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - default List> reverseRange(K key, Range range) { + default List<@NonNull MapRecord> reverseRange(@NonNull K key, @NonNull Range range) { return reverseRange(key, range, Limit.unlimited()); } @@ -588,8 +568,7 @@ default List> reverseRange(K key, Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - @Nullable - List> reverseRange(K key, Range range, Limit limit); + List<@NonNull MapRecord> reverseRange(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Read records from a stream within a specific {@link Range} in reverse order as {@link ObjectRecord}. @@ -600,7 +579,8 @@ default List> reverseRange(K key, Range range) { * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - default List> reverseRange(Class targetType, K key, Range range) { + default List<@NonNull ObjectRecord> reverseRange(@NonNull Class targetType, @NonNull K key, + @NonNull Range range) { return reverseRange(targetType, key, range, Limit.unlimited()); } @@ -615,7 +595,8 @@ default List> reverseRange(Class targetType, K key, Ra * @return list with members of the resulting stream. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XREVRANGE */ - default List> reverseRange(Class targetType, K key, Range range, Limit limit) { + default List<@NonNull ObjectRecord> reverseRange(@NonNull Class targetType, @NonNull K key, + @NonNull Range range, @NonNull Limit limit) { Assert.notNull(targetType, "Target type must not be null"); @@ -630,8 +611,7 @@ default List> reverseRange(Class targetType, K key, Ra * @return number of removed entries. {@literal null} when used in pipeline / transaction. * @see Redis Documentation: XTRIM */ - @Nullable - Long trim(K key, long count); + Long trim(@NonNull K key, long count); /** * Trims the stream to {@code count} elements. @@ -643,8 +623,7 @@ default List> reverseRange(Class targetType, K key, Ra * @since 2.4 * @see Redis Documentation: XTRIM */ - @Nullable - Long trim(K key, long count, boolean approximateTrimming); + Long trim(@NonNull K key, long count, boolean approximateTrimming); /** * Get the {@link HashMapper} for a specific type. @@ -654,7 +633,7 @@ default List> reverseRange(Class targetType, K key, Ra * @return the {@link HashMapper} suitable for a given type; */ @Override - HashMapper getHashMapper(Class targetType); + @NonNull HashMapper getHashMapper(@NonNull Class targetType); /** * Map record from {@link MapRecord} to {@link ObjectRecord}. @@ -664,7 +643,7 @@ default List> reverseRange(Class targetType, K key, Ra * @return the mapped {@link ObjectRecord}. * @since 2.x */ - default ObjectRecord map(MapRecord record, Class targetType) { + default ObjectRecord map(@NonNull MapRecord record, @NonNull Class targetType) { Assert.notNull(record, "Record must not be null"); Assert.notNull(targetType, "Target type must not be null"); @@ -680,8 +659,8 @@ default ObjectRecord map(MapRecord record, Class targetT * @return the mapped {@link ObjectRecord object records}. * @since 2.x */ - @Nullable - default List> map(@Nullable List> records, Class targetType) { + default List<@NonNull ObjectRecord> map(@NonNull List<@NonNull MapRecord> records, + @NonNull Class targetType) { Assert.notNull(records, "Records must not be null"); Assert.notNull(targetType, "Target type must not be null"); @@ -696,5 +675,6 @@ default List> map(@Nullable List> re * @return deserialized {@link MapRecord}. * @since 2.x */ + @NonNull MapRecord deserializeRecord(ByteRecord record); } diff --git a/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java b/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java index 54ecf92735..05486edd8a 100644 --- a/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java +++ b/src/main/java/org/springframework/data/redis/core/TimeToLiveAccessor.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.core; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * {@link TimeToLiveAccessor} extracts the objects time to live used for {@code EXPIRE}. diff --git a/src/main/java/org/springframework/data/redis/core/ValueOperations.java b/src/main/java/org/springframework/data/redis/core/ValueOperations.java index 84ce00f385..b83abbcf2b 100644 --- a/src/main/java/org/springframework/data/redis/core/ValueOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ValueOperations.java @@ -21,8 +21,9 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.connection.BitFieldSubCommands; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -34,6 +35,7 @@ * @author Jiahe Cai * @author Marcin Grzejszczak */ +@NullUnmarked public interface ValueOperations { /** @@ -43,7 +45,7 @@ public interface ValueOperations { * @param value must not be {@literal null}. * @see Redis Documentation: SET */ - void set(K key, V value); + void set(@NonNull K key, @NonNull V value); /** * Set the {@code value} and expiration {@code timeout} for {@code key}. Return the old string stored at key, or @@ -58,7 +60,7 @@ public interface ValueOperations { * @see Redis Documentation: SET * @since 3.5 */ - V setGet(K key, V value, long timeout, TimeUnit unit); + V setGet(@NonNull K key, @NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set the {@code value} and expiration {@code timeout} for {@code key}. Return the old string stored at key, or @@ -72,7 +74,7 @@ public interface ValueOperations { * @see Redis Documentation: SET * @since 3.5 */ - V setGet(K key, V value, Duration duration); + V setGet(@NonNull K key, @NonNull V value, @NonNull Duration duration); /** * Set the {@code value} and expiration {@code timeout} for {@code key}. @@ -83,7 +85,7 @@ public interface ValueOperations { * @param unit must not be {@literal null}. * @see Redis Documentation: SETEX */ - void set(K key, V value, long timeout, TimeUnit unit); + void set(@NonNull K key, @NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set the {@code value} and expiration {@code timeout} for {@code key}. @@ -95,7 +97,7 @@ public interface ValueOperations { * @see Redis Documentation: SET * @since 2.1 */ - default void set(K key, V value, Duration timeout) { + default void set(@NonNull K key, @NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -114,8 +116,7 @@ default void set(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: SET */ - @Nullable - Boolean setIfAbsent(K key, V value); + Boolean setIfAbsent(@NonNull K key, @NonNull V value); /** * Set {@code key} to hold the string {@code value} and expiration {@code timeout} if {@code key} is absent. @@ -128,8 +129,7 @@ default void set(K key, V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: SET */ - @Nullable - Boolean setIfAbsent(K key, V value, long timeout, TimeUnit unit); + Boolean setIfAbsent(@NonNull K key, @NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set {@code key} to hold the string {@code value} and expiration {@code timeout} if {@code key} is absent. @@ -142,8 +142,7 @@ default void set(K key, V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - default Boolean setIfAbsent(K key, V value, Duration timeout) { + default Boolean setIfAbsent(@NonNull K key, @NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -164,8 +163,7 @@ default Boolean setIfAbsent(K key, V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - Boolean setIfPresent(K key, V value); + Boolean setIfPresent(@NonNull K key, @NonNull V value); /** * Set {@code key} to hold the string {@code value} and expiration {@code timeout} if {@code key} is present. @@ -179,8 +177,7 @@ default Boolean setIfAbsent(K key, V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - Boolean setIfPresent(K key, V value, long timeout, TimeUnit unit); + Boolean setIfPresent(@NonNull K key, @NonNull V value, long timeout, @NonNull TimeUnit unit); /** * Set {@code key} to hold the string {@code value} and expiration {@code timeout} if {@code key} is present. @@ -193,8 +190,7 @@ default Boolean setIfAbsent(K key, V value, Duration timeout) { * @see Redis Documentation: SET * @since 2.1 */ - @Nullable - default Boolean setIfPresent(K key, V value, Duration timeout) { + default Boolean setIfPresent(@NonNull K key, @NonNull V value, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); @@ -211,7 +207,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @param map must not be {@literal null}. * @see Redis Documentation: MSET */ - void multiSet(Map map); + void multiSet(Map map); /** * Set multiple keys to multiple values using key-value pairs provided in {@code tuple} only if the provided key does @@ -221,8 +217,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MSETNX */ - @Nullable - Boolean multiSetIfAbsent(Map map); + Boolean multiSetIfAbsent(Map map); /** * Get the value of {@code key}. @@ -231,7 +226,6 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: GET */ - @Nullable V get(Object key); /** @@ -242,8 +236,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @see Redis Documentation: GETDEL * @since 2.6 */ - @Nullable - V getAndDelete(K key); + V getAndDelete(@NonNull K key); /** * Return the value at {@code key} and expire the key by applying {@code timeout}. @@ -255,8 +248,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - V getAndExpire(K key, long timeout, TimeUnit unit); + V getAndExpire(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Return the value at {@code key} and expire the key by applying {@code timeout}. @@ -267,8 +259,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - V getAndExpire(K key, Duration timeout); + V getAndExpire(@NonNull K key, @NonNull Duration timeout); /** * Return the value at {@code key} and persist the key. This operation removes any TTL that is associated with @@ -279,8 +270,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @see Redis Documentation: GETEX * @since 2.6 */ - @Nullable - V getAndPersist(K key); + V getAndPersist(@NonNull K key); /** * Set {@code value} of {@code key} and return its old value. @@ -289,8 +279,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when key does not exist or used in pipeline / transaction. * @see Redis Documentation: GETSET */ - @Nullable - V getAndSet(K key, V value); + V getAndSet(@NonNull K key, @NonNull V value); /** * Get multiple {@code keys}. Values are in the order of the requested keys Absent field values are represented using @@ -300,8 +289,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: MGET */ - @Nullable - List multiGet(Collection keys); + List multiGet(@NonNull Collection<@NonNull K> keys); /** * Increment an integer value stored as string value under {@code key} by one. @@ -311,8 +299,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: INCR */ - @Nullable - Long increment(K key); + Long increment(@NonNull K key); /** * Increment an integer value stored as string value under {@code key} by {@code delta}. @@ -322,8 +309,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBY */ - @Nullable - Long increment(K key, long delta); + Long increment(@NonNull K key, long delta); /** * Increment a floating point number value stored as string value under {@code key} by {@code delta}. @@ -333,8 +319,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: INCRBYFLOAT */ - @Nullable - Double increment(K key, double delta); + Double increment(@NonNull K key, double delta); /** * Decrement an integer value stored as string value under {@code key} by one. @@ -344,8 +329,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: DECR */ - @Nullable - Long decrement(K key); + Long decrement(@NonNull K key); /** * Decrement an integer value stored as string value under {@code key} by {@code delta}. @@ -356,8 +340,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: DECRBY */ - @Nullable - Long decrement(K key, long delta); + Long decrement(@NonNull K key, long delta); /** * Append a {@code value} to {@code key}. @@ -367,8 +350,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: APPEND */ - @Nullable - Integer append(K key, String value); + Integer append(@NonNull K key, @NonNull String value); /** * Get a substring of value of {@code key} between {@code begin} and {@code end}. @@ -379,8 +361,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: GETRANGE */ - @Nullable - String get(K key, long start, long end); + String get(@NonNull K key, long start, long end); /** * Overwrite parts of {@code key} starting at the specified {@code offset} with given {@code value}. @@ -390,7 +371,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @param offset * @see Redis Documentation: SETRANGE */ - void set(K key, V value, long offset); + void set(@NonNull K key, @NonNull V value, long offset); /** * Get the length of the value stored at {@code key}. @@ -399,8 +380,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: STRLEN */ - @Nullable - Long size(K key); + Long size(@NonNull K key); /** * Sets the bit at {@code offset} in value stored at {@code key}. @@ -412,8 +392,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 1.5 * @see Redis Documentation: SETBIT */ - @Nullable - Boolean setBit(K key, long offset, boolean value); + Boolean setBit(@NonNull K key, long offset, boolean value); /** * Get the bit value at {@code offset} of value at {@code key}. @@ -424,8 +403,7 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 1.5 * @see Redis Documentation: GETBIT */ - @Nullable - Boolean getBit(K key, long offset); + Boolean getBit(@NonNull K key, long offset); /** * Get / Manipulate specific integer fields of varying bit widths and arbitrary non (necessary) aligned offset stored @@ -437,8 +415,8 @@ default Boolean setIfPresent(K key, V value, Duration timeout) { * @since 2.1 * @see Redis Documentation: BITFIELD */ - @Nullable - List bitField(K key, BitFieldSubCommands subCommands); + List bitField(@NonNull K key, @NonNull BitFieldSubCommands subCommands); + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/ZSetOperations.java b/src/main/java/org/springframework/data/redis/core/ZSetOperations.java index 263346fe5f..1132c933f2 100644 --- a/src/main/java/org/springframework/data/redis/core/ZSetOperations.java +++ b/src/main/java/org/springframework/data/redis/core/ZSetOperations.java @@ -22,12 +22,15 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.Limit; import org.springframework.data.redis.connection.zset.Aggregate; import org.springframework.data.redis.connection.zset.Tuple; import org.springframework.data.redis.connection.zset.Weights; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -41,12 +44,14 @@ * @author Andrey Shlykov * @author Shyngys Sapraliyev */ +@NullUnmarked public interface ZSetOperations { /** * Typed ZSet tuple. */ - interface TypedTuple extends Comparable> { + @NullMarked + interface TypedTuple extends Comparable> { @Nullable V getValue(); @@ -63,7 +68,7 @@ interface TypedTuple extends Comparable> { * @return new instance of {@link TypedTuple}. * @since 2.5 */ - static TypedTuple of(V value, @Nullable Double score) { + static TypedTuple of(@NonNull V value, @Nullable Double score) { return new DefaultTypedTuple<>(value, score); } } @@ -77,8 +82,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - Boolean add(K key, V value, double score); + Boolean add(@NonNull K key, @NonNull V value, double score); /** * Add {@code value} to a sorted set at {@code key} if it does not already exists. @@ -90,8 +94,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.5 * @see Redis Documentation: ZADD NX */ - @Nullable - Boolean addIfAbsent(K key, V value, double score); + Boolean addIfAbsent(@NonNull K key, @NonNull V value, double score); /** * Add {@code tuples} to a sorted set at {@code key}, or update its {@code score} if it already exists. @@ -101,8 +104,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZADD */ - @Nullable - Long add(K key, Set> tuples); + Long add(@NonNull K key, @NonNull Set<@NonNull TypedTuple> tuples); /** * Add {@code tuples} to a sorted set at {@code key} if it does not already exists. @@ -113,8 +115,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.5 * @see Redis Documentation: ZADD NX */ - @Nullable - Long addIfAbsent(K key, Set> tuples); + Long addIfAbsent(@NonNull K key, @NonNull Set<@NonNull TypedTuple> tuples); /** * Remove {@code values} from sorted set. Return number of removed elements. @@ -124,8 +125,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREM */ - @Nullable - Long remove(K key, Object... values); + Long remove(@NonNull K key, @NonNull Object @NonNull... values); /** * Increment the score of element with {@code value} in sorted set by {@code increment}. @@ -136,8 +136,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINCRBY */ - @Nullable - Double incrementScore(K key, V value, double delta); + Double incrementScore(@NonNull K key, @NonNull V value, double delta); /** * Get random element from set at {@code key}. @@ -147,7 +146,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - V randomMember(K key); + V randomMember(@NonNull K key); /** * Get {@code count} distinct random elements from set at {@code key}. @@ -159,8 +158,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - Set distinctRandomMembers(K key, long count); + Set distinctRandomMembers(@NonNull K key, long count); /** * Get {@code count} random elements from set at {@code key}. @@ -172,8 +170,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List randomMembers(K key, long count); + List randomMembers(@NonNull K key, long count); /** * Get random element with its score from set at {@code key}. @@ -183,7 +180,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - TypedTuple randomMemberWithScore(K key); + TypedTuple randomMemberWithScore(@NonNull K key); /** * Get {@code count} distinct random elements with their score from set at {@code key}. @@ -195,8 +192,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - Set> distinctRandomMembersWithScore(K key, long count); + Set<@NonNull TypedTuple> distinctRandomMembersWithScore(@NonNull K key, long count); /** * Get {@code count} random elements with their score from set at {@code key}. @@ -208,8 +204,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @since 2.6 * @see Redis Documentation: ZRANDMEMBER */ - @Nullable - List> randomMembersWithScore(K key, long count); + List> randomMembersWithScore(@NonNull K key, long count); /** * Determine the index of element with {@code value} in a sorted set. @@ -219,8 +214,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANK */ - @Nullable - Long rank(K key, Object o); + Long rank(@NonNull K key, @NonNull Object o); /** * Determine the index of element with {@code value} in a sorted set when scored high to low. @@ -230,8 +224,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANK */ - @Nullable - Long reverseRank(K key, Object o); + Long reverseRank(@NonNull K key, @NonNull Object o); /** * Get elements between {@code start} and {@code end} from sorted set. @@ -242,8 +235,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGE */ - @Nullable - Set range(K key, long start, long end); + Set range(@NonNull K key, long start, long end); /** * Get set of {@link Tuple}s between {@code start} and {@code end} from sorted set. @@ -254,8 +246,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGE */ - @Nullable - Set> rangeWithScores(K key, long start, long end); + Set<@NonNull TypedTuple> rangeWithScores(@NonNull K key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set. @@ -266,8 +257,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set rangeByScore(K key, double min, double max); + Set rangeByScore(@NonNull K key, double min, double max); /** * Get set of {@link Tuple}s where score is between {@code min} and {@code max} from sorted set. @@ -278,8 +268,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set> rangeByScoreWithScores(K key, double min, double max); + Set<@NonNull TypedTuple> rangeByScoreWithScores(@NonNull K key, double min, double max); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -293,8 +282,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set rangeByScore(K key, double min, double max, long offset, long count); + Set rangeByScore(@NonNull K key, double min, double max, long offset, long count); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} where score is between {@code min} and @@ -308,8 +296,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZRANGEBYSCORE */ - @Nullable - Set> rangeByScoreWithScores(K key, double min, double max, long offset, long count); + Set<@NonNull TypedTuple> rangeByScoreWithScores(@NonNull K key, double min, double max, long offset, long count); /** * Get elements in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -320,8 +307,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - Set reverseRange(K key, long start, long end); + Set reverseRange(@NonNull K key, long start, long end); /** * Get set of {@link Tuple}s in range from {@code start} to {@code end} from sorted set ordered from high to low. @@ -332,8 +318,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGE */ - @Nullable - Set> reverseRangeWithScores(K key, long start, long end); + Set<@NonNull TypedTuple> reverseRangeWithScores(@NonNull K key, long start, long end); /** * Get elements where score is between {@code min} and {@code max} from sorted set ordered from high to low. @@ -344,8 +329,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set reverseRangeByScore(K key, double min, double max); + Set reverseRangeByScore(@NonNull K key, double min, double max); /** * Get set of {@link Tuple} where score is between {@code min} and {@code max} from sorted set ordered from high to @@ -357,8 +341,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set> reverseRangeByScoreWithScores(K key, double min, double max); + Set<@NonNull TypedTuple> reverseRangeByScoreWithScores(@NonNull K key, double min, double max); /** * Get elements in range from {@code start} to {@code end} where score is between {@code min} and {@code max} from @@ -372,8 +355,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set reverseRangeByScore(K key, double min, double max, long offset, long count); + Set reverseRangeByScore(@NonNull K key, double min, double max, long offset, long count); /** * Get set of {@link Tuple} in range from {@code start} to {@code end} where score is between {@code min} and @@ -387,8 +369,8 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREVRANGEBYSCORE */ - @Nullable - Set> reverseRangeByScoreWithScores(K key, double min, double max, long offset, long count); + Set<@NonNull TypedTuple> reverseRangeByScoreWithScores(@NonNull K key, double min, double max, long offset, + long count); /** * Count number of elements within sorted set with scores between {@code min} and {@code max}. @@ -399,8 +381,7 @@ static TypedTuple of(V value, @Nullable Double score) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCOUNT */ - @Nullable - Long count(K key, double min, double max); + Long count(@NonNull K key, double min, double max); /** * Count number of elements within sorted set with value between {@link Range#getLowerBound()} and @@ -413,9 +394,9 @@ static TypedTuple of(V value, @Nullable Double score) { * @see Redis Documentation: ZLEXCOUNT * @deprecated since 3.0. Please use #lexCount(Range) instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Long lexCount(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return lexCount(key, range.toRange()); } @@ -429,8 +410,7 @@ default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSet * @since 3.0 * @see Redis Documentation: ZLEXCOUNT */ - @Nullable - Long lexCount(K key, Range range); + Long lexCount(@NonNull K key, @NonNull Range range); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}. @@ -440,8 +420,7 @@ default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSet * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - TypedTuple popMin(K key); + TypedTuple popMin(@NonNull K key); /** * Remove and return {@code count} values with their score having the lowest score from sorted set at {@code key}. @@ -452,8 +431,7 @@ default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSet * @see Redis Documentation: ZPOPMIN * @since 2.6 */ - @Nullable - Set> popMin(K key, long count); + Set<@NonNull TypedTuple> popMin(@NonNull K key, long count); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}.
@@ -466,8 +444,7 @@ default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSet * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - TypedTuple popMin(K key, long timeout, TimeUnit unit); + TypedTuple popMin(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the lowest score from sorted set at {@code key}.
@@ -480,8 +457,7 @@ default Long lexCount(K key, org.springframework.data.redis.connection.RedisZSet * @see Redis Documentation: BZPOPMIN * @since 2.6 */ - @Nullable - default TypedTuple popMin(K key, Duration timeout) { + default TypedTuple<@NonNull V> popMin(@NonNull K key, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -497,8 +473,7 @@ default TypedTuple popMin(K key, Duration timeout) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - TypedTuple popMax(K key); + TypedTuple popMax(@NonNull K key); /** * Remove and return {@code count} values with their score having the highest score from sorted set at {@code key}. @@ -509,8 +484,7 @@ default TypedTuple popMin(K key, Duration timeout) { * @see Redis Documentation: ZPOPMAX * @since 2.6 */ - @Nullable - Set> popMax(K key, long count); + Set> popMax(@NonNull K key, long count); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}.
@@ -523,8 +497,7 @@ default TypedTuple popMin(K key, Duration timeout) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - TypedTuple popMax(K key, long timeout, TimeUnit unit); + TypedTuple popMax(@NonNull K key, long timeout, @NonNull TimeUnit unit); /** * Remove and return the value with its score having the highest score from sorted set at {@code key}.
@@ -537,8 +510,7 @@ default TypedTuple popMin(K key, Duration timeout) { * @see Redis Documentation: BZPOPMAX * @since 2.6 */ - @Nullable - default TypedTuple popMax(K key, Duration timeout) { + default TypedTuple popMax(@NonNull K key, @NonNull Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -554,8 +526,7 @@ default TypedTuple popMax(K key, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZCARD */ - @Nullable - Long size(K key); + Long size(@NonNull K key); /** * Get the size of sorted set with {@code key}. @@ -565,8 +536,7 @@ default TypedTuple popMax(K key, Duration timeout) { * @since 1.3 * @see Redis Documentation: ZCARD */ - @Nullable - Long zCard(K key); + Long zCard(@NonNull K key); /** * Get the score of element with {@code value} from sorted set with key {@code key}. @@ -576,8 +546,7 @@ default TypedTuple popMax(K key, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZSCORE */ - @Nullable - Double score(K key, Object o); + Double score(@NonNull K key, Object o); /** * Get the scores of elements with {@code values} from sorted set with key {@code key}. @@ -588,8 +557,7 @@ default TypedTuple popMax(K key, Duration timeout) { * @see Redis Documentation: ZMSCORE * @since 2.6 */ - @Nullable - List score(K key, Object... o); + List score(@NonNull K key, Object... o); /** * Remove elements in range between {@code start} and {@code end} from sorted set with {@code key}. @@ -600,8 +568,7 @@ default TypedTuple popMax(K key, Duration timeout) { * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYRANK */ - @Nullable - Long removeRange(K key, long start, long end); + Long removeRange(@NonNull K key, long start, long end); /** * Remove elements in {@link Range} from sorted set with {@literal key}. @@ -613,9 +580,9 @@ default TypedTuple popMax(K key, Duration timeout) { * @see Redis Documentation: ZREMRANGEBYLEX * @deprecated since 3.0. Please use {@link #removeRangeByLex(Object, Range)} instead; */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Long removeRangeByLex(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Long removeRangeByLex(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return removeRangeByLex(key, range.toRange()); } @@ -628,8 +595,7 @@ default Long removeRangeByLex(K key, org.springframework.data.redis.connection.R * @since 3.0 * @see Redis Documentation: ZREMRANGEBYLEX */ - @Nullable - Long removeRangeByLex(K key, Range range); + Long removeRangeByLex(@NonNull K key, @NonNull Range range); /** * Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}. @@ -640,8 +606,7 @@ default Long removeRangeByLex(K key, org.springframework.data.redis.connection.R * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZREMRANGEBYSCORE */ - @Nullable - Long removeRangeByScore(K key, double min, double max); + Long removeRangeByScore(@NonNull K key, double min, double max); /** * Diff sorted {@code sets}. @@ -652,8 +617,7 @@ default Long removeRangeByLex(K key, org.springframework.data.redis.connection.R * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - default Set difference(K key, K otherKey) { + default Set difference(@NonNull K key, @NonNull K otherKey) { return difference(key, Collections.singleton(otherKey)); } @@ -666,8 +630,7 @@ default Set difference(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set difference(K key, Collection otherKeys); + Set difference(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets}. @@ -678,8 +641,7 @@ default Set difference(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - default Set> differenceWithScores(K key, K otherKey) { + default Set<@NonNull TypedTuple> differenceWithScores(@NonNull K key, @NonNull K otherKey) { return differenceWithScores(key, Collections.singleton(otherKey)); } @@ -692,8 +654,7 @@ default Set> differenceWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFF */ - @Nullable - Set> differenceWithScores(K key, Collection otherKeys); + Set<@NonNull TypedTuple> differenceWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Diff sorted {@code sets} and store result in destination {@code destKey}. @@ -705,8 +666,7 @@ default Set> differenceWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZDIFFSTORE */ - @Nullable - Long differenceAndStore(K key, Collection otherKeys, K destKey); + Long differenceAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted {@code sets}. @@ -717,8 +677,7 @@ default Set> differenceWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set intersect(K key, K otherKey) { + default Set intersect(@NonNull K key, @NonNull K otherKey) { return intersect(key, Collections.singleton(otherKey)); } @@ -731,8 +690,7 @@ default Set intersect(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set intersect(K key, Collection otherKeys); + Set intersect(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted {@code sets}. @@ -743,8 +701,7 @@ default Set intersect(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set> intersectWithScores(K key, K otherKey) { + default Set<@NonNull TypedTuple> intersectWithScores(@NonNull K key, @NonNull K otherKey) { return intersectWithScores(key, Collections.singleton(otherKey)); } @@ -757,8 +714,7 @@ default Set> intersectWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set> intersectWithScores(K key, Collection otherKeys); + Set<@NonNull TypedTuple> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Intersect sorted sets at {@code key} and {@code otherKeys} . @@ -770,8 +726,8 @@ default Set> intersectWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - default Set> intersectWithScores(K key, Collection otherKeys, Aggregate aggregate) { + default Set> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate) { return intersectWithScores(key, otherKeys, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -786,8 +742,8 @@ default Set> intersectWithScores(K key, Collection otherKeys, A * @since 2.6 * @see Redis Documentation: ZINTER */ - @Nullable - Set> intersectWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights); + Set<@NonNull TypedTuple> intersectWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Intersect sorted sets at {@code key} and {@code otherKey} and store result in destination {@code destKey}. @@ -798,8 +754,7 @@ default Set> intersectWithScores(K key, Collection otherKeys, A * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(K key, K otherKey, K destKey); + Long intersectAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Intersect sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -810,8 +765,7 @@ default Set> intersectWithScores(K key, Collection otherKeys, A * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(K key, Collection otherKeys, K destKey); + Long intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Intersect sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -824,8 +778,8 @@ default Set> intersectWithScores(K key, Collection otherKeys, A * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - @Nullable - default Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate) { + default Long intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate) { return intersectAndStore(key, otherKeys, destKey, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -841,8 +795,8 @@ default Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggreg * @since 2.1 * @see Redis Documentation: ZINTERSTORE */ - @Nullable - Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Long intersectAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Union sorted {@code sets}. @@ -853,8 +807,7 @@ default Long intersectAndStore(K key, Collection otherKeys, K destKey, Aggreg * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set union(K key, K otherKey) { + default Set union(@NonNull K key, @NonNull K otherKey) { return union(key, Collections.singleton(otherKey)); } @@ -867,8 +820,7 @@ default Set union(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set union(K key, Collection otherKeys); + Set union(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Union sorted {@code sets}. @@ -879,8 +831,7 @@ default Set union(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set> unionWithScores(K key, K otherKey) { + default Set<@NonNull TypedTuple> unionWithScores(@NonNull K key, @NonNull K otherKey) { return unionWithScores(key, Collections.singleton(otherKey)); } @@ -893,8 +844,7 @@ default Set> unionWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set> unionWithScores(K key, Collection otherKeys); + Set<@NonNull TypedTuple> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys); /** * Union sorted sets at {@code key} and {@code otherKeys} . @@ -906,8 +856,8 @@ default Set> unionWithScores(K key, K otherKey) { * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - default Set> unionWithScores(K key, Collection otherKeys, Aggregate aggregate) { + default Set<@NonNull TypedTuple> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate) { return unionWithScores(key, otherKeys, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -922,8 +872,8 @@ default Set> unionWithScores(K key, Collection otherKeys, Aggre * @since 2.6 * @see Redis Documentation: ZUNION */ - @Nullable - Set> unionWithScores(K key, Collection otherKeys, Aggregate aggregate, Weights weights); + Set<@NonNull TypedTuple> unionWithScores(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -934,8 +884,7 @@ default Set> unionWithScores(K key, Collection otherKeys, Aggre * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(K key, K otherKey, K destKey); + Long unionAndStore(@NonNull K key, @NonNull K otherKey, @NonNull K destKey); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -946,8 +895,7 @@ default Set> unionWithScores(K key, Collection otherKeys, Aggre * @return {@literal null} when used in pipeline / transaction. * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(K key, Collection otherKeys, K destKey); + Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey); /** * Union sorted sets at {@code key} and {@code otherKeys} and store result in destination {@code destKey}. @@ -960,8 +908,8 @@ default Set> unionWithScores(K key, Collection otherKeys, Aggre * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - default Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate) { + default Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate) { return unionAndStore(key, otherKeys, destKey, aggregate, Weights.fromSetCount(1 + otherKeys.size())); } @@ -977,21 +925,21 @@ default Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate * @since 2.1 * @see Redis Documentation: ZUNIONSTORE */ - @Nullable - Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate aggregate, Weights weights); + Long unionAndStore(@NonNull K key, @NonNull Collection<@NonNull K> otherKeys, @NonNull K destKey, + @NonNull Aggregate aggregate, @NonNull Weights weights); /** * Use a {@link Cursor} to iterate over entries zset at {@code key}.
* Important: Call {@link Cursor#close()} when done to avoid resource leaks. * * @param key - * @param options must not be {@literal null}. + * @param options can be {@literal null}. * @return the result cursor providing access to the scan result. Must be closed once fully processed (e.g. through a * try-with-resources clause). * @see Redis Documentation: ZSCAN * @since 1.4 */ - Cursor> scan(K key, ScanOptions options); + Cursor<@NonNull TypedTuple> scan(@NonNull K key, @Nullable ScanOptions options); /** * Get all elements with lexicographical ordering from {@literal ZSET} at {@code key} with a value between @@ -1005,9 +953,9 @@ default Long unionAndStore(K key, Collection otherKeys, K destKey, Aggregate * @see Redis Documentation: ZRANGEBYLEX * @deprecated since 3.0. Please use {@link #rangeByLex(Object, Range)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set rangeByLex(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Set rangeByLex(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return rangeByLex(key, range.toRange()); } @@ -1021,8 +969,7 @@ default Set rangeByLex(K key, org.springframework.data.redis.connection.Redis * @since 3.0 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - default Set rangeByLex(K key, Range range) { + default Set rangeByLex(@NonNull K key, @NonNull Range range) { return rangeByLex(key, range, Limit.unlimited()); } @@ -1040,10 +987,9 @@ default Set rangeByLex(K key, Range range) { * @see Redis Documentation: ZRANGEBYLEX * @deprecated since 3.0. Please use {@link #rangeByLex(Object, Range, Limit)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set rangeByLex(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range, - Limit limit) { + default Set rangeByLex(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range, @NonNull Limit limit) { return rangeByLex(key, range.toRange(), limit); } @@ -1059,8 +1005,7 @@ default Set rangeByLex(K key, org.springframework.data.redis.connection.Redis * @since 3.0 * @see Redis Documentation: ZRANGEBYLEX */ - @Nullable - Set rangeByLex(K key, Range range, Limit limit); + Set rangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Get all elements with reverse lexicographical ordering from {@literal ZSET} at {@code key} with a value between @@ -1074,9 +1019,9 @@ default Set rangeByLex(K key, org.springframework.data.redis.connection.Redis * @see Redis Documentation: ZREVRANGEBYLEX * @deprecated since 3.0. Please use {@link #reverseRangeByLex(Object, Range)} */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set reverseRangeByLex(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range) { + default Set reverseRangeByLex(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range) { return reverseRangeByLex(key, range.toRange()); } @@ -1090,8 +1035,7 @@ default Set reverseRangeByLex(K key, org.springframework.data.redis.connectio * @since 3.0 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - default Set reverseRangeByLex(K key, Range range) { + default Set reverseRangeByLex(@NonNull K key, @NonNull Range range) { return reverseRangeByLex(key, range, Limit.unlimited()); } @@ -1109,10 +1053,9 @@ default Set reverseRangeByLex(K key, Range range) { * @see Redis Documentation: ZREVRANGEBYLEX * @deprecated since 3.0. Please use {@link #reverseRangeByLex(Object, Range, Limit)} instead. */ - @Nullable @Deprecated(since = "3.0", forRemoval = true) - default Set reverseRangeByLex(K key, org.springframework.data.redis.connection.RedisZSetCommands.Range range, - Limit limit) { + default Set reverseRangeByLex(@NonNull K key, + org.springframework.data.redis.connection.RedisZSetCommands.@NonNull Range range, @NonNull Limit limit) { return reverseRangeByLex(key, range.toRange(), limit); } @@ -1128,8 +1071,7 @@ default Set reverseRangeByLex(K key, org.springframework.data.redis.connectio * @since 2.4 * @see Redis Documentation: ZREVRANGEBYLEX */ - @Nullable - Set reverseRangeByLex(K key, Range range, Limit limit); + Set reverseRangeByLex(@NonNull K key, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a @@ -1143,8 +1085,7 @@ default Set reverseRangeByLex(K key, org.springframework.data.redis.connectio * @see #rangeByLex(Object, Range) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long rangeAndStoreByLex(K srcKey, K dstKey, Range range) { + default Long rangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return rangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited()); } @@ -1162,8 +1103,7 @@ default Long rangeAndStoreByLex(K srcKey, K dstKey, Range range) { * @see #rangeByLex(Object, Range, Limit) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long rangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit); + Long rangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey} @@ -1177,8 +1117,7 @@ default Long rangeAndStoreByLex(K srcKey, K dstKey, Range range) { * @see #reverseRangeByLex(Object, Range) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range) { + default Long reverseRangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return reverseRangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited()); } @@ -1196,8 +1135,8 @@ default Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range) * @see #reverseRangeByLex(Object, Range, Limit) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range, Limit limit); + Long reverseRangeAndStoreByLex(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at {@code srcKey} with a score @@ -1211,8 +1150,7 @@ default Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range range) * @see #rangeByScore(Object, double, double) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long rangeAndStoreByScore(K srcKey, K dstKey, Range range) { + default Long rangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range) { return rangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited()); } @@ -1230,8 +1168,8 @@ default Long rangeAndStoreByScore(K srcKey, K dstKey, Range ra * @see #rangeByScore(Object, double, double, long, long) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - Long rangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit); + Long rangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a @@ -1245,8 +1183,8 @@ default Long rangeAndStoreByScore(K srcKey, K dstKey, Range ra * @see #reverseRangeByScore(Object, double, double) * @see Redis Documentation: ZRANGESTORE */ - @Nullable - default Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range) { + default Long reverseRangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, + @NonNull Range range) { return reverseRangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited()); } @@ -1264,11 +1202,12 @@ default Long reverseRangeAndStoreByScore(K srcKey, K dstKey, RangeRedis Documentation: ZRANGESTORE */ - @Nullable - Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range range, Limit limit); + Long reverseRangeAndStoreByScore(@NonNull K srcKey, @NonNull K dstKey, @NonNull Range range, + @NonNull Limit limit); /** * @return never {@literal null}. */ + @NonNull RedisOperations getOperations(); } diff --git a/src/main/java/org/springframework/data/redis/core/convert/BinaryConverters.java b/src/main/java/org/springframework/data/redis/core/convert/BinaryConverters.java index 0befb22a44..62960c4def 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/BinaryConverters.java +++ b/src/main/java/org/springframework/data/redis/core/convert/BinaryConverters.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.UUID; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.data.convert.ReadingConverter; @@ -172,7 +173,7 @@ public BytesToEnum(Class enumType) { } @Override - public T convert(byte[] source) { + public @Nullable T convert(byte[] source) { if (ObjectUtils.isEmpty(source)) { return null; @@ -205,7 +206,7 @@ public BytesToNumberConverter(Class targetType) { } @Override - public T convert(byte[] source) { + public @Nullable T convert(byte[] source) { if (ObjectUtils.isEmpty(source)) { return null; @@ -240,7 +241,7 @@ public byte[] convert(Boolean source) { static class BytesToBooleanConverter extends StringBasedConverter implements Converter { @Override - public Boolean convert(byte[] source) { + public @Nullable Boolean convert(byte[] source) { if (ObjectUtils.isEmpty(source)) { return null; @@ -272,7 +273,7 @@ public byte[] convert(Date source) { static class BytesToDateConverter extends StringBasedConverter implements Converter { @Override - public Date convert(byte[] source) { + public @Nullable Date convert(byte[] source) { if (ObjectUtils.isEmpty(source)) { return null; @@ -314,7 +315,7 @@ public byte[] convert(UUID source) { static class BytesToUuidConverter extends StringBasedConverter implements Converter { @Override - public UUID convert(byte[] source) { + public @Nullable UUID convert(byte[] source) { if (ObjectUtils.isEmpty(source)) { return null; diff --git a/src/main/java/org/springframework/data/redis/core/convert/Bucket.java b/src/main/java/org/springframework/data/redis/core/convert/Bucket.java index 5b832b2d62..cecc99f051 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/Bucket.java +++ b/src/main/java/org/springframework/data/redis/core/convert/Bucket.java @@ -31,7 +31,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.comparator.NullSafeComparator; @@ -77,7 +77,7 @@ public Bucket() {} * @param path must not be {@literal null} or {@link String#isEmpty()}. * @param value can be {@literal null}. */ - public void put(String path, @Nullable byte[] value) { + public void put(String path, byte @Nullable[] value) { Assert.hasText(path, "Path to property must not be null or empty"); data.put(path, value); @@ -94,14 +94,14 @@ public void remove(String path) { data.remove(path); } + /** * Get value assigned with path. * * @param path must not be {@literal null} or {@link String#isEmpty()}. * @return {@literal null} if not set. */ - @Nullable - public byte[] get(String path) { + public byte @Nullable[] get(String path) { Assert.hasText(path, "Path to property must not be null or empty"); return data.get(path); @@ -301,8 +301,7 @@ private String safeToString() { } } - @Nullable - private static String toUtf8String(byte[] raw) { + private @Nullable static String toUtf8String(byte[] raw) { try { return new String(raw, CHARSET); @@ -324,7 +323,7 @@ public static class BucketPropertyPath { private final Bucket bucket; private final @Nullable String prefix; - private BucketPropertyPath(Bucket bucket, String prefix) { + private BucketPropertyPath(Bucket bucket, @Nullable String prefix) { Assert.notNull(bucket, "Bucket must not be null"); @@ -354,14 +353,14 @@ public static BucketPropertyPath from(Bucket bucket, @Nullable String prefix) { return new BucketPropertyPath(bucket, prefix); } + /** * Retrieve a value at {@code key} considering top-level/nesting. * * @param key must not be {@literal null} or empty. * @return the resulting value, may be {@literal null}. */ - @Nullable - public byte[] get(String key) { + public byte @Nullable[] get(String key) { return bucket.get(getPath(key)); } @@ -383,8 +382,7 @@ public Bucket getBucket() { return this.bucket; } - @Nullable - public String getPrefix() { + public @Nullable String getPrefix() { return this.prefix; } } diff --git a/src/main/java/org/springframework/data/redis/core/convert/CompositeIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/CompositeIndexResolver.java index 13581c45dc..6e4b345bed 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/CompositeIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/CompositeIndexResolver.java @@ -22,8 +22,8 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -46,6 +46,7 @@ public class CompositeIndexResolver implements IndexResolver { * * @param resolvers must not be {@literal null}. */ + @SuppressWarnings("NullAway") public CompositeIndexResolver(Collection resolvers) { Assert.notNull(resolvers, "Resolvers must not be null"); diff --git a/src/main/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapper.java b/src/main/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapper.java index 9b538ec135..d9d8d95499 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapper.java +++ b/src/main/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapper.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.convert.DefaultTypeMapper; @@ -28,7 +29,6 @@ import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.redis.core.convert.Bucket.BucketPropertyPath; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -144,6 +144,7 @@ public Alias readAliasFrom(BucketPropertyPath source) { return Alias.NONE; } + @SuppressWarnings("NullAway") public void writeTypeTo(BucketPropertyPath sink, Object alias) { if (typeKey != null) { diff --git a/src/main/java/org/springframework/data/redis/core/convert/GeoIndexedPropertyValue.java b/src/main/java/org/springframework/data/redis/core/convert/GeoIndexedPropertyValue.java index d45cd31a16..657b375ecc 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/GeoIndexedPropertyValue.java +++ b/src/main/java/org/springframework/data/redis/core/convert/GeoIndexedPropertyValue.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/core/convert/IndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/IndexResolver.java index b06e82587a..0da4872d57 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/IndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/IndexResolver.java @@ -17,9 +17,9 @@ import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; /** * {@link IndexResolver} extracts secondary index structures to be applied on a given path, {@link PersistentProperty} diff --git a/src/main/java/org/springframework/data/redis/core/convert/IndexedDataFactoryProvider.java b/src/main/java/org/springframework/data/redis/core/convert/IndexedDataFactoryProvider.java index 3c4a51bbf7..fc9428fb27 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/IndexedDataFactoryProvider.java +++ b/src/main/java/org/springframework/data/redis/core/convert/IndexedDataFactoryProvider.java @@ -15,11 +15,11 @@ */ package org.springframework.data.redis.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.redis.core.index.GeoIndexDefinition; import org.springframework.data.redis.core.index.IndexDefinition; import org.springframework.data.redis.core.index.SimpleIndexDefinition; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -50,6 +50,7 @@ static interface IndexedDataFactory { * @author Christoph Strobl * @since 1.8 */ + static class SimpleIndexedPropertyValueFactory implements IndexedDataFactory { final SimpleIndexDefinition indexDefinition; @@ -58,6 +59,7 @@ static class SimpleIndexedPropertyValueFactory implements IndexedDataFactory { this.indexDefinition = indexDefinition; } + @SuppressWarnings("NullAway") public SimpleIndexedPropertyValue createIndexedDataFor(Object value) { return new SimpleIndexedPropertyValue(indexDefinition.getKeyspace(), indexDefinition.getIndexName(), @@ -77,6 +79,7 @@ public GeoIndexedPropertyValueFactory(GeoIndexDefinition indexDefinition) { this.indexDefinition = indexDefinition; } + @SuppressWarnings("NullAway") public GeoIndexedPropertyValue createIndexedDataFor(Object value) { return new GeoIndexedPropertyValue(indexDefinition.getKeyspace(), indexDefinition.getPath(), diff --git a/src/main/java/org/springframework/data/redis/core/convert/KeyspaceConfiguration.java b/src/main/java/org/springframework/data/redis/core/convert/KeyspaceConfiguration.java index 5bb5b0a470..2528f95958 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/KeyspaceConfiguration.java +++ b/src/main/java/org/springframework/data/redis/core/convert/KeyspaceConfiguration.java @@ -19,9 +19,9 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.TimeToLive; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -83,7 +83,7 @@ public boolean hasSettingsFor(Class type) { * @param type must not be {@literal null} * @return {@literal null} if no settings configured. */ - public KeyspaceSettings getKeyspaceSettings(Class type) { + public @Nullable KeyspaceSettings getKeyspaceSettings(Class type) { if (!hasSettingsFor(type)) { return null; @@ -157,8 +157,7 @@ public void setTimeToLive(Long timeToLive) { this.timeToLive = timeToLive; } - @Nullable - public Long getTimeToLive() { + public @Nullable Long getTimeToLive() { return timeToLive; } @@ -166,8 +165,7 @@ public void setTimeToLivePropertyName(String propertyName) { timeToLivePropertyName = propertyName; } - @Nullable - public String getTimeToLivePropertyName() { + public @Nullable String getTimeToLivePropertyName() { return timeToLivePropertyName; } } diff --git a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java index 1cea9a221a..ff9e5d9f4b 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java @@ -30,6 +30,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; @@ -57,7 +58,6 @@ import org.springframework.data.redis.util.ByteUtils; import org.springframework.data.util.ProxyUtils; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -173,7 +173,7 @@ public MappingRedisConverter(@Nullable RedisMappingContext mappingContext, @Null } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "NullAway"}) public R read(Class type, RedisData source) { TypeInformation readType = typeMapper.readType(source.getBucket().getPath(), TypeInformation.of(type)); @@ -184,13 +184,12 @@ public R read(Class type, RedisData source) { } - @Nullable - private R readInternal(String path, Class type, RedisData source) { + private @Nullable R readInternal(String path, Class type, RedisData source) { return source.getBucket().isEmpty() ? null : doReadInternal(path, type, source); } - @SuppressWarnings("unchecked") - private R doReadInternal(String path, Class type, RedisData source) { + @SuppressWarnings({"unchecked", "NullAway"}) + private R doReadInternal(String path, Class type, RedisData source) { TypeInformation readType = typeMapper.readType(source.getBucket().getPath(), TypeInformation.of(type)); @@ -254,8 +253,7 @@ private R doReadInternal(String path, Class type, RedisData source) { return (R) accessor.getBean(); } - @Nullable - protected Object readProperty(String path, RedisData source, RedisPersistentProperty persistentProperty) { + protected @Nullable Object readProperty(String path, RedisData source, RedisPersistentProperty persistentProperty) { String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName(); TypeInformation typeInformation = typeMapper.readType(source.getBucket().getPropertyPath(currentPath), @@ -333,6 +331,7 @@ protected Object readProperty(String path, RedisData source, RedisPersistentProp return fromBytes(sourceBytes, typeToUse); } + @SuppressWarnings("NullAway") private void readAssociation(String path, RedisData source, RedisPersistentEntity entity, PersistentPropertyAccessor accessor) { @@ -357,7 +356,7 @@ private void readAssociation(String path, RedisData source, RedisPersistentEntit } KeyspaceIdentifier identifier = KeyspaceIdentifier.of(referenceKey); - Map rawHash = referenceResolver.resolveReference(identifier.getId(), + Map rawHash = getRequiredReferenceResolver().resolveReference(identifier.getId(), identifier.getKeyspace()); if (!CollectionUtils.isEmpty(rawHash)) { @@ -379,7 +378,7 @@ private void readAssociation(String path, RedisData source, RedisPersistentEntit KeyspaceIdentifier identifier = KeyspaceIdentifier.of(referenceKey); - Map rawHash = referenceResolver.resolveReference(identifier.getId(), + Map rawHash = getRequiredReferenceResolver().resolveReference(identifier.getId(), identifier.getKeyspace()); if (!CollectionUtils.isEmpty(rawHash)) { @@ -393,7 +392,7 @@ private void readAssociation(String path, RedisData source, RedisPersistentEntit @Override @SuppressWarnings({ "rawtypes" }) - public void write(Object source, RedisData sink) { + public void write(@Nullable Object source, RedisData sink) { if (source == null) { return; @@ -480,6 +479,7 @@ protected void writePartialUpdate(PartialUpdate update, RedisData sink) { * @param entity * @param path */ + @SuppressWarnings("NullAway") private void writePartialPropertyUpdate(PartialUpdate update, PropertyUpdate pUpdate, RedisData sink, RedisPersistentEntity entity, String path) { @@ -584,6 +584,7 @@ RedisPersistentProperty getTargetPropertyOrNullForPath(String path, Class typ * @param typeHint * @param sink */ + @SuppressWarnings("NullAway") private void writeInternal(@Nullable String keyspace, String path, @Nullable Object value, TypeInformation typeHint, RedisData sink) { @@ -674,6 +675,12 @@ private void writeInternal(@Nullable String keyspace, String path, @Nullable Obj writeAssociation(path, entity, value, sink); } + private ReferenceResolver getRequiredReferenceResolver() { + + Assert.notNull(referenceResolver, "ReferenceResolver must not be null"); + return referenceResolver; + } + private void writeAssociation(String path, RedisPersistentEntity entity, @Nullable Object value, RedisData sink) { if (value == null) { @@ -762,6 +769,7 @@ private void writeCollection(@Nullable String keyspace, String path, @Nullable I } } + @SuppressWarnings("NullAway") private void writeToBucket(String path, @Nullable Object value, RedisData sink, Class propertyType) { if (value == null || (value instanceof Optional && !((Optional) value).isPresent())) { @@ -798,8 +806,8 @@ private void writeToBucket(String path, @Nullable Object value, RedisData sink, } } - @Nullable - private Object readCollectionOrArray(String path, Class collectionType, Class valueType, Bucket bucket) { + @SuppressWarnings("NullAway") + private @Nullable Object readCollectionOrArray(String path, Class collectionType, Class valueType, Bucket bucket) { List keys = new ArrayList<>(bucket.extractAllKeysFor(path)); keys.sort(listKeyComparator); @@ -865,7 +873,8 @@ private void writeMap(@Nullable String keyspace, String path, Class mapValueT } } - private String mapMapKey(Object key) { + @SuppressWarnings("NullAway") + private @Nullable String mapMapKey(Object key) { if (conversionService.canConvert(key.getClass(), byte[].class)) { return new String(conversionService.convert(key, byte[].class)); @@ -882,8 +891,7 @@ private String mapMapKey(Object key) { * @param source * @return */ - @Nullable - private Map readMapOfSimpleTypes(String path, Class mapType, Class keyType, Class valueType, + private @Nullable Map readMapOfSimpleTypes(String path, Class mapType, Class keyType, Class valueType, RedisData source) { Bucket partial = source.getBucket().extract(path + ".["); @@ -912,8 +920,7 @@ private String mapMapKey(Object key) { * @param source * @return */ - @Nullable - private Map readMapOfComplexTypes(String path, Class mapType, Class keyType, Class valueType, + private @Nullable Map readMapOfComplexTypes(String path, Class mapType, Class keyType, Class valueType, RedisData source) { Set keys = source.getBucket().extractAllKeysFor(path); @@ -936,8 +943,7 @@ private String mapMapKey(Object key) { return target.isEmpty() ? null : target; } - @Nullable - private Object extractMapKeyForPath(String path, String key, Class targetType) { + private @Nullable Object extractMapKeyForPath(String path, String key, Class targetType) { String regex = "^(" + Pattern.quote(path) + "\\.\\[)(.*?)(\\])"; Pattern pattern = Pattern.compile(regex); @@ -970,7 +976,7 @@ private Class getTypeHint(String path, Bucket bucket, Class fallback) { * @return * @throws ConverterNotFoundException */ - public byte[] toBytes(Object source) { + public byte@Nullable[] toBytes(Object source) { if (source instanceof byte[] bytes) { return bytes; @@ -987,7 +993,7 @@ public byte[] toBytes(Object source) { * @return * @throws ConverterNotFoundException */ - public T fromBytes(byte[] source, Class type) { + public @Nullable T fromBytes(byte[] source, Class type) { if (type.isInstance(source)) { return type.cast(source); @@ -1004,8 +1010,7 @@ public T fromBytes(byte[] source, Class type) { * @param valueType to be used for conversion before setting the actual value. * @return */ - @Nullable - private Object toArray(Collection source, Class arrayType, Class valueType) { + private @Nullable Object toArray(Collection source, Class arrayType, Class valueType) { if (source.isEmpty()) { return null; @@ -1099,7 +1104,7 @@ private class ConverterAwareParameterValueProvider implements PropertyValueProvi @Override @SuppressWarnings("unchecked") - public T getPropertyValue(RedisPersistentProperty property) { + public @Nullable T getPropertyValue(RedisPersistentProperty property) { Object value = readProperty(path, source, property); @@ -1178,6 +1183,7 @@ int length() { } @Override + @SuppressWarnings("NullAway") public int compareTo(Part that) { if (this.isNumeric() && that.isNumeric()) { diff --git a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java index 00c1964217..74e3198468 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java @@ -22,6 +22,7 @@ import java.util.Map.Entry; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.PersistentPropertyAccessor; @@ -40,7 +41,6 @@ import org.springframework.data.redis.core.mapping.RedisPersistentEntity; import org.springframework.data.redis.core.mapping.RedisPersistentProperty; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -82,6 +82,7 @@ public PathIndexResolver(RedisMappingContext mappingContext) { this.indexedDataFactoryProvider = new IndexedDataFactoryProvider(); } + @SuppressWarnings("NullAway") public Set resolveIndexesFor(TypeInformation typeInformation, @Nullable Object value) { return doResolveIndexesFor(mappingContext.getRequiredPersistentEntity(typeInformation).getKeySpace(), "", typeInformation, null, value); @@ -89,10 +90,11 @@ public Set resolveIndexesFor(TypeInformation typeInformation, @N @Override public Set resolveIndexesFor(String keyspace, String path, TypeInformation typeInformation, - Object value) { + @Nullable Object value) { return doResolveIndexesFor(keyspace, path, typeInformation, null, value); } + @SuppressWarnings("NullAway") private Set doResolveIndexesFor(final String keyspace, final String path, TypeInformation typeInformation, @Nullable PersistentProperty fallback, @Nullable Object value) { @@ -191,6 +193,7 @@ private TypeInformation updateTypeHintForActualValue(TypeInformation typeH return indexes; } + @SuppressWarnings("NullAway") protected Set resolveIndex(String keyspace, String propertyPath, @Nullable PersistentProperty property, @Nullable Object value) { diff --git a/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java index dbbb692472..1b48022eef 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/RedisConverter.java @@ -15,12 +15,12 @@ */ package org.springframework.data.redis.core.convert; +import org.jspecify.annotations.Nullable; import org.springframework.data.convert.EntityConverter; import org.springframework.data.mapping.model.EntityInstantiators; import org.springframework.data.redis.core.mapping.RedisMappingContext; import org.springframework.data.redis.core.mapping.RedisPersistentEntity; import org.springframework.data.redis.core.mapping.RedisPersistentProperty; -import org.springframework.lang.Nullable; /** * Redis specific {@link EntityConverter}. diff --git a/src/main/java/org/springframework/data/redis/core/convert/RedisData.java b/src/main/java/org/springframework/data/redis/core/convert/RedisData.java index 1b68ebaefd..aaafc6d5e0 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/RedisData.java +++ b/src/main/java/org/springframework/data/redis/core/convert/RedisData.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -83,8 +83,7 @@ public void setId(@Nullable String id) { /** * @return */ - @Nullable - public String getId() { + public @Nullable String getId() { return this.id; } @@ -93,8 +92,7 @@ public String getId() { * * @return {@literal null} if not set. */ - @Nullable - public Long getTimeToLive() { + public @Nullable Long getTimeToLive() { return timeToLive; } @@ -126,8 +124,7 @@ public Set getIndexedData() { /** * @return */ - @Nullable - public String getKeyspace() { + public @Nullable String getKeyspace() { return keyspace; } diff --git a/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolver.java b/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolver.java index 0c2bc6b37f..6313703f88 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolver.java @@ -17,8 +17,8 @@ import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Reference; -import org.springframework.lang.Nullable; /** * {@link ReferenceResolver} retrieves Objects marked with {@link Reference} from Redis. diff --git a/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolverImpl.java b/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolverImpl.java index 32d5b7f496..e209aeb33f 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolverImpl.java +++ b/src/main/java/org/springframework/data/redis/core/convert/ReferenceResolverImpl.java @@ -17,11 +17,11 @@ import java.util.Map; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisKeyValueAdapter; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.convert.BinaryConverters.StringToBytesConverter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -48,8 +48,7 @@ public ReferenceResolverImpl(RedisOperations redisOperations) { } @Override - @Nullable - public Map resolveReference(Object id, String keyspace) { + public @Nullable Map resolveReference(Object id, String keyspace) { byte[] key = converter.convert(keyspace + ":" + id); diff --git a/src/main/java/org/springframework/data/redis/core/convert/SimpleIndexedPropertyValue.java b/src/main/java/org/springframework/data/redis/core/convert/SimpleIndexedPropertyValue.java index 27d8f21612..5f52defb23 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/SimpleIndexedPropertyValue.java +++ b/src/main/java/org/springframework/data/redis/core/convert/SimpleIndexedPropertyValue.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.core.convert; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java index 4b5f8418ae..490a55a4df 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/SpelIndexResolver.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.data.redis.core.index.ConfigurableIndexDefinitionProvider; import org.springframework.data.redis.core.index.IndexDefinition; @@ -32,7 +33,6 @@ import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -75,6 +75,7 @@ public SpelIndexResolver(RedisMappingContext mappingContext, SpelExpressionParse this.parser = parser; } + @SuppressWarnings("NullAway") public Set resolveIndexesFor(TypeInformation typeInformation, @Nullable Object value) { if (value == null) { @@ -117,7 +118,7 @@ public Set resolveIndexesFor(TypeInformation typeInformation, @N @Override public Set resolveIndexesFor(String keyspace, String path, TypeInformation typeInformation, - Object value) { + @Nullable Object value) { return Collections.emptySet(); } diff --git a/src/main/java/org/springframework/data/redis/core/convert/package-info.java b/src/main/java/org/springframework/data/redis/core/convert/package-info.java index bd40f04789..4dbab9f57c 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/convert/package-info.java @@ -1,6 +1,5 @@ /** * Converters for Redis repository support utilizing mapping metadata. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.convert; diff --git a/src/main/java/org/springframework/data/redis/core/index/GeoIndexDefinition.java b/src/main/java/org/springframework/data/redis/core/index/GeoIndexDefinition.java index 9c2af6ca81..ee825af0a2 100644 --- a/src/main/java/org/springframework/data/redis/core/index/GeoIndexDefinition.java +++ b/src/main/java/org/springframework/data/redis/core/index/GeoIndexDefinition.java @@ -15,9 +15,9 @@ */ package org.springframework.data.redis.core.index; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -55,7 +55,7 @@ public GeoIndexDefinition(String keyspace, String path, String name) { static class PointValueTransformer implements IndexValueTransformer { @Override - public Point convert(@Nullable Object source) { + public @Nullable Point convert(@Nullable Object source) { if (source == null || source instanceof Point) { return (Point) source; diff --git a/src/main/java/org/springframework/data/redis/core/index/IndexDefinition.java b/src/main/java/org/springframework/data/redis/core/index/IndexDefinition.java index deb6775be8..e1f0dc2f95 100644 --- a/src/main/java/org/springframework/data/redis/core/index/IndexDefinition.java +++ b/src/main/java/org/springframework/data/redis/core/index/IndexDefinition.java @@ -17,8 +17,8 @@ import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/core/index/PathBasedRedisIndexDefinition.java b/src/main/java/org/springframework/data/redis/core/index/PathBasedRedisIndexDefinition.java index 3f8e90c883..83d511084c 100644 --- a/src/main/java/org/springframework/data/redis/core/index/PathBasedRedisIndexDefinition.java +++ b/src/main/java/org/springframework/data/redis/core/index/PathBasedRedisIndexDefinition.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.core.index; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * {@link IndexDefinition} that is based on a property paths. diff --git a/src/main/java/org/springframework/data/redis/core/index/RedisIndexDefinition.java b/src/main/java/org/springframework/data/redis/core/index/RedisIndexDefinition.java index 9831e3b9a0..0349d51418 100644 --- a/src/main/java/org/springframework/data/redis/core/index/RedisIndexDefinition.java +++ b/src/main/java/org/springframework/data/redis/core/index/RedisIndexDefinition.java @@ -20,7 +20,7 @@ import java.util.Collections; import java.util.List; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -75,8 +75,7 @@ public String getIndexName() { return indexName; } - @Nullable - public String getPath() { + public @Nullable String getPath() { return this.path; } @@ -160,7 +159,8 @@ public CompositeValueTransformer(Collection transformers) } @Override - public Object convert(Object source) { + @SuppressWarnings("NullAway") + public @Nullable Object convert(Object source) { Object tmp = source; for (IndexValueTransformer transformer : transformers) { diff --git a/src/main/java/org/springframework/data/redis/core/index/SpelIndexDefinition.java b/src/main/java/org/springframework/data/redis/core/index/SpelIndexDefinition.java index c346945686..11d662b47b 100644 --- a/src/main/java/org/springframework/data/redis/core/index/SpelIndexDefinition.java +++ b/src/main/java/org/springframework/data/redis/core/index/SpelIndexDefinition.java @@ -15,9 +15,9 @@ */ package org.springframework.data.redis.core.index; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.convert.SpelIndexResolver; import org.springframework.expression.spel.standard.SpelExpression; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/core/index/package-info.java b/src/main/java/org/springframework/data/redis/core/index/package-info.java index 3bd601ffe2..0669c6c587 100644 --- a/src/main/java/org/springframework/data/redis/core/index/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/index/package-info.java @@ -1,6 +1,5 @@ /** * Abstractions for Redis secondary indexes. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.index; diff --git a/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java b/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java index 28eede0b9d..a8da409766 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/BasicRedisPersistentEntity.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.core.mapping; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Id; import org.springframework.data.keyvalue.core.mapping.BasicKeyValuePersistentEntity; import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; @@ -22,7 +23,6 @@ import org.springframework.data.redis.core.TimeToLive; import org.springframework.data.redis.core.TimeToLiveAccessor; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -58,14 +58,13 @@ public TimeToLiveAccessor getTimeToLiveAccessor() { } @Override - @Nullable - public RedisPersistentProperty getExplicitTimeToLiveProperty() { + public @Nullable RedisPersistentProperty getExplicitTimeToLiveProperty() { return this.getPersistentProperty(TimeToLive.class); } @Override - @Nullable - protected RedisPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(RedisPersistentProperty property) { + @SuppressWarnings("NullAway") + protected @Nullable RedisPersistentProperty returnPropertyIfBetterIdPropertyCandidateOrNull(RedisPersistentProperty property) { Assert.notNull(property, "Property must not be null"); diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java index fa445cbfa5..bb7b06d0ec 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisMappingContext.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.keyvalue.annotation.KeySpace; import org.springframework.data.keyvalue.core.mapping.KeySpaceResolver; @@ -41,7 +42,6 @@ import org.springframework.data.redis.core.convert.RedisCustomConversions; import org.springframework.data.redis.core.index.IndexConfiguration; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.NumberUtils; @@ -122,7 +122,8 @@ public ConfigAwareKeySpaceResolver(KeyspaceConfiguration keyspaceConfig) { } @Override - public String resolveKeySpace(Class type) { + @SuppressWarnings("NullAway") + public @Nullable String resolveKeySpace(Class type) { Assert.notNull(type, "Type must not be null"); if (keyspaceConfig.hasSettingsFor(type)) { @@ -188,8 +189,8 @@ static class ConfigAwareTimeToLiveAccessor implements TimeToLiveAccessor { } @Override - @SuppressWarnings({ "rawtypes" }) - public Long getTimeToLive(Object source) { + @SuppressWarnings({ "rawtypes", "NullAway" }) + public @Nullable Long getTimeToLive(Object source) { Assert.notNull(source, "Source must not be null"); Class type = source instanceof Class ? (Class) source @@ -273,8 +274,8 @@ public boolean isExpiringEntity(Class type) { return resolveTimeMethod(type) != null; } - @Nullable - private Long resolveDefaultTimeOut(Class type) { + @SuppressWarnings("NullAway") + private @Nullable Long resolveDefaultTimeOut(Class type) { if (this.defaultTimeouts.containsKey(type)) { return defaultTimeouts.get(type); @@ -295,8 +296,8 @@ private Long resolveDefaultTimeOut(Class type) { return defaultTimeout; } - @Nullable - private PersistentProperty resolveTtlProperty(Class type) { + @SuppressWarnings("NullAway") + private @Nullable PersistentProperty resolveTtlProperty(Class type) { if (timeoutProperties.containsKey(type)) { return timeoutProperties.get(type); @@ -328,8 +329,7 @@ private PersistentProperty resolveTtlProperty(Class type) { return null; } - @Nullable - private Method resolveTimeMethod(Class type) { + private @Nullable Method resolveTimeMethod(Class type) { if (timeoutMethods.containsKey(type)) { return timeoutMethods.get(type); diff --git a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java index 4ef2104351..ebca6045cc 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/RedisPersistentEntity.java @@ -15,11 +15,11 @@ */ package org.springframework.data.redis.core.mapping; +import org.jspecify.annotations.Nullable; import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.redis.core.TimeToLiveAccessor; -import org.springframework.lang.Nullable; /** * Redis specific {@link PersistentEntity}. diff --git a/src/main/java/org/springframework/data/redis/core/mapping/package-info.java b/src/main/java/org/springframework/data/redis/core/mapping/package-info.java index 489b1eacbb..bf59a28af0 100644 --- a/src/main/java/org/springframework/data/redis/core/mapping/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/mapping/package-info.java @@ -1,6 +1,5 @@ /** * Redis specific repository support mapping meta information. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.mapping; diff --git a/src/main/java/org/springframework/data/redis/core/package-info.java b/src/main/java/org/springframework/data/redis/core/package-info.java index 6fb27b61d0..3dc16d7c0f 100644 --- a/src/main/java/org/springframework/data/redis/core/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/package-info.java @@ -3,6 +3,5 @@ *

* Provides template support and callback for low-level access. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core; diff --git a/src/main/java/org/springframework/data/redis/core/query/DefaultSortCriterion.java b/src/main/java/org/springframework/data/redis/core/query/DefaultSortCriterion.java index 5ffecf9c73..a0febc9208 100644 --- a/src/main/java/org/springframework/data/redis/core/query/DefaultSortCriterion.java +++ b/src/main/java/org/springframework/data/redis/core/query/DefaultSortCriterion.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.SortParameters.Order; import org.springframework.data.redis.connection.SortParameters.Range; -import org.springframework.lang.Nullable; /** * Default implementation for {@link SortCriterion}. diff --git a/src/main/java/org/springframework/data/redis/core/query/DefaultSortQuery.java b/src/main/java/org/springframework/data/redis/core/query/DefaultSortQuery.java index 62f07e69ee..1041401adb 100644 --- a/src/main/java/org/springframework/data/redis/core/query/DefaultSortQuery.java +++ b/src/main/java/org/springframework/data/redis/core/query/DefaultSortQuery.java @@ -17,9 +17,9 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.SortParameters.Order; import org.springframework.data.redis.connection.SortParameters.Range; -import org.springframework.lang.Nullable; /** * Default SortQuery implementation. @@ -36,7 +36,7 @@ class DefaultSortQuery implements SortQuery { private final @Nullable String by; private final List getPattern; - DefaultSortQuery(K key, Order order, Boolean alpha, Range limit, String by, List getPattern) { + DefaultSortQuery(K key, @Nullable Order order, @Nullable Boolean alpha, @Nullable Range limit, @Nullable String by, List getPattern) { this.key = key; this.order = order; this.alpha = alpha; @@ -46,7 +46,7 @@ class DefaultSortQuery implements SortQuery { } @Override - public Boolean isAlphabetic() { + public @Nullable Boolean isAlphabetic() { return alpha; } @@ -55,26 +55,22 @@ public K getKey() { return this.key; } - @Nullable @Override - public Order getOrder() { + public @Nullable Order getOrder() { return this.order; } - @Nullable - public Boolean getAlpha() { + public @Nullable Boolean getAlpha() { return this.alpha; } - @Nullable @Override - public Range getLimit() { + public @Nullable Range getLimit() { return this.limit; } - @Nullable @Override - public String getBy() { + public @Nullable String getBy() { return this.by; } diff --git a/src/main/java/org/springframework/data/redis/core/query/SortQuery.java b/src/main/java/org/springframework/data/redis/core/query/SortQuery.java index 7cedfbc180..47ee023d64 100644 --- a/src/main/java/org/springframework/data/redis/core/query/SortQuery.java +++ b/src/main/java/org/springframework/data/redis/core/query/SortQuery.java @@ -17,12 +17,12 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.SortParameters; import org.springframework.data.redis.connection.SortParameters.Order; import org.springframework.data.redis.connection.SortParameters.Range; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.lang.Nullable; /** * High-level abstraction over a Redis SORT (generified equivalent of {@link SortParameters}). To be used with diff --git a/src/main/java/org/springframework/data/redis/core/query/package-info.java b/src/main/java/org/springframework/data/redis/core/query/package-info.java index 73208952ac..d8d0ed764b 100644 --- a/src/main/java/org/springframework/data/redis/core/query/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/query/package-info.java @@ -1,7 +1,6 @@ /** * Query package for Redis template. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.query; diff --git a/src/main/java/org/springframework/data/redis/core/script/DefaultRedisScript.java b/src/main/java/org/springframework/data/redis/core/script/DefaultRedisScript.java index f5e927d6ee..c449d42c93 100644 --- a/src/main/java/org/springframework/data/redis/core/script/DefaultRedisScript.java +++ b/src/main/java/org/springframework/data/redis/core/script/DefaultRedisScript.java @@ -19,9 +19,9 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; import org.springframework.scripting.ScriptSource; import org.springframework.scripting.support.ResourceScriptSource; import org.springframework.scripting.support.StaticScriptSource; @@ -80,6 +80,7 @@ public void afterPropertiesSet() { } @Override + @SuppressWarnings("NullAway") public String getSha1() { lock.lock(); @@ -95,12 +96,12 @@ public String getSha1() { } @Override - @Nullable - public Class getResultType() { + public @Nullable Class getResultType() { return this.resultType; } @Override + @SuppressWarnings("NullAway") public String getScriptAsString() { try { diff --git a/src/main/java/org/springframework/data/redis/core/script/DefaultScriptExecutor.java b/src/main/java/org/springframework/data/redis/core/script/DefaultScriptExecutor.java index d33af3c5f3..2bb8d31062 100644 --- a/src/main/java/org/springframework/data/redis/core/script/DefaultScriptExecutor.java +++ b/src/main/java/org/springframework/data/redis/core/script/DefaultScriptExecutor.java @@ -17,6 +17,8 @@ import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.ReturnType; @@ -35,6 +37,7 @@ * @author Mark Paluch * @param The type of keys that may be passed during script execution */ +@NullUnmarked public class DefaultScriptExecutor implements ScriptExecutor { private final RedisTemplate template; @@ -42,19 +45,20 @@ public class DefaultScriptExecutor implements ScriptExecutor { /** * @param template The {@link RedisTemplate} to use */ - public DefaultScriptExecutor(RedisTemplate template) { + public DefaultScriptExecutor(@NonNull RedisTemplate template) { this.template = template; } @SuppressWarnings("unchecked") - public T execute(final RedisScript script, final List keys, final Object... args) { + public T execute(@NonNull RedisScript script, @NonNull List<@NonNull K> keys, + @NonNull Object @NonNull... args) { // use the Template's value serializer for args and result return execute(script, template.getValueSerializer(), (RedisSerializer) template.getValueSerializer(), keys, args); } - public T execute(final RedisScript script, final RedisSerializer argsSerializer, - final RedisSerializer resultSerializer, final List keys, final Object... args) { + public T execute(@NonNull RedisScript script, @NonNull RedisSerializer argsSerializer, + @NonNull RedisSerializer resultSerializer, @NonNull List<@NonNull K> keys, @NonNull Object @NonNull... args) { return template.execute((RedisCallback) connection -> { final ReturnType returnType = ReturnType.fromJavaType(script.getResultType()); final byte[][] keysAndArgs = keysAndArgs(argsSerializer, keys, args); diff --git a/src/main/java/org/springframework/data/redis/core/script/RedisScript.java b/src/main/java/org/springframework/data/redis/core/script/RedisScript.java index a7cc80f2c2..c697719daa 100644 --- a/src/main/java/org/springframework/data/redis/core/script/RedisScript.java +++ b/src/main/java/org/springframework/data/redis/core/script/RedisScript.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.core.script; +import org.jspecify.annotations.Nullable; import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/core/script/ScriptExecutor.java b/src/main/java/org/springframework/data/redis/core/script/ScriptExecutor.java index ba40f40f0d..5a11cc8739 100644 --- a/src/main/java/org/springframework/data/redis/core/script/ScriptExecutor.java +++ b/src/main/java/org/springframework/data/redis/core/script/ScriptExecutor.java @@ -17,6 +17,8 @@ import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullUnmarked; import org.springframework.data.redis.serializer.RedisSerializer; /** @@ -25,6 +27,7 @@ * @author Jennifer Hickey * @param The type of keys that may be passed during script execution */ +@NullUnmarked public interface ScriptExecutor { /** @@ -36,7 +39,7 @@ public interface ScriptExecutor { * @return The return value of the script or {@literal null} if {@link RedisScript#getResultType()} is * {@literal null}, likely indicating a throw-away status reply (i.e. "OK") */ - T execute(RedisScript script, List keys, Object... args); + T execute(@NonNull RedisScript script, @NonNull List<@NonNull K> keys, @NonNull Object @NonNull... args); /** * Executes the given {@link RedisScript}, using the provided {@link RedisSerializer}s to serialize the script @@ -50,7 +53,7 @@ public interface ScriptExecutor { * @return The return value of the script or {@literal null} if {@link RedisScript#getResultType()} is * {@literal null}, likely indicating a throw-away status reply (i.e. "OK") */ - T execute(RedisScript script, RedisSerializer argsSerializer, RedisSerializer resultSerializer, - List keys, Object... args); + T execute(@NonNull RedisScript script, @NonNull RedisSerializer argsSerializer, + @NonNull RedisSerializer resultSerializer, @NonNull List<@NonNull K> keys, @NonNull Object... args); } diff --git a/src/main/java/org/springframework/data/redis/core/script/ScriptUtils.java b/src/main/java/org/springframework/data/redis/core/script/ScriptUtils.java index 24df5ae572..b1d94d41dd 100644 --- a/src/main/java/org/springframework/data/redis/core/script/ScriptUtils.java +++ b/src/main/java/org/springframework/data/redis/core/script/ScriptUtils.java @@ -19,10 +19,10 @@ import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.dao.NonTransientDataAccessException; import org.springframework.data.redis.serializer.RedisElementReader; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; /** * Utilities for Lua script execution and result deserialization. @@ -44,7 +44,7 @@ private ScriptUtils() {} * @return the deserialized result. */ @SuppressWarnings({ "unchecked" }) - static T deserializeResult(RedisSerializer resultSerializer, Object result) { + static @Nullable T deserializeResult(RedisSerializer resultSerializer, Object result) { if (result instanceof byte[] resultBytes) { return resultSerializer.deserialize(resultBytes); @@ -72,9 +72,8 @@ static T deserializeResult(RedisSerializer resultSerializer, Object resul * @param result must not be {@literal null}. * @return the deserialized result. */ - @Nullable @SuppressWarnings({ "unchecked" }) - static T deserializeResult(RedisElementReader reader, Object result) { + static @Nullable T deserializeResult(RedisElementReader reader, Object result) { if (result instanceof ByteBuffer byteBuffer) { return reader.read(byteBuffer); diff --git a/src/main/java/org/springframework/data/redis/core/script/package-info.java b/src/main/java/org/springframework/data/redis/core/script/package-info.java index 0e50ced964..ab14517d5b 100644 --- a/src/main/java/org/springframework/data/redis/core/script/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/script/package-info.java @@ -1,6 +1,5 @@ /** * Lua script execution abstraction. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.script; diff --git a/src/main/java/org/springframework/data/redis/core/types/Expiration.java b/src/main/java/org/springframework/data/redis/core/types/Expiration.java index 2e4627dbc5..8d9c114501 100644 --- a/src/main/java/org/springframework/data/redis/core/types/Expiration.java +++ b/src/main/java/org/springframework/data/redis/core/types/Expiration.java @@ -18,8 +18,8 @@ import java.time.Duration; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.TimeoutUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -78,6 +78,10 @@ public static Expiration unixTimestamp(long unixTimestamp, TimeUnit timeUnit) { * @return a new {@link Expiration} configured with the given {@link Long length of time} in {@link TimeUnit}. */ public static Expiration from(long expirationTime, @Nullable TimeUnit timeUnit) { + + if(timeUnit == null) { + return new Expiration(expirationTime, TimeUnit.SECONDS); + } if (TimeUnit.NANOSECONDS.equals(timeUnit) || TimeUnit.MICROSECONDS.equals(timeUnit) @@ -86,15 +90,14 @@ public static Expiration from(long expirationTime, @Nullable TimeUnit timeUnit) return new Expiration(timeUnit.toMillis(expirationTime), TimeUnit.MILLISECONDS); } - return timeUnit != null ? new Expiration(timeUnit.toSeconds(expirationTime), TimeUnit.SECONDS) - : new Expiration(expirationTime, TimeUnit.SECONDS); + return new Expiration(timeUnit.toSeconds(expirationTime), TimeUnit.SECONDS); } /** * Creates a new {@link Expiration} with the given, required {@link Duration}. *

- * Durations with at least {@literal seconds} resolution uses {@link TimeUnit#SECONDS}. {@link Duration Durations} - * in {@literal milliseconds} use {@link TimeUnit#MILLISECONDS}. + * Durations with at least {@literal seconds} resolution uses {@link TimeUnit#SECONDS}. {@link Duration Durations} in + * {@literal milliseconds} use {@link TimeUnit#MILLISECONDS}. * * @param duration must not be {@literal null}. * @return a new {@link Expiration} from the given {@link Duration}. @@ -105,15 +108,15 @@ public static Expiration from(Duration duration) { Assert.notNull(duration, "Duration must not be null"); return duration.isZero() ? Expiration.persistent() - : TimeoutUtils.hasMillis(duration) ? new Expiration(duration.toMillis(), TimeUnit.MILLISECONDS) - : new Expiration(duration.getSeconds(), TimeUnit.SECONDS); + : TimeoutUtils.hasMillis(duration) ? new Expiration(duration.toMillis(), TimeUnit.MILLISECONDS) + : new Expiration(duration.getSeconds(), TimeUnit.SECONDS); } /** * Obtain an {@link Expiration} that indicates to keep the existing one, e.g. when sending a {@code SET} command. *

- * NOTE: Please follow the documentation for the individual commands to see - * if keeping the existing TTL is applicable. + * NOTE: Please follow the documentation for the individual commands to see if keeping the existing + * TTL is applicable. * * @return never {@literal null}. * @since 2.4 @@ -186,8 +189,8 @@ public TimeUnit getTimeUnit() { /** * Converts {@link #getExpirationTime() expiration time} into the given, desired {@link TimeUnit}. * - * @param targetTimeUnit {@link TimeUnit} used to convert the {@link #getExpirationTime()} expiration time}; - * must not be {@literal null}. + * @param targetTimeUnit {@link TimeUnit} used to convert the {@link #getExpirationTime()} expiration time}; must not + * be {@literal null}. * @return the {@link #getExpirationTime() expiration time} converted into the given, desired {@link TimeUnit}. * @throws IllegalArgumentException if the given {@link TimeUnit} is {@literal null}. */ diff --git a/src/main/java/org/springframework/data/redis/core/types/Expirations.java b/src/main/java/org/springframework/data/redis/core/types/Expirations.java index 7101cb60fa..0d812d761d 100644 --- a/src/main/java/org/springframework/data/redis/core/types/Expirations.java +++ b/src/main/java/org/springframework/data/redis/core/types/Expirations.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @@ -133,8 +133,7 @@ public Collection keys() { * @return the {@link Expirations expirations} where the {@link TimeToLive#value()} is using the {@link TimeUnit} * defined in {@link #timeUnit()} or {@literal null} if no entry could be found. */ - @Nullable - public TimeToLive expirationOf(K key) { + public @Nullable TimeToLive expirationOf(K key) { TimeToLive timeToLive = expirations.get(key); @@ -151,8 +150,7 @@ public TimeToLive expirationOf(K key) { * {@link TimeToLive#isMissing() missing} nor {@link TimeToLive#isPersistent() persistent}, {@literal null} * otherwise. */ - @Nullable - public Duration ttlOf(K key) { + public @Nullable Duration ttlOf(K key) { return toDuration(expirationOf(key)); } diff --git a/src/main/java/org/springframework/data/redis/core/types/RedisClientInfo.java b/src/main/java/org/springframework/data/redis/core/types/RedisClientInfo.java index e480d995a0..789dea41ee 100644 --- a/src/main/java/org/springframework/data/redis/core/types/RedisClientInfo.java +++ b/src/main/java/org/springframework/data/redis/core/types/RedisClientInfo.java @@ -19,7 +19,7 @@ import java.io.StringReader; import java.util.Properties; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -67,7 +67,7 @@ public RedisClientInfo(Properties properties) { * * @return */ - public String getAddressPort() { + public @Nullable String getAddressPort() { return get(INFO.ADDRESS_PORT); } @@ -76,7 +76,7 @@ public String getAddressPort() { * * @return */ - public String getFileDescriptor() { + public @Nullable String getFileDescriptor() { return get(INFO.FILE_DESCRIPTOR); } @@ -85,7 +85,7 @@ public String getFileDescriptor() { * * @return */ - public String getName() { + public @Nullable String getName() { return get(INFO.CONNECTION_NAME); } @@ -94,7 +94,7 @@ public String getName() { * * @return */ - public Long getAge() { + public @Nullable Long getAge() { return getLongValueOf(INFO.CONNECTION_AGE); } @@ -103,7 +103,7 @@ public Long getAge() { * * @return */ - public Long getIdle() { + public @Nullable Long getIdle() { return getLongValueOf(INFO.CONNECTION_IDLE); } @@ -112,7 +112,7 @@ public Long getIdle() { * * @return */ - public String getFlags() { + public @Nullable String getFlags() { return get(INFO.FLAGS); } @@ -121,7 +121,7 @@ public String getFlags() { * * @return */ - public Long getDatabaseId() { + public @Nullable Long getDatabaseId() { return getLongValueOf(INFO.DATABSE_ID); } @@ -130,7 +130,7 @@ public Long getDatabaseId() { * * @return */ - public Long getChannelSubscribtions() { + public @Nullable Long getChannelSubscribtions() { return getLongValueOf(INFO.CHANNEL_SUBSCRIBTIONS); } @@ -139,7 +139,7 @@ public Long getChannelSubscribtions() { * * @return */ - public Long getPatternSubscrbtions() { + public @Nullable Long getPatternSubscrbtions() { return getLongValueOf(INFO.PATTERN_SUBSCRIBTIONS); } @@ -148,7 +148,7 @@ public Long getPatternSubscrbtions() { * * @return */ - public Long getMultiCommandContext() { + public @Nullable Long getMultiCommandContext() { return getLongValueOf(INFO.MULIT_COMMAND_CONTEXT); } @@ -157,7 +157,7 @@ public Long getMultiCommandContext() { * * @return */ - public Long getBufferLength() { + public @Nullable Long getBufferLength() { return getLongValueOf(INFO.BUFFER_LENGTH); } @@ -166,7 +166,7 @@ public Long getBufferLength() { * * @return */ - public Long getBufferFreeSpace() { + public @Nullable Long getBufferFreeSpace() { return getLongValueOf(INFO.BUFFER_FREE_SPACE); } @@ -175,7 +175,7 @@ public Long getBufferFreeSpace() { * * @return */ - public Long getOutputBufferLength() { + public @Nullable Long getOutputBufferLength() { return getLongValueOf(INFO.OUTPUT_BUFFER_LENGTH); } @@ -184,7 +184,7 @@ public Long getOutputBufferLength() { * * @return */ - public Long getOutputListLength() { + public @Nullable Long getOutputListLength() { return getLongValueOf(INFO.OUTPUT_LIST_LENGTH); } @@ -193,7 +193,7 @@ public Long getOutputListLength() { * * @return */ - public Long getOutputBufferMemoryUsage() { + public @Nullable Long getOutputBufferMemoryUsage() { return getLongValueOf(INFO.OUTPUT_BUFFER_MEMORY_USAGE); } @@ -202,7 +202,7 @@ public Long getOutputBufferMemoryUsage() { * * @return */ - public String getEvents() { + public @Nullable String getEvents() { return get(INFO.EVENTS); } @@ -211,7 +211,7 @@ public String getEvents() { * * @return */ - public String getLastCommand() { + public @Nullable String getLastCommand() { return get(INFO.LAST_COMMAND); } @@ -219,7 +219,7 @@ public String getLastCommand() { * @param info must not be null * @return {@literal null} if no entry found for requested {@link INFO}. */ - public String get(INFO info) { + public @Nullable String get(INFO info) { Assert.notNull(info, "Cannot retrieve client information for 'null'"); return this.clientProperties.getProperty(info.key); @@ -229,14 +229,13 @@ public String get(INFO info) { * @param key must not be {@literal null} or {@literal empty}. * @return {@literal null} if no entry found for requested {@code key}. */ - @Nullable - public String get(String key) { + public @Nullable String get(String key) { Assert.hasText(key, "Cannot get client information for 'empty' / 'null' key"); return this.clientProperties.getProperty(key); } - private Long getLongValueOf(INFO info) { + private @Nullable Long getLongValueOf(INFO info) { String value = get(info); return value == null ? null : Long.valueOf(value); diff --git a/src/main/java/org/springframework/data/redis/core/types/package-info.java b/src/main/java/org/springframework/data/redis/core/types/package-info.java index 4386200f7e..c6be07e8dc 100644 --- a/src/main/java/org/springframework/data/redis/core/types/package-info.java +++ b/src/main/java/org/springframework/data/redis/core/types/package-info.java @@ -1,6 +1,5 @@ /** * Redis domain specific types. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.core.types; diff --git a/src/main/java/org/springframework/data/redis/domain/geo/BoundingBox.java b/src/main/java/org/springframework/data/redis/domain/geo/BoundingBox.java index 77e5aa10ef..c6a3e6b2c6 100644 --- a/src/main/java/org/springframework/data/redis/domain/geo/BoundingBox.java +++ b/src/main/java/org/springframework/data/redis/domain/geo/BoundingBox.java @@ -17,10 +17,10 @@ import java.io.Serial; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Metric; import org.springframework.data.geo.Shape; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/domain/geo/GeoLocation.java b/src/main/java/org/springframework/data/redis/domain/geo/GeoLocation.java index 3ed71bdbc5..e48341e723 100644 --- a/src/main/java/org/springframework/data/redis/domain/geo/GeoLocation.java +++ b/src/main/java/org/springframework/data/redis/domain/geo/GeoLocation.java @@ -15,8 +15,8 @@ */ package org.springframework.data.redis.domain.geo; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/domain/geo/GeoReference.java b/src/main/java/org/springframework/data/redis/domain/geo/GeoReference.java index 75fe501422..b7b4fd87c9 100644 --- a/src/main/java/org/springframework/data/redis/domain/geo/GeoReference.java +++ b/src/main/java/org/springframework/data/redis/domain/geo/GeoReference.java @@ -15,10 +15,10 @@ */ package org.springframework.data.redis.domain.geo; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; import org.springframework.data.redis.connection.RedisGeoCommands; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; diff --git a/src/main/java/org/springframework/data/redis/domain/geo/package-info.java b/src/main/java/org/springframework/data/redis/domain/geo/package-info.java new file mode 100644 index 0000000000..40a7c79a46 --- /dev/null +++ b/src/main/java/org/springframework/data/redis/domain/geo/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package org.springframework.data.redis.domain.geo; diff --git a/src/main/java/org/springframework/data/redis/hash/BeanUtilsHashMapper.java b/src/main/java/org/springframework/data/redis/hash/BeanUtilsHashMapper.java index 98887bfdcb..a6058fbab6 100644 --- a/src/main/java/org/springframework/data/redis/hash/BeanUtilsHashMapper.java +++ b/src/main/java/org/springframework/data/redis/hash/BeanUtilsHashMapper.java @@ -20,6 +20,7 @@ import java.util.Map.Entry; import org.apache.commons.beanutils.BeanUtils; +import org.jspecify.annotations.Nullable; /** * HashMapper based on Apache Commons BeanUtils project. Does NOT supports nested properties. @@ -42,7 +43,11 @@ public BeanUtilsHashMapper(Class type) { } @Override - public T fromHash(Map hash) { + public @Nullable T fromHash(@Nullable Map hash) { + + if(hash == null) { + return null; + } T instance = org.springframework.beans.BeanUtils.instantiateClass(type); @@ -56,7 +61,7 @@ public T fromHash(Map hash) { } @Override - public Map toHash(T object) { + public Map toHash(@Nullable T object) { try { diff --git a/src/main/java/org/springframework/data/redis/hash/DecoratingStringHashMapper.java b/src/main/java/org/springframework/data/redis/hash/DecoratingStringHashMapper.java index 33984c0e01..6058a28d6b 100644 --- a/src/main/java/org/springframework/data/redis/hash/DecoratingStringHashMapper.java +++ b/src/main/java/org/springframework/data/redis/hash/DecoratingStringHashMapper.java @@ -18,6 +18,8 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * Delegating hash mapper used for flattening objects into Strings. Suitable when dealing with mappers that support * Strings and type conversion. @@ -34,14 +36,18 @@ public DecoratingStringHashMapper(HashMapper mapper) { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public T fromHash(Map hash) { + public @Nullable T fromHash(Map hash) { return (T) delegate.fromHash(hash); } @Override - public Map toHash(T object) { + public @Nullable Map toHash(@Nullable T object) { Map hash = delegate.toHash(object); + if(hash == null) { + return null; + } + Map flatten = new LinkedHashMap<>(hash.size()); for (Map.Entry entry : hash.entrySet()) { flatten.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue())); diff --git a/src/main/java/org/springframework/data/redis/hash/HashMapper.java b/src/main/java/org/springframework/data/redis/hash/HashMapper.java index 0ec97f1e89..eb18c9ebd7 100644 --- a/src/main/java/org/springframework/data/redis/hash/HashMapper.java +++ b/src/main/java/org/springframework/data/redis/hash/HashMapper.java @@ -17,6 +17,8 @@ import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * Core mapping contract between Java types and Redis hashes/maps. It's up to the implementation to support nested * objects. @@ -35,7 +37,7 @@ public interface HashMapper { * @param object * @return */ - Map toHash(T object); + @Nullable Map toHash(@Nullable T object); /** * Convert a {@code hash} (map) to an object. @@ -43,5 +45,5 @@ public interface HashMapper { * @param hash * @return */ - T fromHash(Map hash); + @Nullable T fromHash(Map hash); } diff --git a/src/main/java/org/springframework/data/redis/hash/Jackson2HashMapper.java b/src/main/java/org/springframework/data/redis/hash/Jackson2HashMapper.java index 8788c41ba4..193ed02e1c 100644 --- a/src/main/java/org/springframework/data/redis/hash/Jackson2HashMapper.java +++ b/src/main/java/org/springframework/data/redis/hash/Jackson2HashMapper.java @@ -21,12 +21,11 @@ import java.text.ParseException; import java.util.*; import java.util.Map.Entry; - +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.data.mapping.MappingException; import org.springframework.data.redis.support.collections.CollectionUtils; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.NumberUtils; @@ -228,7 +227,7 @@ public Jackson2HashMapper(ObjectMapper mapper, boolean flatten) { @Override @SuppressWarnings("unchecked") - public Map toHash(Object source) { + public Map toHash(@Nullable Object source) { JsonNode tree = this.typingMapper.valueToTree(source); @@ -237,7 +236,7 @@ public Map toHash(Object source) { @Override @SuppressWarnings("all") - public Object fromHash(Map hash) { + public @Nullable Object fromHash(Map hash) { try { if (this.flatten) { @@ -320,23 +319,23 @@ private Map doUnflatten(Map source) { return result; } - private boolean isIndexed(@NonNull String value) { + private boolean isIndexed( String value) { return value.indexOf('[') > -1; } - private boolean isNotIndexed(@NonNull String value) { + private boolean isNotIndexed( String value) { return !isIndexed(value); } - private boolean isNonNestedIndexed(@NonNull String value) { + private boolean isNonNestedIndexed( String value) { return value.endsWith("]"); } - private int getIndex(@NonNull String indexedValue) { + private int getIndex( String indexedValue) { return Integer.parseInt(indexedValue.substring(indexedValue.indexOf('[') + 1, indexedValue.length() - 1)); } - private @NonNull String stripIndex(@NonNull String indexedValue) { + private String stripIndex( String indexedValue) { int indexOfLeftBracket = indexedValue.indexOf("["); @@ -537,13 +536,13 @@ private static class UntypedCalendarDeserializer extends JsonDeserializer toHash(Object source) { + @Contract("null -> !null") + public Map toHash(@Nullable Object source) { if (source == null) { return Collections.emptyMap(); @@ -149,7 +151,8 @@ public Map toHash(Object source) { } @Override - public Object fromHash(Map hash) { + @Contract("null -> null") + public @Nullable Object fromHash(@Nullable Map hash) { if (hash == null || hash.isEmpty()) { return null; @@ -166,7 +169,7 @@ public Object fromHash(Map hash) { * @param * @return */ - public T fromHash(Map hash, Class type) { + public @Nullable T fromHash(Map hash, Class type) { return type.cast(fromHash(hash)); } @@ -195,13 +198,13 @@ private static class NoOpIndexResolver implements IndexResolver { private static final Set NO_INDEXES = Collections.emptySet(); @Override - public Set resolveIndexesFor(TypeInformation typeInformation, Object value) { + public Set resolveIndexesFor(TypeInformation typeInformation, @Nullable Object value) { return NO_INDEXES; } @Override public Set resolveIndexesFor(String keyspace, String path, TypeInformation typeInformation, - Object value) { + @Nullable Object value) { return NO_INDEXES; } } diff --git a/src/main/java/org/springframework/data/redis/hash/package-info.java b/src/main/java/org/springframework/data/redis/hash/package-info.java index 9ad6ab3812..fccb80ec83 100644 --- a/src/main/java/org/springframework/data/redis/hash/package-info.java +++ b/src/main/java/org/springframework/data/redis/hash/package-info.java @@ -1,6 +1,5 @@ /** * Dedicated support package for Redis hashes. Provides mapping of objects to hashes/maps (and vice versa). */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.hash; diff --git a/src/main/java/org/springframework/data/redis/listener/AbstractTopic.java b/src/main/java/org/springframework/data/redis/listener/AbstractTopic.java index 6c233fc043..99f45221fb 100644 --- a/src/main/java/org/springframework/data/redis/listener/AbstractTopic.java +++ b/src/main/java/org/springframework/data/redis/listener/AbstractTopic.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.listener; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** diff --git a/src/main/java/org/springframework/data/redis/listener/KeyExpirationEventMessageListener.java b/src/main/java/org/springframework/data/redis/listener/KeyExpirationEventMessageListener.java index 759d7d33cd..c945237ca8 100644 --- a/src/main/java/org/springframework/data/redis/listener/KeyExpirationEventMessageListener.java +++ b/src/main/java/org/springframework/data/redis/listener/KeyExpirationEventMessageListener.java @@ -15,12 +15,12 @@ */ package org.springframework.data.redis.listener; +import org.jspecify.annotations.Nullable; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.core.RedisKeyExpiredEvent; -import org.springframework.lang.Nullable; /** * {@link MessageListener} publishing {@link RedisKeyExpiredEvent}s via {@link ApplicationEventPublisher} by listening diff --git a/src/main/java/org/springframework/data/redis/listener/KeyspaceEventMessageListener.java b/src/main/java/org/springframework/data/redis/listener/KeyspaceEventMessageListener.java index 1500dd1f1a..b3d3012bd2 100644 --- a/src/main/java/org/springframework/data/redis/listener/KeyspaceEventMessageListener.java +++ b/src/main/java/org/springframework/data/redis/listener/KeyspaceEventMessageListener.java @@ -17,6 +17,7 @@ import java.util.Properties; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.data.redis.connection.Message; @@ -24,7 +25,6 @@ import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisServerCommands; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -76,7 +76,7 @@ public void destroy() throws Exception { } @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { if (ObjectUtils.isEmpty(message.getChannel()) || ObjectUtils.isEmpty(message.getBody())) { return; diff --git a/src/main/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainer.java b/src/main/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainer.java index f58dc7152e..224e2947bd 100644 --- a/src/main/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainer.java +++ b/src/main/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainer.java @@ -33,6 +33,7 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.DisposableBean; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ReactivePubSubCommands; @@ -48,7 +49,6 @@ import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -437,6 +437,7 @@ private ByteBuffer[] getTargets(Iterable topics, Class class .toArray(ByteBuffer[]::new); } + @SuppressWarnings("NullAway") private Message readMessage(RedisElementReader channelSerializer, RedisElementReader messageSerializer, Message message) { @@ -468,7 +469,7 @@ private ReactiveRedisConnection getRequiredConnection() { return connection; } - private static C read(RedisElementReader reader, ByteBuffer buffer) { + private static @Nullable C read(RedisElementReader reader, ByteBuffer buffer) { try { buffer.mark(); diff --git a/src/main/java/org/springframework/data/redis/listener/RedisMessageListenerContainer.java b/src/main/java/org/springframework/data/redis/listener/RedisMessageListenerContainer.java index a563bdb1ed..c77a3981c4 100644 --- a/src/main/java/org/springframework/data/redis/listener/RedisMessageListenerContainer.java +++ b/src/main/java/org/springframework/data/redis/listener/RedisMessageListenerContainer.java @@ -40,6 +40,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -59,7 +60,7 @@ import org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -205,15 +206,15 @@ public void setTaskExecutor(Executor taskExecutor) { * * @return Returns the connectionFactory */ - @Nullable - public RedisConnectionFactory getConnectionFactory() { + public @Nullable RedisConnectionFactory getConnectionFactory() { return this.connectionFactory; } /** * @param connectionFactory The connectionFactory to set. */ - public void setConnectionFactory(RedisConnectionFactory connectionFactory) { + @Contract("null -> fail") + public void setConnectionFactory(@Nullable RedisConnectionFactory connectionFactory) { Assert.notNull(connectionFactory, "ConnectionFactory must not be null"); @@ -365,6 +366,7 @@ public void start() { /** * Lazily initiate subscriptions if the container has listeners. */ + @SuppressWarnings("NullAway") private void lazyListen() { CompletableFuture containerListenFuture = this.listenFuture; @@ -409,6 +411,7 @@ private CompletableFuture lazyListen(BackOffExecution backOffExecution) { return containerListenFuture; } + @SuppressWarnings("NullAway") private boolean doSubscribe(BackOffExecution backOffExecution) { CompletableFuture containerListenFuture = this.listenFuture; @@ -496,6 +499,7 @@ private void stopListening() { } } + @SuppressWarnings("NullAway") private boolean doUnsubscribe() { CompletableFuture listenFuture = this.listenFuture; @@ -540,6 +544,7 @@ public boolean isRunning() { return this.started.get(); } + @SuppressWarnings("NullAway") public boolean isListening() { return this.state.get().isListening(); } @@ -969,7 +974,7 @@ private void dispatchSubscriptionNotification(Collection listen } } - private void dispatchMessage(Collection listeners, Message message, @Nullable byte[] pattern) { + private void dispatchMessage(Collection listeners, Message message, byte @Nullable[] pattern) { byte[] source = (pattern != null ? pattern.clone() : message.getChannel()); Executor executor = getRequiredTaskExecutor(); @@ -998,7 +1003,7 @@ private Executor getRequiredTaskExecutor() { return this.taskExecutor; } - @SuppressWarnings("ConstantConditions") + @SuppressWarnings({"ConstantConditions", "NullAway"}) private byte[] serialize(Topic topic) { return serializer.serialize(topic.getTopic()); } @@ -1147,7 +1152,7 @@ public boolean isPrepareListening() { private class DispatchMessageListener implements MessageListener, SubscriptionListener { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { Collection listeners = null; // if it's a pattern, disregard channel diff --git a/src/main/java/org/springframework/data/redis/listener/SynchronizingMessageListener.java b/src/main/java/org/springframework/data/redis/listener/SynchronizingMessageListener.java index 050e425f3d..5f1d1f3327 100644 --- a/src/main/java/org/springframework/data/redis/listener/SynchronizingMessageListener.java +++ b/src/main/java/org/springframework/data/redis/listener/SynchronizingMessageListener.java @@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.function.BiFunction; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.SubscriptionListener; import org.springframework.data.redis.connection.util.ByteArrayWrapper; -import org.springframework.lang.Nullable; /** * Synchronizing {@link MessageListener} and {@link SubscriptionListener} that allows notifying a {@link Runnable} @@ -59,7 +59,7 @@ public void addSynchronization(SubscriptionSynchronization synchronization) { } @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { messageListener.onMessage(message, pattern); } diff --git a/src/main/java/org/springframework/data/redis/listener/adapter/MessageListenerAdapter.java b/src/main/java/org/springframework/data/redis/listener/adapter/MessageListenerAdapter.java index fb7d827728..313443b52e 100644 --- a/src/main/java/org/springframework/data/redis/listener/adapter/MessageListenerAdapter.java +++ b/src/main/java/org/springframework/data/redis/listener/adapter/MessageListenerAdapter.java @@ -23,6 +23,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.jspecify.annotations.NullUnmarked; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -31,7 +33,6 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -94,6 +95,7 @@ * @author Christoph Strobl * @author Mark Paluch */ +@NullUnmarked public class MessageListenerAdapter implements InitializingBean, MessageListener { // TODO move this down. @@ -221,8 +223,7 @@ public void setDelegate(Object delegate) { * * @return message listening delegation */ - @Nullable - public Object getDelegate() { + public @Nullable Object getDelegate() { return this.delegate; } @@ -287,7 +288,7 @@ public void afterPropertiesSet() { * @see #handleListenerException */ @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { try { // Check whether the delegate is a MessageListener impl itself. // In that case, the adapter will simply act as a pass-through. diff --git a/src/main/java/org/springframework/data/redis/listener/adapter/RedisListenerExecutionFailedException.java b/src/main/java/org/springframework/data/redis/listener/adapter/RedisListenerExecutionFailedException.java index ff22789d16..1208647320 100644 --- a/src/main/java/org/springframework/data/redis/listener/adapter/RedisListenerExecutionFailedException.java +++ b/src/main/java/org/springframework/data/redis/listener/adapter/RedisListenerExecutionFailedException.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.listener.adapter; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; /** @@ -31,7 +32,7 @@ public class RedisListenerExecutionFailedException extends InvalidDataAccessApiU * @param msg * @param cause */ - public RedisListenerExecutionFailedException(String msg, Throwable cause) { + public RedisListenerExecutionFailedException(@Nullable String msg, @Nullable Throwable cause) { super(msg, cause); } diff --git a/src/main/java/org/springframework/data/redis/listener/adapter/package-info.java b/src/main/java/org/springframework/data/redis/listener/adapter/package-info.java index 5172085aae..87918e1641 100644 --- a/src/main/java/org/springframework/data/redis/listener/adapter/package-info.java +++ b/src/main/java/org/springframework/data/redis/listener/adapter/package-info.java @@ -2,6 +2,5 @@ * Message listener adapter package. The adapter delegates to target listener methods, converting messages to * appropriate message content types (such as String or byte array) that get passed into listener methods. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.listener.adapter; diff --git a/src/main/java/org/springframework/data/redis/listener/package-info.java b/src/main/java/org/springframework/data/redis/listener/package-info.java index 3754a1aedc..932d9fe3fc 100644 --- a/src/main/java/org/springframework/data/redis/listener/package-info.java +++ b/src/main/java/org/springframework/data/redis/listener/package-info.java @@ -1,6 +1,5 @@ /** * Base package for Redis message listener / pubsub container facility */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.listener; diff --git a/src/main/java/org/springframework/data/redis/package-info.java b/src/main/java/org/springframework/data/redis/package-info.java index 788c2e0318..84ad5bd006 100644 --- a/src/main/java/org/springframework/data/redis/package-info.java +++ b/src/main/java/org/springframework/data/redis/package-info.java @@ -3,6 +3,5 @@ *

* Provides Redis specific exception hierarchy on top of the {@code org.springframework.dao} package. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis; diff --git a/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java b/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java index 8a85c7bde4..4e9babe5a3 100644 --- a/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java +++ b/src/main/java/org/springframework/data/redis/repository/cdi/RedisRepositoryBean.java @@ -18,6 +18,7 @@ import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; +import org.jspecify.annotations.Nullable; import java.lang.annotation.Annotation; import java.util.Optional; @@ -28,7 +29,6 @@ import org.springframework.data.redis.repository.support.RedisRepositoryFactory; import org.springframework.data.repository.cdi.CdiRepositoryBean; import org.springframework.data.repository.config.CustomRepositoryImplementationDetector; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/repository/cdi/package-info.java b/src/main/java/org/springframework/data/redis/repository/cdi/package-info.java index a49f50514c..b2d2b41966 100644 --- a/src/main/java/org/springframework/data/redis/repository/cdi/package-info.java +++ b/src/main/java/org/springframework/data/redis/repository/cdi/package-info.java @@ -1,6 +1,5 @@ /** * CDI support for Redis specific repository implementation. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.repository.cdi; diff --git a/src/main/java/org/springframework/data/redis/repository/configuration/package-info.java b/src/main/java/org/springframework/data/redis/repository/configuration/package-info.java index cead482e9b..7c2da75ac5 100644 --- a/src/main/java/org/springframework/data/redis/repository/configuration/package-info.java +++ b/src/main/java/org/springframework/data/redis/repository/configuration/package-info.java @@ -1,6 +1,5 @@ /** * Redis repository specific configuration and bean registration. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.repository.configuration; diff --git a/src/main/java/org/springframework/data/redis/repository/core/package-info.java b/src/main/java/org/springframework/data/redis/repository/core/package-info.java index ceb5e04053..a3eefef272 100644 --- a/src/main/java/org/springframework/data/redis/repository/core/package-info.java +++ b/src/main/java/org/springframework/data/redis/repository/core/package-info.java @@ -1,6 +1,5 @@ /** * Core domain entities for repository support. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.repository.core; diff --git a/src/main/java/org/springframework/data/redis/repository/query/ExampleQueryMapper.java b/src/main/java/org/springframework/data/redis/repository/query/ExampleQueryMapper.java index 9a42260958..bb87cdf90b 100644 --- a/src/main/java/org/springframework/data/redis/repository/query/ExampleQueryMapper.java +++ b/src/main/java/org/springframework/data/redis/repository/query/ExampleQueryMapper.java @@ -22,6 +22,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher.MatchMode; @@ -34,7 +35,6 @@ import org.springframework.data.redis.core.mapping.RedisPersistentEntity; import org.springframework.data.redis.core.mapping.RedisPersistentProperty; import org.springframework.data.support.ExampleMatcherAccessor; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -172,7 +172,7 @@ private Set getIndexedData(String path, Object probe, RedisPersiste String keySpace = persistentEntity.getKeySpace(); return keySpace == null ? Collections.emptySet() - : indexResolver.resolveIndexesFor(persistentEntity.getKeySpace(), path, persistentEntity.getTypeInformation(), + : indexResolver.resolveIndexesFor(keySpace, path, persistentEntity.getTypeInformation(), probe); } } diff --git a/src/main/java/org/springframework/data/redis/repository/query/RedisOperationChain.java b/src/main/java/org/springframework/data/redis/repository/query/RedisOperationChain.java index e6985cd4db..a52e1a84cc 100644 --- a/src/main/java/org/springframework/data/redis/repository/query/RedisOperationChain.java +++ b/src/main/java/org/springframework/data/redis/repository/query/RedisOperationChain.java @@ -22,9 +22,9 @@ import java.util.LinkedHashSet; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -80,8 +80,7 @@ public void near(NearPath near) { this.near = near; } - @Nullable - public NearPath getNear() { + public @Nullable NearPath getNear() { return near; } @@ -114,8 +113,7 @@ public Collection values() { return values; } - @Nullable - public Object getFirstValue() { + public @Nullable Object getFirstValue() { return values.isEmpty() ? null : values.iterator().next(); } @@ -156,7 +154,7 @@ public NearPath(String path, Point point, Distance distance) { super(path, Arrays.asList(point, distance)); } - public Point getPoint() { + public @Nullable Point getPoint() { return (Point) getFirstValue(); } diff --git a/src/main/java/org/springframework/data/redis/repository/query/RedisPartTreeQuery.java b/src/main/java/org/springframework/data/redis/repository/query/RedisPartTreeQuery.java index 4b69f8f23d..688541a317 100644 --- a/src/main/java/org/springframework/data/redis/repository/query/RedisPartTreeQuery.java +++ b/src/main/java/org/springframework/data/redis/repository/query/RedisPartTreeQuery.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.DtoInstantiatingConverter; import org.springframework.data.keyvalue.core.KeyValueOperations; @@ -61,7 +62,7 @@ public RedisPartTreeQuery(QueryMethod queryMethod, ValueExpressionDelegate value } @Override - public Object execute(Object[] parameters) { + public @Nullable Object execute(Object[] parameters) { ParameterAccessor accessor = new ParametersParameterAccessor(getQueryMethod().getParameters(), parameters); KeyValueQuery query = prepareQuery(parameters); @@ -104,7 +105,7 @@ public ResultProcessingConverter(ResultProcessor processor, * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) */ @Override - public Object convert(Object source) { + public @Nullable Object convert(Object source) { if (source instanceof Set s) { diff --git a/src/main/java/org/springframework/data/redis/repository/query/RedisQueryCreator.java b/src/main/java/org/springframework/data/redis/repository/query/RedisQueryCreator.java index 2fbf28d2d0..b10aea0130 100644 --- a/src/main/java/org/springframework/data/redis/repository/query/RedisQueryCreator.java +++ b/src/main/java/org/springframework/data/redis/repository/query/RedisQueryCreator.java @@ -18,6 +18,7 @@ import java.util.Collection; import java.util.Iterator; +import org.jspecify.annotations.Nullable; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Sort; import org.springframework.data.geo.Circle; @@ -30,7 +31,6 @@ import org.springframework.data.repository.query.parser.AbstractQueryCreator; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; diff --git a/src/main/java/org/springframework/data/redis/repository/query/package-info.java b/src/main/java/org/springframework/data/redis/repository/query/package-info.java index 1b860d6fc4..7f3ee1a7c8 100644 --- a/src/main/java/org/springframework/data/redis/repository/query/package-info.java +++ b/src/main/java/org/springframework/data/redis/repository/query/package-info.java @@ -1,6 +1,5 @@ /** * Redis specific query execution engine. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.repository.query; diff --git a/src/main/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutor.java b/src/main/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutor.java index 44704c6096..38bf03c64b 100644 --- a/src/main/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutor.java +++ b/src/main/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutor.java @@ -23,6 +23,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; @@ -48,7 +49,6 @@ import org.springframework.data.repository.query.QueryByExampleExecutor; import org.springframework.data.support.PageableExecutionUtils; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -122,8 +122,7 @@ public Optional findOne(Example example) { return Optional.ofNullable(doFindOne(example)); } - @Nullable - private S doFindOne(Example example) { + private @Nullable S doFindOne(Example example) { Iterator iterator = doFind(example); diff --git a/src/main/java/org/springframework/data/redis/repository/support/package-info.java b/src/main/java/org/springframework/data/redis/repository/support/package-info.java index 791d4d2857..ed5191b5fd 100644 --- a/src/main/java/org/springframework/data/redis/repository/support/package-info.java +++ b/src/main/java/org/springframework/data/redis/repository/support/package-info.java @@ -1,6 +1,5 @@ /** * Spring context specific factory support. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.repository.support; diff --git a/src/main/java/org/springframework/data/redis/serializer/ByteArrayRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/ByteArrayRedisSerializer.java index cb24add7a0..88a5a959e5 100644 --- a/src/main/java/org/springframework/data/redis/serializer/ByteArrayRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/ByteArrayRedisSerializer.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.serializer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Raw {@link RedisSerializer} using {@code byte[]}. @@ -27,15 +27,15 @@ enum ByteArrayRedisSerializer implements RedisSerializer { INSTANCE; - @Nullable + @Override - public byte[] serialize(@Nullable byte[] value) throws SerializationException { + public byte @Nullable[] serialize(byte @Nullable[] value) throws SerializationException { return value; } - @Nullable + @Override - public byte[] deserialize(@Nullable byte[] bytes) throws SerializationException { + public byte @Nullable[] deserialize(byte @Nullable[] bytes) throws SerializationException { return bytes; } } diff --git a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementReader.java b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementReader.java index be012f84d0..436501bdec 100644 --- a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementReader.java +++ b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementReader.java @@ -17,8 +17,8 @@ import java.nio.ByteBuffer; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.util.ByteUtils; -import org.springframework.lang.Nullable; /** * Default implementation of {@link RedisElementReader}. @@ -37,7 +37,7 @@ class DefaultRedisElementReader implements RedisElementReader { @Override @SuppressWarnings("unchecked") - public T read(ByteBuffer buffer) { + public @Nullable T read(ByteBuffer buffer) { if (serializer == null) { return (T) buffer; diff --git a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementWriter.java b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementWriter.java index e6f75c5f70..7375f01b05 100644 --- a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementWriter.java +++ b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisElementWriter.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; /** @@ -31,7 +31,7 @@ class DefaultRedisElementWriter implements RedisElementWriter { private final @Nullable RedisSerializer serializer; - DefaultRedisElementWriter(RedisSerializer serializer) { + DefaultRedisElementWriter(@Nullable RedisSerializer serializer) { this.serializer = serializer; } diff --git a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java index b302ea64b9..30f9f89878 100644 --- a/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java +++ b/src/main/java/org/springframework/data/redis/serializer/DefaultRedisSerializationContext.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.serializer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java index c2973aa627..b4cc1faa2d 100644 --- a/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializer.java @@ -20,11 +20,10 @@ import java.util.Collections; import java.util.function.Consumer; import java.util.function.Supplier; - +import org.jspecify.annotations.Nullable; import org.springframework.cache.support.NullValue; import org.springframework.core.KotlinDetector; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -276,8 +275,7 @@ public byte[] serialize(@Nullable Object value) throws SerializationException { } @Override - @Nullable - public Object deserialize(@Nullable byte[] source) throws SerializationException { + public @Nullable Object deserialize(byte @Nullable[] source) throws SerializationException { return deserialize(source, Object.class); } @@ -294,9 +292,8 @@ public Object deserialize(@Nullable byte[] source) throws SerializationException * @throws SerializationException if the array of bytes cannot be deserialized as an instance of the given * {@link Class type} */ - @Nullable @SuppressWarnings("unchecked") - public T deserialize(@Nullable byte[] source, Class type) throws SerializationException { + public @Nullable T deserialize(byte @Nullable[] source, Class type) throws SerializationException { Assert.notNull(type, "Deserialization type must not be null;" + " Please provide Object.class to make use of Jackson2 default typing."); diff --git a/src/main/java/org/springframework/data/redis/serializer/GenericToStringSerializer.java b/src/main/java/org/springframework/data/redis/serializer/GenericToStringSerializer.java index 8159347b89..aa18525f76 100644 --- a/src/main/java/org/springframework/data/redis/serializer/GenericToStringSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/GenericToStringSerializer.java @@ -18,13 +18,13 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import org.jspecify.annotations.Nullable; import org.springframework.beans.BeansException; import org.springframework.beans.TypeConverter; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -81,7 +81,8 @@ public void setTypeConverter(TypeConverter typeConverter) { } @Override - public byte[] serialize(@Nullable T value) { + @SuppressWarnings("NullAway") + public byte @Nullable [] serialize(@Nullable T value) { if (value == null) { return null; @@ -92,8 +93,7 @@ public byte[] serialize(@Nullable T value) { } @Override - @Nullable - public T deserialize(@Nullable byte[] bytes) { + public @Nullable T deserialize(byte @Nullable [] bytes) { if (bytes == null) { return null; @@ -123,8 +123,8 @@ public Converter(TypeConverter typeConverter) { this.typeConverter = typeConverter; } - @Nullable - E convert(Object value, Class targetType) { + @SuppressWarnings("NullAway") + @Nullable E convert(Object value, Class targetType) { return conversionService != null ? conversionService.convert(value, targetType) : typeConverter.convertIfNecessary(value, targetType); diff --git a/src/main/java/org/springframework/data/redis/serializer/Jackson2JsonRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/Jackson2JsonRedisSerializer.java index 32d626bdd8..da3bfca2ce 100644 --- a/src/main/java/org/springframework/data/redis/serializer/Jackson2JsonRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/Jackson2JsonRedisSerializer.java @@ -17,8 +17,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.databind.JavaType; @@ -161,7 +160,7 @@ public byte[] serialize(@Nullable T value) throws SerializationException { @Nullable @Override @SuppressWarnings("unchecked") - public T deserialize(@Nullable byte[] bytes) throws SerializationException { + public T deserialize(byte @Nullable[] bytes) throws SerializationException { if (SerializationUtils.isEmpty(bytes)) { return null; diff --git a/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java index db67928a94..f304b4f25b 100644 --- a/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java @@ -15,12 +15,12 @@ */ package org.springframework.data.redis.serializer; +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.converter.Converter; import org.springframework.core.serializer.DefaultDeserializer; import org.springframework.core.serializer.DefaultSerializer; import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -84,9 +84,9 @@ public JdkSerializationRedisSerializer(Converter serializer, this.deserializer = deserializer; } - @Nullable + @Override - public byte[] serialize(@Nullable Object value) { + public byte @Nullable[] serialize(@Nullable Object value) { if (value == null) { return SerializationUtils.EMPTY_ARRAY; @@ -101,7 +101,7 @@ public byte[] serialize(@Nullable Object value) { @Nullable @Override - public Object deserialize(@Nullable byte[] bytes) { + public Object deserialize(byte @Nullable[] bytes) { if (SerializationUtils.isEmpty(bytes)) { return null; diff --git a/src/main/java/org/springframework/data/redis/serializer/OxmSerializer.java b/src/main/java/org/springframework/data/redis/serializer/OxmSerializer.java index 18ceace01f..b60309ab0a 100644 --- a/src/main/java/org/springframework/data/redis/serializer/OxmSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/OxmSerializer.java @@ -21,8 +21,8 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.InitializingBean; -import org.springframework.lang.Nullable; import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; import org.springframework.util.Assert; @@ -85,7 +85,8 @@ public void afterPropertiesSet() { } @Override - public byte[] serialize(@Nullable Object value) throws SerializationException { + @SuppressWarnings("NullAway") + public byte @Nullable [] serialize(@Nullable Object value) throws SerializationException { if (value == null) { return SerializationUtils.EMPTY_ARRAY; @@ -102,9 +103,9 @@ public byte[] serialize(@Nullable Object value) throws SerializationException { return stream.toByteArray(); } - @Nullable @Override - public Object deserialize(@Nullable byte[] bytes) throws SerializationException { + @SuppressWarnings("NullAway") + public @Nullable Object deserialize(byte @Nullable [] bytes) throws SerializationException { if (SerializationUtils.isEmpty(bytes)) { return null; diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisElementReader.java b/src/main/java/org/springframework/data/redis/serializer/RedisElementReader.java index fb2c37dac4..f38926ee12 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisElementReader.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisElementReader.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisElementWriter.java b/src/main/java/org/springframework/data/redis/serializer/RedisElementWriter.java index c67f2b0fa8..f0cc755322 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisElementWriter.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisElementWriter.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java b/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java index 9136d05cdc..c45963e07b 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisSerializationContext.java @@ -17,7 +17,7 @@ import java.nio.ByteBuffer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -272,8 +272,7 @@ static SerializationPair byteBuffer() { * @param buffer must not be {@literal null}. * @return the deserialized value. Can be {@literal null}. */ - @Nullable - default T read(ByteBuffer buffer) { + default @Nullable T read(ByteBuffer buffer) { return getReader().read(buffer); } diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/RedisSerializer.java index 709bd4c794..9557ca1e1b 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisSerializer.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.serializer; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.ClassUtils; /** @@ -91,8 +91,7 @@ static RedisSerializer byteArray() { * @param value object to serialize. Can be {@literal null}. * @return the equivalent binary data. Can be {@literal null}. */ - @Nullable - byte[] serialize(@Nullable T value) throws SerializationException; + byte @Nullable[] serialize(@Nullable T value) throws SerializationException; /** * Deserialize an object from the given binary data. @@ -101,7 +100,7 @@ static RedisSerializer byteArray() { * @return the equivalent object instance. Can be {@literal null}. */ @Nullable - T deserialize(@Nullable byte[] bytes) throws SerializationException; + T deserialize(byte @Nullable[] bytes) throws SerializationException; /** * Check whether the given value {@code type} can be serialized by this serializer. diff --git a/src/main/java/org/springframework/data/redis/serializer/RedisSerializerToSerializationPairAdapter.java b/src/main/java/org/springframework/data/redis/serializer/RedisSerializerToSerializationPairAdapter.java index f7f5b72fcc..81bc43037e 100644 --- a/src/main/java/org/springframework/data/redis/serializer/RedisSerializerToSerializationPairAdapter.java +++ b/src/main/java/org/springframework/data/redis/serializer/RedisSerializerToSerializationPairAdapter.java @@ -17,8 +17,8 @@ import java.nio.ByteBuffer; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/serializer/SerializationUtils.java b/src/main/java/org/springframework/data/redis/serializer/SerializationUtils.java index ee78179598..6283abdc82 100644 --- a/src/main/java/org/springframework/data/redis/serializer/SerializationUtils.java +++ b/src/main/java/org/springframework/data/redis/serializer/SerializationUtils.java @@ -24,8 +24,9 @@ import java.util.Map; import java.util.Set; +import org.jspecify.annotations.Nullable; import org.springframework.core.CollectionFactory; -import org.springframework.lang.Nullable; +import org.springframework.lang.Contract; /** * Utility class with various serialization-related methods. @@ -36,11 +37,12 @@ public abstract class SerializationUtils { static final byte[] EMPTY_ARRAY = new byte[0]; - static boolean isEmpty(@Nullable byte[] data) { + @Contract("null -> true") + static boolean isEmpty(byte @Nullable [] data) { return (data == null || data.length == 0); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "NullAway" }) static > T deserializeValues(@Nullable Collection rawValues, Class type, @Nullable RedisSerializer redisSerializer) { // connection in pipeline/multi mode diff --git a/src/main/java/org/springframework/data/redis/serializer/StringRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/StringRedisSerializer.java index 1a0abd14bd..459ab80753 100644 --- a/src/main/java/org/springframework/data/redis/serializer/StringRedisSerializer.java +++ b/src/main/java/org/springframework/data/redis/serializer/StringRedisSerializer.java @@ -18,7 +18,7 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** @@ -80,15 +80,15 @@ public StringRedisSerializer(Charset charset) { this.charset = charset; } - @Nullable + @Override - public byte[] serialize(@Nullable String value) { + public byte @Nullable[] serialize(@Nullable String value) { return (value == null ? null : value.getBytes(charset)); } @Nullable @Override - public String deserialize(@Nullable byte[] bytes) { + public String deserialize(byte @Nullable[] bytes) { return (bytes == null ? null : new String(bytes, charset)); } diff --git a/src/main/java/org/springframework/data/redis/serializer/package-info.java b/src/main/java/org/springframework/data/redis/serializer/package-info.java index 45801b579c..c826daf851 100644 --- a/src/main/java/org/springframework/data/redis/serializer/package-info.java +++ b/src/main/java/org/springframework/data/redis/serializer/package-info.java @@ -1,6 +1,5 @@ /** * Serialization/Deserialization package for converting Object to (and from) binary data. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.serializer; diff --git a/src/main/java/org/springframework/data/redis/stream/DefaultStreamMessageListenerContainer.java b/src/main/java/org/springframework/data/redis/stream/DefaultStreamMessageListenerContainer.java index 03c7d6add8..23d01356a9 100644 --- a/src/main/java/org/springframework/data/redis/stream/DefaultStreamMessageListenerContainer.java +++ b/src/main/java/org/springframework/data/redis/stream/DefaultStreamMessageListenerContainer.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - +import org.jspecify.annotations.Nullable; import org.springframework.core.convert.TypeDescriptor; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -38,7 +38,6 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StreamOperations; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ErrorHandler; import org.springframework.util.ObjectUtils; @@ -218,7 +217,7 @@ private Function getDeserializer() { }; } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "NullAway" }) private Function> getReadFunction(StreamReadRequest streamRequest) { byte[] rawKey = ((RedisSerializer) template.getKeySerializer()) diff --git a/src/main/java/org/springframework/data/redis/stream/DefaultStreamReceiver.java b/src/main/java/org/springframework/data/redis/stream/DefaultStreamReceiver.java index 9d9349e18b..81c5861f6c 100644 --- a/src/main/java/org/springframework/data/redis/stream/DefaultStreamReceiver.java +++ b/src/main/java/org/springframework/data/redis/stream/DefaultStreamReceiver.java @@ -601,6 +601,7 @@ void updateReadOffset(String messageId) { this.currentOffset.set(next); } + @SuppressWarnings("NullAway") ReadOffset getCurrentReadOffset() { return currentOffset.get(); } diff --git a/src/main/java/org/springframework/data/redis/stream/StreamMessageListenerContainer.java b/src/main/java/org/springframework/data/redis/stream/StreamMessageListenerContainer.java index b54a0ce67b..ba9b086d81 100644 --- a/src/main/java/org/springframework/data/redis/stream/StreamMessageListenerContainer.java +++ b/src/main/java/org/springframework/data/redis/stream/StreamMessageListenerContainer.java @@ -20,6 +20,7 @@ import java.util.concurrent.Executor; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.springframework.context.SmartLifecycle; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -34,7 +35,6 @@ import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.stream.DefaultStreamMessageListenerContainer.LoggingErrorHandler; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ErrorHandler; @@ -289,8 +289,7 @@ public StreamOffset getStreamOffset() { return streamOffset; } - @Nullable - public ErrorHandler getErrorHandler() { + public @Nullable ErrorHandler getErrorHandler() { return errorHandler; } @@ -410,7 +409,7 @@ public StreamReadRequest build() { */ class ConsumerStreamReadRequestBuilder extends StreamReadRequestBuilder { - private Consumer consumer; + private @Nullable Consumer consumer; private boolean autoAck = true; ConsumerStreamReadRequestBuilder(StreamReadRequestBuilder other) { @@ -477,6 +476,8 @@ public ConsumerStreamReadRequestBuilder autoAcknowledge(boolean autoAck) { * @return a new instance of {@link ConsumerStreamReadRequest}. */ public ConsumerStreamReadRequest build() { + + Assert.notNull(consumer, "Consumer must be set"); return new ConsumerStreamReadRequest<>(streamOffset, errorHandler, cancelSubscriptionOnError, consumer, autoAck); } } @@ -553,11 +554,11 @@ public RedisSerializer getHashValueSerializer() { return hashValueSerializer; } - @Nullable - public HashMapper getHashMapper() { + public @Nullable HashMapper getHashMapper() { return hashMapper; } + @SuppressWarnings("NullAway") public HashMapper getRequiredHashMapper() { if (!hasHashMapper()) { @@ -615,6 +616,7 @@ class StreamMessageListenerContainerOptionsBuilder> { private ErrorHandler errorHandler = LoggingErrorHandler.INSTANCE; private Executor executor = new SimpleAsyncTaskExecutor(); + @SuppressWarnings("NullAway") private StreamMessageListenerContainerOptionsBuilder() {} /** diff --git a/src/main/java/org/springframework/data/redis/stream/StreamReceiver.java b/src/main/java/org/springframework/data/redis/stream/StreamReceiver.java index 96f9591c8f..3760e6f4b5 100644 --- a/src/main/java/org/springframework/data/redis/stream/StreamReceiver.java +++ b/src/main/java/org/springframework/data/redis/stream/StreamReceiver.java @@ -23,6 +23,7 @@ import java.util.OptionalInt; import java.util.function.Function; +import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; @@ -37,7 +38,6 @@ import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializationContext.SerializationPair; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -276,11 +276,11 @@ public SerializationPair getHashValueSerializer() { return hashValueSerializer; } - @Nullable - public HashMapper getHashMapper() { + public @Nullable HashMapper getHashMapper() { return hashMapper; } + @SuppressWarnings("NullAway") public HashMapper getRequiredHashMapper() { if (!hasHashMapper()) { @@ -321,6 +321,7 @@ class StreamReceiverOptionsBuilder> { private @Nullable HashMapper hashMapper; private @Nullable Class targetType; + @SuppressWarnings("NullAway") private StreamReceiverOptionsBuilder() {} /** diff --git a/src/main/java/org/springframework/data/redis/stream/package-info.java b/src/main/java/org/springframework/data/redis/stream/package-info.java new file mode 100644 index 0000000000..db36c4983b --- /dev/null +++ b/src/main/java/org/springframework/data/redis/stream/package-info.java @@ -0,0 +1,2 @@ +@org.jspecify.annotations.NullMarked +package org.springframework.data.redis.stream; diff --git a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicDouble.java b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicDouble.java index a95f78b3e5..8c59555ba8 100644 --- a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicDouble.java +++ b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicDouble.java @@ -22,6 +22,7 @@ import java.util.function.DoubleBinaryOperator; import java.util.function.DoubleUnaryOperator; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -31,7 +32,6 @@ import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java index a4f3e65dba..bb62ff854a 100644 --- a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java +++ b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicInteger.java @@ -22,6 +22,7 @@ import java.util.function.IntBinaryOperator; import java.util.function.IntUnaryOperator; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -31,7 +32,6 @@ import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicLong.java b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicLong.java index 2e488697ae..6a427eb05e 100644 --- a/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicLong.java +++ b/src/main/java/org/springframework/data/redis/support/atomic/RedisAtomicLong.java @@ -22,6 +22,7 @@ import java.util.function.LongBinaryOperator; import java.util.function.LongUnaryOperator; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisConnectionFactory; @@ -32,7 +33,6 @@ import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/support/atomic/package-info.java b/src/main/java/org/springframework/data/redis/support/atomic/package-info.java index f91d1502c0..dae4faee1e 100644 --- a/src/main/java/org/springframework/data/redis/support/atomic/package-info.java +++ b/src/main/java/org/springframework/data/redis/support/atomic/package-info.java @@ -1,6 +1,5 @@ /** * Small toolkit mirroring the {@code java.util.atomic} package in Redis. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.support.atomic; diff --git a/src/main/java/org/springframework/data/redis/support/collections/AbstractRedisCollection.java b/src/main/java/org/springframework/data/redis/support/collections/AbstractRedisCollection.java index 6c6f14d23d..48a5b6c6d5 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/AbstractRedisCollection.java +++ b/src/main/java/org/springframework/data/redis/support/collections/AbstractRedisCollection.java @@ -20,8 +20,8 @@ import java.util.Date; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.RedisOperations; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/support/collections/CollectionUtils.java b/src/main/java/org/springframework/data/redis/support/collections/CollectionUtils.java index 867d1ca3be..51cc59451d 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/CollectionUtils.java +++ b/src/main/java/org/springframework/data/redis/support/collections/CollectionUtils.java @@ -21,11 +21,11 @@ import java.util.Collections; import java.util.List; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.SessionCallback; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; /** * Utility class used mainly for type conversion by the default collection implementations. Meant for internal use. diff --git a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisList.java b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisList.java index 3de2317313..9dcae9c976 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisList.java +++ b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisList.java @@ -24,11 +24,11 @@ import java.util.NoSuchElementException; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisListCommands; import org.springframework.data.redis.core.BoundListOperations; import org.springframework.data.redis.core.RedisOperations; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -335,14 +335,12 @@ public boolean offer(E element) { } @Override - @Nullable - public E peek() { + public @Nullable E peek() { return listOps.getFirst(); } @Override - @Nullable - public E poll() { + public @Nullable E poll() { return listOps.leftPop(); } @@ -406,26 +404,22 @@ public boolean offerLast(E element) { } @Override - @Nullable - public E peekFirst() { + public @Nullable E peekFirst() { return peek(); } @Override - @Nullable - public E peekLast() { + public @Nullable E peekLast() { return listOps.getLast(); } @Override - @Nullable - public E pollFirst() { + public @Nullable E pollFirst() { return poll(); } @Override - @Nullable - public E pollLast() { + public @Nullable E pollLast() { return listOps.rightPop(); } @@ -499,8 +493,7 @@ public boolean offer(E element, long timeout, TimeUnit unit) throws InterruptedE } @Override - @Nullable - public E poll(long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E poll(long timeout, TimeUnit unit) throws InterruptedException { return listOps.leftPop(timeout, unit); } @@ -515,8 +508,7 @@ public int remainingCapacity() { } @Override - @Nullable - public E take() throws InterruptedException { + public @Nullable E take() throws InterruptedException { return poll(0, TimeUnit.SECONDS); } @@ -535,14 +527,12 @@ public boolean offerLast(E element, long timeout, TimeUnit unit) { } @Override - @Nullable - public E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { + public @Nullable E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { return poll(timeout, unit); } @Override - @Nullable - public E pollLast(long timeout, TimeUnit unit) { + public @Nullable E pollLast(long timeout, TimeUnit unit) { return listOps.rightPop(timeout, unit); } @@ -557,14 +547,12 @@ public void putLast(E element) throws InterruptedException { } @Override - @Nullable - public E takeFirst() throws InterruptedException { + public @Nullable E takeFirst() throws InterruptedException { return take(); } @Override - @Nullable - public E takeLast() { + public @Nullable E takeLast() { return pollLast(0, TimeUnit.SECONDS); } diff --git a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java index 3233ec59ac..061d24d2cb 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java +++ b/src/main/java/org/springframework/data/redis/support/collections/DefaultRedisMap.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.core.BoundHashFieldExpirationOperations; import org.springframework.data.redis.core.BoundHashOperations; @@ -29,7 +30,6 @@ import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.SessionCallback; -import org.springframework.lang.Nullable; /** * Default implementation for {@link RedisMap}. Note that the current implementation doesn't provide the same locking @@ -117,8 +117,7 @@ public Set> entrySet() { } @Override - @Nullable - public V get(Object key) { + public @Nullable V get(Object key) { return hashOps.get(key); } @@ -146,8 +145,7 @@ public void putAll(Map m) { } @Override - @Nullable - public V remove(Object key) { + public @Nullable V remove(Object key) { V v = get(key); hashOps.delete(key); @@ -193,8 +191,7 @@ public String toString() { } @Override - @Nullable - public V putIfAbsent(K key, V value) { + public @Nullable V putIfAbsent(K key, V value) { return (hashOps.putIfAbsent(key, value) ? null : get(key)); } @@ -255,8 +252,7 @@ public Boolean execute(RedisOperations ops) { } @Override - @Nullable - public V replace(K key, V value) { + public @Nullable V replace(K key, V value) { if (value == null) { throw new NullPointerException(); diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisCollectionFactoryBean.java b/src/main/java/org/springframework/data/redis/support/collections/RedisCollectionFactoryBean.java index b6fc3e35d2..08f13dda30 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisCollectionFactoryBean.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisCollectionFactoryBean.java @@ -17,6 +17,7 @@ import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.SmartFactoryBean; @@ -24,7 +25,6 @@ import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.util.Lazy; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisIterator.java b/src/main/java/org/springframework/data/redis/support/collections/RedisIterator.java index 10a43ef176..9853255a7f 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisIterator.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisIterator.java @@ -17,7 +17,7 @@ import java.util.Iterator; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Iterator extension for Redis collection removal. diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisList.java b/src/main/java/org/springframework/data/redis/support/collections/RedisList.java index 02fb6b55ab..76e6303758 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisList.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisList.java @@ -15,7 +15,7 @@ */ package org.springframework.data.redis.support.collections; -import static org.springframework.data.redis.connection.RedisListCommands.*; +import static org.springframework.data.redis.connection.RedisListCommands.Direction; import java.time.Duration; import java.util.Deque; @@ -24,10 +24,10 @@ import java.util.concurrent.BlockingDeque; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.BoundListOperations; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.TimeoutUtils; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -135,8 +135,7 @@ static RedisList create(BoundListOperations boundOps, int maxS * @see Direction#first() * @see Direction#last() */ - @Nullable - default E moveFirstTo(RedisList destination, Direction destinationPosition, Duration timeout) { + default @Nullable E moveFirstTo(RedisList destination, Direction destinationPosition, Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -194,8 +193,7 @@ default E moveFirstTo(RedisList destination, Direction destinationPosition, D * @see Direction#first() * @see Direction#last() */ - @Nullable - default E moveLastTo(RedisList destination, Direction destinationPosition, Duration timeout) { + default @Nullable E moveLastTo(RedisList destination, Direction destinationPosition, Duration timeout) { Assert.notNull(timeout, "Timeout must not be null"); Assert.isTrue(!timeout.isNegative(), "Timeout must not be negative"); @@ -263,8 +261,7 @@ default void addLast(E element) { * * @return the head of this {@link Deque}. */ - @Nullable - default E getFirst() { + default @Nullable E getFirst() { return peekFirst(); } @@ -275,8 +272,7 @@ default E getFirst() { * * @return the tail of this {@link Deque}. */ - @Nullable - default E getLast() { + default @Nullable E getLast() { return peekLast(); } @@ -287,8 +283,7 @@ default E getLast() { * * @return the head of this {@link Deque}. */ - @Nullable - default E removeFirst() { + default @Nullable E removeFirst() { return pollFirst(); } @@ -299,8 +294,7 @@ default E removeFirst() { * * @return the tail of this {@link Deque}. */ - @Nullable - default E removeLast() { + default @Nullable E removeLast() { return pollLast(); } diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisMap.java b/src/main/java/org/springframework/data/redis/support/collections/RedisMap.java index d9c8c0a35e..15d572e953 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisMap.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisMap.java @@ -21,8 +21,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentMap; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.core.BoundHashFieldExpirationOperations; -import org.springframework.lang.Nullable; /** * Map view of a Redis hash. @@ -68,8 +68,7 @@ public interface RedisMap extends RedisStore, ConcurrentMap { * @return {@literal null} if the hash does not exist. * @since 2.6 */ - @Nullable - Map.Entry randomEntry(); + Map.@Nullable Entry randomEntry(); /** * @since 1.4 diff --git a/src/main/java/org/springframework/data/redis/support/collections/RedisProperties.java b/src/main/java/org/springframework/data/redis/support/collections/RedisProperties.java index 5d3534fb6e..c3e13bbd39 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/RedisProperties.java +++ b/src/main/java/org/springframework/data/redis/support/collections/RedisProperties.java @@ -29,11 +29,11 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.core.BoundHashFieldExpirationOperations; import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.data.redis.core.RedisOperations; -import org.springframework.lang.Nullable; /** * {@link Properties} extension for a Redis back-store. Useful for reading (and storing) properties inside a Redis hash. diff --git a/src/main/java/org/springframework/data/redis/support/collections/ReversedRedisListView.java b/src/main/java/org/springframework/data/redis/support/collections/ReversedRedisListView.java index 89dd3da3f0..8bf81c95de 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/ReversedRedisListView.java +++ b/src/main/java/org/springframework/data/redis/support/collections/ReversedRedisListView.java @@ -24,10 +24,10 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisListCommands.Direction; import org.springframework.data.redis.core.RedisOperations; -import org.springframework.lang.Nullable; /** * Implementation and view of an existing {@link RedisList} where the elements in the list (deque) are returned in diff --git a/src/main/java/org/springframework/data/redis/support/collections/package-info.java b/src/main/java/org/springframework/data/redis/support/collections/package-info.java index 9e45b4bdb3..431d153708 100644 --- a/src/main/java/org/springframework/data/redis/support/collections/package-info.java +++ b/src/main/java/org/springframework/data/redis/support/collections/package-info.java @@ -11,6 +11,5 @@ * Lastly, for key/value associations {@link org.springframework.data.redis.support.collections.RedisMap} providing a * Map-like abstraction on top of a Redis hash. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullUnmarked package org.springframework.data.redis.support.collections; diff --git a/src/main/java/org/springframework/data/redis/util/RedisAssertions.java b/src/main/java/org/springframework/data/redis/util/RedisAssertions.java index 22da3c395d..0d85686d17 100644 --- a/src/main/java/org/springframework/data/redis/util/RedisAssertions.java +++ b/src/main/java/org/springframework/data/redis/util/RedisAssertions.java @@ -17,7 +17,7 @@ import java.util.function.Supplier; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; /** diff --git a/src/main/java/org/springframework/data/redis/util/package-info.java b/src/main/java/org/springframework/data/redis/util/package-info.java index 2d87f277f6..47637de74f 100644 --- a/src/main/java/org/springframework/data/redis/util/package-info.java +++ b/src/main/java/org/springframework/data/redis/util/package-info.java @@ -1,6 +1,5 @@ /** * Commonly used stuff for data manipulation throughout different driver specific implementations. */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields +@org.jspecify.annotations.NullMarked package org.springframework.data.redis.util; diff --git a/src/test/java/org/springframework/data/redis/Address.java b/src/test/java/org/springframework/data/redis/Address.java index f24a9c6d1d..5c1ef77826 100644 --- a/src/test/java/org/springframework/data/redis/Address.java +++ b/src/test/java/org/springframework/data/redis/Address.java @@ -17,7 +17,7 @@ import java.io.Serializable; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Simple serializable class. diff --git a/src/test/java/org/springframework/data/redis/Person.java b/src/test/java/org/springframework/data/redis/Person.java index 610257d7a0..9c528dde46 100644 --- a/src/test/java/org/springframework/data/redis/Person.java +++ b/src/test/java/org/springframework/data/redis/Person.java @@ -17,7 +17,7 @@ import java.io.Serializable; -import org.springframework.lang.Nullable; +import org.jspecify.annotations.Nullable; /** * Simple serializable class. diff --git a/src/test/java/org/springframework/data/redis/cache/CacheTestParams.java b/src/test/java/org/springframework/data/redis/cache/CacheTestParams.java index b037099902..6bc671ab0c 100644 --- a/src/test/java/org/springframework/data/redis/cache/CacheTestParams.java +++ b/src/test/java/org/springframework/data/redis/cache/CacheTestParams.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; @@ -37,7 +38,6 @@ import org.springframework.data.redis.test.condition.RedisDetector; import org.springframework.data.redis.test.extension.RedisCluster; import org.springframework.data.redis.test.extension.RedisStanalone; -import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -107,14 +107,12 @@ static class FixDamnedJunitParameterizedNameForRedisSerializer/* ¯\_(ツ)_/¯ * } @Override - @Nullable - public byte[] serialize(@Nullable Object value) throws SerializationException { + public byte @Nullable[] serialize(@Nullable Object value) throws SerializationException { return serializer.serialize(value); } @Override - @Nullable - public Object deserialize(@Nullable byte[] bytes) throws SerializationException { + public @Nullable Object deserialize(byte @Nullable[] bytes) throws SerializationException { return serializer.deserialize(bytes); } diff --git a/src/test/java/org/springframework/data/redis/cache/DefaultRedisCacheWriterTests.java b/src/test/java/org/springframework/data/redis/cache/DefaultRedisCacheWriterTests.java index 6b74b80931..24f7d1ad52 100644 --- a/src/test/java/org/springframework/data/redis/cache/DefaultRedisCacheWriterTests.java +++ b/src/test/java/org/springframework/data/redis/cache/DefaultRedisCacheWriterTests.java @@ -32,6 +32,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -44,7 +45,6 @@ import org.springframework.data.redis.test.condition.RedisDriver; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Integration tests for {@link DefaultRedisCacheWriter}. diff --git a/src/test/java/org/springframework/data/redis/cache/RedisCacheConfigurationUnitTests.java b/src/test/java/org/springframework/data/redis/cache/RedisCacheConfigurationUnitTests.java index 94de42115d..0a481f0cc6 100644 --- a/src/test/java/org/springframework/data/redis/cache/RedisCacheConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/redis/cache/RedisCacheConfigurationUnitTests.java @@ -26,12 +26,12 @@ import java.time.Duration; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.beans.DirectFieldAccessor; import org.springframework.core.convert.converter.Converter; import org.springframework.instrument.classloading.ShadowingClassLoader; -import org.springframework.lang.Nullable; /** * Unit tests for {@link RedisCacheConfiguration}. @@ -122,9 +122,8 @@ private static class DomainType { static class DomainTypeConverter implements Converter { - @Nullable @Override - public String convert(DomainType source) { + public @Nullable String convert(DomainType source) { return null; } } diff --git a/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java b/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java index 520b73d09f..d4de89ec41 100644 --- a/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java +++ b/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java @@ -34,6 +34,7 @@ import java.util.function.Function; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.springframework.cache.Cache.ValueWrapper; @@ -50,7 +51,6 @@ import org.springframework.data.redis.test.condition.RedisDriver; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Tests for {@link RedisCache} with {@link DefaultRedisCacheWriter} using different {@link RedisSerializer} and @@ -697,8 +697,7 @@ private RedisCacheWriter usingNonLockingRedisCacheWriter() { return RedisCacheWriter.nonLockingRedisCacheWriter(this.connectionFactory); } - @Nullable - private Object unwrap(@Nullable Object value) { + private @Nullable Object unwrap(@Nullable Object value) { return value instanceof ValueWrapper wrapper ? wrapper.get() : value; } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryIntegrationTests.java index 161561415e..0dbffd22ad 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryIntegrationTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.core.task.AsyncTaskExecutor; @@ -26,7 +27,6 @@ import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvailable; -import org.springframework.lang.Nullable; /** * Integration tests for {@link JedisConnectionFactory}. diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactorySentinelIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactorySentinelIntegrationTests.java index 6a75f265b1..ab28461fc8 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactorySentinelIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactorySentinelIntegrationTests.java @@ -19,13 +19,13 @@ import java.io.IOException; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.RedisSentinelConnection; import org.springframework.data.redis.test.condition.EnabledOnRedisSentinelAvailable; -import org.springframework.lang.Nullable; /** * Sentinel integration tests for {@link JedisConnectionFactory}. diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryUnitTests.java index d766502a8a..5eadfea82d 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionFactoryUnitTests.java @@ -38,6 +38,7 @@ import javax.net.ssl.SSLSocketFactory; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.redis.connection.RedisClusterConfiguration; @@ -45,7 +46,6 @@ import org.springframework.data.redis.connection.RedisSentinelConfiguration; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory.State; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; /** diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java index 5a869da105..40eafd76c3 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConvertersUnitTests.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Range; @@ -43,7 +44,6 @@ import org.springframework.data.redis.connection.RedisStringCommands.SetOption; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.core.types.RedisClientInfo; -import org.springframework.lang.Nullable; import org.springframework.test.util.ReflectionTestUtils; /** diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyspaceNotificationsTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyspaceNotificationsTests.java index 137423dd57..d1d39f28d2 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyspaceNotificationsTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyspaceNotificationsTests.java @@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -46,7 +47,6 @@ import org.springframework.data.redis.connection.RedisConfiguration; import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvailable; import org.springframework.data.redis.test.extension.LettuceTestClientResources; -import org.springframework.lang.Nullable; /** * Integration tests to listen for keyspace notifications. diff --git a/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsIntegrationTests.java b/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsIntegrationTests.java index 0000db4885..cfba8e52ef 100644 --- a/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/core/DefaultGeoOperationsIntegrationTests.java @@ -27,6 +27,7 @@ import java.util.Map; import org.assertj.core.data.Offset; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.springframework.dao.DataAccessException; @@ -44,7 +45,6 @@ import org.springframework.data.redis.test.condition.EnabledOnCommand; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Integration test of {@link org.springframework.data.redis.core.DefaultGeoOperations} diff --git a/src/test/java/org/springframework/data/redis/core/ReactiveOperationsTestParams.java b/src/test/java/org/springframework/data/redis/core/ReactiveOperationsTestParams.java index 77895e3bb2..eca5866593 100644 --- a/src/test/java/org/springframework/data/redis/core/ReactiveOperationsTestParams.java +++ b/src/test/java/org/springframework/data/redis/core/ReactiveOperationsTestParams.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.List; +import org.jspecify.annotations.Nullable; import org.springframework.data.redis.ByteBufferObjectFactory; import org.springframework.data.redis.DoubleObjectFactory; import org.springframework.data.redis.LongObjectFactory; @@ -43,7 +44,6 @@ import org.springframework.data.redis.test.condition.RedisDetector; import org.springframework.data.redis.test.extension.RedisCluster; import org.springframework.data.redis.test.extension.RedisStanalone; -import org.springframework.lang.Nullable; /** * Parameters for testing implementations of {@link ReactiveRedisTemplate} @@ -170,8 +170,7 @@ public ObjectFactory getValueFactory() { return valueFactory; } - @Nullable - public RedisSerializer getSerializer() { + public @Nullable RedisSerializer getSerializer() { return serializer; } diff --git a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java index fb464d61a3..dd575e9d20 100644 --- a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java +++ b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java @@ -26,6 +26,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -40,7 +41,6 @@ import org.springframework.data.redis.test.extension.RedisStanalone; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Integration tests for {@link RedisKeyValueTemplate}. diff --git a/src/test/java/org/springframework/data/redis/core/RedisTemplateUnitTests.java b/src/test/java/org/springframework/data/redis/core/RedisTemplateUnitTests.java index 06bea63fdc..3342b06f7c 100644 --- a/src/test/java/org/springframework/data/redis/core/RedisTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/RedisTemplateUnitTests.java @@ -20,6 +20,7 @@ import java.io.Serializable; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,7 +32,6 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.instrument.classloading.ShadowingClassLoader; -import org.springframework.lang.Nullable; import org.springframework.transaction.support.TransactionSynchronizationManager; /** diff --git a/src/test/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapperUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapperUnitTests.java index a25465545d..778367f551 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapperUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/DefaultRedisTypeMapperUnitTests.java @@ -21,13 +21,13 @@ import java.util.Arrays; import java.util.Collections; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.convert.ConfigurableTypeInformationMapper; import org.springframework.data.convert.SimpleTypeInformationMapper; import org.springframework.data.util.TypeInformation; -import org.springframework.lang.Nullable; /** * Unit tests for {@link DefaultRedisTypeMapper}. diff --git a/src/test/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainerIntegrationTests.java b/src/test/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainerIntegrationTests.java index 4b59bc872d..9734085b27 100644 --- a/src/test/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainerIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/listener/ReactiveRedisMessageListenerContainerIntegrationTests.java @@ -35,6 +35,7 @@ import java.util.function.Supplier; import org.awaitility.Awaitility; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -53,7 +54,6 @@ import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Integration tests for {@link ReactiveRedisMessageListenerContainer} via Lettuce. @@ -133,7 +133,7 @@ void receiveChannelShouldNotifySubscriptionListener() throws Exception { CompositeListener listener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { } @@ -200,7 +200,7 @@ void receivePatternShouldNotifySubscriptionListener() throws Exception { CompositeListener listener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { } diff --git a/src/test/java/org/springframework/data/redis/listener/RedisMessageListenerContainerIntegrationTests.java b/src/test/java/org/springframework/data/redis/listener/RedisMessageListenerContainerIntegrationTests.java index bea301b046..67f5083c2a 100644 --- a/src/test/java/org/springframework/data/redis/listener/RedisMessageListenerContainerIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/listener/RedisMessageListenerContainerIntegrationTests.java @@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.hamcrest.Matchers; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -42,7 +43,6 @@ import org.springframework.data.redis.test.extension.RedisStanalone; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import org.springframework.lang.Nullable; /** * Integration tests for {@link RedisMessageListenerContainer}. @@ -97,7 +97,7 @@ void notifiesChannelSubscriptionState() throws Exception { CompositeListener listener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { } @@ -137,7 +137,7 @@ void notifiesPatternSubscriptionState() throws Exception { CompositeListener listener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { } @@ -176,7 +176,7 @@ void repeatedSubscribeShouldNotifyOnlyOnce() throws Exception { CompositeListener listener1 = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { received.countDown(); } @@ -188,7 +188,7 @@ public void onPatternSubscribed(byte[] pattern, long count) { CompositeListener listener2 = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { received.countDown(); } @@ -224,7 +224,7 @@ void subscribeAfterStart() throws Exception { CompositeListener listener1 = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { received.countDown(); } @@ -236,7 +236,7 @@ public void onPatternSubscribed(byte[] pattern, long count) { CompositeListener listener2 = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { received.countDown(); } @@ -271,7 +271,7 @@ void multipleStarts() throws Exception { CompositeListener listener1 = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { received.countDown(); } @@ -306,7 +306,7 @@ void shouldRegisterChannelsAndTopics() throws Exception { CompositeListener patternListener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { if (message.toString().contains("pattern")) { received.countDown(); } @@ -320,7 +320,7 @@ public void onPatternSubscribed(byte[] pattern, long count) { CompositeListener channelListener = new CompositeListener() { @Override - public void onMessage(Message message, @Nullable byte[] pattern) { + public void onMessage(Message message, byte @Nullable[] pattern) { if (message.toString().contains("channel")) { received.countDown(); } diff --git a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java index 780f630b6b..63119488cd 100644 --- a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java +++ b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java @@ -25,6 +25,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -52,7 +53,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.QueryByExampleExecutor; import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; /** * Base for testing Redis repository support in different configurations. @@ -917,13 +917,11 @@ static User of(String name) { return new User(name); } - @Nullable - public OffsetTime getExpiration() { + public @Nullable OffsetTime getExpiration() { return this.expiration; } - @Nullable - public OffsetDateTime getLastAccessed() { + public @Nullable OffsetDateTime getLastAccessed() { return this.lastAccessed; } diff --git a/src/test/java/org/springframework/data/redis/repository/cdi/Person.java b/src/test/java/org/springframework/data/redis/repository/cdi/Person.java index 5a1d07e737..e0d06be5cc 100644 --- a/src/test/java/org/springframework/data/redis/repository/cdi/Person.java +++ b/src/test/java/org/springframework/data/redis/repository/cdi/Person.java @@ -15,10 +15,10 @@ */ package org.springframework.data.redis.repository.cdi; +import org.jspecify.annotations.Nullable; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; -import org.springframework.lang.Nullable; /** * @author Mark Paluch diff --git a/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java b/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java index 70f7d46615..2270aae7a3 100644 --- a/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java +++ b/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java @@ -29,14 +29,13 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; - +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.msgpack.jackson.dataformat.MessagePackFactory; import org.springframework.beans.BeanUtils; import org.springframework.cache.support.NullValue; -import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; @@ -525,8 +524,7 @@ private static void serializeAndDeserializeNullValue(GenericJackson2JsonRedisSer assertThat(deserializedValue).isInstanceOf(NullValue.class); } - @Nullable - private TypeResolverBuilder extractTypeResolver(GenericJackson2JsonRedisSerializer serializer) { + private @Nullable TypeResolverBuilder extractTypeResolver(GenericJackson2JsonRedisSerializer serializer) { ObjectMapper mapper = (ObjectMapper) getField(serializer, "mapper"); return mapper.getSerializationConfig().getDefaultTyper(TypeFactory.defaultInstance().constructType(Object.class));