Browse Source
Remove base class for STOMP-related message handler classes (AbstractSimpMessageHandler), polish subclasses and fix issues with more significant updates to STOMP broker relay. Introduce base class for SubscribableChannel implementations providing consistent logging for all channel implementations.pull/286/merge
18 changed files with 512 additions and 523 deletions
@ -1,164 +0,0 @@
@@ -1,164 +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.messaging.simp.handler; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
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; |
||||
|
||||
|
||||
/** |
||||
* @author Rossen Stoyanchev |
||||
* @since 4.0 |
||||
*/ |
||||
public abstract class AbstractSimpMessageHandler implements MessageHandler { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private final List<String> allowedDestinations = new ArrayList<String>(); |
||||
|
||||
private final List<String> disallowedDestinations = new ArrayList<String>(); |
||||
|
||||
private final PathMatcher pathMatcher = new AntPathMatcher(); |
||||
|
||||
|
||||
/** |
||||
* Ant-style destination patterns that this service is allowed to process. |
||||
*/ |
||||
public void setAllowedDestinations(String... patterns) { |
||||
this.allowedDestinations.clear(); |
||||
this.allowedDestinations.addAll(Arrays.asList(patterns)); |
||||
} |
||||
|
||||
/** |
||||
* Ant-style destination patterns that this service should skip. |
||||
*/ |
||||
public void setDisallowedDestinations(String... patterns) { |
||||
this.disallowedDestinations.clear(); |
||||
this.disallowedDestinations.addAll(Arrays.asList(patterns)); |
||||
} |
||||
|
||||
protected abstract Collection<SimpMessageType> getSupportedMessageTypes(); |
||||
|
||||
|
||||
protected boolean canHandle(Message<?> message, SimpMessageType messageType) { |
||||
|
||||
if (!CollectionUtils.isEmpty(getSupportedMessageTypes())) { |
||||
if (!getSupportedMessageTypes().contains(messageType)) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return isDestinationAllowed(message); |
||||
} |
||||
|
||||
protected boolean isDestinationAllowed(Message<?> message) { |
||||
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message); |
||||
String destination = headers.getDestination(); |
||||
|
||||
if (destination == null) { |
||||
return true; |
||||
} |
||||
|
||||
if (!this.disallowedDestinations.isEmpty()) { |
||||
for (String pattern : this.disallowedDestinations) { |
||||
if (this.pathMatcher.match(pattern, destination)) { |
||||
if (logger.isTraceEnabled()) { |
||||
logger.trace("Skip message id=" + message.getHeaders().getId()); |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (!this.allowedDestinations.isEmpty()) { |
||||
for (String pattern : this.allowedDestinations) { |
||||
if (this.pathMatcher.match(pattern, destination)) { |
||||
return true; |
||||
} |
||||
} |
||||
if (logger.isTraceEnabled()) { |
||||
logger.trace("Skip message id=" + message.getHeaders().getId()); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public final void handleMessage(Message<?> message) throws MessagingException { |
||||
|
||||
SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.wrap(message); |
||||
SimpMessageType messageType = headers.getMessageType(); |
||||
|
||||
if (!canHandle(message, messageType)) { |
||||
return; |
||||
} |
||||
|
||||
if (SimpMessageType.MESSAGE.equals(messageType)) { |
||||
handlePublish(message); |
||||
} |
||||
else if (SimpMessageType.SUBSCRIBE.equals(messageType)) { |
||||
handleSubscribe(message); |
||||
} |
||||
else if (SimpMessageType.UNSUBSCRIBE.equals(messageType)) { |
||||
handleUnsubscribe(message); |
||||
} |
||||
else if (SimpMessageType.CONNECT.equals(messageType)) { |
||||
handleConnect(message); |
||||
} |
||||
else if (SimpMessageType.DISCONNECT.equals(messageType)) { |
||||
handleDisconnect(message); |
||||
} |
||||
else { |
||||
handleOther(message); |
||||
} |
||||
} |
||||
|
||||
protected void handleConnect(Message<?> message) { |
||||
} |
||||
|
||||
protected void handlePublish(Message<?> message) { |
||||
} |
||||
|
||||
protected void handleSubscribe(Message<?> message) { |
||||
} |
||||
|
||||
protected void handleUnsubscribe(Message<?> message) { |
||||
} |
||||
|
||||
protected void handleDisconnect(Message<?> message) { |
||||
} |
||||
|
||||
protected void handleOther(Message<?> message) { |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
/* |
||||
* 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.support.channel; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.beans.factory.BeanNameAware; |
||||
import org.springframework.messaging.Message; |
||||
import org.springframework.messaging.MessageHandler; |
||||
import org.springframework.messaging.SubscribableChannel; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
|
||||
/** |
||||
* Abstract base class for {@link SubscribableChannel} implementations. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 4.0 |
||||
*/ |
||||
public abstract class AbstractSubscribableChannel implements SubscribableChannel, BeanNameAware { |
||||
|
||||
protected Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private String beanName; |
||||
|
||||
|
||||
public AbstractSubscribableChannel() { |
||||
this.beanName = getClass().getSimpleName() + "@" + ObjectUtils.getIdentityHexString(this); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
* <p>Used primarily for logging purposes. |
||||
*/ |
||||
@Override |
||||
public void setBeanName(String name) { |
||||
this.beanName = name; |
||||
} |
||||
|
||||
/** |
||||
* @return the name for this channel. |
||||
*/ |
||||
public String getBeanName() { |
||||
return this.beanName; |
||||
} |
||||
|
||||
@Override |
||||
public final boolean send(Message<?> message) { |
||||
return send(message, INDEFINITE_TIMEOUT); |
||||
} |
||||
|
||||
@Override |
||||
public final boolean send(Message<?> message, long timeout) { |
||||
Assert.notNull(message, "Message must not be null"); |
||||
if (logger.isTraceEnabled()) { |
||||
logger.trace("[" + this.beanName + "] sending message " + message); |
||||
} |
||||
return sendInternal(message, timeout); |
||||
} |
||||
|
||||
protected abstract boolean sendInternal(Message<?> message, long timeout); |
||||
|
||||
@Override |
||||
public final boolean subscribe(MessageHandler handler) { |
||||
if (hasSubscription(handler)) { |
||||
logger.warn("[" + this.beanName + "] handler already subscribed " + handler); |
||||
return false; |
||||
} |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("[" + this.beanName + "] subscribing " + handler); |
||||
} |
||||
return subscribeInternal(handler); |
||||
} |
||||
|
||||
protected abstract boolean hasSubscription(MessageHandler handler); |
||||
|
||||
protected abstract boolean subscribeInternal(MessageHandler handler); |
||||
|
||||
@Override |
||||
public final boolean unsubscribe(MessageHandler handler) { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("[" + this.beanName + "] unsubscribing " + handler); |
||||
} |
||||
return unsubscribeInternal(handler); |
||||
} |
||||
|
||||
protected abstract boolean unsubscribeInternal(MessageHandler handler); |
||||
|
||||
} |
||||
Loading…
Reference in new issue