From b93dd95475f0897cad1bf851a8cd1e58aef06251 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 22 Aug 2014 22:55:57 +0200 Subject: [PATCH] Polishing --- .../springframework/messaging/Message.java | 10 +- .../messaging/MessageHeaders.java | 17 ++-- .../messaging/support/ErrorMessage.java | 19 ++-- .../support/ExecutorSubscribableChannel.java | 91 +++++++++---------- .../messaging/support/GenericMessage.java | 50 +++++----- .../server/ServerHttpAsyncRequestControl.java | 9 +- .../ServletServerHttpAsyncRequestControl.java | 18 ++-- .../http/server/ServletServerHttpRequest.java | 1 + .../session/AbstractHttpSockJsSession.java | 6 +- 9 files changed, 108 insertions(+), 113 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/Message.java b/spring-messaging/src/main/java/org/springframework/messaging/Message.java index 0aea12d32a..64869741d4 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/Message.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/Message.java @@ -26,14 +26,14 @@ package org.springframework.messaging; */ public interface Message { - /** - * Return message headers for the message (never {@code null}). - */ - MessageHeaders getHeaders(); - /** * Return the message payload. */ T getPayload(); + /** + * Return message headers for the message (never {@code null} but may be empty). + */ + MessageHeaders getHeaders(); + } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java index 058d22753b..93b83bb4c9 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java @@ -59,7 +59,7 @@ import org.springframework.util.IdGenerator; * * * A third option is to use {@link org.springframework.messaging.support.MessageHeaderAccessor} - * or one of its sub-classes to create specific categories of headers. + * or one of its subclasses to create specific categories of headers. * * @author Arjen Poutsma * @author Mark Fisher @@ -177,6 +177,7 @@ public class MessageHeaders implements Map, Serializable { return (T) value; } + @Override public boolean equals(Object other) { return (this == other || @@ -232,28 +233,32 @@ public class MessageHeaders implements Map, Serializable { // Unsupported Map operations /** - * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}. + * Since MessageHeaders are immutable, the call to this method + * will result in {@link UnsupportedOperationException}. */ public Object put(String key, Object value) { throw new UnsupportedOperationException("MessageHeaders is immutable"); } /** - * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}. + * Since MessageHeaders are immutable, the call to this method + * will result in {@link UnsupportedOperationException}. */ - public void putAll(Map t) { + public void putAll(Map map) { throw new UnsupportedOperationException("MessageHeaders is immutable"); } /** - * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}. + * Since MessageHeaders are immutable, the call to this method + * will result in {@link UnsupportedOperationException}. */ public Object remove(Object key) { throw new UnsupportedOperationException("MessageHeaders is immutable"); } /** - * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}. + * Since MessageHeaders are immutable, the call to this method + * will result in {@link UnsupportedOperationException}. */ public void clear() { throw new UnsupportedOperationException("MessageHeaders is immutable"); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/ErrorMessage.java b/spring-messaging/src/main/java/org/springframework/messaging/support/ErrorMessage.java index 59779eccac..3c62934747 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/ErrorMessage.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/ErrorMessage.java @@ -16,17 +16,16 @@ package org.springframework.messaging.support; -import org.springframework.messaging.MessageHeaders; - import java.util.Map; +import org.springframework.messaging.MessageHeaders; + /** * A {@link GenericMessage} with a {@link Throwable} payload. * * @author Mark Fisher * @author Oleg Zhurakousky * @since 4.0 - * * @see MessageBuilder */ public class ErrorMessage extends GenericMessage { @@ -36,8 +35,7 @@ public class ErrorMessage extends GenericMessage { /** * Create a new message with the given payload. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) */ public ErrorMessage(Throwable payload) { super(payload); @@ -46,8 +44,7 @@ public class ErrorMessage extends GenericMessage { /** * Create a new message with the given payload and headers. * The content of the given header map is copied. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) * @param headers message headers to use for initialization */ public ErrorMessage(Throwable payload, Map headers) { @@ -56,11 +53,9 @@ public class ErrorMessage extends GenericMessage { /** * A constructor with the {@link MessageHeaders} instance to use. - * - *

Note: the given {@code MessageHeaders} instance is used - * directly in the new message, i.e. it is not copied. - * - * @param payload the message payload, never {@code null} + *

Note: the given {@code MessageHeaders} instance + * is used directly in the new message, i.e. it is not copied. + * @param payload the message payload (never {@code null}) * @param headers message headers */ public ErrorMessage(Throwable payload, MessageHeaders headers) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/ExecutorSubscribableChannel.java b/spring-messaging/src/main/java/org/springframework/messaging/support/ExecutorSubscribableChannel.java index 42758c72b6..bf96a4c19b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/ExecutorSubscribableChannel.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/ExecutorSubscribableChannel.java @@ -42,18 +42,18 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel { /** - * Create a new {@link ExecutorSubscribableChannel} instance where messages will be sent - * in the callers thread. + * Create a new {@link ExecutorSubscribableChannel} instance + * where messages will be sent in the callers thread. */ public ExecutorSubscribableChannel() { this(null); } /** - * Create a new {@link ExecutorSubscribableChannel} instance where messages will be sent - * via the specified executor. - * @param executor the executor used to send the message or {@code null} to execute in - * the callers thread. + * Create a new {@link ExecutorSubscribableChannel} instance + * where messages will be sent via the specified executor. + * @param executor the executor used to send the message, + * or {@code null} to execute in the callers thread. */ public ExecutorSubscribableChannel(Executor executor) { this.executor = executor; @@ -100,6 +100,45 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel { } + /** + * Helps with the invocation of configured executor channel interceptors. + */ + private class ExecutorChannelInterceptorChain { + + private int interceptorIndex = -1; + + public Message applyBeforeHandle(Message message, MessageChannel channel, MessageHandler handler) { + for (ExecutorChannelInterceptor interceptor : executorInterceptors) { + message = interceptor.beforeHandle(message, channel, handler); + if (message == null) { + String name = interceptor.getClass().getSimpleName(); + if (logger.isDebugEnabled()) { + logger.debug(name + " returned null from beforeHandle, i.e. precluding the send."); + } + triggerAfterMessageHandled(message, channel, handler, null); + return null; + } + this.interceptorIndex++; + } + return message; + } + + public void triggerAfterMessageHandled(Message message, MessageChannel channel, + MessageHandler handler, Exception ex) { + + for (int i = this.interceptorIndex; i >= 0; i--) { + ExecutorChannelInterceptor interceptor = executorInterceptors.get(i); + try { + interceptor.afterMessageHandled(message, channel, handler, ex); + } + catch (Throwable ex2) { + logger.error("Exception from afterMessageHandled in " + interceptor, ex2); + } + } + } + } + + /** * Helps with the invocation of the target MessageHandler and interceptors. */ @@ -113,7 +152,6 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel { private final ExecutorChannelInterceptorChain chain; - public SendTask(Message message, MessageChannel channel, MessageHandler handler, ExecutorChannelInterceptorChain chain) { @@ -151,43 +189,4 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel { } } - /** - * Helps with the invocation of configured executor channel interceptors. - */ - private class ExecutorChannelInterceptorChain { - - private int interceptorIndex = -1; - - - public Message applyBeforeHandle(Message message, MessageChannel channel, MessageHandler handler) { - for (ExecutorChannelInterceptor interceptor : executorInterceptors) { - message = interceptor.beforeHandle(message, channel, handler); - if (message == null) { - String name = interceptor.getClass().getSimpleName(); - if (logger.isDebugEnabled()) { - logger.debug(name + " returned null from beforeHandle, i.e. precluding the send."); - } - triggerAfterMessageHandled(message, channel, handler, null); - return null; - } - this.interceptorIndex++; - } - return message; - } - - public void triggerAfterMessageHandled(Message message, MessageChannel channel, - MessageHandler handler, Exception ex) { - - for (int i = this.interceptorIndex; i >= 0; i--) { - ExecutorChannelInterceptor interceptor = executorInterceptors.get(i); - try { - interceptor.afterMessageHandled(message, channel, handler, ex); - } - catch (Throwable ex2) { - logger.error("Exception from afterMessageHandled in " + interceptor, ex2); - } - } - } - } - } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java index b29f509c66..05884457e5 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java @@ -30,7 +30,6 @@ import org.springframework.util.ObjectUtils; * * @author Mark Fisher * @since 4.0 - * * @see MessageBuilder */ public class GenericMessage implements Message, Serializable { @@ -45,8 +44,7 @@ public class GenericMessage implements Message, Serializable { /** * Create a new message with the given payload. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) */ public GenericMessage(T payload) { this(payload, new MessageHeaders(null)); @@ -55,8 +53,7 @@ public class GenericMessage implements Message, Serializable { /** * Create a new message with the given payload and headers. * The content of the given header map is copied. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) * @param headers message headers to use for initialization */ public GenericMessage(T payload, Map headers) { @@ -65,44 +62,27 @@ public class GenericMessage implements Message, Serializable { /** * A constructor with the {@link MessageHeaders} instance to use. - * *

Note: the given {@code MessageHeaders} instance is used * directly in the new message, i.e. it is not copied. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) * @param headers message headers */ public GenericMessage(T payload, MessageHeaders headers) { + Assert.notNull(payload, "'payload must not be null"); Assert.notNull(headers, "'headers' must not be null"); - Assert.notNull(payload, "payload must not be null"); - this.headers = headers; this.payload = payload; + this.headers = headers; } - public MessageHeaders getHeaders() { - return this.headers; - } - public T getPayload() { return this.payload; } - public String toString() { - StringBuilder sb = new StringBuilder(); - if (this.payload instanceof byte[]) { - sb.append("[Payload byte[").append(((byte[]) this.payload).length).append("]]"); - } - else { - sb.append("[Payload=").append(this.payload).append("]"); - } - sb.append("[Headers=").append(this.headers).append("]"); - return sb.toString(); + public MessageHeaders getHeaders() { + return this.headers; } - public int hashCode() { - return this.headers.hashCode() * 23 + ObjectUtils.nullSafeHashCode(this.payload); - } public boolean equals(Object obj) { if (this == obj) { @@ -116,4 +96,20 @@ public class GenericMessage implements Message, Serializable { return false; } + public int hashCode() { + return this.headers.hashCode() * 23 + ObjectUtils.nullSafeHashCode(this.payload); + } + + public String toString() { + StringBuilder sb = new StringBuilder(getClass().getSimpleName()); + if (this.payload instanceof byte[]) { + sb.append("[payload byte[").append(((byte[]) this.payload).length).append("]]"); + } + else { + sb.append("[payload=").append(this.payload).append("]"); + } + sb.append("[headers=").append(this.headers).append("]"); + return sb.toString(); + } + } diff --git a/spring-web/src/main/java/org/springframework/http/server/ServerHttpAsyncRequestControl.java b/spring-web/src/main/java/org/springframework/http/server/ServerHttpAsyncRequestControl.java index 5fc6a9f8d2..44bc8560e5 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServerHttpAsyncRequestControl.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServerHttpAsyncRequestControl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.http.server; /** @@ -39,17 +40,17 @@ public interface ServerHttpAsyncRequestControl { void start(long timeout); /** - * Whether asynchronous request processing has been started. + * Return whether asynchronous request processing has been started. */ boolean isStarted(); /** - * Causes asynchronous request processing to be completed. + * Mark asynchronous request processing as completed. */ void complete(); /** - * Whether asynchronous request processing has been completed. + * Return whether asynchronous request processing has been completed. */ boolean isCompleted(); diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java index b9087a9050..7df09448bf 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpAsyncRequestControl.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -37,6 +37,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ private static long NO_TIMEOUT_VALUE = Long.MIN_VALUE; + private final ServletServerHttpRequest request; private final ServletServerHttpResponse response; @@ -52,7 +53,6 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ * respectively. */ public ServletServerHttpAsyncRequestControl(ServletServerHttpRequest request, ServletServerHttpResponse response) { - Assert.notNull(request, "request is required"); Assert.notNull(response, "response is required"); @@ -69,7 +69,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ @Override public boolean isStarted() { - return ((this.asyncContext != null) && this.request.getServletRequest().isAsyncStarted()); + return (this.asyncContext != null && this.request.getServletRequest().isAsyncStarted()); } @Override @@ -84,9 +84,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ @Override public void start(long timeout) { - Assert.state(!isCompleted(), "Async processing has already completed"); - if (isStarted()) { return; } @@ -109,6 +107,7 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ } } + // --------------------------------------------------------------------- // Implementation of AsyncListener methods // --------------------------------------------------------------------- @@ -120,12 +119,15 @@ public class ServletServerHttpAsyncRequestControl implements ServerHttpAsyncRequ } @Override - public void onStartAsync(AsyncEvent event) throws IOException { } + public void onStartAsync(AsyncEvent event) throws IOException { + } @Override - public void onError(AsyncEvent event) throws IOException { } + public void onError(AsyncEvent event) throws IOException { + } @Override - public void onTimeout(AsyncEvent event) throws IOException { } + public void onTimeout(AsyncEvent event) throws IOException { + } } diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index 0afab0b302..b9725ea569 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -45,6 +45,7 @@ import org.springframework.util.Assert; * {@link ServerHttpRequest} implementation that is based on a {@link HttpServletRequest}. * * @author Arjen Poutsma + * @author Rossen Stoyanchev * @since 3.0 */ public class ServletServerHttpRequest implements ServerHttpRequest { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java index b98fd3d8cc..c44b7e8191 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java @@ -177,13 +177,11 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { /** * Handle the first request for receiving messages on a SockJS HTTP transport * based session. - * *

Long polling-based transports (e.g. "xhr", "jsonp") complete the request * after writing the open frame. Streaming-based transports ("xhr_streaming", * "eventsource", and "htmlfile") leave the response open longer for further * streaming of message frames but will also close it eventually after some * amount of data has been sent. - * * @param request the current request * @param response the current response * @param frameFormat the transport-specific SocksJS frame format to use @@ -235,13 +233,11 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { /** * Handle all requests, except the first one, to receive messages on a SockJS * HTTP transport based session. - * *

Long polling-based transports (e.g. "xhr", "jsonp") complete the request * after writing any buffered message frames (or the next one). Streaming-based * transports ("xhr_streaming", "eventsource", and "htmlfile") leave the * response open longer for further streaming of message frames but will also * close it eventually after some amount of data has been sent. - * * @param request the current request * @param response the current response * @param frameFormat the transport-specific SocksJS frame format to use @@ -302,7 +298,7 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { /** * Called when the connection is active and ready to write to the response. - * Sub-classes should implement but never call this method directly. + * Subclasses should implement but never call this method directly. */ protected abstract void flushCache() throws SockJsTransportFailureException;