Polishing

This commit is contained in:
Juergen Hoeller 2014-07-09 22:25:35 +02:00
parent fa4f51c5d0
commit 0d4ff1adbf
17 changed files with 267 additions and 300 deletions

View File

@ -1,3 +1,4 @@
/** /**
* *
* Useful generic {@code java.util.Comparator} implementations, * Useful generic {@code java.util.Comparator} implementations,

View File

@ -2,6 +2,7 @@
/** /**
* *
* Useful generic {@code java.util.concurrent.Future} extension. * Useful generic {@code java.util.concurrent.Future} extension.
*
*/ */
package org.springframework.util.concurrent; package org.springframework.util.concurrent;

View File

@ -16,11 +16,7 @@
package org.springframework.jms.listener.adapter; package org.springframework.jms.listener.adapter;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.jms.Destination; import javax.jms.Destination;
import javax.jms.JMSException; import javax.jms.JMSException;
import javax.jms.Session; import javax.jms.Session;
@ -32,12 +28,15 @@ import org.junit.Test;
import org.springframework.context.support.StaticApplicationContext; import org.springframework.context.support.StaticApplicationContext;
import org.springframework.jms.StubTextMessage; import org.springframework.jms.StubTextMessage;
import org.springframework.jms.config.DefaultJmsHandlerMethodFactory; import org.springframework.jms.config.DefaultJmsHandlerMethodFactory;
import org.springframework.jms.support.converter.JmsHeaders; import org.springframework.jms.support.JmsHeaders;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.messaging.converter.MessageConversionException; import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.messaging.support.MessageBuilder; import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/** /**
* *
* @author Stephane Nicoll * @author Stephane Nicoll
@ -48,6 +47,7 @@ public class MessagingMessageListenerAdapterTests {
private final SampleBean sample = new SampleBean(); private final SampleBean sample = new SampleBean();
@Before @Before
public void setup() { public void setup() {
initializeFactory(factory); initializeFactory(factory);
@ -85,12 +85,12 @@ public class MessagingMessageListenerAdapterTests {
listener.onMessage(message, session); listener.onMessage(message, session);
fail("Should have thrown an exception"); fail("Should have thrown an exception");
} }
catch (JMSException e) { catch (JMSException ex) {
fail("Should not have thrown a JMS exception"); fail("Should not have thrown a JMS exception");
} }
catch (ListenerExecutionFailedException e) { catch (ListenerExecutionFailedException ex) {
assertEquals(IllegalArgumentException.class, e.getCause().getClass()); assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
assertEquals("Expected test exception", e.getCause().getMessage()); assertEquals("Expected test exception", ex.getCause().getMessage());
} }
} }
@ -104,11 +104,11 @@ public class MessagingMessageListenerAdapterTests {
listener.onMessage(message, session); listener.onMessage(message, session);
fail("Should have thrown an exception"); fail("Should have thrown an exception");
} }
catch (JMSException e) { catch (JMSException ex) {
fail("Should not have thrown a JMS exception"); fail("Should not have thrown a JMS exception");
} }
catch (ListenerExecutionFailedException e) { catch (ListenerExecutionFailedException ex) {
assertEquals(MessageConversionException.class, e.getCause().getClass()); assertEquals(MessageConversionException.class, ex.getCause().getClass());
} }
} }
@ -145,4 +145,5 @@ public class MessagingMessageListenerAdapterTests {
throw new IllegalArgumentException("Should not have been called"); throw new IllegalArgumentException("Should not have been called");
} }
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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<T> { public interface Message<T> {
/** /**
* Return message headers for the message, never {@code null}. * Return message headers for the message (never {@code null}).
*/ */
MessageHeaders getHeaders(); MessageHeaders getHeaders();

View File

