From 54ba5c5e7bdf1836123ed5af558a60d1a6f207a8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 22 Aug 2014 23:39:37 +0200 Subject: [PATCH] Polishing --- .../springframework/messaging/Message.java | 10 ++-- .../messaging/MessageHeaders.java | 17 ++++--- .../messaging/support/ErrorMessage.java | 9 ++-- .../messaging/support/GenericMessage.java | 48 +++++++++-------- .../support/MessageHeaderAccessor.java | 51 ++++++++++--------- .../springframework/http/ResponseEntity.java | 10 ++-- .../server/ServerHttpAsyncRequestControl.java | 9 ++-- .../ServletServerHttpAsyncRequestControl.java | 18 ++++--- .../http/server/ServletServerHttpRequest.java | 1 + .../session/AbstractHttpSockJsSession.java | 11 ++-- 10 files changed, 94 insertions(+), 90 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 e2ca8b86c6..f2d3c19ca1 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java @@ -60,7 +60,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 @@ -135,6 +135,7 @@ public final class MessageHeaders implements Map, Serializable { return (T) value; } + @Override public boolean equals(Object other) { return (this == other || @@ -193,28 +194,32 @@ public final 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 737543246a..7b7fd00860 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 @@ -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. @@ -24,7 +24,6 @@ import java.util.Map; * @author Mark Fisher * @author Oleg Zhurakousky * @since 4.0 - * * @see MessageBuilder */ public class ErrorMessage extends GenericMessage { @@ -34,8 +33,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); @@ -43,8 +41,7 @@ public class ErrorMessage extends GenericMessage { /** * Create a new message with the given payload and headers. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) * @param headers message headers */ public ErrorMessage(Throwable payload, Map headers) { 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 ae50a5ee9d..746eaef70e 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,32 +44,47 @@ 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, null); + this(payload, new MessageHeaders(null)); } /** * Create a new message with the given payload and headers. - * - * @param payload the message payload, never {@code null} + * @param payload the message payload (never {@code null}) * @param headers message headers */ public GenericMessage(T payload, Map headers) { - Assert.notNull(payload, "payload must not be null"); + Assert.notNull(payload, "Payload must not be null"); this.headers = new MessageHeaders(headers); this.payload = payload; } + public T getPayload() { + return this.payload; + } + public MessageHeaders getHeaders() { return this.headers; } - public T getPayload() { - return this.payload; + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj != null && obj instanceof GenericMessage) { + GenericMessage other = (GenericMessage) obj; + return (ObjectUtils.nullSafeEquals(this.headers.getId(), other.headers.getId()) && + this.headers.equals(other.headers) && this.payload.equals(other.payload)); + } + return false; + } + + public int hashCode() { + return (this.headers.hashCode() * 23 + ObjectUtils.nullSafeHashCode(this.payload)); } public String toString() { @@ -86,20 +100,4 @@ public class GenericMessage implements Message, Serializable { return sb.toString(); } - public int hashCode() { - return this.headers.hashCode() * 23 + ObjectUtils.nullSafeHashCode(this.payload); - } - - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj != null && obj instanceof GenericMessage) { - GenericMessage other = (GenericMessage) obj; - return (this.headers.getId().equals(other.headers.getId()) && - this.headers.equals(other.headers) && this.payload.equals(other.payload)); - } - return false; - } - } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java index 2fd996f2e2..e810c03e4b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java @@ -94,7 +94,7 @@ public class MessageHeaderAccessor { } public boolean isModified() { - return (!this.headers.isEmpty()); + return !this.headers.isEmpty(); } public Object getHeader(String headerName) { @@ -132,10 +132,6 @@ public class MessageHeaderAccessor { } } - protected boolean isReadOnly(String headerName) { - return MessageHeaders.ID.equals(headerName) || MessageHeaders.TIMESTAMP.equals(headerName); - } - /** * Set the value for the given header name only if the header name is not * already associated with a value. @@ -146,6 +142,15 @@ public class MessageHeaderAccessor { } } + /** + * Remove the value for the given header name. + */ + public void removeHeader(String headerName) { + if (StringUtils.hasLength(headerName) && !isReadOnly(headerName)) { + setHeader(headerName, null); + } + } + /** * Removes all headers provided via array of 'headerPatterns'. *

As the name suggests, array may contain simple matching patterns for header @@ -181,15 +186,6 @@ public class MessageHeaderAccessor { return matchingHeaderNames; } - /** - * Remove the value for the given header name. - */ - public void removeHeader(String headerName) { - if (StringUtils.hasLength(headerName) && !isReadOnly(headerName)) { - setHeader(headerName, null); - } - } - /** * Copy the name-value pairs from the provided Map. *

This operation will overwrite any existing values. Use @@ -214,13 +210,18 @@ public class MessageHeaderAccessor { if (headersToCopy != null) { Set keys = headersToCopy.keySet(); for (String key : keys) { - if (!this.isReadOnly(key)) { + if (!isReadOnly(key)) { setHeaderIfAbsent(key, headersToCopy.get(key)); } } } } + protected boolean isReadOnly(String headerName) { + return (MessageHeaders.ID.equals(headerName) || MessageHeaders.TIMESTAMP.equals(headerName)); + } + + public UUID getId() { return (UUID) getHeader(MessageHeaders.ID); } @@ -229,6 +230,10 @@ public class MessageHeaderAccessor { return (Long) getHeader(MessageHeaders.TIMESTAMP); } + public void setReplyChannelName(String replyChannelName) { + setHeader(MessageHeaders.REPLY_CHANNEL, replyChannelName); + } + public void setReplyChannel(MessageChannel replyChannel) { setHeader(MessageHeaders.REPLY_CHANNEL, replyChannel); } @@ -237,8 +242,8 @@ public class MessageHeaderAccessor { return getHeader(MessageHeaders.REPLY_CHANNEL); } - public void setReplyChannelName(String replyChannelName) { - setHeader(MessageHeaders.REPLY_CHANNEL, replyChannelName); + public void setErrorChannelName(String errorChannelName) { + setHeader(MessageHeaders.ERROR_CHANNEL, errorChannelName); } public void setErrorChannel(MessageChannel errorChannel) { @@ -249,18 +254,14 @@ public class MessageHeaderAccessor { return getHeader(MessageHeaders.ERROR_CHANNEL); } - public void setErrorChannelName(String errorChannelName) { - setHeader(MessageHeaders.ERROR_CHANNEL, errorChannelName); - } - - public MimeType getContentType() { - return (MimeType) getHeader(MessageHeaders.CONTENT_TYPE); - } - public void setContentType(MimeType contentType) { setHeader(MessageHeaders.CONTENT_TYPE, contentType); } + public MimeType getContentType() { + return (MimeType) getHeader(MessageHeaders.CONTENT_TYPE); + } + @Override public String toString() { diff --git a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java index 56fa4c1ba5..e4451aec28 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseEntity.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 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. @@ -21,15 +21,19 @@ import org.springframework.util.ObjectUtils; /** * Extension of {@link HttpEntity} that adds a {@link HttpStatus} status code. + * Used in {@code RestTemplate} as well {@code @Controller} methods. * - *

Returned by {@link org.springframework.web.client.RestTemplate#getForEntity}: + *

In {@code RestTemplate}, this class is returned by + * {@link org.springframework.web.client.RestTemplate#getForEntity getForEntity()} and + * {@link org.springframework.web.client.RestTemplate#exchange exchange()}: *

  * ResponseEntity<String> entity = template.getForEntity("http://example.com", String.class);
  * String body = entity.getBody();
  * MediaType contentType = entity.getHeaders().getContentType();
  * HttpStatus statusCode = entity.getStatusCode();
  * 
- *

Can also be used in Spring MVC, as a return value from a @Controller method: + * + *

Can also be used in Spring MVC, as the return value from a @Controller method: *

  * @RequestMapping("/handle")
  * public ResponseEntity<String> handle() {
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 a75348301f..0136a8b611 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,19 +233,17 @@ 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 */ - public void handleSuccessiveRequest(ServerHttpRequest request, - ServerHttpResponse response, SockJsFrameFormat frameFormat) throws SockJsException { + public void handleSuccessiveRequest(ServerHttpRequest request, ServerHttpResponse response, + SockJsFrameFormat frameFormat) throws SockJsException { synchronized (this.responseLock) { try { @@ -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; @@ -324,7 +320,6 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { if (control != null && !control.isCompleted()) { if (control.isStarted()) { try { - logger.debug("Completing asynchronous request"); control.complete(); } catch (Throwable ex) {