001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.activemq.pool;
018
019 import java.io.Serializable;
020 import java.util.Iterator;
021 import java.util.concurrent.CopyOnWriteArrayList;
022
023 import javax.jms.BytesMessage;
024 import javax.jms.Destination;
025 import javax.jms.JMSException;
026 import javax.jms.MapMessage;
027 import javax.jms.Message;
028 import javax.jms.MessageConsumer;
029 import javax.jms.MessageListener;
030 import javax.jms.MessageProducer;
031 import javax.jms.ObjectMessage;
032 import javax.jms.Queue;
033 import javax.jms.QueueBrowser;
034 import javax.jms.QueueReceiver;
035 import javax.jms.QueueSender;
036 import javax.jms.QueueSession;
037 import javax.jms.StreamMessage;
038 import javax.jms.TemporaryQueue;
039 import javax.jms.TemporaryTopic;
040 import javax.jms.TextMessage;
041 import javax.jms.Topic;
042 import javax.jms.TopicPublisher;
043 import javax.jms.TopicSession;
044 import javax.jms.TopicSubscriber;
045
046 import org.apache.activemq.ActiveMQMessageProducer;
047 import org.apache.activemq.ActiveMQQueueSender;
048 import org.apache.activemq.ActiveMQSession;
049 import org.apache.activemq.ActiveMQTopicPublisher;
050 import org.apache.activemq.AlreadyClosedException;
051 import org.apache.commons.logging.Log;
052 import org.apache.commons.logging.LogFactory;
053
054 /**
055 * @version $Revision: 1.1 $
056 */
057 public class PooledSession implements TopicSession, QueueSession {
058 private static final transient Log LOG = LogFactory.getLog(PooledSession.class);
059
060 private ActiveMQSession session;
061 private SessionPool sessionPool;
062 private ActiveMQMessageProducer messageProducer;
063 private ActiveMQQueueSender queueSender;
064 private ActiveMQTopicPublisher topicPublisher;
065 private boolean transactional = true;
066 private boolean ignoreClose;
067
068 private final CopyOnWriteArrayList<MessageConsumer> consumers = new CopyOnWriteArrayList<MessageConsumer>();
069 private final CopyOnWriteArrayList<QueueBrowser> browsers = new CopyOnWriteArrayList<QueueBrowser>();
070
071 public PooledSession(ActiveMQSession aSession, SessionPool sessionPool) {
072 this.session = aSession;
073 this.sessionPool = sessionPool;
074 this.transactional = session.isTransacted();
075 }
076
077 protected boolean isIgnoreClose() {
078 return ignoreClose;
079 }
080
081 protected void setIgnoreClose(boolean ignoreClose) {
082 this.ignoreClose = ignoreClose;
083 }
084
085 public void close() throws JMSException {
086 if (!ignoreClose) {
087 // TODO a cleaner way to reset??
088
089 // lets reset the session
090 getSession().setMessageListener(null);
091
092 // Close any consumers and browsers that may have been created.
093 for (Iterator<MessageConsumer> iter = consumers.iterator(); iter.hasNext();) {
094 MessageConsumer consumer = iter.next();
095 consumer.close();
096 }
097 consumers.clear();
098
099 for (Iterator<QueueBrowser> iter = browsers.iterator(); iter.hasNext();) {
100 QueueBrowser browser = iter.next();
101 browser.close();
102 }
103 browsers.clear();
104
105 // maybe do a rollback?
106 if (transactional) {
107 try {
108 getSession().rollback();
109 } catch (JMSException e) {
110 LOG.warn("Caught exception trying rollback() when putting session back into the pool: " + e, e);
111
112 // lets close the session and not put the session back into
113 // the pool
114 try {
115 session.close();
116 } catch (JMSException e1) {
117 LOG.trace("Ignoring exception as discarding session: " + e1, e1);
118 }
119 session = null;
120 return;
121 }
122 }
123
124 sessionPool.returnSession(this);
125 }
126 }
127
128 public void commit() throws JMSException {
129 getSession().commit();
130 }
131
132 public BytesMessage createBytesMessage() throws JMSException {
133 return getSession().createBytesMessage();
134 }
135
136 public MapMessage createMapMessage() throws JMSException {
137 return getSession().createMapMessage();
138 }
139
140 public Message createMessage() throws JMSException {
141 return getSession().createMessage();
142 }
143
144 public ObjectMessage createObjectMessage() throws JMSException {
145 return getSession().createObjectMessage();
146 }
147
148 public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException {
149 return getSession().createObjectMessage(serializable);
150 }
151
152 public Queue createQueue(String s) throws JMSException {
153 return getSession().createQueue(s);
154 }
155
156 public StreamMessage createStreamMessage() throws JMSException {
157 return getSession().createStreamMessage();
158 }
159
160 public TemporaryQueue createTemporaryQueue() throws JMSException {
161 return getSession().createTemporaryQueue();
162 }
163
164 public TemporaryTopic createTemporaryTopic() throws JMSException {
165 return getSession().createTemporaryTopic();
166 }
167
168 public void unsubscribe(String s) throws JMSException {
169 getSession().unsubscribe(s);
170 }
171
172 public TextMessage createTextMessage() throws JMSException {
173 return getSession().createTextMessage();
174 }
175
176 public TextMessage createTextMessage(String s) throws JMSException {
177 return getSession().createTextMessage(s);
178 }
179
180 public Topic createTopic(String s) throws JMSException {
181 return getSession().createTopic(s);
182 }
183
184 public int getAcknowledgeMode() throws JMSException {
185 return getSession().getAcknowledgeMode();
186 }
187
188 public boolean getTransacted() throws JMSException {
189 return getSession().getTransacted();
190 }
191
192 public void recover() throws JMSException {
193 getSession().recover();
194 }
195
196 public void rollback() throws JMSException {
197 getSession().rollback();
198 }
199
200 public void run() {
201 if (session != null) {
202 session.run();
203 }
204 }
205
206 // Consumer related methods
207 // -------------------------------------------------------------------------
208 public QueueBrowser createBrowser(Queue queue) throws JMSException {
209 return addQueueBrowser(getSession().createBrowser(queue));
210 }
211
212 public QueueBrowser createBrowser(Queue queue, String selector) throws JMSException {
213 return addQueueBrowser(getSession().createBrowser(queue, selector));
214 }
215
216 public MessageConsumer createConsumer(Destination destination) throws JMSException {
217 return addConsumer(getSession().createConsumer(destination));
218 }
219
220 public MessageConsumer createConsumer(Destination destination, String selector) throws JMSException {
221 return addConsumer(getSession().createConsumer(destination, selector));
222 }
223
224 public MessageConsumer createConsumer(Destination destination, String selector, boolean noLocal) throws JMSException {
225 return addConsumer(getSession().createConsumer(destination, selector, noLocal));
226 }
227
228 public TopicSubscriber createDurableSubscriber(Topic topic, String selector) throws JMSException {
229 return addTopicSubscriber(getSession().createDurableSubscriber(topic, selector));
230 }
231
232 public TopicSubscriber createDurableSubscriber(Topic topic, String name, String selector, boolean noLocal) throws JMSException {
233 return addTopicSubscriber(getSession().createDurableSubscriber(topic, name, selector, noLocal));
234 }
235
236 public MessageListener getMessageListener() throws JMSException {
237 return getSession().getMessageListener();
238 }
239
240 public void setMessageListener(MessageListener messageListener) throws JMSException {
241 getSession().setMessageListener(messageListener);
242 }
243
244 public TopicSubscriber createSubscriber(Topic topic) throws JMSException {
245 return addTopicSubscriber(getSession().createSubscriber(topic));
246 }
247
248 public TopicSubscriber createSubscriber(Topic topic, String selector, boolean local) throws JMSException {
249 return addTopicSubscriber(getSession().createSubscriber(topic, selector, local));
250 }
251
252 public QueueReceiver createReceiver(Queue queue) throws JMSException {
253 return addQueueReceiver(getSession().createReceiver(queue));
254 }
255
256 public QueueReceiver createReceiver(Queue queue, String selector) throws JMSException {
257 return addQueueReceiver(getSession().createReceiver(queue, selector));
258 }
259
260 // Producer related methods
261 // -------------------------------------------------------------------------
262 public MessageProducer createProducer(Destination destination) throws JMSException {
263 return new PooledProducer(getMessageProducer(), destination);
264 }
265
266 public QueueSender createSender(Queue queue) throws JMSException {
267 return new PooledQueueSender(getQueueSender(), queue);
268 }
269
270 public TopicPublisher createPublisher(Topic topic) throws JMSException {
271 return new PooledTopicPublisher(getTopicPublisher(), topic);
272 }
273
274 // Implementation methods
275 // -------------------------------------------------------------------------
276 protected ActiveMQSession getSession() throws AlreadyClosedException {
277 if (session == null) {
278 throw new AlreadyClosedException("The session has already been closed");
279 }
280 return session;
281 }
282
283 public ActiveMQMessageProducer getMessageProducer() throws JMSException {
284 if (messageProducer == null) {
285 messageProducer = (ActiveMQMessageProducer)getSession().createProducer(null);
286 }
287 return messageProducer;
288 }
289
290 public ActiveMQQueueSender getQueueSender() throws JMSException {
291 if (queueSender == null) {
292 queueSender = (ActiveMQQueueSender)getSession().createSender(null);
293 }
294 return queueSender;
295 }
296
297 public ActiveMQTopicPublisher getTopicPublisher() throws JMSException {
298 if (topicPublisher == null) {
299 topicPublisher = (ActiveMQTopicPublisher)getSession().createPublisher(null);
300 }
301 return topicPublisher;
302 }
303
304 private QueueBrowser addQueueBrowser(QueueBrowser browser) {
305 browsers.add(browser);
306 return browser;
307 }
308
309 private MessageConsumer addConsumer(MessageConsumer consumer) {
310 consumers.add(consumer);
311 return consumer;
312 }
313
314 private TopicSubscriber addTopicSubscriber(TopicSubscriber subscriber) {
315 consumers.add(subscriber);
316 return subscriber;
317 }
318
319 private QueueReceiver addQueueReceiver(QueueReceiver receiver) {
320 consumers.add(receiver);
321 return receiver;
322 }
323
324 public String toString() {
325 return "PooledSession { " + session + " }";
326 }
327 }