diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/GenericMessage.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/GenericMessage.java index fea4b7fd38..ae11fe2305 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/GenericMessage.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/GenericMessage.java @@ -17,6 +17,7 @@ package org.springframework.integration.message; import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -55,14 +56,14 @@ public class GenericMessage implements Message, Serializable { */ public GenericMessage(T payload, Map headers) { Assert.notNull(payload, "payload must not be null"); - this.payload = payload; if (headers == null) { headers = new HashMap(); } - else if (headers instanceof MessageHeaders) { + else { headers = new HashMap(headers); } this.headers = new MessageHeaders(headers); + this.payload = payload; } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageBuilder.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageBuilder.java index 075c504015..31e1c731b9 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageBuilder.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageBuilder.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * @author Arjen Poutsma @@ -45,10 +46,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 will - * also be taken from the provided message. + * 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 messageToCopy the Message from which the paylaod and all headers + * @param messageToCopy the Message from which the payload and all headers * will be copied */ public static MessageBuilder fromMessage(Message message) { @@ -73,7 +74,7 @@ public final class MessageBuilder { * null, the header will be removed. */ public MessageBuilder setHeader(String headerName, Object headerValue) { - if (headerName != null) { + if (StringUtils.hasLength(headerName)) { if (headerValue == null) { this.headers.remove(headerName); } @@ -128,10 +129,19 @@ public final class MessageBuilder { return this; } - public MessageBuilder setExpirationDate(Date expirationDate) { + public MessageBuilder setExpirationDate(Long expirationDate) { return this.setHeader(MessageHeaders.EXPIRATION_DATE, expirationDate); } + public MessageBuilder setExpirationDate(Date expirationDate) { + if (expirationDate != null) { + return this.setHeader(MessageHeaders.EXPIRATION_DATE, expirationDate.getTime()); + } + else { + return this.setHeader(MessageHeaders.EXPIRATION_DATE, null); + } + } + public MessageBuilder setCorrelationId(Object correlationId) { return this.setHeader(MessageHeaders.CORRELATION_ID, correlationId); } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageHeaders.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageHeaders.java index 5281e1350e..ad51e2868b 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageHeaders.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/MessageHeaders.java @@ -19,13 +19,10 @@ package org.springframework.integration.message; import java.io.Serializable; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Set; - -import org.springframework.integration.util.IdGenerator; -import org.springframework.integration.util.RandomUuidGenerator; +import java.util.UUID; /** * The headers for a {@link Message}. @@ -56,12 +53,11 @@ public final class MessageHeaders implements Map, Serializable { private final Map headers; - private transient final IdGenerator idGenerator = new RandomUuidGenerator(); - public MessageHeaders(Map headers) { - this.headers = (headers != null ? headers : new HashMap()); - this.headers.put(ID, this.idGenerator.generateId()); + this.headers = (headers != null ? headers + : new HashMap()); + this.headers.put(ID, UUID.randomUUID()); this.headers.put(TIMESTAMP, new Long(System.currentTimeMillis())); } @@ -74,8 +70,8 @@ public final class MessageHeaders implements Map, Serializable { return this.get(TIMESTAMP, Long.class); } - public Date getExpirationDate() { - return this.get(EXPIRATION_DATE, Date.class); + public Long getExpirationDate() { + return this.get(EXPIRATION_DATE, Long.class); } public Object getCorrelationId() { @@ -104,22 +100,6 @@ public final class MessageHeaders implements Map, Serializable { return this.get(PRIORITY, MessagePriority.class); } - public void clear() { - this.headers.clear(); - } - - public boolean containsKey(Object key) { - return this.headers.containsKey(key); - } - - public boolean containsValue(Object value) { - return this.headers.containsValue(value); - } - - public Set> entrySet() { - return Collections.unmodifiableSet(this.headers.entrySet()); - } - @SuppressWarnings("unchecked") public T get(Object key, Class type) { Object value = this.headers.get(key); @@ -127,44 +107,14 @@ public final class MessageHeaders implements Map, Serializable { return null; } if (!type.isAssignableFrom(value.getClass())) { - throw new IllegalArgumentException("Incorrect type specified for header '" + key - + "'. Expected [" + type + "] but actual type is [" + value.getClass() + "]"); + throw new IllegalArgumentException( + "Incorrect type specified for header '" + key + + "'. Expected [" + type + "] but actual type is [" + + value.getClass() + "]"); } return (T) value; } - public Object get(Object key) { - return this.headers.get(key); - } - - public boolean isEmpty() { - return this.headers.isEmpty(); - } - - public Set keySet() { - return Collections.unmodifiableSet(this.headers.keySet()); - } - - public Object put(String key, Object value) { - throw new UnsupportedOperationException("MessageHeaders is immutable."); - } - - public void putAll(Map t) { - throw new UnsupportedOperationException("MessageHeaders is immutable."); - } - - public Object remove(Object key) { - throw new UnsupportedOperationException("MessageHeaders is immutable."); - } - - public int size() { - return this.headers.size(); - } - - public Collection values() { - return Collections.unmodifiableCollection(this.headers.values()); - } - public int hashCode() { return headers.hashCode(); } @@ -184,4 +134,60 @@ public final class MessageHeaders implements Map, Serializable { return this.headers.toString(); } + /* + * Map implementation + */ + + public void clear() { + this.headers.clear(); + } + + public boolean containsKey(Object key) { + return this.headers.containsKey(key); + } + + public boolean containsValue(Object value) { + return this.headers.containsValue(value); + } + + public Set> entrySet() { + return Collections.unmodifiableSet(this.headers.entrySet()); + } + + public Object get(Object key) { + return this.headers.get(key); + } + + public boolean isEmpty() { + return this.headers.isEmpty(); + } + + public Set keySet() { + return Collections.unmodifiableSet(this.headers.keySet()); + } + + public int size() { + return this.headers.size(); + } + + public Collection values() { + return Collections.unmodifiableCollection(this.headers.values()); + } + + /* + * Unsupported operations + */ + + public Object put(String key, Object value) { + throw new UnsupportedOperationException("MessageHeaders is immutable."); + } + + public void putAll(Map t) { + throw new UnsupportedOperationException("MessageHeaders is immutable."); + } + + public Object remove(Object key) { + throw new UnsupportedOperationException("MessageHeaders is immutable."); + } + } diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/message/selector/UnexpiredMessageSelector.java b/org.springframework.integration/src/main/java/org/springframework/integration/message/selector/UnexpiredMessageSelector.java index 7e9751a30d..f7404f2bd0 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/message/selector/UnexpiredMessageSelector.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/message/selector/UnexpiredMessageSelector.java @@ -16,24 +16,23 @@ package org.springframework.integration.message.selector; -import java.util.Date; - import org.springframework.integration.message.Message; /** * A {@link MessageSelector} that accepts {@link Message Messages} that are - * not expired. + * not yet expired. If a Message's expiration date header is + * null, that Message never expires. * * @author Mark Fisher */ public class UnexpiredMessageSelector implements MessageSelector { public boolean accept(Message message) { - Date expirationDate = message.getHeaders().getExpirationDate(); + Long expirationDate = message.getHeaders().getExpirationDate(); if (expirationDate == null) { return true; } - return expirationDate.getTime() > System.currentTimeMillis(); + return expirationDate > System.currentTimeMillis(); } } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/channel/QueueChannelTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/channel/QueueChannelTests.java index 6fcd9aa339..9ed770823f 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/channel/QueueChannelTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/channel/QueueChannelTests.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.Date; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -224,8 +223,8 @@ public class QueueChannelTests { QueueChannel channel = new QueueChannel(2); long minute = 60 * 1000; long time = System.currentTimeMillis(); - Date past = new Date(time - minute); - Date future = new Date(time + minute); + long past = time - minute; + long future = time + minute; Message expiredMessage = MessageBuilder.fromPayload("test1") .setExpirationDate(past).build(); Message unexpiredMessage = MessageBuilder.fromPayload("test2") diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/message/MessageBuilderTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/message/MessageBuilderTests.java index 5097403ee3..4821246628 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/message/MessageBuilderTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/message/MessageBuilderTests.java @@ -101,11 +101,19 @@ public class MessageBuilderTests { } @Test - public void testExpirationDate() { - Date past = new Date(System.currentTimeMillis() - (60 * 1000)); + public void testExpirationDateSetAsLong() { + Long past = System.currentTimeMillis() - (60 * 1000); Message expiredMessage = MessageBuilder.fromPayload(1) .setExpirationDate(past).build(); assertEquals(past, expiredMessage.getHeaders().getExpirationDate()); } + @Test + public void testExpirationDateSetAsDate() { + Long past = System.currentTimeMillis() - (60 * 1000); + Message expiredMessage = MessageBuilder.fromPayload(1) + .setExpirationDate(new Date(past)).build(); + assertEquals(past, expiredMessage.getHeaders().getExpirationDate()); + } + } diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/message/selector/UnexpiredMessageSelectorTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/message/selector/UnexpiredMessageSelectorTests.java index cfb0ce35b5..9ec65fd12e 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/message/selector/UnexpiredMessageSelectorTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/message/selector/UnexpiredMessageSelectorTests.java @@ -19,8 +19,6 @@ package org.springframework.integration.message.selector; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Date; - import org.junit.Test; import org.springframework.integration.message.Message; @@ -35,7 +33,7 @@ public class UnexpiredMessageSelectorTests { public void testExpiredMessageRejected() { long past = System.currentTimeMillis() - 60000; Message message = MessageBuilder.fromPayload("expired") - .setExpirationDate(new Date(past)).build(); + .setExpirationDate(past).build(); UnexpiredMessageSelector selector = new UnexpiredMessageSelector(); assertFalse(selector.accept(message)); } @@ -44,7 +42,7 @@ public class UnexpiredMessageSelectorTests { public void testUnexpiredMessageAccepted() { long future = System.currentTimeMillis() + 60000; Message message = MessageBuilder.fromPayload("unexpired") - .setExpirationDate(new Date(future)).build(); + .setExpirationDate(future).build(); UnexpiredMessageSelector selector = new UnexpiredMessageSelector(); assertTrue(selector.accept(message)); }