Skip to content

Commit 6224ef9

Browse files
authored
GH-10083: Add nullability to Core metadata package
Related to: #10083 * `ConcurrentMetadataStore`: Added `@Nullable` annotation to `putIfAbsent` method return type for better null safety. * `MetadataStore`: Added `@Nullable` annotations to `get` and `remove` method return types to indicate they can return null. * `PropertiesPersistingMetadataStore`: Removed explicit null checks with `Assert.notNull()` calls and added `@Nullable` annotations to method signatures while simplifying `saveMetadata` logic. * `SimpleMetadataStore`: Added `@Nullable` annotations to `get`, `remove`, and `putIfAbsent` method return types for consistency with interface. * `MetadataStoreSelector`: Added `Assert.state()` calls to validate that `keyStrategy` and `valueStrategy` do not return null values.
1 parent b5cf9b3 commit 6224ef9

File tree

6 files changed

+27
-20
lines changed

6 files changed

+27
-20
lines changed

spring-integration-core/src/main/java/org/springframework/integration/metadata/ConcurrentMetadataStore.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package org.springframework.integration.metadata;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
/**
2022
* Supports atomic updates to values in the store.
2123
*
2224
* @author Gary Russell
25+
* @author Glenn Renfro
2326
* @since 4.0
2427
*
2528
*/
@@ -32,6 +35,7 @@ public interface ConcurrentMetadataStore extends MetadataStore {
3235
* @param value The value.
3336
* @return null if successful, the old value otherwise.
3437
*/
38+
@Nullable
3539
String putIfAbsent(String key, String value);
3640

3741
/**

spring-integration-core/src/main/java/org/springframework/integration/metadata/MetadataStore.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.integration.metadata;
1818

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.jmx.export.annotation.ManagedAttribute;
2022
import org.springframework.jmx.export.annotation.ManagedResource;
2123

@@ -27,6 +29,7 @@
2729
* @author Oleg Zhurakousky
2830
* @author Mark Fisher
2931
* @author Gary Russell
32+
* @author Glenn Renfro
3033
* @since 2.0
3134
*/
3235
@ManagedResource
@@ -47,7 +50,7 @@ public interface MetadataStore {
4750
* @return The value.
4851
*/
4952
@ManagedAttribute
50-
String get(String key);
53+
@Nullable String get(String key);
5154

5255
/**
5356
* Remove a value for the given key from this MetadataStore.
@@ -56,6 +59,6 @@ public interface MetadataStore {
5659
* null if there was no mapping for key.
5760
*/
5861
@ManagedAttribute
59-
String remove(String key);
62+
@Nullable String remove(String key);
6063

6164
}

spring-integration-core/src/main/java/org/springframework/integration/metadata/PropertiesPersistingMetadataStore.java

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import org.apache.commons.logging.Log;
3333
import org.apache.commons.logging.LogFactory;
34+
import org.jspecify.annotations.Nullable;
3435

3536
import org.springframework.beans.factory.DisposableBean;
3637
import org.springframework.beans.factory.InitializingBean;
@@ -51,14 +52,13 @@
5152
* @author Mark Fisher
5253
* @author Gary Russell
5354
* @author Artem Bilan
55+
* @author Glenn Renfro
5456
*
5557
* @since 2.0
5658
*/
5759
public class PropertiesPersistingMetadataStore implements ConcurrentMetadataStore, InitializingBean, DisposableBean,
5860
Closeable, Flushable {
5961

60-
private static final String KEY_CANNOT_BE_NULL = "'key' cannot be null";
61-
6262
private final Log logger = LogFactory.getLog(getClass());
6363

6464
private final Properties metadata = new Properties();
@@ -71,6 +71,7 @@ public class PropertiesPersistingMetadataStore implements ConcurrentMetadataStor
7171

7272
private String fileName = "metadata-store.properties";
7373

74+
@SuppressWarnings("NullAway.Init")
7475
private File file;
7576

7677
private volatile boolean dirty;
@@ -115,8 +116,6 @@ public void afterPropertiesSet() {
115116

116117
@Override
117118
public void put(String key, String value) {
118-
Assert.notNull(key, KEY_CANNOT_BE_NULL);
119-
Assert.notNull(value, "'value' cannot be null");
120119
Lock lock = this.lockRegistry.obtain(key);
121120
lock.lock();
122121
try {
@@ -129,8 +128,7 @@ public void put(String key, String value) {
129128
}
130129

131130
@Override
132-
public String get(String key) {
133-
Assert.notNull(key, KEY_CANNOT_BE_NULL);
131+
public @Nullable String get(String key) {
134132
Lock lock = this.lockRegistry.obtain(key);
135133
lock.lock();
136134
try {
@@ -142,8 +140,7 @@ public String get(String key) {
142140
}
143141

144142
@Override
145-
public String remove(String key) {
146-
Assert.notNull(key, KEY_CANNOT_BE_NULL);
143+
public @Nullable String remove(String key) {
147144
Lock lock = this.lockRegistry.obtain(key);
148145
lock.lock();
149146
try {
@@ -156,9 +153,7 @@ public String remove(String key) {
156153
}
157154

158155
@Override
159-
public String putIfAbsent(String key, String value) {
160-
Assert.notNull(key, KEY_CANNOT_BE_NULL);
161-
Assert.notNull(value, "'value' cannot be null");
156+
public @Nullable String putIfAbsent(String key, String value) {
162157
Lock lock = this.lockRegistry.obtain(key);
163158
lock.lock();
164159
try {
@@ -179,9 +174,6 @@ public String putIfAbsent(String key, String value) {
179174

180175
@Override
181176
public boolean replace(String key, String oldValue, String newValue) {
182-
Assert.notNull(key, KEY_CANNOT_BE_NULL);
183-
Assert.notNull(oldValue, "'oldValue' cannot be null");
184-
Assert.notNull(newValue, "'newValue' cannot be null");
185177
Lock lock = this.lockRegistry.obtain(key);
186178
lock.lock();
187179
try {
@@ -216,7 +208,7 @@ public void destroy() {
216208
}
217209

218210
private void saveMetadata() {
219-
if (this.file == null || !this.dirty) {
211+
if (!this.dirty) {
220212
return;
221213
}
222214
this.dirty = false;

spring-integration-core/src/main/java/org/springframework/integration/metadata/SimpleMetadataStore.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.concurrent.ConcurrentHashMap;
2020
import java.util.concurrent.ConcurrentMap;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.util.Assert;
2325

2426
/**
@@ -29,6 +31,7 @@
2931
* @author Mark Fisher
3032
* @author Gary Russell
3133
* @author Artem Bilan
34+
* @author Glenn Renfro
3235
* @since 2.0
3336
*/
3437
public class SimpleMetadataStore implements ConcurrentMetadataStore {
@@ -59,17 +62,17 @@ public void put(String key, String value) {
5962
}
6063

6164
@Override
62-
public String get(String key) {
65+
public @Nullable String get(String key) {
6366
return this.metadata.get(key);
6467
}
6568

6669
@Override
67-
public String remove(String key) {
70+
public @Nullable String remove(String key) {
6871
return this.metadata.remove(key);
6972
}
7073

7174
@Override
72-
public String putIfAbsent(String key, String value) {
75+
public @Nullable String putIfAbsent(String key, String value) {
7376
return this.metadata.putIfAbsent(key, value);
7477
}
7578

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
22
* Provides classes supporting metadata stores.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.metadata;

spring-integration-core/src/main/java/org/springframework/integration/selector/MetadataStoreSelector.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
* @author Artem Bilan
5555
* @author Gary Russell
5656
* @author Christian Tzolov
57+
* @author Glenn Renfro
5758
*
5859
* @since 4.1
5960
*/
@@ -114,10 +115,13 @@ public MetadataStoreSelector compareValues(@Nullable BiPredicate<String, String>
114115
@Override
115116
public boolean accept(Message<?> message) {
116117
String key = this.keyStrategy.processMessage(message);
118+
Assert.state(key != null, () -> "The keyStrategy.processMessage must not return null.");
119+
117120
Long timestamp = message.getHeaders().getTimestamp();
118121
String value = (this.valueStrategy != null)
119122
? this.valueStrategy.processMessage(message)
120123
: (timestamp == null ? "0" : Long.toString(timestamp));
124+
Assert.state(value != null, () -> "The valueStrategy.processMessage must not return null.");
121125

122126
BiPredicate<String, String> predicate = this.compareValues;
123127
if (predicate == null) {

0 commit comments

Comments
 (0)