Backport selected refinements from the nullability efforts

Issue: SPR-15656
This commit is contained in:
Juergen Hoeller
2017-09-27 00:09:58 +02:00
parent 18a3322d2f
commit 9fdc4404a5
194 changed files with 1236 additions and 1218 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.springframework.messaging.converter;
import org.springframework.messaging.MessageHeaders;
import org.springframework.util.InvalidMimeTypeException;
import org.springframework.util.MimeType;
/**
@@ -29,15 +30,11 @@ 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
*
* @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
* @return the resolved {@code MimeType}, or {@code null} if none found
* @throws InvalidMimeTypeException if the content type is a String that cannot be parsed
* @throws IllegalArgumentException if there is a content type but its type is unknown
*/
MimeType resolve(MessageHeaders headers);
MimeType resolve(MessageHeaders headers) throws InvalidMimeTypeException;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -175,7 +175,7 @@ public class MarshallingMessageConverter extends AbstractMessageConverter {
payload = writer.toString();
}
}
catch (Exception ex) {
catch (Throwable ex) {
throw new MessageConversionException("Could not marshal XML: " + ex.getMessage(), ex);
}
return payload;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -190,6 +190,9 @@ public class DestinationPatternsMessageCondition extends AbstractMessageConditio
@Override
public int compareTo(DestinationPatternsMessageCondition other, Message<?> message) {
String destination = (String) message.getHeaders().get(LOOKUP_DESTINATION_HEADER);
if (destination == null) {
return 0;
}
Comparator<String> patternComparator = this.pathMatcher.getPatternComparator(destination);
Iterator<String> iterator = patterns.iterator();

View File

@@ -38,11 +38,14 @@ import org.springframework.util.ClassUtils;
*/
public abstract class AbstractExceptionHandlerMethodResolver {
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
private static final Method NO_METHOD_FOUND =
ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
private final Map<Class<? extends Throwable>, Method> mappedMethods = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
private final Map<Class<? extends Throwable>, Method> mappedMethods =
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache =
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,13 +40,13 @@ public interface HandlerMethodReturnValueHandler {
/**
* Handle the given return value.
* @param returnValue the value returned from the handler method
* @param returnType the type of the return value. This type must have
* previously been passed to
* {@link #supportsReturnType(org.springframework.core.MethodParameter)}
* and it must have returned {@code true}
* @param returnType the type of the return value. This type must have previously
* been passed to {@link #supportsReturnType(org.springframework.core.MethodParameter)}
* and it must have returned {@code true}.
* @param message the message that caused this method to be called
* @throws Exception if the return value handling results in an error
*/
void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) throws Exception;
void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message)
throws Exception;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.messaging.simp;
import org.springframework.core.NamedThreadLocal;
import org.springframework.messaging.Message;
/**
* Holder class to expose SiMP attributes associated with a session (e.g. WebSocket)
* in the form of a thread-bound {@link SimpAttributes} object.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,17 +34,17 @@ public class SimpSessionScope implements Scope {
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
SimpAttributes simpAttributes = SimpAttributesContextHolder.currentAttributes();
Object value = simpAttributes.getAttribute(name);
if (value != null) {
return value;
Object scopedObject = simpAttributes.getAttribute(name);
if (scopedObject != null) {
return scopedObject;
}
synchronized (simpAttributes.getSessionMutex()) {
value = simpAttributes.getAttribute(name);
if (value == null) {
value = objectFactory.getObject();
simpAttributes.setAttribute(name, value);
scopedObject = simpAttributes.getAttribute(name);
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
simpAttributes.setAttribute(name, scopedObject);
}
return value;
return scopedObject;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
public SendToMethodReturnValueHandler(SimpMessageSendingOperations messagingTemplate, boolean annotationRequired) {
Assert.notNull(messagingTemplate, "messagingTemplate must not be null");
Assert.notNull(messagingTemplate, "'messagingTemplate' must not be null");
this.messagingTemplate = messagingTemplate;
this.annotationRequired = annotationRequired;
}
@@ -124,7 +124,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
}
/**
* @return the configured header initializer.
* Return the configured header initializer.
*/
public MessageHeaderInitializer getHeaderInitializer() {
return this.headerInitializer;
@@ -141,7 +141,9 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message) throws Exception {
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message)
throws Exception {
if (returnValue == null) {
return;
}
@@ -151,7 +153,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
PlaceholderResolver varResolver = initVarResolver(headers);
Object annotation = findAnnotation(returnType);
if (annotation != null && annotation instanceof SendToUser) {
if (annotation instanceof SendToUser) {
SendToUser sendToUser = (SendToUser) annotation;
boolean broadcast = sendToUser.broadcast();
String user = getUserName(message, headers);
@@ -176,7 +178,7 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH
}
}
else {
SendTo sendTo = (SendTo) annotation;
SendTo sendTo = (SendTo) annotation; // possibly null
String[] destinations = getTargetDestinations(sendTo, message, this.defaultDestinationPrefix);
for (String destination : destinations) {
destination = this.placeholderHelper.replacePlaceholders(destination, varResolver);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -109,12 +109,12 @@ public class SubscriptionMethodReturnValueHandler implements HandlerMethodReturn
}
MessageHeaders headers = message.getHeaders();
String destination = SimpMessageHeaderAccessor.getDestination(headers);
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
String subscriptionId = SimpMessageHeaderAccessor.getSubscriptionId(headers);
String destination = SimpMessageHeaderAccessor.getDestination(headers);
if (subscriptionId == null) {
throw new IllegalStateException("No subscriptionId in " + message +
throw new IllegalStateException("No subscription id in " + message +
" returned by: " + returnType.getMethod());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -105,7 +105,7 @@ public abstract class AbstractBrokerMessageHandler
this.clientOutboundChannel = outboundChannel;
this.brokerChannel = brokerChannel;
destinationPrefixes = (destinationPrefixes != null) ? destinationPrefixes : Collections.<String>emptyList();
destinationPrefixes = (destinationPrefixes != null ? destinationPrefixes : Collections.<String>emptyList());
this.destinationPrefixes = Collections.unmodifiableCollection(destinationPrefixes);
}
@@ -242,7 +242,7 @@ public abstract class AbstractBrokerMessageHandler
protected boolean checkDestinationPrefix(String destination) {
if ((destination == null) || CollectionUtils.isEmpty(this.destinationPrefixes)) {
if (destination == null || CollectionUtils.isEmpty(this.destinationPrefixes)) {
return true;
}
for (String prefix : this.destinationPrefixes) {

View File

@@ -347,7 +347,9 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler {
getClientOutboundChannel().send(reply);
}
catch (Throwable ex) {
logger.error("Failed to send " + message, ex);
if (logger.isErrorEnabled()) {
logger.error("Failed to send " + message, ex);
}
}
finally {
SessionInfo info = this.sessions.get(subscriptionEntry.getKey());

View File

@@ -268,8 +268,8 @@ public class DefaultStompSession implements ConnectionHandlingStompSession {
}
private void execute(Message<byte[]> message) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (logger.isTraceEnabled()) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
logger.trace("Sending " + accessor.getDetailedLogMessage(message.getPayload()));
}
TcpConnection<byte[]> conn = this.connection;

View File

@@ -75,7 +75,7 @@ public abstract class StompClientSupport {
/**
* Configure a scheduler to use for heartbeats and for receipt tracking.
* <p><strong>Note:</strong> some transports have built-in support to work
* <p><strong>Note:</strong> Some transports have built-in support to work
* with heartbeats and therefore do not require a TaskScheduler.
* Receipts however, if needed, do require a TaskScheduler to be configured.
* <p>By default, this is not set.
@@ -123,7 +123,8 @@ public abstract class StompClientSupport {
* is set to "0,0", and {@code true} otherwise.
*/
public boolean isDefaultHeartbeatEnabled() {
return (getDefaultHeartbeat() != null && getDefaultHeartbeat()[0] != 0 && getDefaultHeartbeat()[1] != 0);
long[] heartbeat = getDefaultHeartbeat();
return (heartbeat[0] != 0 && heartbeat[1] != 0);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -131,6 +131,7 @@ public interface StompSession {
void addReceiptLostTask(Runnable runnable);
}
/**
* A handle to use to unsubscribe or to track a receipt.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,8 @@ public class UserDestinationResult {
private final String user;
public UserDestinationResult(String sourceDestination,
Set<String> targetDestinations, String subscribeDestination, String user) {
public UserDestinationResult(String sourceDestination, Set<String> targetDestinations,
String subscribeDestination, String user) {
Assert.notNull(sourceDestination, "'sourceDestination' must not be null");
Assert.notNull(targetDestinations, "'targetDestinations' must not be null");
@@ -93,9 +93,11 @@ public class UserDestinationResult {
return this.user;
}
@Override
public String toString() {
return "UserDestinationResult[source=" + this.sourceDestination + ", target=" + this.targetDestinations +
return "UserDestinationResult [source=" + this.sourceDestination + ", target=" + this.targetDestinations +
", subscribeDestination=" + this.subscribeDestination + ", user=" + this.user + "]";
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,8 +35,7 @@ import org.springframework.util.Assert;
* application servers and periodically broadcasts the content of the local
* user registry.
*
* The aggregated information
* is maintained in a {@link MultiServerUserRegistry}.
* <p>The aggregated information is maintained in a {@link MultiServerUserRegistry}.
*
* @author Rossen Stoyanchev
* @since 4.2
@@ -62,8 +61,8 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
* Constructor.
* @param userRegistry the registry with local and remote user registry information
* @param brokerTemplate template for broadcasting local registry information
* @param broadcastDestination the destination to broadcast to
* @param scheduler
* @param broadcastDestination the destination to broadcast to
* @param scheduler the task scheduler to use
*/
public UserRegistryMessageHandler(MultiServerUserRegistry userRegistry,
SimpMessagingTemplate brokerTemplate, String broadcastDestination, TaskScheduler scheduler) {
@@ -112,9 +111,12 @@ public class UserRegistryMessageHandler implements MessageHandler, ApplicationLi
long delay = getRegistryExpirationPeriod() / 2;
this.scheduledFuture = this.scheduler.scheduleWithFixedDelay(this.schedulerTask, delay);
}
else if (this.scheduledFuture != null ){
this.scheduledFuture.cancel(true);
this.scheduledFuture = null;
else {
ScheduledFuture<?> future = this.scheduledFuture;
if (future != null ){
future.cancel(true);
this.scheduledFuture = null;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -152,9 +152,10 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel {
}
private Message<?> applyBeforeHandle(Message<?> message) {
Message<?> messageToUse = message;
for (ExecutorChannelInterceptor interceptor : executorInterceptors) {
message = interceptor.beforeHandle(message, ExecutorSubscribableChannel.this, this.messageHandler);
if (message == null) {
messageToUse = interceptor.beforeHandle(messageToUse, ExecutorSubscribableChannel.this, this.messageHandler);
if (messageToUse == null) {
String name = interceptor.getClass().getSimpleName();
if (logger.isDebugEnabled()) {
logger.debug(name + " returned null from beforeHandle, i.e. precluding the send.");
@@ -164,7 +165,7 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel {
}
this.interceptorIndex++;
}
return message;
return messageToUse;
}
private void triggerAfterMessageHandled(Message<?> message, Exception ex) {

View File

@@ -578,7 +578,7 @@ public class MessageHeaderAccessor {
if (messageHeaders instanceof MutableMessageHeaders) {
MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) messageHeaders;
MessageHeaderAccessor headerAccessor = mutableHeaders.getAccessor();
if (requiredType.isAssignableFrom(headerAccessor.getClass())) {
if (requiredType == null || requiredType.isInstance(headerAccessor)) {
return (T) headerAccessor;
}
}