diff --git a/spring-core/src/main/java/org/springframework/util/comparator/package-info.java b/spring-core/src/main/java/org/springframework/util/comparator/package-info.java index 7bcb8576d86..f2213670b90 100644 --- a/spring-core/src/main/java/org/springframework/util/comparator/package-info.java +++ b/spring-core/src/main/java/org/springframework/util/comparator/package-info.java @@ -1,3 +1,4 @@ + /** * * Useful generic {@code java.util.Comparator} implementations, diff --git a/spring-core/src/main/java/org/springframework/util/concurrent/package-info.java b/spring-core/src/main/java/org/springframework/util/concurrent/package-info.java index a03788bd271..ce15f2eb7c5 100644 --- a/spring-core/src/main/java/org/springframework/util/concurrent/package-info.java +++ b/spring-core/src/main/java/org/springframework/util/concurrent/package-info.java @@ -2,6 +2,7 @@ /** * * Useful generic {@code java.util.concurrent.Future} extension. + * */ package org.springframework.util.concurrent; 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 b93988e9bd4..0aea12d32a3 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/Message.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/Message.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. @@ -27,7 +27,7 @@ package org.springframework.messaging; public interface Message { /** - * Return message headers for the message, never {@code null}. + * Return message headers for the message (never {@code null}). */ 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 0f15080521f..e2ca8b86c66 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.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,17 +37,19 @@ import org.springframework.util.AlternativeJdkIdGenerator; import org.springframework.util.IdGenerator; /** - * The headers for a {@link Message} - *

- * IMPORTANT: This class is immutable. Any mutating operation such as + * The headers for a {@link Message}. + * + *

IMPORTANT: This class is immutable. Any mutating operation such as * {@code put(..)}, {@code putAll(..)} and others will throw * {@link UnsupportedOperationException}. - *

- * One way to create message headers is to use the + *

Subclasses do have access to the raw headers, however, via {@link #getRawHeaders()}. + * + *

One way to create message headers is to use the * {@link org.springframework.messaging.support.MessageBuilder MessageBuilder}: *

  * MessageBuilder.withPayload("foo").setHeader("key1", "value1").setHeader("key2", "value2");
  * 
+ * * A second option is to create {@link org.springframework.messaging.support.GenericMessage} * passing a payload as {@link Object} and headers as a {@link Map java.util.Map}: *
@@ -56,6 +58,7 @@ import org.springframework.util.IdGenerator;
  * headers.put("key2", "value2");
  * new GenericMessage("foo", headers);
  * 
+ * * A third option is to use {@link org.springframework.messaging.support.MessageHeaderAccessor} * or one of its sub-classes to create specific categories of headers. * @@ -98,7 +101,7 @@ public final class MessageHeaders implements Map, Serializable { public MessageHeaders(Map headers) { this.headers = (headers != null) ? new HashMap(headers) : new HashMap(); - this.headers.put(ID, ((idGenerator != null) ? idGenerator : defaultIdGenerator).generateId()); + this.headers.put(ID, (idGenerator != null ? idGenerator : defaultIdGenerator).generateId()); this.headers.put(TIMESTAMP, System.currentTimeMillis()); } @@ -133,20 +136,14 @@ public final class MessageHeaders implements Map, Serializable { } @Override - public int hashCode() { - return this.headers.hashCode(); + public boolean equals(Object other) { + return (this == other || + (other instanceof MessageHeaders && this.headers.equals(((MessageHeaders) other).headers))); } @Override - public boolean equals(Object object) { - if (this == object) { - return true; - } - if (object != null && object instanceof MessageHeaders) { - MessageHeaders other = (MessageHeaders) object; - return this.headers.equals(other.headers); - } - return false; + public int hashCode() { + return this.headers.hashCode(); } @Override @@ -157,9 +154,8 @@ public final class MessageHeaders implements Map, Serializable { return map.toString(); } - /* - * Map implementation - */ + + // Map implementation public boolean containsKey(Object key) { return this.headers.containsKey(key); @@ -193,7 +189,8 @@ public final class MessageHeaders implements Map, Serializable { return Collections.unmodifiableCollection(this.headers.values()); } - // Unsupported operations + + // Unsupported Map operations /** * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}. @@ -223,6 +220,7 @@ public final class MessageHeaders implements Map, Serializable { throw new UnsupportedOperationException("MessageHeaders is immutable"); } + // Serialization methods private void writeObject(ObjectOutputStream out) throws IOException { @@ -234,7 +232,7 @@ public final class MessageHeaders implements Map, Serializable { } for (String key : keysToRemove) { if (logger.isInfoEnabled()) { - logger.info("removing non-serializable header: " + key); + logger.info("Removing non-serializable header: " + key); } this.headers.remove(key); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java index 89b504995f2..89fc91d781e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MessageConverter.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. @@ -38,7 +38,7 @@ public interface MessageConverter { * conversion, it should return {@code null}. * @param message the input message * @param targetClass the target class for the conversion - * @return the result of the conversion or {@code null} if the converter cannot + * @return the result of the conversion, or {@code null} if the converter cannot * perform the conversion */ Object fromMessage(Message message, Class targetClass); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/SimpleMessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/SimpleMessageConverter.java index 28a4f373571..d2086a0519d 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/SimpleMessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/SimpleMessageConverter.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. @@ -39,7 +39,7 @@ public class SimpleMessageConverter implements MessageConverter { if (targetClass == null) { return payload; } - return ClassUtils.isAssignableValue(targetClass, payload) ? payload : null; + return (ClassUtils.isAssignableValue(targetClass, payload) ? payload : null); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageBuilder.java b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageBuilder.java index d0cef013f5c..acb0efb9f46 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageBuilder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageBuilder.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. @@ -23,14 +23,13 @@ import org.springframework.messaging.MessageChannel; import org.springframework.util.Assert; /** - * A builder for creating a {@link GenericMessage} (or {@link ErrorMessage} if - * the payload is of type {@link Throwable}). + * A builder for creating a {@link GenericMessage} + * (or {@link ErrorMessage} if the payload is of type {@link Throwable}). * * @author Arjen Poutsma * @author Mark Fisher * @author Rossen Stoyanchev * @since 4.0 - * * @see GenericMessage * @see ErrorMessage */ @@ -38,16 +37,13 @@ public final class MessageBuilder { private final T payload; - private MessageHeaderAccessor headerAccessor; - private final Message originalMessage; + private MessageHeaderAccessor headerAccessor; + - /** - * Private constructor to be invoked from the static factory methods only. - */ private MessageBuilder(T payload, Message originalMessage) { - Assert.notNull(payload, "payload must not be null"); + Assert.notNull(payload, "Payload must not be null"); this.payload = payload; this.originalMessage = originalMessage; this.headerAccessor = new MessageHeaderAccessor(originalMessage); @@ -58,11 +54,10 @@ public final class MessageBuilder { * Create a builder for a new {@link Message} instance pre-populated with all of the * headers copied from the provided message. The payload of the provided Message will * also be used as the payload for the new message. - * * @param message the Message from which the payload and all headers will be copied */ public static MessageBuilder fromMessage(Message message) { - Assert.notNull(message, "message must not be null"); + Assert.notNull(message, "Message must not be null"); return new MessageBuilder(message.getPayload(), message); } @@ -76,12 +71,12 @@ public final class MessageBuilder { /** - * Set the message headers. - * @param headerAccessor the headers for the message + * Set the message headers to use by providing a {@code MessageHeaderAccessor}. + * @param accessor the headers to use */ - public MessageBuilder setHeaders(MessageHeaderAccessor headerAccessor) { - Assert.notNull(headerAccessor, "HeaderAccessor must not be null"); - this.headerAccessor = headerAccessor; + public MessageBuilder setHeaders(MessageHeaderAccessor accessor) { + Assert.notNull(accessor, "MessageHeaderAccessor must not be null"); + this.headerAccessor = accessor; return this; } @@ -161,13 +156,15 @@ public final class MessageBuilder { @SuppressWarnings("unchecked") public Message build() { - if ((this.originalMessage != null) && !this.headerAccessor.isModified()) { + if (this.originalMessage != null && !this.headerAccessor.isModified()) { return this.originalMessage; } if (this.payload instanceof Throwable) { return (Message) new ErrorMessage((Throwable) this.payload, this.headerAccessor.toMap()); } - return new GenericMessage(this.payload, this.headerAccessor.toMap()); + else { + return new GenericMessage(this.payload, this.headerAccessor.toMap()); + } } } 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 0f659930495..2fd996f2e20 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 @@ -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. @@ -25,10 +25,10 @@ import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHeaders; -import org.springframework.util.Assert; import org.springframework.util.MimeType; import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; @@ -48,8 +48,7 @@ import org.springframework.util.StringUtils; */ public class MessageHeaderAccessor { - protected Log logger = LogFactory.getLog(getClass()); - + protected final Log logger = LogFactory.getLog(getClass()); // wrapped read-only message headers private final MessageHeaders originalHeaders; @@ -69,7 +68,7 @@ public class MessageHeaderAccessor { * A constructor for accessing and modifying existing message headers. */ public MessageHeaderAccessor(Message message) { - this.originalHeaders = (message != null) ? message.getHeaders() : null; + this.originalHeaders = (message != null ? message.getHeaders() : null); } @@ -109,23 +108,37 @@ public class MessageHeaderAccessor { } /** - * Set the value for the given header name. If the provided value is {@code null} the - * header will be removed. + * Set the value for the given header name. + *

If the provided value is {@code null}, the header will be removed. */ public void setHeader(String name, Object value) { - Assert.isTrue(!isReadOnly(name), "The '" + name + "' header is read-only."); + if (isReadOnly(name)) { + throw new IllegalArgumentException("'" + name + "' header is read-only"); + } verifyType(name, value); if (!ObjectUtils.nullSafeEquals(value, getHeader(name))) { this.headers.put(name, value); } } + protected void verifyType(String headerName, Object headerValue) { + if (headerName != null && headerValue != null) { + if (MessageHeaders.ERROR_CHANNEL.equals(headerName) || MessageHeaders.REPLY_CHANNEL.endsWith(headerName)) { + if (!(headerValue instanceof MessageChannel || headerValue instanceof String)) { + throw new IllegalArgumentException( + "'" + headerName + "' header value must be a MessageChannel or String"); + } + } + } + } + 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. + * Set the value for the given header name only if the header name is not + * already associated with a value. */ public void setHeaderIfAbsent(String name, Object value) { if (getHeader(name) == null) { @@ -134,9 +147,9 @@ public class MessageHeaderAccessor { } /** - * Removes all headers provided via array of 'headerPatterns'. As the name suggests - * the array may contain simple matching patterns for header names. Supported pattern - * styles are: "xxx*", "*xxx", "*xxx*" and "xxx*yyy". + * Removes all headers provided via array of 'headerPatterns'. + *

As the name suggests, array may contain simple matching patterns for header + * names. Supported pattern styles are: "xxx*", "*xxx", "*xxx*" and "xxx*yyy". */ public void removeHeaders(String... headerPatterns) { List headersToRemove = new ArrayList(); @@ -178,9 +191,9 @@ public class MessageHeaderAccessor { } /** - * Copy the name-value pairs from the provided Map. This operation will overwrite any - * existing values. Use { {@link #copyHeadersIfAbsent(Map)} to avoid overwriting - * values. + * Copy the name-value pairs from the provided Map. + *

This operation will overwrite any existing values. Use + * {@link #copyHeadersIfAbsent(Map)} to avoid overwriting values. */ public void copyHeaders(Map headersToCopy) { if (headersToCopy != null) { @@ -194,8 +207,8 @@ public class MessageHeaderAccessor { } /** - * Copy the name-value pairs from the provided Map. This operation will not - * overwrite any existing values. + * Copy the name-value pairs from the provided Map. + *

This operation will not overwrite any existing values. */ public void copyHeadersIfAbsent(Map headersToCopy) { if (headersToCopy != null) { @@ -251,17 +264,8 @@ public class MessageHeaderAccessor { @Override public String toString() { - return getClass().getSimpleName() + " [originalHeaders=" + this.originalHeaders - + ", updated headers=" + this.headers + "]"; + return getClass().getSimpleName() + " [originalHeaders=" + this.originalHeaders + + ", updated headers=" + this.headers + "]"; } - protected void verifyType(String headerName, Object headerValue) { - if (headerName != null && headerValue != null) { - if (MessageHeaders.ERROR_CHANNEL.equals(headerName) - || MessageHeaders.REPLY_CHANNEL.endsWith(headerName)) { - Assert.isTrue(headerValue instanceof MessageChannel || headerValue instanceof String, "The '" - + headerName + "' header value must be a MessageChannel or String."); - } - } - } }