/* * Copyright 2014 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.dsl; import java.util.ArrayList; import java.util.List; import org.springframework.beans.BeansException; import org.springframework.expression.Expression; import org.springframework.integration.core.GenericSelector; import org.springframework.integration.core.MessageSelector; import org.springframework.integration.dsl.support.MessageChannelReference; import org.springframework.integration.dsl.support.tuple.Tuple2; import org.springframework.integration.dsl.support.tuple.Tuples; import org.springframework.integration.filter.ExpressionEvaluatingSelector; import org.springframework.integration.filter.MethodInvokingSelector; import org.springframework.integration.router.RecipientListRouter; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.core.DestinationResolutionException; import org.springframework.util.StringUtils; /** * @author Artem Bilan */ class DslRecipientListRouter extends RecipientListRouter { private final List<Tuple2<?, ?>> recipients = new ArrayList<Tuple2<?, ?>>(); void add(String channelName, Expression expression) { this.recipients.add(Tuples.of(channelName, expression)); } void add(String channelName, GenericSelector<?> selector) { this.recipients.add(Tuples.of(channelName, selector)); } void add(MessageChannel channel, Expression expression) { this.recipients.add(Tuples.of(channel, expression)); } void add(MessageChannel channel, GenericSelector<?> selector) { this.recipients.add(Tuples.of(channel, selector)); } @Override public void onInit() throws Exception { List<Recipient> recipients = new ArrayList<Recipient>(this.recipients.size()); for (Tuple2<?, ?> recipient : this.recipients) { if (recipient.getT1() instanceof String) { recipients.add(new DslRecipient(new MessageChannelReference((String) recipient.getT1()), populateRecipientSelector(recipient.getT2()))); } else { recipients.add(new Recipient((MessageChannel) recipient.getT1(), populateRecipientSelector(recipient.getT2()))); } } setRecipients(recipients); this.recipients.clear(); super.onInit(); } private MessageSelector populateRecipientSelector(final Object recipientSelector) { if (recipientSelector instanceof String) { String expression = (String) recipientSelector; if (StringUtils.hasText(expression)) { ExpressionEvaluatingSelector selector = new ExpressionEvaluatingSelector(expression); selector.setBeanFactory(getBeanFactory()); return selector; } } else if (recipientSelector instanceof Expression) { ExpressionEvaluatingSelector selector = new ExpressionEvaluatingSelector((Expression) recipientSelector); selector.setBeanFactory(getBeanFactory()); return selector; } else if (recipientSelector instanceof MessageSelector) { return (MessageSelector) recipientSelector; } else if (recipientSelector instanceof GenericSelector) { return new MethodInvokingSelector(new LambdaMessageProcessor(recipientSelector, null)); } return null; } private class DslRecipient extends Recipient { private volatile MessageChannel channel; DslRecipient(MessageChannelReference channel, MessageSelector selector) { super(channel, selector); } @Override public MessageChannel getChannel() { if (this.channel == null) { synchronized (this) { if (this.channel == null) { this.channel = resolveChannelName((MessageChannelReference) super.getChannel()); } } } return this.channel; } private MessageChannel resolveChannelName(MessageChannelReference channelReference) { String channelName = channelReference.getName(); try { return DslRecipientListRouter.this.getBeanFactory().getBean(channelName, MessageChannel.class); } catch (BeansException e) { throw new DestinationResolutionException("Failed to look up MessageChannel with name '" + channelName + "' in the BeanFactory."); } } } }