diff --git a/spring-integration-core/src/main/java/org/springframework/integration/metadata/ConcurrentMetadataStore.java b/spring-integration-core/src/main/java/org/springframework/integration/metadata/ConcurrentMetadataStore.java index 17fb4086c4c..13df9913ec9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/metadata/ConcurrentMetadataStore.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/metadata/ConcurrentMetadataStore.java @@ -16,10 +16,13 @@ package org.springframework.integration.metadata; +import org.jspecify.annotations.Nullable; + /** * Supports atomic updates to values in the store. * * @author Gary Russell + * @author Glenn Renfro * @since 4.0 * */ @@ -32,6 +35,7 @@ public interface ConcurrentMetadataStore extends MetadataStore { * @param value The value. * @return null if successful, the old value otherwise. */ + @Nullable String putIfAbsent(String key, String value); /** diff --git a/spring-integration-core/src/main/java/org/springframework/integration/metadata/MetadataStore.java b/spring-integration-core/src/main/java/org/springframework/integration/metadata/MetadataStore.java index 4aafb6140a4..d3150c44b67 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/metadata/MetadataStore.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/metadata/MetadataStore.java @@ -16,6 +16,8 @@ package org.springframework.integration.metadata; +import org.jspecify.annotations.Nullable; + import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedResource; @@ -27,6 +29,7 @@ * @author Oleg Zhurakousky * @author Mark Fisher * @author Gary Russell + * @author Glenn Renfro * @since 2.0 */ @ManagedResource @@ -47,7 +50,7 @@ public interface MetadataStore { * @return The value. */ @ManagedAttribute - String get(String key); + @Nullable String get(String key); /** * Remove a value for the given key from this MetadataStore. @@ -56,6 +59,6 @@ public interface MetadataStore { * null if there was no mapping for key. */ @ManagedAttribute - String remove(String key); + @Nullable String remove(String key); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/metadata/PropertiesPersistingMetadataStore.java b/spring-integration-core/src/main/java/org/springframework/integration/metadata/PropertiesPersistingMetadataStore.java index 7b2a5c48e1a..0c7f7108d0a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/metadata/PropertiesPersistingMetadataStore.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/metadata/PropertiesPersistingMetadataStore.java @@ -31,6 +31,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; @@ -51,14 +52,13 @@ * @author Mark Fisher * @author Gary Russell * @author Artem Bilan + * @author Glenn Renfro * * @since 2.0 */ public class PropertiesPersistingMetadataStore implements ConcurrentMetadataStore, InitializingBean, DisposableBean, Closeable, Flushable { - private static final String KEY_CANNOT_BE_NULL = "'key' cannot be null"; - private final Log logger = LogFactory.getLog(getClass()); private final Properties metadata = new Properties(); @@ -71,6 +71,7 @@ public class PropertiesPersistingMetadataStore implements ConcurrentMetadataStor private String fileName = "metadata-store.properties"; + @SuppressWarnings("NullAway.Init") private File file; private volatile boolean dirty; @@ -115,8 +116,6 @@ public void afterPropertiesSet() { @Override public void put(String key, String value) { - Assert.notNull(key, KEY_CANNOT_BE_NULL); - Assert.notNull(value, "'value' cannot be null"); Lock lock = this.lockRegistry.obtain(key); lock.lock(); try { @@ -129,8 +128,7 @@ public void put(String key, String value) { } @Override - public String get(String key) { - Assert.notNull(key, KEY_CANNOT_BE_NULL); + public @Nullable String get(String key) { Lock lock = this.lockRegistry.obtain(key); lock.lock(); try { @@ -142,8 +140,7 @@ public String get(String key) { } @Override - public String remove(String key) { - Assert.notNull(key, KEY_CANNOT_BE_NULL); + public @Nullable String remove(String key) { Lock lock = this.lockRegistry.obtain(key); lock.lock(); try { @@ -156,9 +153,7 @@ public String remove(String key) { } @Override - public String putIfAbsent(String key, String value) { - Assert.notNull(key, KEY_CANNOT_BE_NULL); - Assert.notNull(value, "'value' cannot be null"); + public @Nullable String putIfAbsent(String key, String value) { Lock lock = this.lockRegistry.obtain(key); lock.lock(); try { @@ -179,9 +174,6 @@ public String putIfAbsent(String key, String value) { @Override public boolean replace(String key, String oldValue, String newValue) { - Assert.notNull(key, KEY_CANNOT_BE_NULL); - Assert.notNull(oldValue, "'oldValue' cannot be null"); - Assert.notNull(newValue, "'newValue' cannot be null"); Lock lock = this.lockRegistry.obtain(key); lock.lock(); try { @@ -216,7 +208,7 @@ public void destroy() { } private void saveMetadata() { - if (this.file == null || !this.dirty) { + if (!this.dirty) { return; } this.dirty = false; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/metadata/SimpleMetadataStore.java b/spring-integration-core/src/main/java/org/springframework/integration/metadata/SimpleMetadataStore.java index 011b140a3f8..1509bf39773 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/metadata/SimpleMetadataStore.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/metadata/SimpleMetadataStore.java @@ -19,6 +19,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.jspecify.annotations.Nullable; + import org.springframework.util.Assert; /** @@ -29,6 +31,7 @@ * @author Mark Fisher * @author Gary Russell * @author Artem Bilan + * @author Glenn Renfro * @since 2.0 */ public class SimpleMetadataStore implements ConcurrentMetadataStore { @@ -59,17 +62,17 @@ public void put(String key, String value) { } @Override - public String get(String key) { + public @Nullable String get(String key) { return this.metadata.get(key); } @Override - public String remove(String key) { + public @Nullable String remove(String key) { return this.metadata.remove(key); } @Override - public String putIfAbsent(String key, String value) { + public @Nullable String putIfAbsent(String key, String value) { return this.metadata.putIfAbsent(key, value); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/metadata/package-info.java b/spring-integration-core/src/main/java/org/springframework/integration/metadata/package-info.java index d27403d529a..1653b89386c 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/metadata/package-info.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/metadata/package-info.java @@ -1,4 +1,5 @@ /** * Provides classes supporting metadata stores. */ +@org.jspecify.annotations.NullMarked package org.springframework.integration.metadata; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/selector/MetadataStoreSelector.java b/spring-integration-core/src/main/java/org/springframework/integration/selector/MetadataStoreSelector.java index 00122c9db1b..071b278587a 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/selector/MetadataStoreSelector.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/selector/MetadataStoreSelector.java @@ -54,6 +54,7 @@ * @author Artem Bilan * @author Gary Russell * @author Christian Tzolov + * @author Glenn Renfro * * @since 4.1 */ @@ -114,10 +115,13 @@ public MetadataStoreSelector compareValues(@Nullable BiPredicate @Override public boolean accept(Message message) { String key = this.keyStrategy.processMessage(message); + Assert.state(key != null, () -> "The keyStrategy.processMessage must not return null."); + Long timestamp = message.getHeaders().getTimestamp(); String value = (this.valueStrategy != null) ? this.valueStrategy.processMessage(message) : (timestamp == null ? "0" : Long.toString(timestamp)); + Assert.state(value != null, () -> "The valueStrategy.processMessage must not return null."); BiPredicate predicate = this.compareValues; if (predicate == null) {