@ -36,18 +36,19 @@ import org.springframework.util.AlternativeJdkIdGenerator;
import org.springframework.util.IdGenerator; import org.springframework.util.IdGenerator;
/** /**
* The headers for a {@link Message} * The headers for a {@link Message}.
* <p> *
* <b>IMPORTANT</b>: This class is immutable. Any mutating operation such as * <p><b>IMPORTANT</b>: This class is immutable. Any mutating operation such as
* {@code put(..)}, {@code putAll(..)} and others will throw * {@code put(..)}, {@code putAll(..)} and others will throw
* {@link UnsupportedOperationException}. * {@link UnsupportedOperationException}.
* <p>Subclasses do have access to the raw headers, however, via {@link #getRawHeaders()}. * <p>Subclasses do have access to the raw headers, however, via {@link #getRawHeaders()}.
* <p> *
* One way to create message headers is to use the * <p>One way to create message headers is to use the
* {@link org.springframework.messaging.support.MessageBuilder MessageBuilder}: * {@link org.springframework.messaging.support.MessageBuilder MessageBuilder}:
* <pre class="code"> * <pre class="code">
* MessageBuilder.withPayload("foo").setHeader("key1", "value1").setHeader("key2", "value2"); * MessageBuilder.withPayload("foo").setHeader("key1", "value1").setHeader("key2", "value2");
* </pre> * </pre>
*
* A second option is to create {@link org.springframework.messaging.support.GenericMessage} * 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}: * passing a payload as {@link Object} and headers as a {@link Map java.util.Map}:
* <pre class="code"> * <pre class="code">
@ -56,6 +57,7 @@ import org.springframework.util.IdGenerator;
* headers.put("key2", "value2"); * headers.put("key2", "value2");
* new GenericMessage("foo", headers); * new GenericMessage("foo", headers);
* </pre> * </pre>
*
* A third option is to use {@link org.springframework.messaging.support.MessageHeaderAccessor} * 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 sub-classes to create specific categories of headers.
* *
@ -101,7 +103,6 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
/** /**
* Construct a {@link MessageHeaders} with the given headers. An {@link #ID} and * Construct a {@link MessageHeaders} with the given headers. An {@link #ID} and
* {@link #TIMESTAMP} headers will also be added, overriding any existing values. * {@link #TIMESTAMP} headers will also be added, overriding any existing values.
*
* @param headers a map with headers to add * @param headers a map with headers to add
*/ */
public MessageHeaders(Map<String, Object> headers) { public MessageHeaders(Map<String, Object> headers) {
@ -110,14 +111,12 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
/** /**
* Constructor providing control over the ID and TIMESTAMP header values. * Constructor providing control over the ID and TIMESTAMP header values.
*
* @param headers a map with headers to add * @param headers a map with headers to add
* @param id the {@link #ID} header value * @param id the {@link #ID} header value
* @param timestamp the {@link #TIMESTAMP} header value * @param timestamp the {@link #TIMESTAMP} header value
*/ */
protected MessageHeaders(Map<String, Object> headers, UUID id, Long timestamp) { protected MessageHeaders(Map<String, Object> headers, UUID id, Long timestamp) {
this.headers = (headers != null ? new HashMap<String, Object>(headers) : new HashMap<String, Object>());
this.headers = (headers != null) ? new HashMap<String, Object>(headers) : new HashMap<String, Object>();
if (id == null) { if (id == null) {
this.headers.put(ID, getIdGenerator().generateId()); this.headers.put(ID, getIdGenerator().generateId());
@ -146,7 +145,7 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
} }
protected static IdGenerator getIdGenerator() { protected static IdGenerator getIdGenerator() {
return ((idGenerator != null) ? idGenerator : defaultIdGenerator); return (idGenerator != null ? idGenerator : defaultIdGenerator);
} }
public UUID getId() { public UUID getId() {
@ -179,20 +178,14 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
} }
@Override @Override
public int hashCode() { public boolean equals(Object other) {
return this.headers.hashCode(); return (this == other ||
(other instanceof MessageHeaders && this.headers.equals(((MessageHeaders) other).headers)));
} }
@Override @Override
public boolean equals(Object object) { public int hashCode() {
if (this == object) { return this.headers.hashCode();
return true;
}
if (object != null && object instanceof MessageHeaders) {
MessageHeaders other = (MessageHeaders) object;
return this.headers.equals(other.headers);
}
return false;
} }
@Override @Override
@ -200,9 +193,8 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
return this.headers.toString(); return this.headers.toString();
} }
/*
* Map implementation // Map implementation
*/
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
return this.headers.containsKey(key); return this.headers.containsKey(key);
@ -236,7 +228,8 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
return Collections.unmodifiableCollection(this.headers.values()); 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}. * Since MessageHeaders are immutable, the call to this method will result in {@link UnsupportedOperationException}.
@ -266,6 +259,7 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
throw new UnsupportedOperationException("MessageHeaders is immutable"); throw new UnsupportedOperationException("MessageHeaders is immutable");
} }
// Serialization methods // Serialization methods
private void writeObject(ObjectOutputStream out) throws IOException { private void writeObject(ObjectOutputStream out) throws IOException {
@ -277,7 +271,7 @@ public class MessageHeaders implements Map<String, Object>, Serializable {
} }
for (String key : keysToRemove) { for (String key : keysToRemove) {
if (logger.isInfoEnabled()) { if (logger.isInfoEnabled()) {
logger.info("removing non-serializable header: " + key); logger.info("Removing non-serializable header: " + key);
} }
this.headers.remove(key); this.headers.remove(key);
} }

View File

@ -18,8 +18,10 @@ package org.springframework.messaging.converter;
import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/** /**
* An extension of the {@link SimpleMessageConverter} that uses a * An extension of the {@link SimpleMessageConverter} that uses a
@ -37,26 +39,39 @@ public class GenericMessageConverter extends SimpleMessageConverter {
private final ConversionService conversionService; private final ConversionService conversionService;
/** /**
* Create a new instance with the {@link ConversionService} to use. * Create a new instance with a default {@link ConversionService}.
*/
public GenericMessageConverter() {
this.conversionService = new DefaultConversionService();
}
/**
* Create a new instance with the given {@link ConversionService}.
*/ */
public GenericMessageConverter(ConversionService conversionService) { public GenericMessageConverter(ConversionService conversionService) {
Assert.notNull(conversionService, "ConversionService must not be null"); Assert.notNull(conversionService, "ConversionService must not be null");
this.conversionService = conversionService; this.conversionService = conversionService;
} }
@Override @Override
public Object fromMessage(Message<?> message, Class<?> targetClass) { public Object fromMessage(Message<?> message, Class<?> targetClass) {
Object payload = message.getPayload(); Object payload = message.getPayload();
if (conversionService.canConvert(payload.getClass(), targetClass)) { if (targetClass == null) {
return payload;
}
if (payload != null && this.conversionService.canConvert(payload.getClass(), targetClass)) {
try { try {
return conversionService.convert(payload, targetClass); return this.conversionService.convert(payload, targetClass);
} }
catch (ConversionException e) { catch (ConversionException ex) {
throw new MessageConversionException(message, "Failed to convert message payload '" throw new MessageConversionException(message, "Failed to convert message payload '" +
+ payload + "' to '" + targetClass.getName() + "'", e); payload + "' to '" + targetClass.getName() + "'", ex);
} }
} }
return null; return (ClassUtils.isAssignableValue(targetClass, payload) ? payload : null);
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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}. * conversion, it should return {@code null}.
* @param message the input message * @param message the input message
* @param targetClass the target class for the conversion * @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 * perform the conversion
*/ */
Object fromMessage(Message<?> message, Class<?> targetClass); Object fromMessage(Message<?> message, Class<?> targetClass);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -40,7 +40,7 @@ public class SimpleMessageConverter implements MessageConverter {
if (targetClass == null) { if (targetClass == null) {
return payload; return payload;
} }
return ClassUtils.isAssignableValue(targetClass, payload) ? payload : null; return (ClassUtils.isAssignableValue(targetClass, payload) ? payload : null);
} }
@Override @Override

View File

@ -13,17 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.messaging.simp; package org.springframework.messaging.simp;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.Map;
/** /**
* A wrapper class for access to attributes associated with a SiMP session * A wrapper class for access to attributes associated with a SiMP session
* (e.g. WebSocket session). * (e.g. WebSocket session).
@ -62,24 +64,6 @@ public class SimpAttributes {
this.attributes = attributes; this.attributes = attributes;
} }
/**
* Extract the SiMP session attributes from the given message, wrap them in
* a {@link SimpAttributes} instance.
* @param message the message to extract session attributes from
*/
public static SimpAttributes fromMessage(Message<?> message) {
Assert.notNull(message);
MessageHeaders headers = message.getHeaders();
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
Map<String, Object> sessionAttributes = SimpMessageHeaderAccessor.getSessionAttributes(headers);
if (sessionId == null) {
throw new IllegalStateException("No session id in " + message);
}
if (sessionAttributes == null) {
throw new IllegalStateException("No session attributes in " + message);
}
return new SimpAttributes(sessionId, sessionAttributes);
}
/** /**
* Return the value for the attribute of the given name, if any. * Return the value for the attribute of the given name, if any.
@ -193,4 +177,24 @@ public class SimpAttributes {
} }
} }
/**
* Extract the SiMP session attributes from the given message and
* wrap them in a {@link SimpAttributes} instance.
* @param message the message to extract session attributes from
*/
public static SimpAttributes fromMessage(Message<?> message) {
Assert.notNull(message, "Message must not be null");
MessageHeaders headers = message.getHeaders();
String sessionId = SimpMessageHeaderAccessor.getSessionId(headers);
Map<String, Object> sessionAttributes = SimpMessageHeaderAccessor.getSessionAttributes(headers);
if (sessionId == null) {
throw new IllegalStateException("No session id in " + message);
}
if (sessionAttributes == null) {
throw new IllegalStateException("No session attributes in " + message);
}
return new SimpAttributes(sessionId, sessionAttributes);
}
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.messaging.simp; package org.springframework.messaging.simp;
import org.springframework.core.NamedThreadLocal; import org.springframework.core.NamedThreadLocal;
@ -41,7 +42,6 @@ public abstract class SimpAttributesContextHolder {
/** /**
* Bind the given SimpAttributes to the current thread, * Bind the given SimpAttributes to the current thread,
*
* @param attributes the RequestAttributes to expose * @param attributes the RequestAttributes to expose
*/ */
public static void setAttributes(SimpAttributes attributes) { public static void setAttributes(SimpAttributes attributes) {
@ -56,7 +56,6 @@ public abstract class SimpAttributesContextHolder {
/** /**
* Extract the SiMP session attributes from the given message, wrap them in * Extract the SiMP session attributes from the given message, wrap them in
* a {@link SimpAttributes} instance and bind it to the current thread, * a {@link SimpAttributes} instance and bind it to the current thread,
*
* @param message the message to extract session attributes from * @param message the message to extract session attributes from
*/ */
public static void setAttributesFromMessage(Message<?> message) { public static void setAttributesFromMessage(Message<?> message) {
@ -65,7 +64,6 @@ public abstract class SimpAttributesContextHolder {
/** /**
* Return the SimpAttributes currently bound to the thread. * Return the SimpAttributes currently bound to the thread.
*
* @return the attributes or {@code null} if not bound * @return the attributes or {@code null} if not bound
*/ */
public static SimpAttributes getAttributes() { public static SimpAttributes getAttributes() {
@ -75,7 +73,6 @@ public abstract class SimpAttributesContextHolder {
/** /**
* Return the SimpAttributes currently bound to the thread or raise an * Return the SimpAttributes currently bound to the thread or raise an
* {@link java.lang.IllegalStateException} if none are bound.. * {@link java.lang.IllegalStateException} if none are bound..
*
* @return the attributes, never {@code null} * @return the attributes, never {@code null}
* @throws java.lang.IllegalStateException if attributes are not bound * @throws java.lang.IllegalStateException if attributes are not bound
*/ */

View File

@ -20,7 +20,6 @@ import java.security.Principal;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.logging.Log;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.messaging.support.IdTimestampMessageHeaderInitializer; import org.springframework.messaging.support.IdTimestampMessageHeaderInitializer;
import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.messaging.support.MessageHeaderAccessor;
@ -68,7 +67,6 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
/** /**
* For internal use. * For internal use.
*
* <p>The original destination used by a client when subscribing. Such a * <p>The original destination used by a client when subscribing. Such a
* destination may have been modified (e.g. user destinations) on the server * destination may have been modified (e.g. user destinations) on the server
* side. This header provides a hint so messages sent to clients may have * side. This header provides a hint so messages sent to clients may have
@ -98,30 +96,6 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
} }
/**
* Create an instance with
* {@link org.springframework.messaging.simp.SimpMessageType} {@code MESSAGE}.
*/
public static SimpMessageHeaderAccessor create() {
return new SimpMessageHeaderAccessor(SimpMessageType.MESSAGE, null);
}
/**
* Create an instance with the given
* {@link org.springframework.messaging.simp.SimpMessageType}.
*/
public static SimpMessageHeaderAccessor create(SimpMessageType messageType) {
return new SimpMessageHeaderAccessor(messageType, null);
}
/**
* Create an instance from the payload and headers of the given Message.
*/
public static SimpMessageHeaderAccessor wrap(Message<?> message) {
return new SimpMessageHeaderAccessor(message);
}
@Override @Override
protected MessageHeaderAccessor createAccessor(Message<?> message) { protected MessageHeaderAccessor createAccessor(Message<?> message) {
return wrap(message); return wrap(message);
@ -133,57 +107,27 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
} }
} }
/**
* @return the message type
*/
public SimpMessageType getMessageType() { public SimpMessageType getMessageType() {
return (SimpMessageType) getHeader(MESSAGE_TYPE_HEADER); return (SimpMessageType) getHeader(MESSAGE_TYPE_HEADER);
} }
/**
* A static alternative for access to the message type.
*/
public static SimpMessageType getMessageType(Map<String, Object> headers) {
return (SimpMessageType) headers.get(MESSAGE_TYPE_HEADER);
}
public void setDestination(String destination) { public void setDestination(String destination) {
Assert.notNull(destination, "Destination must not be null"); Assert.notNull(destination, "Destination must not be null");
setHeader(DESTINATION_HEADER, destination); setHeader(DESTINATION_HEADER, destination);
} }
/**
* @return the message destination
*/
public String getDestination() { public String getDestination() {
return (String) getHeader(DESTINATION_HEADER); return (String) getHeader(DESTINATION_HEADER);
} }
/**
* A static alternative for access to the destination header.
*/
public static String getDestination(Map<String, Object> headers) {
return (String) headers.get(DESTINATION_HEADER);
}
public void setSubscriptionId(String subscriptionId) { public void setSubscriptionId(String subscriptionId) {
setHeader(SUBSCRIPTION_ID_HEADER, subscriptionId); setHeader(SUBSCRIPTION_ID_HEADER, subscriptionId);
} }
/**
* @return the subscription id (if any) of the message
*/
public String getSubscriptionId() { public String getSubscriptionId() {
return (String) getHeader(SUBSCRIPTION_ID_HEADER); return (String) getHeader(SUBSCRIPTION_ID_HEADER);
} }
/**
* A static alternative for access to the subscription id header.
*/
public static String getSubscriptionId(Map<String, Object> headers) {
return (String) headers.get(SUBSCRIPTION_ID_HEADER);
}
public void setSessionId(String sessionId) { public void setSessionId(String sessionId) {
setHeader(SESSION_ID_HEADER, sessionId); setHeader(SESSION_ID_HEADER, sessionId);
} }
@ -195,13 +139,6 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
return (String) getHeader(SESSION_ID_HEADER); return (String) getHeader(SESSION_ID_HEADER);
} }
/**
* A static alternative for access to the session id header.
*/
public static String getSessionId(Map<String, Object> headers) {
return (String) headers.get(SESSION_ID_HEADER);
}
/** /**
* A static alternative for access to the session attributes header. * A static alternative for access to the session attributes header.
*/ */
@ -210,39 +147,24 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
} }
/** /**
* @return attributes associated with the current session. * Return the attributes associated with the current session.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Map<String, Object> getSessionAttributes() { public Map<String, Object> getSessionAttributes() {
return (Map<String, Object>) getHeader(SESSION_ATTRIBUTES); return (Map<String, Object>) getHeader(SESSION_ATTRIBUTES);
} }
/**
* A static alternative for access to the session attributes header.
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> getSessionAttributes(Map<String, Object> headers) {
return (Map<String, Object>) headers.get(SESSION_ATTRIBUTES);
}
public void setUser(Principal principal) { public void setUser(Principal principal) {
setHeader(USER_HEADER, principal); setHeader(USER_HEADER, principal);
} }
/** /**
* @return the user associated with the current session. * Return the user associated with the current session.
*/ */
public Principal getUser() { public Principal getUser() {
return (Principal) getHeader(USER_HEADER); return (Principal) getHeader(USER_HEADER);
} }
/**
* A static alternative for access to the user header.
*/
public static Principal getUser(Map<String, Object> headers) {
return (Principal) headers.get(USER_HEADER);
}
@Override @Override
public String getShortLogMessage(Object payload) { public String getShortLogMessage(Object payload) {
if (getMessageType() == null) { if (getMessageType() == null) {
@ -289,4 +211,55 @@ public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
return sb; return sb;
} }
// Static factory methods and accessors
/**
* Create an instance with
* {@link org.springframework.messaging.simp.SimpMessageType} {@code MESSAGE}.
*/
public static SimpMessageHeaderAccessor create() {
return new SimpMessageHeaderAccessor(SimpMessageType.MESSAGE, null);
}
/**
* Create an instance with the given
* {@link org.springframework.messaging.simp.SimpMessageType}.
*/
public static SimpMessageHeaderAccessor create(SimpMessageType messageType) {
return new SimpMessageHeaderAccessor(messageType, null);
}
/**
* Create an instance from the payload and headers of the given Message.
*/
public static SimpMessageHeaderAccessor wrap(Message<?> message) {
return new SimpMessageHeaderAccessor(message);
}
public static SimpMessageType getMessageType(Map<String, Object> headers) {
return (SimpMessageType) headers.get(MESSAGE_TYPE_HEADER);
}
public static String getDestination(Map<String, Object> headers) {
return (String) headers.get(DESTINATION_HEADER);
}
public static String getSubscriptionId(Map<String, Object> headers) {
return (String) headers.get(SUBSCRIPTION_ID_HEADER);
}
public static String getSessionId(Map<String, Object> headers) {
return (String) headers.get(SESSION_ID_HEADER);
}
@SuppressWarnings("unchecked")
public static Map<String, Object> getSessionAttributes(Map<String, Object> headers) {
return (Map<String, Object>) headers.get(SESSION_ATTRIBUTES);
}
public static Principal getUser(Map<String, Object> headers) {
return (Principal) headers.get(USER_HEADER);
}
} }

View File

@ -24,15 +24,13 @@ import org.springframework.beans.factory.config.Scope;
* (e.g. WebSocket session). * (e.g. WebSocket session).
* *
* <p>Relies on a thread-bound {@link SimpAttributes} instance exported by * <p>Relies on a thread-bound {@link SimpAttributes} instance exported by
* {@link org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler * {@link org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler}.
* SimpAnnotationMethodMessageHandler}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 4.1 * @since 4.1
*/ */
public class SimpSessionScope implements Scope { public class SimpSessionScope implements Scope {
@Override @Override
public Object get(String name, ObjectFactory<?> objectFactory) { public Object get(String name, ObjectFactory<?> objectFactory) {
SimpAttributes simpAttributes = SimpAttributesContextHolder.currentAttributes(); SimpAttributes simpAttributes = SimpAttributesContextHolder.currentAttributes();
@ -78,4 +76,5 @@ public class SimpSessionScope implements Scope {
public String getConversationId() { public String getConversationId() {
return SimpAttributesContextHolder.currentAttributes().getSessionId(); return SimpAttributesContextHolder.currentAttributes().getSessionId();
} }
} }

View File

@ -131,6 +131,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
super(SimpMessageType.HEARTBEAT, null); super(SimpMessageType.HEARTBEAT, null);
} }
void updateSimpMessageHeadersFromStompHeaders() { void updateSimpMessageHeadersFromStompHeaders() {
if (getNativeHeaders() == null) { if (getNativeHeaders() == null) {
return; return;
@ -171,35 +172,6 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
trySetStompHeaderForSubscriptionId(); trySetStompHeaderForSubscriptionId();
} }
/**
* Create an instance for the given STOMP command.
*/
public static StompHeaderAccessor create(StompCommand command) {
return new StompHeaderAccessor(command, null);
}
/**
* Create an instance for the given STOMP command and headers.
*/
public static StompHeaderAccessor create(StompCommand command, Map<String, List<String>> headers) {
return new StompHeaderAccessor(command, headers);
}
/**
* Create headers for a heartbeat. While a STOMP heartbeat frame does not
* have headers, a session id is needed for processing purposes at a minimum.
*/
public static StompHeaderAccessor createForHeartbeat() {
return new StompHeaderAccessor();
}
/**
* Create an instance from the payload and headers of the given Message.
*/
public static StompHeaderAccessor wrap(Message<?> message) {
return new StompHeaderAccessor(message);
}
@Override @Override
protected MessageHeaderAccessor createAccessor(Message<?> message) { protected MessageHeaderAccessor createAccessor(Message<?> message) {
@ -213,23 +185,18 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
} }
public StompCommand updateStompCommandAsClientMessage() { public StompCommand updateStompCommandAsClientMessage() {
Assert.state(SimpMessageType.MESSAGE.equals(getMessageType()), "Unexpected message type " + getMessage()); Assert.state(SimpMessageType.MESSAGE.equals(getMessageType()), "Unexpected message type " + getMessage());
if (getCommand() == null) { if (getCommand() == null) {
setHeader(COMMAND_HEADER, StompCommand.SEND); setHeader(COMMAND_HEADER, StompCommand.SEND);
} }
else if (!getCommand().equals(StompCommand.SEND)) { else if (!getCommand().equals(StompCommand.SEND)) {
throw new IllegalStateException("Unexpected STOMP command " + getCommand()); throw new IllegalStateException("Unexpected STOMP command " + getCommand());
} }
return getCommand(); return getCommand();
} }
public void updateStompCommandAsServerMessage() { public void updateStompCommandAsServerMessage() {
Assert.state(SimpMessageType.MESSAGE.equals(getMessageType()), "Unexpected message type " + getMessage()); Assert.state(SimpMessageType.MESSAGE.equals(getMessageType()), "Unexpected message type " + getMessage());
StompCommand command = getCommand(); StompCommand command = getCommand();
if ((command == null) || StompCommand.SEND.equals(command)) { if ((command == null) || StompCommand.SEND.equals(command)) {
setHeader(COMMAND_HEADER, StompCommand.MESSAGE); setHeader(COMMAND_HEADER, StompCommand.MESSAGE);
@ -237,9 +204,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
else if (!StompCommand.MESSAGE.equals(command)) { else if (!StompCommand.MESSAGE.equals(command)) {
throw new IllegalStateException("Unexpected STOMP command " + command); throw new IllegalStateException("Unexpected STOMP command " + command);
} }
trySetStompHeaderForSubscriptionId(); trySetStompHeaderForSubscriptionId();
if (getMessageId() == null) { if (getMessageId() == null) {
String messageId = getSessionId() + "-" + messageIdCounter.getAndIncrement(); String messageId = getSessionId() + "-" + messageIdCounter.getAndIncrement();
setNativeHeader(STOMP_MESSAGE_ID_HEADER, messageId); setNativeHeader(STOMP_MESSAGE_ID_HEADER, messageId);
@ -247,22 +212,15 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
} }
/** /**
* @return the STOMP command, or {@code null} if not yet set. * Return the STOMP command, or {@code null} if not yet set.
*/ */
public StompCommand getCommand() { public StompCommand getCommand() {
return (StompCommand) getHeader(COMMAND_HEADER); return (StompCommand) getHeader(COMMAND_HEADER);
} }
/**
* A static alternative for access to the STOMP command.
*/
public static StompCommand getCommand(Map<String, Object> headers) {
return (StompCommand) headers.get(COMMAND_HEADER);
}
public Set<String> getAcceptVersion() { public Set<String> getAcceptVersion() {
String rawValue = getFirstNativeHeader(STOMP_ACCEPT_VERSION_HEADER); String rawValue = getFirstNativeHeader(STOMP_ACCEPT_VERSION_HEADER);
return (rawValue != null) ? StringUtils.commaDelimitedListToSet(rawValue) : Collections.<String>emptySet(); return (rawValue != null ? StringUtils.commaDelimitedListToSet(rawValue) : Collections.<String>emptySet());
} }
public boolean isHeartbeat() { public boolean isHeartbeat() {
@ -329,15 +287,6 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
return null; return null;
} }
public static Integer getContentLength(Map<String, List<String>> nativeHeaders) {
if (nativeHeaders.containsKey(STOMP_CONTENT_LENGTH_HEADER)) {
List<String> values = nativeHeaders.get(STOMP_CONTENT_LENGTH_HEADER);
String value = (values != null ? values.get(0) : null);
return Integer.valueOf(value);
}
return null;
}
public void setContentLength(int contentLength) { public void setContentLength(int contentLength) {
setNativeHeader(STOMP_CONTENT_LENGTH_HEADER, String.valueOf(contentLength)); setNativeHeader(STOMP_CONTENT_LENGTH_HEADER, String.valueOf(contentLength));
} }
@ -370,7 +319,6 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
return getFirstNativeHeader(STOMP_LOGIN_HEADER); return getFirstNativeHeader(STOMP_LOGIN_HEADER);
} }
public void setPasscode(String passcode) { public void setPasscode(String passcode) {
setNativeHeader(STOMP_PASSCODE_HEADER, passcode); setNativeHeader(STOMP_PASSCODE_HEADER, passcode);
protectPasscode(); protectPasscode();
@ -385,21 +333,13 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
} }
/** /**
* @return the passcode header value or {@code null}. * Return the passcode header value, or {@code null} if not set.
*/ */
public String getPasscode() { public String getPasscode() {
StompPasscode credentials = (StompPasscode) getHeader(CREDENTIALS_HEADER); StompPasscode credentials = (StompPasscode) getHeader(CREDENTIALS_HEADER);
return (credentials != null ? credentials.passcode : null); return (credentials != null ? credentials.passcode : null);
} }
/**
* A static alternative for access to the passcode header.
*/
public static String getPasscode(Map<String, Object> headers) {
StompPasscode credentials = (StompPasscode) headers.get(CREDENTIALS_HEADER);
return (credentials != null ? credentials.passcode : null);
}
public void setReceiptId(String receiptId) { public void setReceiptId(String receiptId) {
setNativeHeader(STOMP_RECEIPT_ID_HEADER, receiptId); setNativeHeader(STOMP_RECEIPT_ID_HEADER, receiptId);
} }
@ -440,6 +380,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
setNativeHeader(STOMP_VERSION_HEADER, version); setNativeHeader(STOMP_VERSION_HEADER, version);
} }
// Logging related // Logging related
@Override @Override
@ -506,6 +447,62 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
} }
// Static factory methods and accessors
/**
* Create an instance for the given STOMP command.
*/
public static StompHeaderAccessor create(StompCommand command) {
return new StompHeaderAccessor(command, null);
}
/**
* Create an instance for the given STOMP command and headers.
*/
public static StompHeaderAccessor create(StompCommand command, Map<String, List<String>> headers) {
return new StompHeaderAccessor(command, headers);
}
/**
* Create headers for a heartbeat. While a STOMP heartbeat frame does not
* have headers, a session id is needed for processing purposes at a minimum.
*/
public static StompHeaderAccessor createForHeartbeat() {
return new StompHeaderAccessor();
}
/**
* Create an instance from the payload and headers of the given Message.
*/
public static StompHeaderAccessor wrap(Message<?> message) {
return new StompHeaderAccessor(message);
}
/**
* Return the STOMP command from the given headers, or {@code null} if not set.
*/
public static StompCommand getCommand(Map<String, Object> headers) {
return (StompCommand) headers.get(COMMAND_HEADER);
}
/**
* Return the passcode header value, or {@code null} if not set.
*/
public static String getPasscode(Map<String, Object> headers) {
StompPasscode credentials = (StompPasscode) headers.get(CREDENTIALS_HEADER);
return (credentials != null ? credentials.passcode : null);
}
public static Integer getContentLength(Map<String, List<String>> nativeHeaders) {
if (nativeHeaders.containsKey(STOMP_CONTENT_LENGTH_HEADER)) {
List<String> values = nativeHeaders.get(STOMP_CONTENT_LENGTH_HEADER);
String value = (values != null ? values.get(0) : null);
return Integer.valueOf(value);
}
return null;
}
private static class StompPasscode { private static class StompPasscode {
private final String passcode; private final String passcode;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,11 +16,11 @@
package org.springframework.messaging.support; package org.springframework.messaging.support;
import java.util.UUID;
import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.MessageHeaders;
import org.springframework.util.IdGenerator; import org.springframework.util.IdGenerator;
import java.util.UUID;
/** /**
* A {@link org.springframework.messaging.support.MessageHeaderInitializer MessageHeaderInitializer} * A {@link org.springframework.messaging.support.MessageHeaderInitializer MessageHeaderInitializer}
* to customize the strategy for ID and TIMESTAMP message header generation. * to customize the strategy for ID and TIMESTAMP message header generation.
@ -38,10 +38,8 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
/** /**
* Configure the IdGenerator strategy to initialize {@code MessageHeaderAccessor} * Configure the IdGenerator strategy to initialize {@code MessageHeaderAccessor}
* instances with. * instances with.
*
* <p>By default this property is set to {@code null} in which case the default * <p>By default this property is set to {@code null} in which case the default
* IdGenerator of {@link org.springframework.messaging.MessageHeaders} is used. * IdGenerator of {@link org.springframework.messaging.MessageHeaders} is used.
*
* <p>To have no id's generated at all, see {@@link #setDisableIdGeneration()}. * <p>To have no id's generated at all, see {@@link #setDisableIdGeneration()}.
*/ */
public void setIdGenerator(IdGenerator idGenerator) { public void setIdGenerator(IdGenerator idGenerator) {
@ -49,17 +47,15 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
} }
/** /**
* A shortcut for calling * A shortcut for calling {@link #setIdGenerator(org.springframework.util.IdGenerator)}
* {@link #setIdGenerator(org.springframework.util.IdGenerator)} with an * with an id generation strategy to disable id generation completely.
* id generation strategy to
*
*/ */
public void setDisableIdGeneration() { public void setDisableIdGeneration() {
this.idGenerator = ID_VALUE_NONE_GENERATOR; this.idGenerator = ID_VALUE_NONE_GENERATOR;
} }
/** /**
* @return the configured {@code IdGenerator} if any. * Return the configured {@code IdGenerator}, if any.
*/ */
public IdGenerator getIdGenerator() { public IdGenerator getIdGenerator() {
return this.idGenerator; return this.idGenerator;
@ -69,7 +65,6 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
* Whether to enable the automatic addition of the * Whether to enable the automatic addition of the
* {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on * {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on
* {@code MessageHeaderAccessor} instances being initialized. * {@code MessageHeaderAccessor} instances being initialized.
*
* <p>By default this property is set to false. * <p>By default this property is set to false.
*/ */
public void setEnableTimestamp(boolean enableTimestamp) { public void setEnableTimestamp(boolean enableTimestamp) {
@ -77,12 +72,13 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
} }
/** /**
* @return Whether the timestamp header is enabled or not. * Return whether the timestamp header is enabled or not.
*/ */
public boolean isEnableTimestamp() { public boolean isEnableTimestamp() {
return this.enableTimestamp; return this.enableTimestamp;
} }
@Override @Override
public void initHeaders(MessageHeaderAccessor headerAccessor) { public void initHeaders(MessageHeaderAccessor headerAccessor) {
headerAccessor.setIdGenerator(getIdGenerator()); headerAccessor.setIdGenerator(getIdGenerator());

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,14 +24,13 @@ import org.springframework.messaging.MessageHeaders;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* A builder for creating a {@link GenericMessage} (or {@link ErrorMessage} if * A builder for creating a {@link GenericMessage}
* the payload is of type {@link Throwable}). * (or {@link ErrorMessage} if the payload is of type {@link Throwable}).
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Mark Fisher * @author Mark Fisher
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 4.0 * @since 4.0
*
* @see GenericMessage * @see GenericMessage
* @see ErrorMessage * @see ErrorMessage
*/ */
@ -59,52 +58,9 @@ public final class MessageBuilder<T> {
this.originalMessage = null; this.originalMessage = null;
} }
/**
* 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 <T> MessageBuilder<T> fromMessage(Message<T> message) {
return new MessageBuilder<T>(message);
}
/**
* Create a new builder for a message with the given payload.
* @param payload the payload
*/
public static <T> MessageBuilder<T> withPayload(T payload) {
return new MessageBuilder<T>(payload, new MessageHeaderAccessor());
}
/**
* A shortcut factory method for creating a message with the given payload
* and {@code MessageHeaders}.
*
* <p><strong>Note:</strong> the given {@code MessageHeaders} instance is used
* directly in the new message, i.e. it is not copied.
*
* @param payload the payload to use, never {@code null}
* @param messageHeaders the headers to use, never {@code null}
* @return the created message
* @since 4.1
*/
@SuppressWarnings("unchecked")
public static <T> Message<T> createMessage(T payload, MessageHeaders messageHeaders) {
Assert.notNull(payload, "'payload' must not be null");
Assert.notNull(messageHeaders, "'messageHeaders' must not be null");
if (payload instanceof Throwable) {
return (Message<T>) new ErrorMessage((Throwable) payload, messageHeaders);
}
else {
return new GenericMessage<T>(payload, messageHeaders);
}
}
/** /**
* Set the message headers to use by providing a {@code MessageHeaderAccessor}. * Set the message headers to use by providing a {@code MessageHeaderAccessor}.
*
* @param accessor the headers to use * @param accessor the headers to use
*/ */
public MessageBuilder<T> setHeaders(MessageHeaderAccessor accessor) { public MessageBuilder<T> setHeaders(MessageHeaderAccessor accessor) {
@ -189,11 +145,9 @@ public final class MessageBuilder<T> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Message<T> build() { public Message<T> build() {
if (this.originalMessage != null && !this.headerAccessor.isModified()) { if (this.originalMessage != null && !this.headerAccessor.isModified()) {
return this.originalMessage; return this.originalMessage;
} }
if (this.payload instanceof Throwable) { if (this.payload instanceof Throwable) {
return (Message<T>) new ErrorMessage((Throwable) this.payload, this.headerAccessor.toMap()); return (Message<T>) new ErrorMessage((Throwable) this.payload, this.headerAccessor.toMap());
} }
@ -202,4 +156,45 @@ public final class MessageBuilder<T> {
} }
} }
/**
* 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 <T> MessageBuilder<T> fromMessage(Message<T> message) {
return new MessageBuilder<T>(message);
}
/**
* Create a new builder for a message with the given payload.
* @param payload the payload
*/
public static <T> MessageBuilder<T> withPayload(T payload) {
return new MessageBuilder<T>(payload, new MessageHeaderAccessor());
}
/**
* A shortcut factory method for creating a message with the given payload
* and {@code MessageHeaders}.
* <p><strong>Note:</strong> the given {@code MessageHeaders} instance is used
* directly in the new message, i.e. it is not copied.
* @param payload the payload to use, never {@code null}
* @param messageHeaders the headers to use, never {@code null}
* @return the created message
* @since 4.1
*/
@SuppressWarnings("unchecked")
public static <T> Message<T> createMessage(T payload, MessageHeaders messageHeaders) {
Assert.notNull(payload, "'payload' must not be null");
Assert.notNull(messageHeaders, "'messageHeaders' must not be null");
if (payload instanceof Throwable) {
return (Message<T>) new ErrorMessage((Throwable) payload, messageHeaders);
}
else {
return new GenericMessage<T>(payload, messageHeaders);
}
}
} }

View File

@ -17,8 +17,7 @@
package org.springframework.messaging.support; package org.springframework.messaging.support;
/** /**
* Callback interface for initializing a * Callback interface for initializing a {@link MessageHeaderAccessor}.
* {@link org.springframework.messaging.support.MessageHeaderAccessor MessageHeaderAccessor}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 4.1 * @since 4.1
@ -27,8 +26,7 @@ public interface MessageHeaderInitializer {
/** /**
* Initialize the given {@code MessageHeaderAccessor}. * Initialize the given {@code MessageHeaderAccessor}.
* * @param headerAccessor the MessageHeaderAccessor to initialize
* @param headerAccessor the instance to initialize
*/ */
void initHeaders(MessageHeaderAccessor headerAccessor); void initHeaders(MessageHeaderAccessor headerAccessor);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,28 +16,26 @@
package org.springframework.messaging.core; package org.springframework.messaging.core;
import java.io.Writer;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
import org.springframework.messaging.converter.GenericMessageConverter; import org.springframework.messaging.converter.GenericMessageConverter;
import org.springframework.messaging.converter.MessageConversionException; import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.messaging.support.GenericMessage; import org.springframework.messaging.support.GenericMessage;
import static org.hamcrest.CoreMatchers.isA; import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.Writer;
/** /**
* Unit tests for receiving operations in {@link AbstractMessagingTemplate}. * Unit tests for receiving operations in {@link AbstractMessagingTemplate}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*
* @see MessageRequestReplyTemplateTests * @see MessageRequestReplyTemplateTests
*/ */
public class MessageReceivingTemplateTests { public class MessageReceivingTemplateTests {
@ -104,7 +102,7 @@ public class MessageReceivingTemplateTests {
public void receiveAndConvertFailed() { public void receiveAndConvertFailed() {
Message<?> expected = new GenericMessage<Object>("not a number test"); Message<?> expected = new GenericMessage<Object>("not a number test");
this.template.setReceiveMessage(expected); this.template.setReceiveMessage(expected);
this.template.setMessageConverter(new GenericMessageConverter(new DefaultConversionService())); this.template.setMessageConverter(new GenericMessageConverter());
thrown.expect(MessageConversionException.class); thrown.expect(MessageConversionException.class);
thrown.expectCause(isA(ConversionFailedException.class)); thrown.expectCause(isA(ConversionFailedException.class));
@ -116,13 +114,13 @@ public class MessageReceivingTemplateTests {
Message<?> expected = new GenericMessage<Object>("payload"); Message<?> expected = new GenericMessage<Object>("payload");
this.template.setDefaultDestination("home"); this.template.setDefaultDestination("home");
this.template.setReceiveMessage(expected); this.template.setReceiveMessage(expected);
this.template.setMessageConverter(new GenericMessageConverter(new DefaultConversionService())); this.template.setMessageConverter(new GenericMessageConverter());
try { try {
this.template.receiveAndConvert(Writer.class); this.template.receiveAndConvert(Writer.class);
} }
catch (MessageConversionException e) { catch (MessageConversionException ex) {
assertTrue("Invalid exception message '"+e.getMessage()+"'", e.getMessage().contains("payload")); assertTrue("Invalid exception message '" + ex.getMessage() + "'", ex.getMessage().contains("payload"));
assertSame(expected, e.getFailedMessage()); assertSame(expected, ex.getFailedMessage());
} }
} }
@ -134,7 +132,6 @@ public class MessageReceivingTemplateTests {
private Message<?> receiveMessage; private Message<?> receiveMessage;
private void setReceiveMessage(Message<?> receiveMessage) { private void setReceiveMessage(Message<?> receiveMessage) {
this.receiveMessage = receiveMessage; this.receiveMessage = receiveMessage;
} }
@ -154,7 +151,6 @@ public class MessageReceivingTemplateTests {
this.destination = destination; this.destination = destination;
return null; return null;
} }
} }
} }