KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jms > listener > serversession > ServerSessionMessageListenerContainer


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jms.listener.serversession;
18
19 import javax.jms.Connection JavaDoc;
20 import javax.jms.ConnectionConsumer JavaDoc;
21 import javax.jms.Destination JavaDoc;
22 import javax.jms.JMSException JavaDoc;
23 import javax.jms.Message JavaDoc;
24 import javax.jms.MessageListener JavaDoc;
25 import javax.jms.ServerSession JavaDoc;
26 import javax.jms.ServerSessionPool JavaDoc;
27 import javax.jms.Session JavaDoc;
28 import javax.jms.Topic JavaDoc;
29
30 import org.springframework.jms.listener.AbstractMessageListenerContainer;
31 import org.springframework.jms.support.JmsUtils;
32
33 /**
34  * Message listener container that builds on the JMS ServerSessionPool SPI,
35  * creating JMS ServerSessions through a pluggable ServerSessionFactory.
36  *
37  * <p>This is the most sophisticated message listener container possible
38  * with standard JMS. It allows for dynamic management of JMS Sessions,
39  * potentially using a pool of Sessions that receive messages in parallel.
40  *
41  * <p>Note that the default ServerSessionFactory is a {@link SimpleServerSessionFactory},
42  * which will create a new ServerSession for each listener execution.
43  * Consider specifying a {@link CommonsPoolServerSessionFactory} to reuse JMS Sessions
44  * and/or to limit the number of concurrent ServerSession executions
45  *
46  * <p>See the {@link AbstractMessageListenerContainer} javadoc for details
47  * on acknowledge modes and transaction options.
48  *
49  * <p>For a simpler message listener container, in particular when using
50  * a JMS provider without ServerSessionPool support, consider using
51  * {@link org.springframework.jms.listener.SimpleMessageListenerContainer}.
52  *
53  * <p>This class requires a JMS 1.1+ provider, because it builds on the
54  * domain-independent API. <b>Use the {@link ServerSessionMessageListenerContainer102}
55  * subclass for JMS 1.0.2 providers.</b>
56  *
57  * @author Juergen Hoeller
58  * @since 2.0
59  * @see org.springframework.jms.listener.SimpleMessageListenerContainer
60  * @see ServerSessionMessageListenerContainer102
61  */

