View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.core.messaging;
16  
17  import org.figure8.join.util.LogUtil;
18  
19  import org.apache.commons.logging.Log;
20  import org.springframework.beans.factory.DisposableBean;
21  import org.springframework.jms.core.support.JmsGatewaySupport;
22  
23  import javax.jms.Session;
24  import javax.jms.Connection;
25  import javax.jms.Destination;
26  import javax.jms.JMSException;
27  import javax.jms.MessageConsumer;
28  import javax.jms.ConnectionFactory;
29  /**
30   * This is a base class for JMS messages consumer implementations, based on Spring
31   * JMS templates. This class defines lifecyle methods (<code>start()</code> and
32   * <code>stop()</code>) that deals by connecting/deconnecting to JMS provider and
33   * listened destination.
34   * <br/>
35   * Subclasses should only have to implement the <code>processMessage()</code>
36   * method where real work has to be done. This last method should not throw any
37   * exception. This means that implementation should handle every errors. 
38   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
39   * @version $Revision: 1.2 $
40   */
41  public class JMSConsumerBeanSpringWrapper extends JmsGatewaySupport
42          implements DisposableBean{
43  
44     // Static -------------------------------------------------------------------
45  
46     /** Commons logger. */
47     protected static Log log = LogUtil.getLog(JMSConsumerBeanSpringWrapper.class);
48  
49  
50     // Attributes ---------------------------------------------------------------
51  
52     /** The message selector when listening to messages */
53     private String selector;
54     /** The JMS destination on which to consume messages */
55     private Destination destination;
56  
57     /** Created session for listening to messages */
58     private Session session;
59     /** Created connnection for listening to messages */
60     private Connection connection;
61     /** Created consumer for listening to messages */
62     private MessageConsumer consumer;
63  
64     /** Wrapped JMSConsumerBean instance */
65     private JMSConsumerBean consumerBean;
66  
67  
68     // Constructors -------------------------------------------------------------
69  
70     /** Default constructor. */
71     public JMSConsumerBeanSpringWrapper(){
72     }
73  
74  
75     // Public -------------------------------------------------------------------
76  
77     /** @return Message selector expression used when listening to messages */
78     public String getSelector(){
79        return selector;
80     }
81     /** @param selector Message selector expression to use for filtering messages */
82     public void setSelector(String selector){
83        this.selector = selector;
84     }
85  
86     /** @return JMS destination whose messages are consumed by this object */
87     public Destination getDestination(){
88        return destination;
89     }
90     /** @param destination JMS destination to consume messages for */
91     public void setDestination(Destination destination){
92        this.destination = destination;
93     }
94  
95     /** @return */
96     public JMSConsumerBean getConsumerBean(){
97        return consumerBean;
98     }
99     /** @param consumerBean */
100    public void setConsumerBean(JMSConsumerBean consumerBean){
101       this.consumerBean = consumerBean;
102    }
103 
104    /**
105     * Lifecycle method. This method is called after bean properties intilization.
106     * It is responsible for connecting to the JMS provider using the connection
107     * factory injected and register the current bean as a message listener for
108     * the specified JMS destination.
109     * @throws JMSException if connection to provider or registration as a listener
110     * is not possible
111     */
112    public void start() throws JMSException{
113       log.info("Start method called on consumer. Trying to connect JMS provider...");
114       try{
115          // Let connect to JMS provider.
116          ConnectionFactory factory = getConnectionFactory();
117          connection = factory.createConnection();
118          connection.start();
119          log.info("Connection is started. Trying to register as a message listener...");
120          // Create a session and a register this as a listener for consumer.
121          session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
122          consumer = session.createConsumer(destination, selector, false);
123          consumer.setMessageListener(consumerBean);
124          log.info("Start listening messages with selector: " + selector);
125       }
126       catch (JMSException e){
127          // Log error and propagates.
128          log.error("Caught a JMSException when trying initialize JMSConsumerBeanSpringWrapper", e);
129          throw e;
130       }
131    }
132 
133    /**
134     * Lifecycle method. This method is called on destruction of this beans. It
135     * is responsible for closing and releasing all the resources acquired for
136     * connection and registration as a listener (MessageConsumer, Session and
137     * Connection)
138     * @throws JMSException if closing a resource is not possible
139     */
140    public void stop() throws JMSException{
141       log.info("Stop method called con consumer. Trying to close connected resources...");
142       // Close consumer.
143       if (consumer != null)
144          consumer.close();
145       // Then, close session.
146       if (session != null)
147          session.close();
148       // Finally, close connection.
149       if (connection != null)
150          connection.close();
151    }
152 
153 
154    // Implementation of DisposableBean -----------------------------------------
155 
156    /**
157     * Invoked by a BeanFactory on destruction of a singleton.
158     * @throws Exception in case of shutdown errors.
159     */
160    public void destroy() throws Exception{
161       log.debug("destroy() called on message consumer. Calling stop() method.");
162       consumerBean.stop();
163       stop();
164    }
165 
166 
167    // Override of JmsGatewaySupport --------------------------------------------
168 
169    /**
170     * Gets called after population of this instance's bean properties, just call
171     * <code>start()</code> method. Convenience method for testing with Spring.
172     * @throws Exception if initialization fails
173     */
174    protected void initGateway() throws Exception{
175       if (consumerBean == null)
176          throw new IllegalArgumentException("consumerBean is a required property");
177       log.debug("initGateway() called on message consumer. Calling start() method");
178       start();
179    }
180 }