Create spring-messaging module

Consolidates new, messaging-related classes from spring-context and
spring-websocket into one module.
This commit is contained in:
Rossen Stoyanchev 2013-07-12 09:02:51 -04:00
parent 2803845151
commit d3cecfc6cc
81 changed files with 404 additions and 315 deletions

View File

@ -301,9 +301,6 @@ project("spring-context") {
optional("org.hibernate:hibernate-validator:4.3.0.Final")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.0")
optional("org.projectreactor:reactor-core:1.0.0.BUILD-SNAPSHOT")
optional("com.lmax:disruptor:3.1.1")
testCompile("commons-dbcp:commons-dbcp:1.2.2")
testCompile("javax.inject:javax.inject-tck:1")
}
@ -314,6 +311,25 @@ project("spring-context") {
test {
jvmArgs = ["-disableassertions:org.aspectj.weaver.UnresolvedType"] // SPR-7989
}
}
project("spring-messaging") {
description = "Spring Messaging"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-context"))
optional(project(":spring-web")) // TODO: MediaType/HandlerMethod/EHMR
optional(project(":spring-websocket"))
optional("com.fasterxml.jackson.core:jackson-databind:2.2.0")
optional("org.projectreactor:reactor-core:1.0.0.BUILD-SNAPSHOT")
optional("org.projectreactor:reactor-tcp:1.0.0.BUILD-SNAPSHOT")
optional("com.lmax:disruptor:3.1.1")
testCompile("commons-dbcp:commons-dbcp:1.2.2")
testCompile("javax.inject:javax.inject-tck:1")
}
repositories {
maven { url 'http://repo.springsource.org/snapshot' } // reactor
}
@ -472,7 +488,7 @@ project("spring-web") {
}
project("spring-websocket") {
description = "Spring WebSocket support"
description = "Spring WebSocket"
dependencies {
compile(project(":spring-core"))
@ -492,15 +508,11 @@ project("spring-websocket") {
optional("org.eclipse.jetty.websocket:websocket-server:9.0.4.v20130625")
optional("org.eclipse.jetty.websocket:websocket-client:9.0.4.v20130625")
optional("com.fasterxml.jackson.core:jackson-databind:2.2.0") // required for SockJS support currently
optional("org.projectreactor:reactor-core:1.0.0.BUILD-SNAPSHOT")
optional("org.projectreactor:reactor-tcp:1.0.0.BUILD-SNAPSHOT")
optional("com.lmax:disruptor:3.1.1")
}
repositories {
maven { url "https://repository.apache.org/content/repositories/snapshots" } // tomcat-websocket-* snapshots
maven { url "https://maven.java.net/content/repositories/releases" } // javax.websocket, tyrus
maven { url 'http://repo.springsource.org/snapshot' } // reactor
}
}

View File

@ -11,6 +11,7 @@ include "spring-instrument"
include "spring-instrument-tomcat"
include "spring-jdbc"
include "spring-jms"
include "spring-messaging"
include "spring-orm"
include "spring-orm-hibernate4"
include "spring-oxm"

View File

@ -1,4 +0,0 @@
/**
* Generic support for working with messaging APIs and protocols.
*/
package org.springframework.messaging;

View File

@ -19,8 +19,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.converter.SimplePayloadMessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.support.converter.MessageConverter;
import org.springframework.messaging.support.converter.SimplePayloadMessageConverter;
import org.springframework.util.Assert;
@ -34,7 +34,7 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
private volatile D defaultDestination;
protected volatile MessageConverter converter = new SimplePayloadMessageConverter();
private volatile MessageConverter converter = new SimplePayloadMessageConverter();
public void setDefaultDestination(D defaultDestination) {
@ -51,6 +51,19 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
this.converter = messageConverter;
}
/**
* @return the configured {@link MessageConverter}
*/
public MessageConverter getConverter() {
return this.converter;
}
/**
* @param converter the converter to set
*/
public void setConverter(MessageConverter converter) {
this.converter = converter;
}
@Override
public <P> void send(Message<P> message) {
@ -91,6 +104,7 @@ public abstract class AbstractMessageSendingTemplate<D> implements MessageSendin
public <T> void convertAndSend(D destination, T object, MessagePostProcessor postProcessor)
throws MessagingException {
@SuppressWarnings("unchecked")
Message<?> message = this.converter.toMessage(object);
if (postProcessor != null) {
message = postProcessor.postProcessMessage(message);

View File

@ -44,10 +44,11 @@ public abstract class AbstractMessagingTemplate<D> extends AbstractMessageSendin
return this.receiveAndConvert(getRequiredDefaultDestination());
}
@SuppressWarnings("unchecked")
@Override
public Object receiveAndConvert(D destination) {
Message<?> message = this.doReceive(destination);
return (message != null) ? this.converter.fromMessage(message, null) : null;
return (message != null) ? getConverter().fromMessage(message, null) : null;
}
@ -79,14 +80,15 @@ public abstract class AbstractMessagingTemplate<D> extends AbstractMessageSendin
return this.convertSendAndReceive(getRequiredDefaultDestination(), request, postProcessor);
}
@SuppressWarnings("unchecked")
@Override
public Object convertSendAndReceive(D destination, Object request, MessagePostProcessor postProcessor) {
Message<?> requestMessage = this.converter.toMessage(request);
Message<?> requestMessage = getConverter().toMessage(request);
if (postProcessor != null) {
requestMessage = postProcessor.postProcessMessage(requestMessage);
}
Message<?> replyMessage = this.sendAndReceive(destination, requestMessage);
return this.converter.fromMessage(replyMessage, null);
return getConverter().fromMessage(replyMessage, null);
}
}

View File

@ -13,13 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.channel;
package org.springframework.messaging.core;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.core.DestinationResolutionException;
import org.springframework.messaging.core.DestinationResolver;
import org.springframework.util.Assert;

View File

@ -28,7 +28,6 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.channel.BeanFactoryMessageChannelDestinationResolver;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.annotation;
package org.springframework.messaging.handler.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.annotation;
package org.springframework.messaging.handler.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.annotation;
package org.springframework.messaging.handler.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -0,0 +1,4 @@
/**
* Annotations and support classes for handling messages.
*/
package org.springframework.messaging.handler.annotation;

View File

@ -14,20 +14,21 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.annotation.support;
import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.MessageBody;
import org.springframework.messaging.handler.method.MessageArgumentResolver;
import org.springframework.messaging.support.converter.MessageConverter;
import org.springframework.util.Assert;
import org.springframework.web.messaging.annotation.MessageBody;
/**
* @author Rossen Stoyanchev
* @since 4.0
*/
public class MessageBodyArgumentResolver implements ArgumentResolver {
public class MessageBodyArgumentResolver implements MessageArgumentResolver {
private final MessageConverter<?> converter;

View File

@ -14,15 +14,15 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.annotation.support;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.web.messaging.annotation.MessageExceptionHandler;
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;

View File

@ -0,0 +1,4 @@
/**
* Support classes for working with annotated message-handling methods.
*/
package org.springframework.messaging.handler.annotation.support;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -26,19 +26,13 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.messaging.Message;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.method.HandlerMethod;
/**
* Invokes the handler method for a given message after resolving
* its method argument values through registered {@link ArgumentResolver}s.
* its method argument values through registered {@link MessageArgumentResolver}s.
* <p>
* Argument resolution often requires a {@link WebDataBinder} for data binding or for type
* conversion. Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to
* supply a binder factory to pass to argument resolvers.
* <p>
* Use {@link #setMessageMethodArgumentResolvers(ArgumentResolverComposite)}
* Use {@link #setMessageMethodArgumentResolvers(MessageArgumentResolverComposite)}
* to customize the list of argument resolvers.
*
* @author Rossen Stoyanchev
@ -46,7 +40,7 @@ import org.springframework.web.method.HandlerMethod;
*/
public class InvocableMessageHandlerMethod extends HandlerMethod {
private ArgumentResolverComposite argumentResolvers = new ArgumentResolverComposite();
private MessageArgumentResolverComposite argumentResolvers = new MessageArgumentResolverComposite();
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
@ -81,10 +75,10 @@ public class InvocableMessageHandlerMethod extends HandlerMethod {
}
/**
* Set {@link ArgumentResolver}s to use to use for resolving method
* Set {@link MessageArgumentResolver}s to use to use for resolving method
* argument values.
*/
public void setMessageMethodArgumentResolvers(ArgumentResolverComposite argumentResolvers) {
public void setMessageMethodArgumentResolvers(MessageArgumentResolverComposite argumentResolvers) {
this.argumentResolvers = argumentResolvers;
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.method;
import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
@ -22,12 +22,12 @@ import org.springframework.messaging.Message;
/**
* Strategy interface for resolving method parameters into argument values in
* the context of a given message.
* the context of a given {@link Message}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public interface ArgumentResolver {
public interface MessageArgumentResolver {
/**
* Whether the given {@linkplain MethodParameter method parameter} is

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.method;
import java.util.Collections;
import java.util.LinkedList;
@ -30,32 +30,32 @@ import org.springframework.util.Assert;
/**
* Resolves method parameters by delegating to a list of registered
* {@link ArgumentResolver}. Previously resolved method parameters are cached
* {@link MessageArgumentResolver}. Previously resolved method parameters are cached
* for faster lookups.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class ArgumentResolverComposite implements ArgumentResolver {
public class MessageArgumentResolverComposite implements MessageArgumentResolver {
protected final Log logger = LogFactory.getLog(getClass());
private final List<ArgumentResolver> argumentResolvers = new LinkedList<ArgumentResolver>();
private final List<MessageArgumentResolver> argumentResolvers = new LinkedList<MessageArgumentResolver>();
private final Map<MethodParameter, ArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<MethodParameter, ArgumentResolver>(256);
private final Map<MethodParameter, MessageArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<MethodParameter, MessageArgumentResolver>(256);
/**
* Return a read-only list with the contained resolvers, or an empty list.
*/
public List<ArgumentResolver> getResolvers() {
public List<MessageArgumentResolver> getResolvers() {
return Collections.unmodifiableList(this.argumentResolvers);
}
/**
* Whether the given {@linkplain MethodParameter method parameter} is supported by any registered
* {@link ArgumentResolver}.
* {@link MessageArgumentResolver}.
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
@ -63,24 +63,24 @@ public class ArgumentResolverComposite implements ArgumentResolver {
}
/**
* Iterate over registered {@link ArgumentResolver}s and invoke the one that supports it.
* @exception IllegalStateException if no suitable {@link ArgumentResolver} is found.
* Iterate over registered {@link MessageArgumentResolver}s and invoke the one that supports it.
* @exception IllegalStateException if no suitable {@link MessageArgumentResolver} is found.
*/
@Override
public Object resolveArgument(MethodParameter parameter, Message<?> message) throws Exception {
ArgumentResolver resolver = getArgumentResolver(parameter);
MessageArgumentResolver resolver = getArgumentResolver(parameter);
Assert.notNull(resolver, "Unknown parameter type [" + parameter.getParameterType().getName() + "]");
return resolver.resolveArgument(parameter, message);
}
/**
* Find a registered {@link ArgumentResolver} that supports the given method parameter.
* Find a registered {@link MessageArgumentResolver} that supports the given method parameter.
*/
private ArgumentResolver getArgumentResolver(MethodParameter parameter) {
ArgumentResolver result = this.argumentResolverCache.get(parameter);
private MessageArgumentResolver getArgumentResolver(MethodParameter parameter) {
MessageArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (ArgumentResolver resolver : this.argumentResolvers) {
for (MessageArgumentResolver resolver : this.argumentResolvers) {
if (resolver.supportsParameter(parameter)) {
result = resolver;
this.argumentResolverCache.put(parameter, result);
@ -92,19 +92,19 @@ public class ArgumentResolverComposite implements ArgumentResolver {
}
/**
* Add the given {@link ArgumentResolver}.
* Add the given {@link MessageArgumentResolver}.
*/
public ArgumentResolverComposite addResolver(ArgumentResolver argumentResolver) {
public MessageArgumentResolverComposite addResolver(MessageArgumentResolver argumentResolver) {
this.argumentResolvers.add(argumentResolver);
return this;
}
/**
* Add the given {@link ArgumentResolver}s.
* Add the given {@link MessageArgumentResolver}s.
*/
public ArgumentResolverComposite addResolvers(List<? extends ArgumentResolver> argumentResolvers) {
public MessageArgumentResolverComposite addResolvers(List<? extends MessageArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) {
for (ArgumentResolver resolver : argumentResolvers) {
for (MessageArgumentResolver resolver : argumentResolvers) {
this.argumentResolvers.add(resolver);
}
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.method;
import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
@ -22,12 +22,12 @@ import org.springframework.messaging.Message;
/**
* Strategy interface to handle the value returned from the invocation of a
* handler method .
* method handling a {@link Message}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public interface ReturnValueHandler {
public interface MessageReturnValueHandler {
/**
* Whether the given {@linkplain MethodParameter method return type} is

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.handler.method;
import java.util.ArrayList;
import java.util.List;
@ -28,25 +28,25 @@ import org.springframework.util.Assert;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class ReturnValueHandlerComposite implements ReturnValueHandler {
public class MessageReturnValueHandlerComposite implements MessageReturnValueHandler {
private final List<ReturnValueHandler> returnValueHandlers = new ArrayList<ReturnValueHandler>();
private final List<MessageReturnValueHandler> returnValueHandlers = new ArrayList<MessageReturnValueHandler>();
/**
* Add the given {@link ReturnValueHandler}.
* Add the given {@link MessageReturnValueHandler}.
*/
public ReturnValueHandlerComposite addHandler(ReturnValueHandler returnValuehandler) {
public MessageReturnValueHandlerComposite addHandler(MessageReturnValueHandler returnValuehandler) {
this.returnValueHandlers.add(returnValuehandler);
return this;
}
/**
* Add the given {@link ReturnValueHandler}s.
* Add the given {@link MessageReturnValueHandler}s.
*/
public ReturnValueHandlerComposite addHandlers(List<? extends ReturnValueHandler> handlers) {
public MessageReturnValueHandlerComposite addHandlers(List<? extends MessageReturnValueHandler> handlers) {
if (handlers != null) {
for (ReturnValueHandler handler : handlers) {
for (MessageReturnValueHandler handler : handlers) {
this.returnValueHandlers.add(handler);
}
}
@ -58,8 +58,8 @@ public class ReturnValueHandlerComposite implements ReturnValueHandler {
return getReturnValueHandler(returnType) != null;
}
private ReturnValueHandler getReturnValueHandler(MethodParameter returnType) {
for (ReturnValueHandler handler : this.returnValueHandlers) {
private MessageReturnValueHandler getReturnValueHandler(MethodParameter returnType) {
for (MessageReturnValueHandler handler : this.returnValueHandlers) {
if (handler.supportsReturnType(returnType)) {
return handler;
}
@ -71,7 +71,7 @@ public class ReturnValueHandlerComposite implements ReturnValueHandler {
public void handleReturnValue(Object returnValue, MethodParameter returnType, Message<?> message)
throws Exception {
ReturnValueHandler handler = getReturnValueHandler(returnType);
MessageReturnValueHandler handler = getReturnValueHandler(returnType);
Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]");
handler.handleReturnValue(returnValue, returnType, message);
}

View File

@ -0,0 +1,4 @@
/**
* Abstractions and classes for working with message-handling methods.
*/
package org.springframework.messaging.handler.method;

View File

@ -0,0 +1,4 @@
/**
* Support for working with messaging APIs and protocols.
*/
package org.springframework.messaging;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.support;
package org.springframework.messaging.simp;
import org.springframework.core.NamedThreadLocal;
import org.springframework.messaging.Message;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.support;
package org.springframework.messaging.simp;
import java.util.Arrays;
import java.util.List;
@ -25,14 +25,13 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.support.NativeMessageHeaderAccessor;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.messaging.MessageType;
/**
* A base class for working with message headers in Web, messaging protocols that support
* the publish-subscribe message pattern. Provides uniform access to specific values
* common across protocols such as a destination, message type (publish,
* subscribe/unsubscribe), session id, and others.
* A base class for working with message headers in simple messaging protocols that
* support basic messaging patterns. Provides uniform access to specific values common
* across protocols such as a destination, message type (e.g. publish, subscribe, etc),
* session id, and others.
* <p>
* Use one of the static factory method in this class, then call getters and setters, and
* at the end if necessary call {@link #toMap()} to obtain the updated headers.
@ -40,10 +39,11 @@ import org.springframework.web.messaging.MessageType;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class WebMessageHeaderAccesssor extends NativeMessageHeaderAccessor {
public class SimpMessageHeaderAccessor extends NativeMessageHeaderAccessor {
public static final String DESTINATIONS = "destinations";
// TODO
public static final String CONTENT_TYPE = "contentType";
public static final String MESSAGE_TYPE = "messageType";
@ -59,7 +59,7 @@ public class WebMessageHeaderAccesssor extends NativeMessageHeaderAccessor {
* A constructor for creating new message headers.
* This constructor is protected. See factory methods in this and sub-classes.
*/
protected WebMessageHeaderAccesssor(MessageType messageType, Object protocolMessageType,
protected SimpMessageHeaderAccessor(SimpMessageType messageType, Object protocolMessageType,
Map<String, List<String>> externalSourceHeaders) {
super(externalSourceHeaders);
@ -76,37 +76,37 @@ public class WebMessageHeaderAccesssor extends NativeMessageHeaderAccessor {
* A constructor for accessing and modifying existing message headers. This
* constructor is protected. See factory methods in this and sub-classes.
*/
protected WebMessageHeaderAccesssor(Message<?> message) {
protected SimpMessageHeaderAccessor(Message<?> message) {
super(message);
Assert.notNull(message, "message is required");
}
/**
* Create {@link WebMessageHeaderAccesssor} for a new {@link Message} with
* {@link MessageType#MESSAGE}.
* Create {@link SimpMessageHeaderAccessor} for a new {@link Message} with
* {@link SimpMessageType#MESSAGE}.
*/
public static WebMessageHeaderAccesssor create() {
return new WebMessageHeaderAccesssor(MessageType.MESSAGE, null, null);
public static SimpMessageHeaderAccessor create() {
return new SimpMessageHeaderAccessor(SimpMessageType.MESSAGE, null, null);
}
/**
* Create {@link WebMessageHeaderAccesssor} for a new {@link Message} of a specific type.
* Create {@link SimpMessageHeaderAccessor} for a new {@link Message} of a specific type.
*/
public static WebMessageHeaderAccesssor create(MessageType messageType) {
return new WebMessageHeaderAccesssor(messageType, null, null);
public static SimpMessageHeaderAccessor create(SimpMessageType messageType) {
return new SimpMessageHeaderAccessor(messageType, null, null);
}
/**
* Create {@link WebMessageHeaderAccesssor} from the headers of an existing message.
* Create {@link SimpMessageHeaderAccessor} from the headers of an existing message.
*/
public static WebMessageHeaderAccesssor wrap(Message<?> message) {
return new WebMessageHeaderAccesssor(message);
public static SimpMessageHeaderAccessor wrap(Message<?> message) {
return new SimpMessageHeaderAccessor(message);
}
public MessageType getMessageType() {
return (MessageType) getHeader(MESSAGE_TYPE);
public SimpMessageType getMessageType() {
return (SimpMessageType) getHeader(MESSAGE_TYPE);
}
protected void setProtocolMessageType(Object protocolMessageType) {

View File

@ -14,14 +14,17 @@
* limitations under the License.
*/
package org.springframework.web.messaging;
package org.springframework.messaging.simp;
/**
* A generic representation of different kinds of messages found in simple messaging
* protocols like STOMP.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public enum MessageType {
public enum SimpMessageType {
CONNECT,

View File

@ -1,4 +1,19 @@
package org.springframework.web.messaging.support;
/*
* Copyright 2002-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@ -6,17 +21,23 @@ import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.core.AbstractMessageSendingTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.web.messaging.MessageType;
public class WebMessagingTemplate extends AbstractMessageSendingTemplate<String> {
/**
* A specialization of {@link AbstractMessageSendingTemplate} that adds String-based
* destinations as a message header.
*
* @author Mark Fisher
* @since 4.0
*/
public class SimpMessagingTemplate extends AbstractMessageSendingTemplate<String> {
private final MessageChannel outputChannel;
private volatile long sendTimeout = -1;
public WebMessagingTemplate(MessageChannel outputChannel) {
public SimpMessagingTemplate(MessageChannel outputChannel) {
Assert.notNull(outputChannel, "outputChannel is required");
this.outputChannel = outputChannel;
}
@ -54,7 +75,7 @@ public class WebMessagingTemplate extends AbstractMessageSendingTemplate<String>
protected <P> Message<P> addDestinationToMessage(Message<P> message, String destination) {
Assert.notNull(destination, "destination is required");
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.MESSAGE);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headers.copyHeaders(message.getHeaders());
headers.setDestination(destination);
message = MessageBuilder.withPayload(message.getPayload()).copyHeaders(headers.toMap()).build();

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.annotation;
package org.springframework.messaging.simp.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.annotation;
package org.springframework.messaging.simp.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;

View File

@ -14,22 +14,23 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.simp.annotation.support;
import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.method.MessageReturnValueHandler;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.support.converter.MessageConverter;
import org.springframework.util.Assert;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
/**
* @author Rossen Stoyanchev
* @since 4.0
*/
public class MessageSendingReturnValueHandler implements ReturnValueHandler {
public class MessageSendingReturnValueHandler implements MessageReturnValueHandler {
private MessageChannel outboundChannel;
@ -58,12 +59,12 @@ public class MessageSendingReturnValueHandler implements ReturnValueHandler {
return;
}
WebMessageHeaderAccesssor inputHeaders = WebMessageHeaderAccesssor.wrap(message);
SimpMessageHeaderAccessor inputHeaders = SimpMessageHeaderAccessor.wrap(message);
Message<?> returnMessage = (returnValue instanceof Message) ? (Message<?>) returnValue : null;
Object returnPayload = (returnMessage != null) ? returnMessage.getPayload() : returnValue;
WebMessageHeaderAccesssor returnHeaders = (returnMessage != null) ?
WebMessageHeaderAccesssor.wrap(returnMessage) : WebMessageHeaderAccesssor.create();
SimpMessageHeaderAccessor returnHeaders = (returnMessage != null) ?
SimpMessageHeaderAccessor.wrap(returnMessage) : SimpMessageHeaderAccessor.create();
returnHeaders.setSessionId(inputHeaders.getSessionId());
returnHeaders.setSubscriptionId(inputHeaders.getSubscriptionId());

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service;
package org.springframework.messaging.simp.handler;
import java.util.ArrayList;
import java.util.Arrays;
@ -26,18 +26,18 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
/**
* @author Rossen Stoyanchev
* @since 4.0
*/
public abstract class AbstractWebMessageHandler implements MessageHandler {
public abstract class AbstractSimpMessageHandler implements MessageHandler {
protected final Log logger = LogFactory.getLog(getClass());
@ -64,10 +64,10 @@ public abstract class AbstractWebMessageHandler implements MessageHandler {
this.disallowedDestinations.addAll(Arrays.asList(patterns));
}
protected abstract Collection<MessageType> getSupportedMessageTypes();
protected abstract Collection<SimpMessageType> getSupportedMessageTypes();
protected boolean canHandle(Message<?> message, MessageType messageType) {
protected boolean canHandle(Message<?> message, SimpMessageType messageType) {
if (!CollectionUtils.isEmpty(getSupportedMessageTypes())) {
if (!getSupportedMessageTypes().contains(messageType)) {
@ -80,7 +80,7 @@ public abstract class AbstractWebMessageHandler implements MessageHandler {
protected boolean isDestinationAllowed(Message<?> message) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
String destination = headers.getDestination();
if (destination == null) {
@ -116,26 +116,26 @@ public abstract class AbstractWebMessageHandler implements MessageHandler {
@Override
public final void handleMessage(Message<?> message) throws MessagingException {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
MessageType messageType = headers.getMessageType();
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
SimpMessageType messageType = headers.getMessageType();
if (!canHandle(message, messageType)) {
return;
}
if (MessageType.MESSAGE.equals(messageType)) {
if (SimpMessageType.MESSAGE.equals(messageType)) {
handlePublish(message);
}
else if (MessageType.SUBSCRIBE.equals(messageType)) {
else if (SimpMessageType.SUBSCRIBE.equals(messageType)) {
handleSubscribe(message);
}
else if (MessageType.UNSUBSCRIBE.equals(messageType)) {
else if (SimpMessageType.UNSUBSCRIBE.equals(messageType)) {
handleUnsubscribe(message);
}
else if (MessageType.CONNECT.equals(messageType)) {
else if (SimpMessageType.CONNECT.equals(messageType)) {
handleConnect(message);
}
else if (MessageType.DISCONNECT.equals(messageType)) {
else if (SimpMessageType.DISCONNECT.equals(messageType)) {
handleDisconnect(message);
}
else {

View File

@ -14,14 +14,14 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.broker;
package org.springframework.messaging.simp.handler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
/**
@ -35,8 +35,8 @@ public abstract class AbstractSubscriptionRegistry implements SubscriptionRegist
@Override
public void addSubscription(Message<?> message) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
if (!MessageType.SUBSCRIBE.equals(headers.getMessageType())) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
if (!SimpMessageType.SUBSCRIBE.equals(headers.getMessageType())) {
logger.error("Expected SUBSCRIBE message: " + message);
return;
}
@ -63,8 +63,8 @@ public abstract class AbstractSubscriptionRegistry implements SubscriptionRegist
@Override
public void removeSubscription(Message<?> message) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
if (!MessageType.UNSUBSCRIBE.equals(headers.getMessageType())) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
if (!SimpMessageType.UNSUBSCRIBE.equals(headers.getMessageType())) {
logger.error("Expected UNSUBSCRIBE message: " + message);
return;
}
@ -89,8 +89,8 @@ public abstract class AbstractSubscriptionRegistry implements SubscriptionRegist
@Override
public MultiValueMap<String, String> findSubscriptions(Message<?> message) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
if (!MessageType.MESSAGE.equals(headers.getMessageType())) {
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
if (!SimpMessageType.MESSAGE.equals(headers.getMessageType())) {
logger.error("Unexpected message type: " + message);
return null;
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.method;
package org.springframework.messaging.simp.handler;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@ -34,18 +34,23 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.annotation.MessageMapping;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.support.MessageBodyArgumentResolver;
import org.springframework.messaging.handler.annotation.support.MessageExceptionHandlerMethodResolver;
import org.springframework.messaging.handler.method.MessageArgumentResolverComposite;
import org.springframework.messaging.handler.method.InvocableMessageHandlerMethod;
import org.springframework.messaging.handler.method.MessageReturnValueHandlerComposite;
import org.springframework.messaging.simp.annotation.SubscribeEvent;
import org.springframework.messaging.simp.annotation.UnsubscribeEvent;
import org.springframework.messaging.simp.annotation.support.MessageSendingReturnValueHandler;
import org.springframework.messaging.simp.MessageHolder;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.converter.MessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.annotation.SubscribeEvent;
import org.springframework.web.messaging.annotation.UnsubscribeEvent;
import org.springframework.web.messaging.service.AbstractWebMessageHandler;
import org.springframework.web.messaging.support.MessageHolder;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.HandlerMethodSelector;
@ -54,11 +59,9 @@ import org.springframework.web.method.HandlerMethodSelector;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class AnnotationWebMessageHandler extends AbstractWebMessageHandler
public class AnnotationSimpMessageHandler extends AbstractSimpMessageHandler
implements ApplicationContextAware, InitializingBean {
private final MessageChannel inboundChannel;
private final MessageChannel outboundChannel;
private MessageConverter<?> messageConverter;
@ -74,19 +77,17 @@ public class AnnotationWebMessageHandler extends AbstractWebMessageHandler
private final Map<Class<?>, MessageExceptionHandlerMethodResolver> exceptionHandlerCache =
new ConcurrentHashMap<Class<?>, MessageExceptionHandlerMethodResolver>(64);
private ArgumentResolverComposite argumentResolvers = new ArgumentResolverComposite();
private MessageArgumentResolverComposite argumentResolvers = new MessageArgumentResolverComposite();
private ReturnValueHandlerComposite returnValueHandlers = new ReturnValueHandlerComposite();
private MessageReturnValueHandlerComposite returnValueHandlers = new MessageReturnValueHandlerComposite();
/**
* @param inboundChannel a channel for processing incoming messages from clients
* @param outboundChannel a channel for messages going out to clients
*/
public AnnotationWebMessageHandler(MessageChannel inboundChannel, MessageChannel outboundChannel) {
Assert.notNull(inboundChannel, "inboundChannel is required");
public AnnotationSimpMessageHandler(MessageChannel outboundChannel) {
Assert.notNull(outboundChannel, "outboundChannel is required");
this.inboundChannel = inboundChannel;
this.outboundChannel = outboundChannel;
}
@ -103,8 +104,8 @@ public class AnnotationWebMessageHandler extends AbstractWebMessageHandler
}
@Override
protected Collection<MessageType> getSupportedMessageTypes() {
return Arrays.asList(MessageType.MESSAGE, MessageType.SUBSCRIBE, MessageType.UNSUBSCRIBE);
protected Collection<SimpMessageType> getSupportedMessageTypes() {
return Arrays.asList(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
}
@Override
@ -196,7 +197,7 @@ public class AnnotationWebMessageHandler extends AbstractWebMessageHandler
private void handleMessageInternal(final Message<?> message, Map<MappingInfo, HandlerMethod> handlerMethods) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
String destination = headers.getDestination();
HandlerMethod match = getHandlerMethod(destination, handlerMethods);

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.broker;
package org.springframework.messaging.simp.handler;
import java.util.Collection;
import java.util.HashMap;

View File

@ -14,26 +14,25 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.broker;
package org.springframework.messaging.simp.handler;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.util.MultiValueMap;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.service.AbstractWebMessageHandler;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
/**
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SimpleBrokerWebMessageHandler extends AbstractWebMessageHandler {
public class SimpleBrokerMessageHandler extends AbstractSimpMessageHandler {
private final MessageChannel outboundChannel;
@ -44,7 +43,7 @@ public class SimpleBrokerWebMessageHandler extends AbstractWebMessageHandler {
* @param outboundChannel the channel to which messages for clients should be sent
* @param observable an Observable to use to manage subscriptions
*/
public SimpleBrokerWebMessageHandler(MessageChannel outboundChannel) {
public SimpleBrokerMessageHandler(MessageChannel outboundChannel) {
Assert.notNull(outboundChannel, "outboundChannel is required");
this.outboundChannel = outboundChannel;
}
@ -56,8 +55,8 @@ public class SimpleBrokerWebMessageHandler extends AbstractWebMessageHandler {
}
@Override
protected Collection<MessageType> getSupportedMessageTypes() {
return Arrays.asList(MessageType.MESSAGE, MessageType.SUBSCRIBE, MessageType.UNSUBSCRIBE);
protected Collection<SimpMessageType> getSupportedMessageTypes() {
return Arrays.asList(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
}
@Override
@ -82,18 +81,18 @@ public class SimpleBrokerWebMessageHandler extends AbstractWebMessageHandler {
@Override
public void handlePublish(Message<?> message) {
if (logger.isDebugEnabled()) {
logger.debug("Message received: " + message);
if (logger.isTraceEnabled()) {
logger.trace("Message received: " + message);
}
String destination = WebMessageHeaderAccesssor.wrap(message).getDestination();
String destination = SimpMessageHeaderAccessor.wrap(message).getDestination();
MultiValueMap<String,String> subscriptions = this.subscriptionRegistry.findSubscriptions(message);
for (String sessionId : subscriptions.keySet()) {
for (String subscriptionId : subscriptions.get(sessionId)) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
headers.setSessionId(sessionId);
headers.setSubscriptionId(subscriptionId);
@ -113,7 +112,7 @@ public class SimpleBrokerWebMessageHandler extends AbstractWebMessageHandler {
@Override
public void handleDisconnect(Message<?> message) {
String sessionId = WebMessageHeaderAccesssor.wrap(message).getSessionId();
String sessionId = SimpMessageHeaderAccessor.wrap(message).getSessionId();
this.subscriptionRegistry.removeSessionSubscriptions(sessionId);
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.broker;
package org.springframework.messaging.simp.handler;
import org.springframework.messaging.Message;
import org.springframework.util.MultiValueMap;

View File

@ -0,0 +1,4 @@
/**
* Generic support for simple messaging protocols (like STOMP).
*/
package org.springframework.messaging.simp;

View File

@ -0,0 +1,69 @@
/*
* Copyright 2002-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.simp.stomp;
import java.util.HashMap;
import java.util.Map;
import org.springframework.messaging.simp.SimpMessageType;
/**
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public enum StompCommand {
// client
CONNECT,
STOMP,
SEND,
SUBSCRIBE,
UNSUBSCRIBE,
ACK,
NACK,
BEGIN,
COMMIT,
ABORT,
DISCONNECT,
// server
CONNECTED,
MESSAGE,
RECEIPT,
ERROR;
private static Map<StompCommand, SimpMessageType> commandToMessageType = new HashMap<StompCommand, SimpMessageType>();
static {
commandToMessageType.put(StompCommand.CONNECT, SimpMessageType.CONNECT);
commandToMessageType.put(StompCommand.STOMP, SimpMessageType.CONNECT);
commandToMessageType.put(StompCommand.SEND, SimpMessageType.MESSAGE);
commandToMessageType.put(StompCommand.MESSAGE, SimpMessageType.MESSAGE);
commandToMessageType.put(StompCommand.SUBSCRIBE, SimpMessageType.SUBSCRIBE);
commandToMessageType.put(StompCommand.UNSUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
commandToMessageType.put(StompCommand.DISCONNECT, SimpMessageType.DISCONNECT);
}
public SimpMessageType getMessageType() {
SimpMessageType messageType = commandToMessageType.get(this);
return (messageType != null) ? messageType : SimpMessageType.OTHER;
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.messaging.stomp;
package org.springframework.messaging.simp.stomp;
import org.springframework.core.NestedRuntimeException;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.stomp.support;
package org.springframework.messaging.simp.stomp;
import java.util.Arrays;
import java.util.Collections;
@ -25,10 +25,9 @@ import java.util.concurrent.atomic.AtomicLong;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.messaging.stomp.StompCommand;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
/**
@ -42,7 +41,7 @@ import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class StompHeaderAccessor extends WebMessageHeaderAccesssor {
public class StompHeaderAccessor extends SimpMessageHeaderAccessor {
public static final String STOMP_ID = "id";
@ -85,10 +84,10 @@ public class StompHeaderAccessor extends WebMessageHeaderAccesssor {
*/
private StompHeaderAccessor(StompCommand command, Map<String, List<String>> externalSourceHeaders) {
super(command.getMessageType(), command, externalSourceHeaders);
initWebMessageHeaders();
initSimpMessageHeaders();
}
private void initWebMessageHeaders() {
private void initSimpMessageHeaders() {
String destination = getFirstNativeHeader(DESTINATION);
if (destination != null) {
super.setDestination(destination);

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.messaging.stomp.support;
package org.springframework.messaging.simp.stomp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -26,8 +26,6 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.messaging.stomp.StompCommand;
import org.springframework.web.messaging.stomp.StompConversionException;
/**

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.stomp.support;
package org.springframework.messaging.simp.stomp;
import java.nio.charset.Charset;
import java.util.ArrayList;
@ -29,13 +29,12 @@ import java.util.concurrent.TimeUnit;
import org.springframework.context.SmartLifecycle;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.handler.AbstractSimpMessageHandler;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.service.AbstractWebMessageHandler;
import org.springframework.web.messaging.stomp.StompCommand;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import reactor.core.Environment;
import reactor.core.composable.Promise;
@ -52,7 +51,7 @@ import reactor.tcp.spec.TcpClientSpec;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class StompRelayWebMessageHandler extends AbstractWebMessageHandler implements SmartLifecycle {
public class StompRelayMessageHandler extends AbstractSimpMessageHandler implements SmartLifecycle {
private static final String STOMP_RELAY_SYSTEM_SESSION_ID = "stompRelaySystemSessionId";
@ -83,7 +82,7 @@ public class StompRelayWebMessageHandler extends AbstractWebMessageHandler imple
/**
* @param outboundChannel a channel for messages going out to clients
*/
public StompRelayWebMessageHandler(MessageChannel outboundChannel) {
public StompRelayMessageHandler(MessageChannel outboundChannel) {
Assert.notNull(outboundChannel, "outboundChannel is required");
this.outboundChannel = outboundChannel;
}
@ -150,7 +149,7 @@ public class StompRelayWebMessageHandler extends AbstractWebMessageHandler imple
}
@Override
protected Collection<MessageType> getSupportedMessageTypes() {
protected Collection<SimpMessageType> getSupportedMessageTypes() {
return null;
}
@ -266,7 +265,7 @@ public class StompRelayWebMessageHandler extends AbstractWebMessageHandler imple
@Override
public void handleOther(Message<?> message) {
StompCommand command = (StompCommand) message.getHeaders().get(WebMessageHeaderAccesssor.PROTOCOL_MESSAGE_TYPE);
StompCommand command = (StompCommand) message.getHeaders().get(SimpMessageHeaderAccessor.PROTOCOL_MESSAGE_TYPE);
Assert.notNull(command, "Expected STOMP command: " + message.getHeaders());
forwardMessage(message, command);
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.messaging.stomp.support;
package org.springframework.messaging.simp.stomp;
import java.io.IOException;
import java.nio.charset.Charset;
@ -26,11 +26,9 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.stomp.StompCommand;
import org.springframework.web.messaging.stomp.StompConversionException;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
@ -94,20 +92,20 @@ public class StompWebSocketHandler extends TextWebSocketHandlerAdapter implement
try {
StompHeaderAccessor stompHeaders = StompHeaderAccessor.wrap(message);
MessageType messageType = stompHeaders.getMessageType();
if (MessageType.CONNECT.equals(messageType)) {
SimpMessageType messageType = stompHeaders.getMessageType();
if (SimpMessageType.CONNECT.equals(messageType)) {
handleConnect(session, message);
}
else if (MessageType.MESSAGE.equals(messageType)) {
else if (SimpMessageType.MESSAGE.equals(messageType)) {
handlePublish(message);
}
else if (MessageType.SUBSCRIBE.equals(messageType)) {
else if (SimpMessageType.SUBSCRIBE.equals(messageType)) {
handleSubscribe(message);
}
else if (MessageType.UNSUBSCRIBE.equals(messageType)) {
else if (SimpMessageType.UNSUBSCRIBE.equals(messageType)) {
handleUnsubscribe(message);
}
else if (MessageType.DISCONNECT.equals(messageType)) {
else if (SimpMessageType.DISCONNECT.equals(messageType)) {
handleDisconnect(message);
}
this.outputChannel.send(message);
@ -187,7 +185,7 @@ public class StompWebSocketHandler extends TextWebSocketHandlerAdapter implement
this.sessions.remove(session.getId());
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.DISCONNECT);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.DISCONNECT);
headers.setSessionId(session.getId());
Message<?> message = MessageBuilder.withPayload(new byte[0]).copyHeaders(headers.toMap()).build();
this.outputChannel.send(message);

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.channel;
package org.springframework.messaging.support.channel;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@ -33,9 +33,9 @@ import org.springframework.util.Assert;
*/
public class PublishSubscribeChannel implements SubscribableChannel {
private Executor executor;
private final Executor executor;
private Set<MessageHandler> handlers = new CopyOnWriteArraySet<MessageHandler>();
private final Set<MessageHandler> handlers = new CopyOnWriteArraySet<MessageHandler>();
/**

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.channel;
package org.springframework.messaging.support.channel;
import java.util.HashMap;
import java.util.Map;

View File

@ -1,4 +1,4 @@
/**
* Provides classes representing various channel types.
*/
package org.springframework.messaging.channel;
package org.springframework.messaging.support.channel;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.converter;
package org.springframework.messaging.support.converter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.converter;
package org.springframework.messaging.support.converter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.converter;
package org.springframework.messaging.support.converter;
import java.lang.reflect.Type;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.messaging.converter;
package org.springframework.messaging.support.converter;
import java.lang.reflect.Type;

View File

@ -1,4 +1,4 @@
/**
* Provides classes supporting message conversion.
*/
package org.springframework.messaging.converter;
package org.springframework.messaging.support.converter;

View File

@ -0,0 +1,7 @@
<html>
<body>
<p>
Spring's support for messaging architectures and messaging protocols.
</p>
</body>
</html>

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service.broker;
package org.springframework.messaging.simp.handler;
import java.util.Arrays;
import java.util.Collections;
@ -23,10 +23,11 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.simp.handler.DefaultSubscriptionRegistry;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.MultiValueMap;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import static org.junit.Assert.*;
@ -38,7 +39,6 @@ import static org.junit.Assert.*;
*/
public class DefaultSubscriptionRegistryTests {
private DefaultSubscriptionRegistry registry;
@ -212,7 +212,7 @@ public class DefaultSubscriptionRegistryTests {
private Message<?> subscribeMessage(String sessionId, String subscriptionId, String destination) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.SUBSCRIBE);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.SUBSCRIBE);
headers.setSessionId(sessionId);
headers.setSubscriptionId(subscriptionId);
if (destination != null) {
@ -222,14 +222,14 @@ public class DefaultSubscriptionRegistryTests {
}
private Message<?> unsubscribeMessage(String sessionId, String subscriptionId) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.UNSUBSCRIBE);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.UNSUBSCRIBE);
headers.setSessionId(sessionId);
headers.setSubscriptionId(subscriptionId);
return MessageBuilder.withPayload("").copyHeaders(headers.toMap()).build();
}
private Message<?> message(String destination) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create();
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create();
headers.setDestination(destination);
return MessageBuilder.withPayload("").copyHeaders(headers.toMap()).build();
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.web.messaging.service;
package org.springframework.messaging.simp.handler;
import java.util.Arrays;
@ -26,10 +26,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.simp.handler.SimpleBrokerMessageHandler;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.service.broker.SimpleBrokerWebMessageHandler;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@ -42,7 +42,7 @@ import static org.mockito.Mockito.*;
*/
public class SimpleBrokerWebMessageHandlerTests {
private AbstractWebMessageHandler messageHandler;
private SimpleBrokerMessageHandler messageHandler;
@Mock
private MessageChannel clientChannel;
@ -54,13 +54,13 @@ public class SimpleBrokerWebMessageHandlerTests {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.messageHandler = new SimpleBrokerWebMessageHandler(this.clientChannel);
this.messageHandler = new SimpleBrokerMessageHandler(this.clientChannel);
}
@Test
public void getSupportedMessageTypes() {
assertEquals(Arrays.asList(MessageType.MESSAGE, MessageType.SUBSCRIBE, MessageType.UNSUBSCRIBE),
assertEquals(Arrays.asList(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE),
this.messageHandler.getSupportedMessageTypes());
}
@ -101,7 +101,7 @@ public class SimpleBrokerWebMessageHandlerTests {
this.messageHandler.handleSubscribe(createSubscriptionMessage(sess2, "sub2", "/foo"));
this.messageHandler.handleSubscribe(createSubscriptionMessage(sess2, "sub3", "/bar"));
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.DISCONNECT);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.DISCONNECT);
headers.setSessionId(sess1);
Message<byte[]> message = MessageBuilder.withPayload(new byte[0]).copyHeaders(headers.toMap()).build();
this.messageHandler.handleDisconnect(message);
@ -118,7 +118,7 @@ public class SimpleBrokerWebMessageHandlerTests {
protected Message<String> createSubscriptionMessage(String sessionId, String subcriptionId, String destination) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.SUBSCRIBE);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.SUBSCRIBE);
headers.setSubscriptionId(subcriptionId);
headers.setDestination(destination);
headers.setSessionId(sessionId);
@ -128,7 +128,7 @@ public class SimpleBrokerWebMessageHandlerTests {
protected Message<String> createMessage(String destination, String payload) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.create(MessageType.MESSAGE);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headers.setDestination(destination);
return MessageBuilder.withPayload(payload).copyHeaders(headers.toMap()).build();
@ -136,7 +136,7 @@ public class SimpleBrokerWebMessageHandlerTests {
protected boolean assertCapturedMessage(String sessionId, String subcriptionId, String destination) {
for (Message<?> message : this.messageCaptor.getAllValues()) {
WebMessageHeaderAccesssor headers = WebMessageHeaderAccesssor.wrap(message);
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message);
if (sessionId.equals(headers.getSessionId())) {
if (subcriptionId.equals(headers.getSubscriptionId())) {
if (destination.equals(headers.getDestination())) {

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.messaging.stomp.support;
package org.springframework.messaging.simp.stomp;
import java.util.Collections;
import java.util.Map;
@ -22,9 +22,11 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.web.messaging.MessageType;
import org.springframework.web.messaging.stomp.StompCommand;
import org.springframework.web.messaging.support.WebMessageHeaderAccesssor;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.simp.stomp.StompMessageConverter;
import static org.junit.Assert.*;
@ -59,15 +61,15 @@ public class StompMessageConverterTests {
assertEquals(6, map.size());
assertNotNull(map.get(MessageHeaders.ID));
assertNotNull(map.get(MessageHeaders.TIMESTAMP));
assertNotNull(map.get(WebMessageHeaderAccesssor.SESSION_ID));
assertNotNull(map.get(WebMessageHeaderAccesssor.NATIVE_HEADERS));
assertNotNull(map.get(WebMessageHeaderAccesssor.MESSAGE_TYPE));
assertNotNull(map.get(WebMessageHeaderAccesssor.PROTOCOL_MESSAGE_TYPE));
assertNotNull(map.get(SimpMessageHeaderAccessor.SESSION_ID));
assertNotNull(map.get(SimpMessageHeaderAccessor.NATIVE_HEADERS));
assertNotNull(map.get(SimpMessageHeaderAccessor.MESSAGE_TYPE));
assertNotNull(map.get(SimpMessageHeaderAccessor.PROTOCOL_MESSAGE_TYPE));
assertEquals(Collections.singleton("1.1"), stompHeaders.getAcceptVersion());
assertEquals("github.org", stompHeaders.getHost());
assertEquals(MessageType.CONNECT, stompHeaders.getMessageType());
assertEquals(SimpMessageType.CONNECT, stompHeaders.getMessageType());
assertEquals(StompCommand.CONNECT, stompHeaders.getStompCommand());
assertEquals("session-123", stompHeaders.getSessionId());
assertNotNull(headers.get(MessageHeaders.ID));

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.messaging.channel;
package org.springframework.messaging.support.channel;
import java.util.concurrent.Executor;
@ -29,8 +29,8 @@ import org.mockito.MockitoAnnotations;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.channel.PublishSubscribeChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.support.channel.PublishSubscribeChannel;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<logger name="org.springframework.messaging">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>

View File

@ -1,69 +0,0 @@
/*
* Copyright 2002-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.messaging.stomp;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.messaging.MessageType;
/**
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public enum StompCommand {
// client
CONNECT,
STOMP,
SEND,
SUBSCRIBE,
UNSUBSCRIBE,
ACK,
NACK,
BEGIN,
COMMIT,
ABORT,
DISCONNECT,
// server
CONNECTED,
MESSAGE,
RECEIPT,
ERROR;
private static Map<StompCommand, MessageType> commandToMessageType = new HashMap<StompCommand, MessageType>();
static {
commandToMessageType.put(StompCommand.CONNECT, MessageType.CONNECT);
commandToMessageType.put(StompCommand.STOMP, MessageType.CONNECT);
commandToMessageType.put(StompCommand.SEND, MessageType.MESSAGE);
commandToMessageType.put(StompCommand.MESSAGE, MessageType.MESSAGE);
commandToMessageType.put(StompCommand.SUBSCRIBE, MessageType.SUBSCRIBE);
commandToMessageType.put(StompCommand.UNSUBSCRIBE, MessageType.UNSUBSCRIBE);
commandToMessageType.put(StompCommand.DISCONNECT, MessageType.DISCONNECT);
}
public MessageType getMessageType() {
MessageType messageType = commandToMessageType.get(this);
return (messageType != null) ? messageType : MessageType.OTHER;
}
}