RouterEndpoint now delegates directly to a single ChannelResolver strategy. This removes the extra level of indirection that was provided by the Router interface. Also, instead of providing multiple ChannelResolver strategy interfaces, the name-resolving and single-channel implementations are now available as abstract base classes.

This commit is contained in:
Mark Fisher
2008-09-04 01:55:32 +00:00
parent b3a155de94
commit 40fc9c207d
30 changed files with 617 additions and 794 deletions

View File

@@ -17,7 +17,7 @@
package org.springframework.integration.config;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.router.MethodInvokingRouter;
import org.springframework.integration.router.MethodInvokingChannelResolver;
import org.springframework.integration.router.RouterEndpoint;
/**
@@ -34,7 +34,7 @@ public class RouterParser extends AbstractEndpointParser {
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingRouter.class;
return MethodInvokingChannelResolver.class;
}
}

View File

@@ -24,7 +24,7 @@ import org.springframework.integration.annotation.Router;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.router.MethodInvokingRouter;
import org.springframework.integration.router.MethodInvokingChannelResolver;
import org.springframework.integration.router.RouterEndpoint;
import org.springframework.util.StringUtils;
@@ -42,13 +42,13 @@ public class RouterAnnotationPostProcessor extends AbstractMethodAnnotationPostP
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, Router annotation) {
return new MethodInvokingRouter(bean, method);
return new MethodInvokingChannelResolver(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object adapter) {
if (adapter instanceof MethodInvokingRouter) {
return new RouterEndpoint((MethodInvokingRouter) adapter);
if (adapter instanceof MethodInvokingChannelResolver) {
return new RouterEndpoint((MethodInvokingChannelResolver) adapter);
}
return null;
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.Collection;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessagingException;
/**
* @author Mark Fisher
*/
public abstract class AbstractChannelResolver implements ChannelResolver, ChannelRegistryAware {
private volatile ChannelRegistry channelRegistry;
public void setChannelRegistry(ChannelRegistry channelRegistry) {
this.channelRegistry = channelRegistry;
}
protected MessageChannel lookupChannel(String channelName, boolean required) {
MessageChannel channel = null;
if (channelName != null) {
if (this.channelRegistry == null) {
throw new ConfigurationException("unable to resolve channels, no ChannelRegistry available");
}
channel = this.channelRegistry.lookupChannel(channelName);
}
if (channel == null && required) {
throw new MessagingException("unable to resolve channel '" + channelName + "'");
}
return channel;
}
public abstract Collection<MessageChannel> resolveChannels(Message<?> message);
}

View File

