org.springframework.integration.jms.JmsDestinationBackedMessageChannel.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.integration.jms.JmsDestinationBackedMessageChannel.java

Source

/*
 * Copyright 2002-2010 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.jms;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.dispatcher.BroadcastingDispatcher;
import org.springframework.integration.dispatcher.MessageDispatcher;
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
import org.springframework.integration.dispatcher.UnicastingDispatcher;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.AbstractMessageListenerContainer;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;

/**
 * A {@link MessageChannel} implementation that is actually backed by a JMS
 * Destination. This class is useful as a drop-in replacement for any
 * Spring Integration channel. The benefit of using this channel is that
 * the full power of any JMS provider is available with only minimal
 * configuration changes and without requiring any code changes. The most
 * obvious benefit is the ability to delegate message persistence to the
 * JMS provider.
 * 
 * @author Mark Fisher
 * @since 2.0
 */
public class JmsDestinationBackedMessageChannel extends MessageListenerContainerConfigurationSupport
        implements SubscribableChannel, MessageListener, BeanNameAware, SmartLifecycle, InitializingBean {

    private final Log logger = LogFactory.getLog(this.getClass());

    private final JmsTemplate jmsTemplate = new JmsTemplate();

    private volatile MessageDispatcher dispatcher;

    private volatile String name;

    public JmsDestinationBackedMessageChannel(ConnectionFactory connectionFactory, Destination destination) {
        this.setConnectionFactory(connectionFactory);
        this.setDestination(destination);
    }

    public JmsDestinationBackedMessageChannel(ConnectionFactory connectionFactory, String destinationName,
            boolean isPubSub) {
        this.setConnectionFactory(connectionFactory);
        this.setDestinationName(destinationName);
        this.setPubSubDomain(isPubSub);
    }

    @Override
    public void setConnectionFactory(ConnectionFactory connectionFactory) {
        super.setConnectionFactory(connectionFactory);
        this.jmsTemplate.setConnectionFactory(connectionFactory);
    }

    @Override
    public void setDestination(Destination destination) {
        super.setDestination(destination);
        this.jmsTemplate.setDefaultDestination(destination);
    }

    @Override
    public void setDestinationName(String destinationName) {
        super.setDestinationName(destinationName);
        this.jmsTemplate.setDefaultDestinationName(destinationName);
    }

    @Override
    public void setDestinationResolver(DestinationResolver destinationResolver) {
        super.setDestinationResolver(destinationResolver);
        this.jmsTemplate.setDestinationResolver(destinationResolver);
    }

    @Override
    public void setPubSubDomain(boolean pubSubDomain) {
        super.setPubSubDomain(pubSubDomain);
        this.jmsTemplate.setPubSubDomain(pubSubDomain);
    }

    public void setDeliveryPersistent(boolean deliveryPersistent) {
        this.jmsTemplate.setDeliveryPersistent(deliveryPersistent);
    }

    public void setExplicitQosEnabled(boolean explicitQosEnabled) {
        this.jmsTemplate.setExplicitQosEnabled(explicitQosEnabled);
    }

    public void setMessageConverter(MessageConverter messageConverter) {
        this.jmsTemplate.setMessageConverter(messageConverter);
    }

    public void setMessageIdEnabled(boolean messageIdEnabled) {
        this.jmsTemplate.setMessageIdEnabled(messageIdEnabled);
    }

    public void setMessageTimestampEnabled(boolean messageTimestampEnabled) {
        this.jmsTemplate.setMessageTimestampEnabled(messageTimestampEnabled);
    }

    public void setPriority(int priority) {
        this.jmsTemplate.setPriority(priority);
    }

    @Override
    public void setPubSubNoLocal(boolean pubSubNoLocal) {
        super.setPubSubNoLocal(pubSubNoLocal);
        this.jmsTemplate.setPubSubNoLocal(pubSubNoLocal);
    }

    @Override
    public void setSessionAcknowledgeMode(int sessionAcknowledgeMode) {
        super.setSessionAcknowledgeMode(sessionAcknowledgeMode);
        this.jmsTemplate.setSessionAcknowledgeMode(sessionAcknowledgeMode);
    }

    @Override
    public void setSessionTransacted(boolean sessionTransacted) {
        super.setSessionTransacted(sessionTransacted);
        this.jmsTemplate.setSessionTransacted(sessionTransacted);
    }

    public void setTimeToLive(long timeToLive) {
        this.jmsTemplate.setTimeToLive(timeToLive);
    }

    public void setBeanName(String beanName) {
        this.name = beanName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        AbstractMessageListenerContainer container = this.getListenerContainer();
        this.configureDispatcher(container.isPubSubDomain());
        container.setMessageListener(this);
        if (!container.isActive()) {
            container.afterPropertiesSet();
        }
    }

    private void configureDispatcher(boolean isPubSub) {
        if (isPubSub) {
            this.dispatcher = new BroadcastingDispatcher();
        } else {
            UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher();
            unicastingDispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy());
            this.dispatcher = unicastingDispatcher;
        }
    }

    public String getName() {
        return this.name;
    }

    public boolean subscribe(MessageHandler handler) {
        return this.dispatcher.addHandler(handler);
    }

    public boolean unsubscribe(MessageHandler handler) {
        return this.dispatcher.removeHandler(handler);
    }

    public boolean send(Message<?> message) {
        this.jmsTemplate.convertAndSend(message);
        return true;
    }

    public boolean send(Message<?> message, long timeout) {
        return this.send(message);
    }

    // MessageListener implementation

    public void onMessage(javax.jms.Message message) {
        try {
            Object converted = this.jmsTemplate.getMessageConverter().fromMessage(message);
            if (converted != null) {
                Message<?> messageToSend = (converted instanceof Message<?>) ? (Message<?>) converted
                        : MessageBuilder.withPayload(converted).build();
                this.dispatcher.dispatch(messageToSend);
            } else if (this.logger.isWarnEnabled()) {
                logger.warn("MessageConverter returned null, no Message to dispatch");
            }
        } catch (Exception e) {
            throw new MessagingException("failed to handle incoming JMS Message", e);
        }
    }

}