Introduce null-safety of Spring Framework API
This commit introduces 2 new @Nullable and @NonNullApi annotations that leverage JSR 305 (dormant but available via Findbugs jsr305 dependency and already used by libraries like OkHttp) meta-annotations to specify explicitly null-safety of Spring Framework parameters and return values. In order to avoid adding too much annotations, the default is set at package level with @NonNullApi and @Nullable annotations are added when needed at parameter or return value level. These annotations are intended to be used on Spring Framework itself but also by other Spring projects. @Nullable annotations have been introduced based on Javadoc and search of patterns like "return null;". It is expected that nullability of Spring Framework API will be polished with complementary commits. In practice, this will make the whole Spring Framework API null-safe for Kotlin projects (when KT-10942 will be fixed) since Kotlin will be able to leverage these annotations to know if a parameter or a return value is nullable or not. But this is also useful for Java developers as well since IntelliJ IDEA, for example, also understands these annotations to generate warnings when unsafe nullable usages are detected. Issue: SPR-15540
This commit is contained in:
@@ -31,6 +31,7 @@ import java.util.UUID;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
import org.springframework.util.IdGenerator;
|
||||
|
||||
@@ -164,24 +165,29 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
|
||||
return (idGenerator != null ? idGenerator : defaultIdGenerator);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UUID getId() {
|
||||
return get(ID, UUID.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
return get(TIMESTAMP, Long.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getReplyChannel() {
|
||||
return get(REPLY_CHANNEL);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getErrorChannel() {
|
||||
return get(ERROR_CHANNEL);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T> T get(Object key, Class<T> type) {
|
||||
Object value = this.headers.get(key);
|
||||
if (value == null) {
|
||||
@@ -209,6 +215,7 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
|
||||
return Collections.unmodifiableMap(this.headers).entrySet();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object get(Object key) {
|
||||
return this.headers.get(key);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.messaging;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link MessageChannel} from which messages may be actively received through polling.
|
||||
*
|
||||
@@ -28,6 +30,7 @@ public interface PollableChannel extends MessageChannel {
|
||||
* Receive a message from this channel, blocking indefinitely if necessary.
|
||||
* @return the next available {@link Message} or {@code null} if interrupted
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> receive();
|
||||
|
||||
/**
|
||||
@@ -37,6 +40,7 @@ public interface PollableChannel extends MessageChannel {
|
||||
* @return the next available {@link Message} or {@code null} if the specified timeout
|
||||
* period elapses or the message reception is interrupted
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> receive(long timeout);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
@@ -157,6 +158,7 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
|
||||
* @param payload the payload being converted to message
|
||||
* @return the content type, or {@code null} if not known
|
||||
*/
|
||||
@Nullable
|
||||
protected MimeType getDefaultContentType(Object payload) {
|
||||
List<MimeType> mimeTypes = getSupportedMimeTypes();
|
||||
return (!mimeTypes.isEmpty() ? mimeTypes.get(0) : null);
|
||||
@@ -255,7 +257,8 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
|
||||
* perform the conversion
|
||||
* @since 4.2
|
||||
*/
|
||||
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, Object conversionHint) {
|
||||
@Nullable
|
||||
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -269,7 +272,8 @@ public abstract class AbstractMessageConverter implements SmartMessageConverter
|
||||
* cannot perform the conversion
|
||||
* @since 4.2
|
||||
*/
|
||||
protected Object convertToInternal(Object payload, MessageHeaders headers, Object conversionHint) {
|
||||
@Nullable
|
||||
protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.converter;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
@@ -32,13 +33,14 @@ public interface ContentTypeResolver {
|
||||
* Determine the {@link MimeType} of a message from the given MessageHeaders.
|
||||
*
|
||||
* @param headers the headers to use for the resolution
|
||||
* @return the resolved {@code MimeType} of {@code null} if none found
|
||||
* @return the resolved {@code MimeType} or {@code null} if none found
|
||||
*
|
||||
* @throws org.springframework.util.InvalidMimeTypeException if the content type
|
||||
* is a String that cannot be parsed
|
||||
* @throws java.lang.IllegalArgumentException if there is a content type but
|
||||
* its type is unknown
|
||||
*/
|
||||
@Nullable
|
||||
MimeType resolve(MessageHeaders headers);
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -266,6 +267,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter {
|
||||
* @return the serialization view class, or {@code null} if none
|
||||
* @since 4.2
|
||||
*/
|
||||
@Nullable
|
||||
protected Class<?> getSerializationView(Object conversionHint) {
|
||||
if (conversionHint instanceof MethodParameter) {
|
||||
MethodParameter param = (MethodParameter) conversionHint;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.converter;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
@@ -41,6 +42,7 @@ public interface MessageConverter {
|
||||
* @return the result of the conversion, or {@code null} if the converter cannot
|
||||
* perform the conversion
|
||||
*/
|
||||
@Nullable
|
||||
Object fromMessage(Message<?> message, Class<?> targetClass);
|
||||
|
||||
/**
|
||||
@@ -56,6 +58,7 @@ public interface MessageConverter {
|
||||
* @return the new message, or {@code null} if the converter does not support the
|
||||
* Object type or the target media type
|
||||
*/
|
||||
Message<?> toMessage(Object payload, MessageHeaders headers);
|
||||
@Nullable
|
||||
Message<?> toMessage(Object payload, @Nullable MessageHeaders headers);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.converter;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
@@ -43,7 +44,8 @@ public interface SmartMessageConverter extends MessageConverter {
|
||||
* perform the conversion
|
||||
* @see #fromMessage(Message, Class)
|
||||
*/
|
||||
Object fromMessage(Message<?> message, Class<?> targetClass, Object conversionHint);
|
||||
@Nullable
|
||||
Object fromMessage(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint);
|
||||
|
||||
/**
|
||||
* A variant of {@link #toMessage(Object, MessageHeaders)} which takes an extra
|
||||
@@ -57,6 +59,7 @@ public interface SmartMessageConverter extends MessageConverter {
|
||||
* Object type or the target media type
|
||||
* @see #toMessage(Object, MessageHeaders)
|
||||
*/
|
||||
Message<?> toMessage(Object payload, MessageHeaders headers, Object conversionHint);
|
||||
@Nullable
|
||||
Message<?> toMessage(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Provides support for message conversion.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.converter;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.core;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
@@ -48,6 +49,7 @@ public abstract class AbstractMessageReceivingTemplate<D> extends AbstractMessag
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract Message<?> doReceive(D destination);
|
||||
|
||||
|
||||
@@ -74,6 +76,7 @@ public abstract class AbstractMessageReceivingTemplate<D> extends AbstractMessag
|
||||
* @return the converted payload of the reply message (never {@code null})
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
protected <T> T doConvert(Message<?> message, Class<T> targetClass) {
|
||||
MessageConverter messageConverter = getMessageConverter();
|
||||
T value = (T) messageConverter.fromMessage(message, targetClass);
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
@@ -189,7 +190,8 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
|
||||
* @param headers the headers to send (or {@code null} if none)
|
||||
* @return the actual headers to send (or {@code null} if none)
|
||||
*/
|
||||
protected Map<String, Object> processHeadersToSend(Map<String, Object> headers) {
|
||||
@Nullable
|
||||
protected Map<String, Object> processHeadersToSend(@Nullable Map<String, Object> headers) {
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
@@ -40,6 +41,7 @@ public interface DestinationResolvingMessageRequestReplyOperations<D> extends Me
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> sendAndReceive(String destinationName, Message<?> requestMessage) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -54,6 +56,7 @@ public interface DestinationResolvingMessageRequestReplyOperations<D> extends Me
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(String destinationName, Object request, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
|
||||
@@ -70,6 +73,7 @@ public interface DestinationResolvingMessageRequestReplyOperations<D> extends Me
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers,
|
||||
Class<T> targetClass) throws MessagingException;
|
||||
|
||||
@@ -87,6 +91,7 @@ public interface DestinationResolvingMessageRequestReplyOperations<D> extends Me
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(String destinationName, Object request,
|
||||
Class<T> targetClass, MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
@@ -105,6 +110,7 @@ public interface DestinationResolvingMessageRequestReplyOperations<D> extends Me
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(String destinationName, Object request, Map<String, Object> headers,
|
||||
Class<T> targetClass, MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.core;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
@@ -35,6 +36,7 @@ public interface MessageReceivingOperations<D> {
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> receive() throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,7 @@ public interface MessageReceivingOperations<D> {
|
||||
* @return the received message, possibly {@code null} if the message could not
|
||||
* be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> receive(D destination) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -52,6 +55,7 @@ public interface MessageReceivingOperations<D> {
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T receiveAndConvert(Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -62,6 +66,7 @@ public interface MessageReceivingOperations<D> {
|
||||
* @return the converted payload of the reply message, possibly {@code null} if
|
||||
* the message could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T receiveAndConvert(D destination, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
@@ -38,6 +39,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the reply, possibly {@code null} if the message could not be received,
|
||||
* for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> sendAndReceive(Message<?> requestMessage) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -47,6 +49,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the reply, possibly {@code null} if the message could not be received,
|
||||
* for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> sendAndReceive(D destination, Message<?> requestMessage) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -59,6 +62,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(Object request, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -72,6 +76,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(D destination, Object request, Class<T> targetClass) throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -86,6 +91,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(D destination, Object request, Map<String, Object> headers, Class<T> targetClass)
|
||||
throws MessagingException;
|
||||
|
||||
@@ -101,6 +107,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(Object request, Class<T> targetClass, MessagePostProcessor requestPostProcessor)
|
||||
throws MessagingException;
|
||||
|
||||
@@ -117,6 +124,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(D destination, Object request, Class<T> targetClass,
|
||||
MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
@@ -133,6 +141,7 @@ public interface MessageRequestReplyOperations<D> {
|
||||
* @return the payload of the reply message, possibly {@code null} if the message
|
||||
* could not be received, for example due to a timeout
|
||||
*/
|
||||
@Nullable
|
||||
<T> T convertSendAndReceive(D destination, Object request, Map<String, Object> headers,
|
||||
Class<T> targetClass, MessagePostProcessor requestPostProcessor) throws MessagingException;
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Defines interfaces and implementation classes for messaging templates.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.core;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.handler;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -46,6 +47,7 @@ public interface MessageCondition<T> {
|
||||
* condition with sorted, matching patterns only.
|
||||
* @return a condition instance in case of a match; or {@code null} if there is no match.
|
||||
*/
|
||||
@Nullable
|
||||
T getMatchingCondition(Message<?> message);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Annotations and support classes for handling messages.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.handler.annotation;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.ValueConstants;
|
||||
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
|
||||
@@ -75,7 +76,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||
* and {@code #{...}} SpEL expressions in default values, or {@code null} if default
|
||||
* values are not expected to contain expressions
|
||||
*/
|
||||
protected AbstractNamedValueMethodArgumentResolver(ConversionService cs, ConfigurableBeanFactory beanFactory) {
|
||||
protected AbstractNamedValueMethodArgumentResolver(ConversionService cs, @Nullable ConfigurableBeanFactory beanFactory) {
|
||||
this.conversionService = (cs != null ? cs : DefaultConversionService.getSharedInstance());
|
||||
this.configurableBeanFactory = beanFactory;
|
||||
this.expressionContext = (beanFactory != null ? new BeanExpressionContext(beanFactory, null) : null);
|
||||
@@ -177,6 +178,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||
* @return the resolved argument. May be {@code null}
|
||||
* @throws Exception in case of errors
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract Object resolveArgumentInternal(MethodParameter parameter, Message<?> message, String name)
|
||||
throws Exception;
|
||||
|
||||
@@ -194,7 +196,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||
* A {@code null} results in a {@code false} value for {@code boolean}s or an
|
||||
* exception for other primitives.
|
||||
*/
|
||||
private Object handleNullValue(String name, Object value, Class<?> paramType) {
|
||||
private Object handleNullValue(String name, @Nullable Object value, Class<?> paramType) {
|
||||
if (value == null) {
|
||||
if (Boolean.TYPE.equals(paramType)) {
|
||||
return Boolean.FALSE;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
@@ -76,6 +77,7 @@ public class HeaderMethodArgumentResolver extends AbstractNamedValueMethodArgume
|
||||
return (headerValue != null ? headerValue : nativeHeaderValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object getNativeHeaderValue(Message<?> message, String name) {
|
||||
Map<String, List<String>> nativeHeaders = getNativeHeaders(message);
|
||||
if (name.startsWith("nativeHeaders.")) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.lang.reflect.Type;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
@@ -57,7 +58,7 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol
|
||||
* @param converter the MessageConverter to use (may be {@code null})
|
||||
* @since 4.3
|
||||
*/
|
||||
public MessageMethodArgumentResolver(MessageConverter converter) {
|
||||
public MessageMethodArgumentResolver(@Nullable MessageConverter converter) {
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
@@ -103,7 +104,7 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol
|
||||
* Check if the given {@code payload} is empty.
|
||||
* @param payload the payload to check (can be {@code null})
|
||||
*/
|
||||
protected boolean isEmptyPayload(Object payload) {
|
||||
protected boolean isEmptyPayload(@Nullable Object payload) {
|
||||
if (payload == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.messaging.handler.annotation.support;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.invocation.MethodArgumentResolutionException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
@@ -57,6 +58,7 @@ public class MethodArgumentNotValidException extends MethodArgumentResolutionExc
|
||||
* Return the BindingResult if the failure is validation-related,
|
||||
* or {@code null} if none.
|
||||
*/
|
||||
@Nullable
|
||||
public final BindingResult getBindingResult() {
|
||||
return this.bindingResult;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
@@ -155,7 +156,7 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
* Specify if the given {@code payload} is empty.
|
||||
* @param payload the payload to check (can be {@code null})
|
||||
*/
|
||||
protected boolean isEmptyPayload(Object payload) {
|
||||
protected boolean isEmptyPayload(@Nullable Object payload) {
|
||||
if (payload == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.core.ExceptionDepthComparator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -84,6 +85,7 @@ public abstract class AbstractExceptionHandlerMethodResolver {
|
||||
* @param exception the exception
|
||||
* @return a Method to handle the exception, or {@code null} if none found
|
||||
*/
|
||||
@Nullable
|
||||
public Method resolveMethod(Exception exception) {
|
||||
Method method = resolveMethodByExceptionType(exception.getClass());
|
||||
if (method == null) {
|
||||
@@ -102,6 +104,7 @@ public abstract class AbstractExceptionHandlerMethodResolver {
|
||||
* @return a Method to handle the exception, or {@code null} if none found
|
||||
* @since 4.3.1
|
||||
*/
|
||||
@Nullable
|
||||
public Method resolveMethodByExceptionType(Class<? extends Throwable> exceptionType) {
|
||||
Method method = this.exceptionLookupCache.get(exceptionType);
|
||||
if (method == null) {
|
||||
@@ -114,6 +117,7 @@ public abstract class AbstractExceptionHandlerMethodResolver {
|
||||
/**
|
||||
* Return the {@link Method} mapped to the given exception type, or {@code null} if none.
|
||||
*/
|
||||
@Nullable
|
||||
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
|
||||
List<Class<? extends Throwable>> matches = new ArrayList<>();
|
||||
for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.MethodIntrospector;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
@@ -304,6 +305,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
* @param handlerType the handler type, possibly a sub-type of the method's declaring class
|
||||
* @return the mapping, or {@code null} if the method is not mapped
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract T getMappingForMethod(Method method, Class<?> handlerType);
|
||||
|
||||
/**
|
||||
@@ -409,6 +411,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
* <p>If there are no matching prefixes, return {@code null}.
|
||||
* <p>If there are no destination prefixes, return the destination as is.
|
||||
*/
|
||||
@Nullable
|
||||
protected String getLookupDestination(String destination) {
|
||||
if (destination == null) {
|
||||
return null;
|
||||
@@ -477,6 +480,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
* @param message the message being handled
|
||||
* @return the match or {@code null} if there is no match
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract T getMatchingMapping(T mapping, Message<?> message);
|
||||
|
||||
protected void handleNoMatch(Set<T> ts, String lookupDestination, Message<?> message) {
|
||||
@@ -559,6 +563,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
||||
* @return a method to handle the exception, or {@code null}
|
||||
* @since 4.2
|
||||
*/
|
||||
@Nullable
|
||||
protected InvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Searching methods to handle " + exception.getClass().getSimpleName());
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
@@ -61,6 +62,7 @@ public interface AsyncHandlerMethodReturnValueHandler extends HandlerMethodRetur
|
||||
* @return the resulting ListenableFuture or {@code null} in which case no
|
||||
* further handling will be performed.
|
||||
*/
|
||||
@Nullable
|
||||
ListenableFuture<?> toListenableFuture(Object returnValue, MethodParameter returnType);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -47,6 +48,7 @@ public interface HandlerMethodArgumentResolver {
|
||||
* @return the resolved argument value, or {@code null}
|
||||
* @throws Exception in case of errors with the preparation of argument values
|
||||
*/
|
||||
@Nullable
|
||||
Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
@@ -80,6 +81,7 @@ public class HandlerMethodReturnValueHandlerComposite implements AsyncHandlerMet
|
||||
return getReturnValueHandler(returnType) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HandlerMethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) {
|
||||
for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
|
||||
if (handler.supportsReturnType(returnType)) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.HandlerMethod;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -158,6 +159,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
/**
|
||||
* Attempt to resolve a method parameter from the list of provided argument values.
|
||||
*/
|
||||
@Nullable
|
||||
private Object resolveProvidedArgument(MethodParameter parameter, Object... providedArgs) {
|
||||
if (providedArgs == null) {
|
||||
return null;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Common infrastructure for invoking message handler methods.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.handler.invocation;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Basic abstractions for working with message handler methods.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.handler;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Support for working with messaging APIs and protocols.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -70,6 +71,7 @@ public class SimpAttributes {
|
||||
* @param name the name of the attribute
|
||||
* @return the current attribute value, or {@code null} if not found
|
||||
*/
|
||||
@Nullable
|
||||
public Object getAttribute(String name) {
|
||||
return this.attributes.get(name);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.messaging.simp;
|
||||
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
|
||||
@@ -66,6 +67,7 @@ public abstract class SimpAttributesContextHolder {
|
||||
* Return the SimpAttributes currently bound to the thread.
|
||||
* @return the attributes or {@code null} if not bound
|
||||
*/
|
||||
@Nullable
|
||||
public static SimpAttributes getAttributes() {
|
||||
return attributesHolder.get();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.simp;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.core.MessagePostProcessor;
|
||||
import org.springframework.messaging.core.MessageSendingOperations;
|
||||
@@ -83,7 +84,7 @@ public interface SimpMessageSendingOperations extends MessageSendingOperations<S
|
||||
* @param payload the payload to send (may be {@code null})
|
||||
* @param headers the message headers (may be {@code null})
|
||||
*/
|
||||
void convertAndSendToUser(String user, String destination, Object payload, Map<String, Object> headers)
|
||||
void convertAndSendToUser(String user, String destination, @Nullable Object payload, @Nullable Map<String, Object> headers)
|
||||
throws MessagingException;
|
||||
|
||||
/**
|
||||
@@ -93,7 +94,7 @@ public interface SimpMessageSendingOperations extends MessageSendingOperations<S
|
||||
* @param payload the payload to send (may be {@code null})
|
||||
* @param postProcessor a postProcessor to post-process or modify the created message
|
||||
*/
|
||||
void convertAndSendToUser(String user, String destination, Object payload,
|
||||
void convertAndSendToUser(String user, String destination, @Nullable Object payload,
|
||||
MessagePostProcessor postProcessor) throws MessagingException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Annotations and for handling messages from SImple Messaging Protocols such as STOMP.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.annotation;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -185,6 +186,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object findAnnotation(MethodParameter returnType) {
|
||||
Annotation[] anns = new Annotation[4];
|
||||
anns[0] = AnnotatedElementUtils.findMergedAnnotation(returnType.getMethod(), SendToUser.class);
|
||||
@@ -221,6 +223,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
|
||||
return new DestinationVariablePlaceholderResolver(vars);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getUserName(Message<?> message, MessageHeaders headers) {
|
||||
Principal principal = SimpMessageHeaderAccessor.getUser(headers);
|
||||
if (principal != null) {
|
||||
|
||||
@@ -2,4 +2,7 @@
|
||||
* Support classes for handling messages from simple messaging protocols
|
||||
* (like STOMP).
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.annotation.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.SpelEvaluationException;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
@@ -428,6 +429,7 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||
return this.destinationLookup.get(destination);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Subscription getSubscription(String subscriptionId) {
|
||||
for (Map.Entry<String, Set<DefaultSubscriptionRegistry.Subscription>> destinationEntry : this.destinationLookup.entrySet()) {
|
||||
Set<Subscription> subs = destinationEntry.getValue();
|
||||
@@ -456,6 +458,7 @@ public class DefaultSubscriptionRegistry extends AbstractSubscriptionRegistry {
|
||||
subs.add(new Subscription(subscriptionId, selectorExpression));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String removeSubscription(String subscriptionId) {
|
||||
for (Map.Entry<String, Set<DefaultSubscriptionRegistry.Subscription>> destinationEntry : this.destinationLookup.entrySet()) {
|
||||
Set<Subscription> subs = destinationEntry.getValue();
|
||||
|
||||
@@ -2,4 +2,7 @@
|
||||
* Provides a "simple" message broker implementation along with an abstract base
|
||||
* class and other supporting types such as a registry for subscriptions.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.broker;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.converter.ByteArrayMessageConverter;
|
||||
@@ -447,6 +448,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
|
||||
* Override this method to provide a custom {@link Validator}.
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@Nullable
|
||||
public Validator getValidator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.messaging.simp.config;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler;
|
||||
@@ -188,6 +189,7 @@ public class MessageBrokerRegistry {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
protected SimpleBrokerMessageHandler getSimpleBroker(SubscribableChannel brokerChannel) {
|
||||
if (this.simpleBrokerRegistration == null && this.brokerRelayRegistration == null) {
|
||||
enableSimpleBroker();
|
||||
@@ -201,6 +203,7 @@ public class MessageBrokerRegistry {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected StompBrokerRelayMessageHandler getStompBrokerRelay(SubscribableChannel brokerChannel) {
|
||||
if (this.brokerRelayRegistration != null) {
|
||||
return this.brokerRelayRegistration.getMessageHandler(brokerChannel);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Configuration support for WebSocket messaging using higher level messaging protocols.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.config;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Generic support for SImple Messaging Protocols including protocols such as STOMP.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.messaging.support.MessageHeaderInitializer;
|
||||
@@ -66,6 +67,7 @@ public class StompDecoder {
|
||||
/**
|
||||
* Return the configured {@code MessageHeaderInitializer}, if any.
|
||||
*/
|
||||
@Nullable
|
||||
public MessageHeaderInitializer getHeaderInitializer() {
|
||||
return this.headerInitializer;
|
||||
}
|
||||
@@ -80,6 +82,7 @@ public class StompDecoder {
|
||||
* @return the decoded messages, or an empty list if none
|
||||
* @throws StompConversionException raised in case of decoding issues
|
||||
*/
|
||||
@Nullable
|
||||
public List<Message<byte[]>> decode(ByteBuffer byteBuffer) {
|
||||
return decode(byteBuffer, null);
|
||||
}
|
||||
@@ -285,6 +288,7 @@ public class StompDecoder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private byte[] readPayload(ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) {
|
||||
Integer contentLength;
|
||||
try {
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Contract to handle a STOMP frame.
|
||||
*
|
||||
@@ -39,6 +41,6 @@ public interface StompFrameHandler {
|
||||
* @param headers the headers of the frame
|
||||
* @param payload the payload or {@code null} if there was no payload
|
||||
*/
|
||||
void handleFrame(StompHeaders headers, Object payload);
|
||||
void handleFrame(StompHeaders headers, @Nullable Object payload);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
@@ -219,6 +220,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
|
||||
/**
|
||||
* Return the STOMP command, or {@code null} if not yet set.
|
||||
*/
|
||||
@Nullable
|
||||
public StompCommand getCommand() {
|
||||
return (StompCommand) getHeader(COMMAND_HEADER);
|
||||
}
|
||||
@@ -286,6 +288,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getContentLength() {
|
||||
if (containsNativeHeader(STOMP_CONTENT_LENGTH_HEADER)) {
|
||||
return Integer.valueOf(getFirstNativeHeader(STOMP_CONTENT_LENGTH_HEADER));
|
||||
@@ -341,6 +344,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
|
||||
/**
|
||||
* Return the passcode header value, or {@code null} if not set.
|
||||
*/
|
||||
@Nullable
|
||||
public String getPasscode() {
|
||||
StompPasscode credentials = (StompPasscode) getHeader(CREDENTIALS_HEADER);
|
||||
return (credentials != null ? credentials.passcode : null);
|
||||
@@ -490,6 +494,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
|
||||
/**
|
||||
* Return the STOMP command from the given headers, or {@code null} if not set.
|
||||
*/
|
||||
@Nullable
|
||||
public static StompCommand getCommand(Map<String, Object> headers) {
|
||||
return (StompCommand) headers.get(COMMAND_HEADER);
|
||||
}
|
||||
@@ -497,6 +502,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
|
||||
/**
|
||||
* Return the passcode header value, or {@code null} if not set.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getPasscode(Map<String, Object> headers) {
|
||||
StompPasscode credentials = (StompPasscode) headers.get(CREDENTIALS_HEADER);
|
||||
return (credentials != null ? credentials.passcode : null);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a STOMP session with operations to send messages, create
|
||||
* subscriptions and receive messages on those subscriptions.
|
||||
@@ -115,6 +117,7 @@ public interface StompSession {
|
||||
* Return the receipt id, or {@code null} if the STOMP frame for which
|
||||
* the handle was returned did not have a "receipt" header.
|
||||
*/
|
||||
@Nullable
|
||||
String getReceiptId();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Generic support for simple messaging protocols (like STOMP).
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.stomp;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Set;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
@@ -138,6 +139,7 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
|
||||
return new UserDestinationResult(sourceDestination, targetSet, subscribeDestination, user);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ParseResult parse(Message<?> message) {
|
||||
MessageHeaders headers = message.getHeaders();
|
||||
String destination = SimpMessageHeaderAccessor.getDestination(headers);
|
||||
@@ -215,8 +217,9 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
|
||||
* @return a target destination, or {@code null} if none
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Nullable
|
||||
protected String getTargetDestination(String sourceDestination, String actualDestination,
|
||||
String sessionId, String user) {
|
||||
String sessionId, @Nullable String user) {
|
||||
|
||||
return actualDestination + "-user" + sessionId;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a connected user.
|
||||
*
|
||||
@@ -39,8 +41,9 @@ public interface SimpUser {
|
||||
/**
|
||||
* Look up the session for the given id.
|
||||
* @param sessionId the session id
|
||||
* @return the matching session of {@code null}.
|
||||
* @return the matching session or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
SimpSession getSession(String sessionId);
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A registry of currently connected users.
|
||||
*
|
||||
@@ -31,6 +33,7 @@ public interface SimpUserRegistry {
|
||||
* @param userName the name of the user to look up
|
||||
* @return the user, or {@code null} if not connected
|
||||
*/
|
||||
@Nullable
|
||||
SimpUser getUser(String userName);
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -253,6 +254,7 @@ public class UserDestinationMessageHandler implements MessageHandler, SmartLifec
|
||||
return this.broadcastDestination;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Message<?> preHandle(Message<?> message) throws MessagingException {
|
||||
String destination = SimpMessageHeaderAccessor.getDestination(message.getHeaders());
|
||||
if (!getBroadcastDestination().equals(destination)) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,7 @@ public interface UserDestinationResolver {
|
||||
* @return 0 or more target messages (one for each active session), or
|
||||
* {@code null} if the source message does not contain a user destination.
|
||||
*/
|
||||
@Nullable
|
||||
UserDestinationResult resolveDestination(Message<?> message);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.simp.user;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -89,6 +90,7 @@ public class UserDestinationResult {
|
||||
* sessionId in place of a user name thus removing the need for a user-to-session
|
||||
* lookup via {@link SimpUserRegistry}.
|
||||
*/
|
||||
@Nullable
|
||||
public String getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,7 @@
|
||||
* <p>Also included is {@link org.springframework.messaging.simp.user.SimpUserRegistry}
|
||||
* for keeping track of connected user sessions.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.simp.user;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -88,6 +89,7 @@ public abstract class AbstractHeaderMapper<T> implements HeaderMapper<T> {
|
||||
* Return the header value, or {@code null} if it does not exist
|
||||
* or does not match the requested {@code type}.
|
||||
*/
|
||||
@Nullable
|
||||
protected <V> V getHeaderIfAvailable(Map<String, Object> headers, String name, Class<V> type) {
|
||||
Object value = headers.get(name);
|
||||
if (value == null) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
@@ -152,6 +153,7 @@ public abstract class AbstractMessageChannel implements MessageChannel, Intercep
|
||||
|
||||
private int receiveInterceptorIndex = -1;
|
||||
|
||||
@Nullable
|
||||
public Message<?> applyPreSend(Message<?> message, MessageChannel channel) {
|
||||
Message<?> messageToUse = message;
|
||||
for (ChannelInterceptor interceptor : interceptors) {
|
||||
@@ -199,6 +201,7 @@ public abstract class AbstractMessageChannel implements MessageChannel, Intercep
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Message<?> applyPostReceive(Message<?> message, MessageChannel channel) {
|
||||
for (ChannelInterceptor interceptor : interceptors) {
|
||||
message = interceptor.postReceive(message, channel);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.support;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
@@ -36,6 +37,7 @@ public interface ChannelInterceptor {
|
||||
* If this method returns {@code null} then the actual
|
||||
* send invocation will not occur.
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> preSend(Message<?> message, MessageChannel channel);
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.messaging.support;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
@@ -42,6 +43,7 @@ public interface ExecutorChannelInterceptor extends ChannelInterceptor {
|
||||
* @param handler the target handler to handle the message
|
||||
* @return the input message, or a new instance, or {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
Message<?> beforeHandle(Message<?> message, MessageChannel channel, MessageHandler handler);
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
@@ -54,7 +55,7 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel {
|
||||
* @param executor the executor used to send the message,
|
||||
* or {@code null} to execute in the callers thread.
|
||||
*/
|
||||
public ExecutorSubscribableChannel(Executor executor) {
|
||||
public ExecutorSubscribableChannel(@Nullable Executor executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@@ -151,6 +152,7 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Message<?> applyBeforeHandle(Message<?> message) {
|
||||
for (ExecutorChannelInterceptor interceptor : executorInterceptors) {
|
||||
message = interceptor.beforeHandle(message, ExecutorSubscribableChannel.this, this.messageHandler);
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.support;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.IdGenerator;
|
||||
|
||||
@@ -57,6 +58,7 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
||||
/**
|
||||
* Return the configured {@code IdGenerator}, if any.
|
||||
*/
|
||||
@Nullable
|
||||
public IdGenerator getIdGenerator() {
|
||||
return this.idGenerator;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.messaging.support;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -73,7 +74,7 @@ public final class MessageBuilder<T> {
|
||||
* Set the value for the given header name. If the provided value is {@code null},
|
||||
* the header will be removed.
|
||||
*/
|
||||
public MessageBuilder<T> setHeader(String headerName, Object headerValue) {
|
||||
public MessageBuilder<T> setHeader(String headerName, @Nullable Object headerValue) {
|
||||
this.headerAccessor.setHeader(headerName, headerValue);
|
||||
return this;
|
||||
}
|
||||
@@ -187,7 +188,7 @@ public final class MessageBuilder<T> {
|
||||
* @since 4.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Message<T> createMessage(T payload, MessageHeaders messageHeaders) {
|
||||
public static <T> Message<T> createMessage(@Nullable T payload, MessageHeaders messageHeaders) {
|
||||
Assert.notNull(payload, "Payload must not be null");
|
||||
Assert.notNull(messageHeaders, "MessageHeaders must not be null");
|
||||
if (payload instanceof Throwable) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -143,7 +144,7 @@ public class MessageHeaderAccessor {
|
||||
* A constructor accepting the headers of an existing message to copy.
|
||||
* @param message a message to copy the headers from, or {@code null} if none
|
||||
*/
|
||||
public MessageHeaderAccessor(Message<?> message) {
|
||||
public MessageHeaderAccessor(@Nullable Message<?> message) {
|
||||
this.headers = new MutableMessageHeaders(message != null ? message.getHeaders() : null);
|
||||
}
|
||||
|
||||
@@ -284,6 +285,7 @@ public class MessageHeaderAccessor {
|
||||
* @param headerName the name of the header
|
||||
* @return the associated value, or {@code null} if none found
|
||||
*/
|
||||
@Nullable
|
||||
public Object getHeader(String headerName) {
|
||||
return this.headers.get(headerName);
|
||||
}
|
||||
@@ -292,7 +294,7 @@ public class MessageHeaderAccessor {
|
||||
* Set the value for the given header name.
|
||||
* <p>If the provided value is {@code null}, the header will be removed.
|
||||
*/
|
||||
public void setHeader(String name, Object value) {
|
||||
public void setHeader(String name, @Nullable Object value) {
|
||||
if (isReadOnly(name)) {
|
||||
throw new IllegalArgumentException("'" + name + "' header is read-only");
|
||||
}
|
||||
@@ -414,6 +416,7 @@ public class MessageHeaderAccessor {
|
||||
|
||||
// Specific header accessors
|
||||
|
||||
@Nullable
|
||||
public UUID getId() {
|
||||
Object value = getHeader(MessageHeaders.ID);
|
||||
if (value == null) {
|
||||
@@ -422,6 +425,7 @@ public class MessageHeaderAccessor {
|
||||
return (value instanceof UUID ? (UUID) value : UUID.fromString(value.toString()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTimestamp() {
|
||||
Object value = getHeader(MessageHeaders.TIMESTAMP);
|
||||
if (value == null) {
|
||||
@@ -434,6 +438,7 @@ public class MessageHeaderAccessor {
|
||||
setHeader(MessageHeaders.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MimeType getContentType() {
|
||||
Object value = getHeader(MessageHeaders.CONTENT_TYPE);
|
||||
if (value == null) {
|
||||
@@ -561,6 +566,7 @@ public class MessageHeaderAccessor {
|
||||
* @return an accessor instance of the specified type, or {@code null} if none
|
||||
* @since 4.1
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends MessageHeaderAccessor> T getAccessor(Message<?> message, Class<T> requiredType) {
|
||||
return getAccessor(message.getHeaders(), requiredType);
|
||||
}
|
||||
@@ -573,6 +579,7 @@ public class MessageHeaderAccessor {
|
||||
* @since 4.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static <T extends MessageHeaderAccessor> T getAccessor(
|
||||
MessageHeaders messageHeaders, Class<T> requiredType) {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -62,7 +63,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
|
||||
* A protected constructor to create new headers.
|
||||
* @param nativeHeaders native headers to create the message with (may be {@code null})
|
||||
*/
|
||||
protected NativeMessageHeaderAccessor(Map<String, List<String>> nativeHeaders) {
|
||||
protected NativeMessageHeaderAccessor(@Nullable Map<String, List<String>> nativeHeaders) {
|
||||
if (!CollectionUtils.isEmpty(nativeHeaders)) {
|
||||
setHeader(NATIVE_HEADERS, new LinkedMultiValueMap<>(nativeHeaders));
|
||||
}
|
||||
@@ -121,14 +122,16 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
|
||||
/**
|
||||
* @return all values for the specified native header or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
public List<String> getNativeHeader(String headerName) {
|
||||
Map<String, List<String>> map = getNativeHeaders();
|
||||
return (map != null ? map.get(headerName) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the first value for the specified native header of {@code null}.
|
||||
* @return the first value for the specified native header or {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
public String getFirstNativeHeader(String headerName) {
|
||||
Map<String, List<String>> map = getNativeHeaders();
|
||||
if (map != null) {
|
||||
@@ -198,6 +201,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<String> removeNativeHeader(String name) {
|
||||
Assert.state(isMutable(), "Already immutable");
|
||||
Map<String, List<String>> nativeHeaders = getNativeHeaders();
|
||||
@@ -208,6 +212,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static String getFirstNativeHeader(String headerName, Map<String, Object> headers) {
|
||||
Map<String, List<String>> map = (Map<String, List<String>>) headers.get(NATIVE_HEADERS);
|
||||
if (map != null) {
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
* message headers, as well as various {@link org.springframework.messaging.MessageChannel}
|
||||
* implementations and channel interceptor support.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.messaging.tcp;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A contract to determine the frequency of reconnect attempts after connection failure.
|
||||
*
|
||||
@@ -30,6 +32,7 @@ public interface ReconnectStrategy {
|
||||
* @param attemptCount how many reconnect attempts have been made already
|
||||
* @return the amount of time in milliseconds or {@code null} to stop
|
||||
*/
|
||||
@Nullable
|
||||
Long getTimeToNextAttempt(int attemptCount);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,4 +6,7 @@
|
||||
* as well as sending messages via
|
||||
* {@link org.springframework.messaging.tcp.TcpConnection TcpConnection}.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.tcp;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/**
|
||||
* Contains support for TCP messaging based on Reactor.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.messaging.tcp.reactor;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
|
||||
Reference in New Issue
Block a user