/* * Copyright 2002-2016 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.config; import java.util.Map; import org.springframework.expression.Expression; import org.springframework.integration.handler.AbstractMessageProducingHandler; import org.springframework.integration.router.AbstractMappingMessageRouter; import org.springframework.integration.router.AbstractMessageRouter; import org.springframework.integration.router.ExpressionEvaluatingRouter; import org.springframework.integration.router.MethodInvokingRouter; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * Factory bean for creating a Message Router. * * @author Mark Fisher * @author Jonas Partner * @author Oleg Zhurakousky * @author Dave Syer * @author Gary Russell * @author David Liu */ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean { private volatile Map<String, String> channelMappings; private volatile MessageChannel defaultOutputChannel; private volatile String defaultOutputChannelName; private volatile Long sendTimeout; private volatile Boolean resolutionRequired; private volatile Boolean applySequence; private volatile Boolean ignoreSendFailures; public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) { this.defaultOutputChannel = defaultOutputChannel; } public void setDefaultOutputChannelName(String defaultOutputChannelName) { this.defaultOutputChannelName = defaultOutputChannelName; } public void setSendTimeout(Long timeout) { this.sendTimeout = timeout; } public void setResolutionRequired(Boolean resolutionRequired) { this.resolutionRequired = resolutionRequired; } public void setApplySequence(Boolean applySequence) { this.applySequence = applySequence; } public void setIgnoreSendFailures(Boolean ignoreSendFailures) { this.ignoreSendFailures = ignoreSendFailures; } public void setChannelMappings(Map<String, String> channelMappings) { this.channelMappings = channelMappings; } @Override protected MessageHandler createMethodInvokingHandler(Object targetObject, String targetMethodName) { Assert.notNull(targetObject, "target object must not be null"); AbstractMessageRouter router = this.extractTypeIfPossible(targetObject, AbstractMessageRouter.class); if (router == null) { if (targetObject instanceof MessageHandler && this.noRouterAttributesProvided() && this.methodIsHandleMessageOrEmpty(targetMethodName)) { return (MessageHandler) targetObject; } router = this.createMethodInvokingRouter(targetObject, targetMethodName); this.configureRouter(router); } else { Assert.isTrue(!StringUtils.hasText(targetMethodName), "target method should not be provided when the target " + "object is an implementation of AbstractMessageRouter"); this.configureRouter(router); if (targetObject instanceof MessageHandler) { return (MessageHandler) targetObject; } } return router; } @Override protected MessageHandler createExpressionEvaluatingHandler(Expression expression) { return this.configureRouter(new ExpressionEvaluatingRouter(expression)); } protected AbstractMappingMessageRouter createMethodInvokingRouter(Object targetObject, String targetMethodName) { return (StringUtils.hasText(targetMethodName)) ? new MethodInvokingRouter(targetObject, targetMethodName) : new MethodInvokingRouter(targetObject); } protected AbstractMessageRouter configureRouter(AbstractMessageRouter router) { if (this.defaultOutputChannel != null) { router.setDefaultOutputChannel(this.defaultOutputChannel); } if (this.defaultOutputChannelName != null) { router.setDefaultOutputChannelName(this.defaultOutputChannelName); } if (this.sendTimeout != null) { router.setSendTimeout(this.sendTimeout); } if (this.applySequence != null) { router.setApplySequence(this.applySequence); } if (this.ignoreSendFailures != null) { router.setIgnoreSendFailures(this.ignoreSendFailures); } if (router instanceof AbstractMappingMessageRouter) { this.configureMappingRouter((AbstractMappingMessageRouter) router); } return router; } protected void configureMappingRouter(AbstractMappingMessageRouter router) { if (this.channelMappings != null) { router.setChannelMappings(this.channelMappings); } if (this.resolutionRequired != null) { router.setResolutionRequired(this.resolutionRequired); } } @Override protected boolean canBeUsedDirect(AbstractMessageProducingHandler handler) { return noRouterAttributesProvided(); } protected boolean noRouterAttributesProvided() { return this.channelMappings == null && this.defaultOutputChannel == null && this.sendTimeout == null && this.resolutionRequired == null && this.applySequence == null && this.ignoreSendFailures == null; } @Override protected Class<? extends MessageHandler> getPreCreationHandlerType() { return AbstractMessageRouter.class; } }