diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterAnnotationPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterAnnotationPostProcessor.java index bff94817c9b..9a60613db71 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/RouterAnnotationPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/RouterAnnotationPostProcessor.java @@ -37,6 +37,7 @@ import org.springframework.integration.router.MethodInvokingRouter; import org.springframework.integration.util.MessagingAnnotationUtils; import org.springframework.messaging.MessageHandler; +import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -169,6 +170,7 @@ private void routerAttributes(List annotations, AbstractMessageRoute } Properties properties = (Properties) getConversionService().convert(mappings.toString(), TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Properties.class)); + Assert.state(properties != null, "The properties for channel mappings must not be null."); methodInvokingRouter.replaceChannelMappings(properties); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java index 289633dbbbe..f28fb331f16 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMappingMessageRouter.java @@ -27,6 +27,8 @@ import java.util.Properties; import java.util.Set; +import org.jspecify.annotations.Nullable; + import org.springframework.core.convert.ConversionService; import org.springframework.core.log.LogMessage; import org.springframework.integration.support.management.MappingMessageRouterManagement; @@ -50,6 +52,7 @@ * @author Artem Bilan * @author Trung Pham * @author Ngoc Nhan + * @author Glenn Renfro * * @since 2.1 */ @@ -72,9 +75,9 @@ protected boolean removeEldestEntry(Entry eldest) { }); - private String prefix; + private @Nullable String prefix; - private String suffix; + private @Nullable String suffix; private boolean resolutionRequired = true; @@ -104,7 +107,7 @@ public void setChannelMappings(Map channelMappings) { * Specify a prefix to be added to each channel name prior to resolution. * @param prefix The prefix. */ - public void setPrefix(String prefix) { + public void setPrefix(@Nullable String prefix) { this.prefix = prefix; } @@ -112,7 +115,7 @@ public void setPrefix(String prefix) { * Specify a suffix to be added to each channel name prior to resolution. * @param suffix The suffix. */ - public void setSuffix(String suffix) { + public void setSuffix(@Nullable String suffix) { this.suffix = suffix; } @@ -274,7 +277,7 @@ protected Collection determineTargetChannels(Message message) * @param message The message. * @return The channel keys. */ - protected abstract List getChannelKeys(Message message); + protected abstract @Nullable List getChannelKeys(Message message); /** * Convenience method allowing conversion of a list @@ -289,7 +292,6 @@ protected Collection determineTargetChannels(Message message) @Override @ManagedOperation public void replaceChannelMappings(Properties channelMappings) { - Assert.notNull(channelMappings, "'channelMappings' must not be null"); Map newChannelMappings = new LinkedHashMap<>(); Set keys = channelMappings.stringPropertyNames(); for (String key : keys) { @@ -304,7 +306,7 @@ private void doSetChannelMappings(Map newChannelMappings) { logger.debug(LogMessage.format("Channel mappings: %s replaced with: %s", oldChannelMappings, newChannelMappings)); } - private MessageChannel resolveChannelForName(String channelName, Message message) { + private @Nullable MessageChannel resolveChannelForName(String channelName, Message message) { MessageChannel channel = null; try { channel = getChannelResolver().resolveDestination(channelName); @@ -360,7 +362,7 @@ private void addChannel(Collection channels, Message message, } } - private void addToCollection(Collection channels, Collection channelKeys, Message message) { + private void addToCollection(Collection channels, @Nullable Collection channelKeys, Message message) { if (channelKeys == null) { return; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java index f43e4a37244..a0da6d2c71d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/AbstractMessageRouter.java @@ -21,6 +21,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import org.jspecify.annotations.Nullable; + import org.springframework.beans.factory.BeanFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; @@ -47,6 +49,7 @@ * @author Stefan Ferstl * @author Artem Bilan * @author Christian Tzolov + * @author Glenn Renfro */ @ManagedResource @IntegrationManagedResource @@ -56,9 +59,9 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler imple private final MessagingTemplate messagingTemplate = new MessagingTemplate(); - private volatile MessageChannel defaultOutputChannel; + private volatile @Nullable MessageChannel defaultOutputChannel; - private volatile String defaultOutputChannelName; + private volatile @Nullable String defaultOutputChannelName; private volatile boolean ignoreSendFailures; @@ -85,7 +88,7 @@ public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) { * @since 4.3 */ @Override - public MessageChannel getDefaultOutputChannel() { + public @Nullable MessageChannel getDefaultOutputChannel() { if (this.defaultOutputChannelName != null) { this.lock.lock(); try { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/MessageRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/MessageRouter.java index 19178da0b83..bbd6521cb22 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/MessageRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/MessageRouter.java @@ -16,6 +16,8 @@ package org.springframework.integration.router; +import org.jspecify.annotations.Nullable; + import org.springframework.messaging.MessageChannel; /** @@ -31,6 +33,7 @@ public interface MessageRouter { * Get the default output channel. * @return the channel. */ + @Nullable MessageChannel getDefaultOutputChannel(); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java index fb6cc71e59f..7cd7a347c18 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/PayloadTypeRouter.java @@ -20,6 +20,8 @@ import java.util.LinkedList; import java.util.List; +import org.jspecify.annotations.Nullable; + import org.springframework.messaging.Message; import org.springframework.util.CollectionUtils; @@ -31,6 +33,7 @@ * @author Oleg Zhurakousky * @author Gary Russell * @author Artem Bilan + * @author Glenn Renfro */ public class PayloadTypeRouter extends AbstractMappingMessageRouter { @@ -46,7 +49,7 @@ public class PayloadTypeRouter extends AbstractMappingMessageRouter { * preferring direct interface over indirect subclass */ @Override - protected List getChannelKeys(Message message) { + protected @Nullable List getChannelKeys(Message message) { if (CollectionUtils.isEmpty(getChannelMappings())) { return null; } @@ -59,7 +62,7 @@ protected List getChannelKeys(Message message) { return (closestMatch != null) ? Collections.singletonList(closestMatch) : null; } - private String findClosestMatch(Class type, boolean isArray) { // NOSONAR + private @Nullable String findClosestMatch(Class type, boolean isArray) { // NOSONAR int minTypeDiffWeight = Integer.MAX_VALUE; List matches = new LinkedList<>(); for (String candidate : getChannelMappings().keySet()) { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java b/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java index 0fa99db99ce..cd730312e9e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/RecipientListRouter.java @@ -76,6 +76,7 @@ * @author Artem Bilan * @author Liujiong * @author Gary Russell + * @author Glenn Renfro */ public class RecipientListRouter extends AbstractMessageRouter implements RecipientListRouterManagement { @@ -151,11 +152,11 @@ public void addRecipient(String channelName) { addRecipient(channelName, (MessageSelector) null); } - public void addRecipient(String channelName, MessageSelector selector) { + public void addRecipient(String channelName, @Nullable MessageSelector selector) { addRecipient(channelName, selector, this.recipients); } - private void addRecipient(String channelName, MessageSelector selector, Queue recipientsToAdd) { + private void addRecipient(String channelName, @Nullable MessageSelector selector, Queue recipientsToAdd) { Assert.hasText(channelName, "'channelName' must not be empty."); Recipient recipient = new Recipient(channelName, selector); setupRecipient(recipient); @@ -166,7 +167,7 @@ public void addRecipient(MessageChannel channel) { addRecipient(channel, null); } - public void addRecipient(MessageChannel channel, MessageSelector selector) { + public void addRecipient(MessageChannel channel, @Nullable MessageSelector selector) { Recipient recipient = new Recipient(channel, selector); setupRecipient(recipient); this.recipients.add(recipient); @@ -273,19 +274,19 @@ protected void onInit() { public static class Recipient { - private final MessageSelector selector; + private final @Nullable MessageSelector selector; - private MessageChannel channel; + private @Nullable MessageChannel channel; - private String channelName; + private @Nullable String channelName; - private DestinationResolver channelResolver; + private @Nullable DestinationResolver channelResolver; public Recipient(MessageChannel channel) { this(channel, null); } - public Recipient(MessageChannel channel, MessageSelector selector) { + public Recipient(MessageChannel channel, @Nullable MessageSelector selector) { this.channel = channel; this.selector = selector; } @@ -294,7 +295,7 @@ public Recipient(String channelName) { this(channelName, null); } - public Recipient(String channelName, MessageSelector selector) { + public Recipient(String channelName, @Nullable MessageSelector selector) { this.channelName = channelName; this.selector = selector; } @@ -303,7 +304,7 @@ public void setChannelResolver(DestinationResolver channelResolv this.channelResolver = channelResolver; } - private MessageSelector getSelector() { + private @Nullable MessageSelector getSelector() { return this.selector; } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/router/package-info.java b/spring-integration-core/src/main/java/org/springframework/integration/router/package-info.java index 53ed711dea5..4cfa0791c1e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/router/package-info.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/router/package-info.java @@ -1,4 +1,5 @@ /** * Provides classes supporting the router pattern. */ +@org.jspecify.annotations.NullMarked package org.springframework.integration.router;