62 public class ServerSessionMessageListenerContainer extends AbstractMessageListenerContainer
63         implements ListenerSessionManager {
64
65     private ServerSessionFactory serverSessionFactory = new SimpleServerSessionFactory();
66
67     private int maxMessagesPerTask = 1;
68
69     private ConnectionConsumer JavaDoc consumer;
70
71
72     /**
73      * Set the Spring ServerSessionFactory to use.
74      * <p>Default is a plain SimpleServerSessionFactory.
75      * Consider using a CommonsPoolServerSessionFactory to reuse JMS Sessions
76      * and/or to limit the number of concurrent ServerSession executions.
77      * @see SimpleServerSessionFactory
78      * @see CommonsPoolServerSessionFactory
79      */

80     public void setServerSessionFactory(ServerSessionFactory serverSessionFactory) {
81         this.serverSessionFactory =
82                 (serverSessionFactory != null ? serverSessionFactory : new SimpleServerSessionFactory());
83     }
84
85     /**
86      * Return the Spring ServerSessionFactory to use.
87      */

88     protected ServerSessionFactory getServerSessionFactory() {
89         return this.serverSessionFactory;
90     }
91
92     /**
93      * Set the maximum number of messages to load into a JMS Session.
94      * Default is 1.
95      * <p>See the corresponding JMS <code>createConnectionConsumer</code>
96      * argument for details.
97      * @see javax.jms.Connection#createConnectionConsumer
98      */

99     public void setMaxMessagesPerTask(int maxMessagesPerTask) {
100         this.maxMessagesPerTask = maxMessagesPerTask;
101     }
102
103     /**
104      * Return the maximum number of messages to load into a JMS Session.
105      */

106     protected int getMaxMessagesPerTask() {
107         return this.maxMessagesPerTask;
108     }
109
110
111     //-------------------------------------------------------------------------
112
// Implementation of AbstractMessageListenerContainer's template methods
113
//-------------------------------------------------------------------------
114

115     /**
116      * Always use a shared JMS Connection.
117      */

118     protected final boolean sharedConnectionEnabled() {
119         return true;
120     }
121
122     /**
123      * Creates a JMS ServerSessionPool for the specified listener and registers
124      * it with a JMS ConnectionConsumer for the specified destination.
125      * @see #createServerSessionPool
126      * @see #createConsumer
127      */

128     protected void doInitialize() throws JMSException JavaDoc {
129         Connection JavaDoc con = getSharedConnection();
130         Destination JavaDoc destination = getDestination();
131         if (destination == null) {
132             Session JavaDoc session = createSession(con);
133             try {
134                 destination = resolveDestinationName(session, getDestinationName());
135             }
136             finally {
137                 JmsUtils.closeSession(session);
138             }
139         }
140         ServerSessionPool JavaDoc pool = createServerSessionPool();
141         this.consumer = createConsumer(con, destination, pool);
142     }
143
144     /**
145      * Create a JMS ServerSessionPool for the specified message listener,
146      * via this container's ServerSessionFactory.
147      * <p>This message listener container implements the ListenerSessionManager
148      * interface, hence can be passed to the ServerSessionFactory itself.
149      * @see #setServerSessionFactory
150      * @see ServerSessionFactory#getServerSession(ListenerSessionManager)
151      */

152     protected ServerSessionPool JavaDoc createServerSessionPool() throws JMSException JavaDoc {
153         return new ServerSessionPool JavaDoc() {
154             public ServerSession JavaDoc getServerSession() throws JMSException JavaDoc {
155                 logger.debug("JMS ConnectionConsumer requests ServerSession");
156                 return getServerSessionFactory().getServerSession(ServerSessionMessageListenerContainer.this);
157             }
158         };
159     }
160
161     /**
162      * Return the JMS ConnectionConsumer used by this message listener container.
163      * Available after initialization.
164      */

165     protected final ConnectionConsumer JavaDoc getConsumer() {
166         return this.consumer;
167     }
168
169     /**
170      * Close the JMS ServerSessionPool for the specified message listener,
171      * via this container's ServerSessionFactory, and subsequently also
172      * this container's JMS ConnectionConsumer.
173      * <p>This message listener container implements the ListenerSessionManager
174      * interface, hence can be passed to the ServerSessionFactory itself.
175      * @see #setServerSessionFactory
176      * @see ServerSessionFactory#getServerSession(ListenerSessionManager)
177      */

178     protected void doShutdown() throws JMSException JavaDoc {
179         logger.debug("Closing ServerSessionFactory");
180         getServerSessionFactory().close(this);
181         logger.debug("Closing JMS ConnectionConsumer");
182         this.consumer.close();
183     }
184
185
186     //-------------------------------------------------------------------------
187
// Implementation of the ListenerSessionManager interface
188
//-------------------------------------------------------------------------
189

190     /**
191      * Create a JMS Session with the specified listener registered.
192      * Listener execution is delegated to the <code>executeListener</code> method.
193      * <p>Default implementation simply calls <code>setMessageListener</code>
194      * on a newly created JMS Session, according to the JMS specification's
195      * ServerSessionPool section.
196      * @return the JMS Session
197      * @throws JMSException if thrown by JMS API methods
198      * @see #executeListener
199      */

200     public Session JavaDoc createListenerSession() throws JMSException JavaDoc {
201         final Session JavaDoc session = createSession(getSharedConnection());
202
203         session.setMessageListener(new MessageListener JavaDoc() {
204             public void onMessage(Message JavaDoc message) {
205                 executeListener(session, message);
206             }
207         });
208
209         return session;
210     }
211
212     /**
213      * Execute the given JMS Session, triggering invocation
214      * of its listener.
215      * <p>Default implementation simply calls <code>run()</code>
216      * on the JMS Session, according to the JMS specification's
217      * ServerSessionPool section.
218      * @param session the JMS Session to execute
219      */

220     public void executeListenerSession(Session JavaDoc session) {
221         session.run();
222     }
223
224
225     //-------------------------------------------------------------------------
226
// JMS 1.1 factory methods, potentially overridden for JMS 1.0.2
227
//-------------------------------------------------------------------------
228

229     /**
230      * Create a JMS ConnectionConsumer for the given Connection.
231      * <p>This implementation uses JMS 1.1 API.
232      * @param con the JMS Connection to create a Session for
233      * @return the new JMS Session
234      * @throws JMSException if thrown by JMS API methods
235      */

236     protected ConnectionConsumer JavaDoc createConsumer(Connection JavaDoc con, Destination JavaDoc destination, ServerSessionPool JavaDoc pool)
237             throws JMSException JavaDoc {
238
239         if (isSubscriptionDurable() && destination instanceof Topic JavaDoc) {
240             return con.createDurableConnectionConsumer(
241                     (Topic JavaDoc) destination, getDurableSubscriptionName(), getMessageSelector(), pool, getMaxMessagesPerTask());
242         }
243         else {
244             return con.createConnectionConsumer(destination, getMessageSelector(), pool, getMaxMessagesPerTask());
245         }
246     }
247
248 }
249
Popular Tags