@@ -16,15 +16,31 @@
package org.springframework.integration.router;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* Strategy interface for routing a Message to one or more channels.
*
* @author Mark Fisher
*/
public interface Router {
public abstract class AbstractMultiChannelNameResolver extends AbstractChannelResolver {
boolean route(Message<?> message);
@Override
public Collection<MessageChannel> resolveChannels(Message<?> message) {
Collection<MessageChannel> channels = new ArrayList<MessageChannel>();
String[] channelNames = this.resolveChannelNames(message);
if (channelNames == null) {
return null;
}
for (String channelName : channelNames) {
MessageChannel channel = this.lookupChannel(channelName, true);
channels.add(channel);
}
return channels;
}
protected abstract String[] resolveChannelNames(Message<?> message);
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.MessageExchangeTemplate;
import org.springframework.integration.message.MessageTarget;
import org.springframework.integration.message.MessagingException;
/**
* Base class for message router implementations.
*
* @author Mark Fisher
*/
public abstract class AbstractRouter implements Router, ChannelRegistryAware {
protected final Log logger = LogFactory.getLog(this.getClass());
private volatile ChannelRegistry channelRegistry;
private final MessageExchangeTemplate messageExchangeTemplate = new MessageExchangeTemplate();
public void setChannelRegistry(ChannelRegistry channelRegistry) {
this.channelRegistry = channelRegistry;
}
protected ChannelRegistry getChannelRegistry() {
return this.channelRegistry;
}
public final boolean route(Message<?> message) {
Collection<?> results = this.resolveChannels(message);
if (results == null || results.isEmpty()) {
return false;
}
boolean sent = false;
for (Object channelOrName : results) {
MessageTarget target = null;
if (channelOrName == null) {
continue;
}
if (channelOrName instanceof MessageTarget) {
target = (MessageTarget) channelOrName;
}
else if (channelOrName instanceof String) {
if (this.channelRegistry == null) {
throw new MessagingException(message, "router has no ChannelRegistry");
}
target = this.channelRegistry.lookupChannel((String) channelOrName);
}
else {
throw new MessagingException(message, "unsupported return type for router [" + channelOrName.getClass() + "]");
}
if (target == null) {
throw new MessageDeliveryException(message, "unable to resolve channel for '" + channelOrName + "'");
}
this.messageExchangeTemplate.send(message, target);
sent = true;
}
return sent;
}
/**
* Subclasses must implement this method to return 0 or more MessageChannel
* instances or channel names to which the given Message should be routed.
*/
protected abstract Collection<?> resolveChannels(Message<?> message);
}

View File

@@ -16,18 +16,20 @@
package org.springframework.integration.router;
import java.util.List;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* Strategy interface for content-based routing to multiple channels.
*
* @author Mark Fisher
*/
public interface MultiChannelResolver {
public abstract class AbstractSingleChannelNameResolver extends AbstractSingleChannelResolver {
List<MessageChannel> resolve(Message<?> message);
@Override
protected MessageChannel resolveChannel(Message<?> message) {
String channelName = this.resolveChannelName(message);
return this.lookupChannel(channelName, true);
}
protected abstract String resolveChannelName(Message<?> message);
}

View File

@@ -16,15 +16,23 @@
package org.springframework.integration.router;
import java.util.Collection;
import java.util.Collections;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* Strategy interface for content-based routing to a channel name.
*
* @author Mark Fisher
*/
public interface ChannelNameResolver {
public abstract class AbstractSingleChannelResolver extends AbstractChannelResolver {
String resolve(Message<?> message);
public Collection<MessageChannel> resolveChannels(Message<?> message) {
MessageChannel channel = this.resolveChannel(message);
return (channel != null) ?
Collections.singletonList(channel) : null;
}
protected abstract MessageChannel resolveChannel(Message<?> message);
}

View File

@@ -16,16 +16,18 @@
package org.springframework.integration.router;
import java.util.Collection;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* Strategy interface for content-based routing to a channel instance.
* Strategy interface for content-based routing.
*
* @author Mark Fisher
*/
public interface ChannelResolver {
MessageChannel resolve(Message<?> message);
Collection<MessageChannel> resolveChannels(Message<?> message);
}

View File

@@ -27,25 +27,26 @@ import org.springframework.integration.ConfigurationException;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageMappingMethodInvoker;
import org.springframework.integration.message.MessagingException;
/**
* A {@link Router} implementation that invokes the specified method
* on the given object. The method's return value may be a single
* MessageChannel instance, a single String to be interpreted as
* a channel name, or a Collection (or Array) of either type.
* A {@link ChannelResolver} implementation that invokes the specified method
* on the given object. The method's return value may be a single MessageChannel
* instance, a single String to be interpreted as a channel name, or a Collection
* (or Array) of either type.
*
* @author Mark Fisher
*/
public class MethodInvokingRouter extends AbstractRouter implements InitializingBean {
public class MethodInvokingChannelResolver extends AbstractChannelResolver implements InitializingBean {
private final MessageMappingMethodInvoker invoker;
public MethodInvokingRouter(Object object, Method method) {
public MethodInvokingChannelResolver(Object object, Method method) {
this.invoker = new MessageMappingMethodInvoker(object, method);
}
public MethodInvokingRouter(Object object, String methodName) {
public MethodInvokingChannelResolver(Object object, String methodName) {
this.invoker = new MessageMappingMethodInvoker(object, methodName);
}
@@ -55,26 +56,30 @@ public class MethodInvokingRouter extends AbstractRouter implements Initializing
}
@Override
protected Collection<?> resolveChannels(Message<?> message) {
public final Collection<MessageChannel> resolveChannels(Message<?> message) {
Object result = this.invoker.invokeMethod(message);
if (result == null) {
return null;
}
List<Object> channels = new ArrayList<Object>();
List<MessageChannel> channels = new ArrayList<MessageChannel>();
if (result instanceof Collection) {
channels.addAll((Collection<?>) result);
for (Object next : (Collection<?>) result) {
this.addChannel(next, channels);
}
}
else if (result instanceof MessageChannel[]) {
channels.addAll(Arrays.asList((MessageChannel[]) result));
}
else if (result instanceof String[]) {
channels.addAll(Arrays.asList((String[]) result));
for (String channelName : (String[]) result) {
this.addChannel(channelName, channels);
}
}
else if (result instanceof MessageChannel) {
channels.add((MessageChannel) result);
}
else if (result instanceof String) {
channels.add(result);
this.addChannel((String) result, channels);
}
else {
throw new ConfigurationException(
@@ -83,4 +88,20 @@ public class MethodInvokingRouter extends AbstractRouter implements Initializing
return channels;
}
private void addChannel(Object channelOrName, List<MessageChannel> channels) {
if (channelOrName == null) {
return;
}
if (channelOrName instanceof MessageChannel) {
channels.add((MessageChannel) channelOrName);
}
else if (channelOrName instanceof String) {
MessageChannel channel = this.lookupChannel((String) channelOrName, true);
channels.add(channel);
}
else {
throw new MessagingException("unsupported return type for router [" + channelOrName.getClass() + "]");
}
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2002-2008 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.integration.router;
import org.springframework.integration.message.Message;
/**
* Strategy interface for content-based routing to multiple channel names.
*
* @author Mark Fisher
*/
public interface MultiChannelNameResolver {
String[] resolve(Message<?> message);
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
import org.springframework.util.ObjectUtils;
/**
* A router implementation for sending to potentially multiple {@link MessageChannel MessageChannels}.
* Requires either a {@link MultiChannelResolver} or {@link MultiChannelNameResolver} strategy instance.
*
* @author Mark Fisher
*/
public class MultiChannelRouter extends AbstractRouter implements InitializingBean {
private volatile MultiChannelResolver channelResolver;
private volatile MultiChannelNameResolver channelNameResolver;
public void setChannelResolver(MultiChannelResolver channelResolver) {
this.channelResolver = channelResolver;
}
public void setChannelNameResolver(MultiChannelNameResolver channelNameResolver) {
this.channelNameResolver = channelNameResolver;
}
public void afterPropertiesSet() {
if (!(this.channelResolver != null ^ this.channelNameResolver != null)) {
throw new ConfigurationException(
"exactly one of 'channelResolver' or 'channelNameResolver' must be provided");
}
}
@Override
public Collection<?> resolveChannels(Message<?> message) {
if (this.channelResolver != null) {
return this.channelResolver.resolve(message);
}
String[] channelNames = this.channelNameResolver.resolve(message);
if (ObjectUtils.isEmpty(channelNames)) {
return null;
}
return Arrays.asList(channelNames);
}
}

View File

@@ -24,39 +24,24 @@ import org.springframework.integration.message.Message;
import org.springframework.util.Assert;
/**
* A router implementation that resolves the {@link MessageChannel} based on the
* {@link Message Message's} payload type.
* A ChannelResolver implementation that resolves the {@link MessageChannel} based
* on the {@link Message Message's} payload type.
*
* @author Mark Fisher
*/
public class PayloadTypeRouter extends SingleChannelRouter {
public class PayloadTypeChannelResolver extends AbstractSingleChannelResolver {
private Map<Class<?>, MessageChannel> channelMappings = new ConcurrentHashMap<Class<?>, MessageChannel>();
private MessageChannel defaultChannel;
public PayloadTypeRouter() {
this.setChannelResolver(new PayloadTypeChannelResolver());
}
public void setChannelMappings(Map<Class<?>, MessageChannel> channelMappings) {
Assert.notNull(channelMappings, "'channelMappings' must not be null");
this.channelMappings = channelMappings;
}
public void setDefaultChannel(MessageChannel defaultChannel) {
this.defaultChannel = defaultChannel;
}
private class PayloadTypeChannelResolver implements ChannelResolver {
public MessageChannel resolve(Message<?> message) {
MessageChannel channel = channelMappings.get(message.getPayload().getClass());
return channel != null ? channel : defaultChannel;
}
@Override
protected MessageChannel resolveChannel(Message<?> message) {
return this.channelMappings.get(message.getPayload().getClass());
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* A {@link ChannelResolver} implementation that routes to a statically
* configured list of recipients. The recipients are provided either as a list
* of {@link MessageChannel} instances or as a String array of channel names.
* For dynamic recipient lists, either implement {@link ChannelResolver} or
* extend the {@link AbstractMultiChannelNameResolver} base class.
*
* @author Mark Fisher
*/
public class RecipientListChannelResolver extends AbstractChannelResolver implements InitializingBean {
private volatile List<MessageChannel> channels;
private volatile String[] channelNames;
public void setChannels(List<MessageChannel> channels) {
this.channels = channels;
}
public void setChannelNames(String[] channelNames) {
this.channelNames = channelNames;
}
public void afterPropertiesSet() {
if ((this.channels != null && this.channelNames != null)
|| (this.channels == null && this.channelNames == null)) {
throw new ConfigurationException("either 'channels' or 'channelNames' should be provided, but not both");
}
}
@Override
public Collection<MessageChannel> resolveChannels(Message<?> message) {
if (this.channels == null && this.channelNames != null) {
List<MessageChannel> resolved = new ArrayList<MessageChannel>();
for (String channelName : channelNames) {
resolved.add(this.lookupChannel(channelName, true));
}
return resolved;
}
return this.channels;
}
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.List;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* A simple extension of {@link MultiChannelRouter} that routes to a statically
* configured list of recipients. The recipients are provided either as a list
* of {@link MessageChannel} instances or as a String array of channel names.
* For dynamic recipient lists, implement either {@link MultiChannelResolver} or
* {@link MultiChannelNameResolver} and then explicitly configure an instance of
* {@link MultiChannelRouter}.
*
* @author Mark Fisher
*/
public class RecipientListRouter extends MultiChannelRouter {
public void setChannelNames(String[] channelNames) {
this.setChannelNameResolver(new RecipientListChannelNameResolver(channelNames));
}
public void setChannels(List<MessageChannel> channels) {
this.setChannelResolver(new RecipientListChannelResolver(channels));
}
private static class RecipientListChannelResolver implements MultiChannelResolver {
private List<MessageChannel> channels;
RecipientListChannelResolver(List<MessageChannel> channels) {
this.channels = channels;
}
public List<MessageChannel> resolve(Message<?> message) {
return this.channels;
}
}
private static class RecipientListChannelNameResolver implements MultiChannelNameResolver {
private String[] channelNames;
RecipientListChannelNameResolver(String[] channelNames) {
this.channelNames = channelNames;
}
public String[] resolve(Message<?> message) {
return this.channelNames;
}
}
}

View File

@@ -24,52 +24,39 @@ import org.springframework.integration.message.Message;
import org.springframework.util.Assert;
/**
* A router implementation that resolves the {@link MessageChannel} for messages
* whose payload is an Exception. The channel resolution is based upon the most
* specific cause of the error for which a channel-mapping exists.
* A ChannelResolver implementation that resolves the {@link MessageChannel} for
* messages whose payload is an Exception. The channel resolution is based upon the
* most specific cause of the error for which a channel-mapping exists.
*
* @author Mark Fisher
*/
public class RootCauseErrorMessageRouter extends SingleChannelRouter {
public class RootCauseErrorMessageChannelResolver extends AbstractSingleChannelResolver {
private Map<Class<? extends Throwable>, MessageChannel> channelMappings =
new ConcurrentHashMap<Class<? extends Throwable>, MessageChannel>();
private MessageChannel defaultChannel;
public RootCauseErrorMessageRouter() {
this.setChannelResolver(new RootCauseResolver());
}
public void setChannelMappings(Map<Class<? extends Throwable>, MessageChannel> channelMappings) {
Assert.notNull(channelMappings, "'channelMappings' must not be null");
this.channelMappings = channelMappings;
}
public void setDefaultChannel(MessageChannel defaultChannel) {
this.defaultChannel = defaultChannel;
}
private class RootCauseResolver implements ChannelResolver {
public MessageChannel resolve(Message<?> message) {
MessageChannel channel = null;
Object payload = message.getPayload();
if (payload != null && (payload instanceof Throwable)) {
Throwable mostSpecificCause = (Throwable) payload;
while (mostSpecificCause != null) {
MessageChannel mappedChannel = channelMappings.get(mostSpecificCause.getClass());
if (mappedChannel != null) {
channel = mappedChannel;
}
mostSpecificCause = mostSpecificCause.getCause();
@Override
protected MessageChannel resolveChannel(Message<?> message) {
MessageChannel channel = null;
Object payload = message.getPayload();
if (payload != null && (payload instanceof Throwable)) {
Throwable mostSpecificCause = (Throwable) payload;
while (mostSpecificCause != null) {
MessageChannel mappedChannel = this.channelMappings.get(mostSpecificCause.getClass());
if (mappedChannel != null) {
channel = mappedChannel;
}
mostSpecificCause = mostSpecificCause.getCause();
}
return channel != null ? channel : defaultChannel;
}
return channel;
}
}

View File

@@ -16,12 +16,15 @@
package org.springframework.integration.router;
import java.util.Collection;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.MessageExchangeTemplate;
import org.springframework.util.Assert;
/**
@@ -29,24 +32,26 @@ import org.springframework.util.Assert;
*/
public class RouterEndpoint extends AbstractEndpoint {
private final Router router;
private final ChannelResolver channelResolver;
private volatile MessageChannel defaultOutputChannel;
private volatile boolean resolutionRequired;
private final MessageExchangeTemplate messageExchangeTemplate = new MessageExchangeTemplate();
public RouterEndpoint(Router router) {
Assert.notNull(router, "router must not be null");
this.router = router;
public RouterEndpoint(ChannelResolver channelResolver) {
Assert.notNull(channelResolver, "ChannelResolver must not be null");
this.channelResolver = channelResolver;
}
@Override
public void setChannelRegistry(ChannelRegistry channelRegistry) {
super.setChannelRegistry(channelRegistry);
if (this.router instanceof ChannelRegistryAware) {
((ChannelRegistryAware) this.router).setChannelRegistry(channelRegistry);
if (this.channelResolver instanceof ChannelRegistryAware) {
((ChannelRegistryAware) this.channelResolver).setChannelRegistry(channelRegistry);
}
}
@@ -74,7 +79,17 @@ public class RouterEndpoint extends AbstractEndpoint {
@Override
protected boolean sendInternal(Message<?> message) {
boolean sent = this.router.route(message);
boolean sent = false;
Collection<MessageChannel> results = this.channelResolver.resolveChannels(message);
if (results != null) {
for (MessageChannel channel : results) {
if (channel != null) {
if (this.messageExchangeTemplate.send(message, channel)) {
sent = true;
}
}
}
}
if (!sent) {
if (this.defaultOutputChannel != null) {
sent = this.getMessageExchangeTemplate().send(message, this.defaultOutputChannel);

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2002-2008 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.integration.router;
import java.util.Collection;
import java.util.Collections;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.ConfigurationException;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.message.Message;
/**
* A router implementation for sending to at most one {@link MessageChannel}.
* Requires either a {@link ChannelResolver} or {@link ChannelNameResolver}
* strategy instance.
*
* @author Mark Fisher
*/
public class SingleChannelRouter extends AbstractRouter implements InitializingBean {
private ChannelResolver channelResolver;
private ChannelNameResolver channelNameResolver;
public void setChannelResolver(ChannelResolver channelResolver) {
this.channelResolver = channelResolver;
}
public void setChannelNameResolver(ChannelNameResolver channelNameResolver) {
this.channelNameResolver = channelNameResolver;
}
public void afterPropertiesSet() {
if (!(this.channelResolver != null ^ this.channelNameResolver != null)) {
throw new ConfigurationException(
"exactly one of 'channelResolver' or 'channelNameResolver' must be provided");
}
}
@Override
protected Collection<?> resolveChannels(Message<?> message) {
Object result = (this.channelResolver != null)
? this.channelResolver.resolve(message)
: this.channelNameResolver.resolve(message);
if (result == null) {
return null;
}
return Collections.singletonList(result);
}
}