View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2000-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: JmsMessageConsumer.java,v 1.37 2004/01/20 14:14:21 tanderson Exp $ 44 */ 45 package org.exolab.jms.client; 46 47 import javax.jms.JMSException; 48 import javax.jms.Message; 49 import javax.jms.MessageConsumer; 50 import javax.jms.MessageListener; 51 52 import org.apache.commons.logging.Log; 53 import org.apache.commons.logging.LogFactory; 54 55 import org.exolab.jms.message.MessageImpl; 56 57 58 /*** 59 * Client implementation of the <code>javax.jms.MessageConsumer</code> 60 * interface 61 * 62 * @version $Revision: 1.37 $ $Date: 2004/01/20 14:14:21 $ 63 * @author <a href="mailto:jima@comware.com.au">Jim Alateras</a> 64 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 65 */ 66 abstract class JmsMessageConsumer 67 implements MessageListener, MessageConsumer { 68 69 /*** 70 * A message listener may be assigned to this session, for 71 * asynchronous message delivery. 72 */ 73 private MessageListener _messageListener = null; 74 75 /*** 76 * The session which created this 77 */ 78 private JmsSession _session = null; 79 80 /*** 81 * The message selector, for filtering messages. May be <code>null</code> 82 */ 83 private String _selector = null; 84 85 /*** 86 * Indicates if the session is closed 87 */ 88 private volatile boolean _closed = false; 89 90 /*** 91 * The consumer's identity, allocated by the session 92 */ 93 private long _clientId = -1; 94 95 /*** 96 * This is the last time that the listener had been set through 97 * {@link #setMessageListener} 98 */ 99 private long _listenerSetTimestamp = 0; 100 101 /*** 102 * This is the last message id asynchronously delivered to the listener. 103 */ 104 private String _lastMessageDelivered; 105 106 /*** 107 * The logger 108 */ 109 private static final Log _log = 110 LogFactory.getLog(JmsMessageConsumer.class); 111 112 113 /*** 114 * Construct a new <code>JmsMessageProducer</code>. 115 * 116 * @param session the session responsible for the consumer 117 * @param clientId the session allocated consumer identifier 118 * @param selector the message selector. May be <code>null</code 119 */ 120 public JmsMessageConsumer(JmsSession session, long clientId, 121 String selector) { 122 if (session == null) { 123 throw new IllegalArgumentException("Argument 'session' is null"); 124 } 125 _session = session; 126 _clientId = clientId; 127 _selector = selector; 128 } 129 130 /*** 131 * Return the session allocated consumer identifier 132 * 133 * @return the identifier allocated to this by the session 134 */ 135 public long getClientId() { 136 return _clientId; 137 } 138 139 /*** 140 * Return the message consumer's message selector expression 141 * 142 * @return the selector expression, or <code>null</code> if one isn't set 143 */ 144 public String getMessageSelector() { 145 return _selector; 146 } 147 148 /*** 149 * Return the consumer's listener 150 * 151 * @return the listener for the consumer, or <code>null</code> if there 152 * isn't one set 153 */ 154 public MessageListener getMessageListener() { 155 return _messageListener; 156 } 157 158 /*** 159 * Set the consumer's listener 160 * 161 * @param listener the message listener, or <code>null</code> to deregister 162 * an existing listener 163 * @throws JMSException if the listener cannot be set 164 */ 165 public void setMessageListener(MessageListener listener) 166 throws JMSException { 167 // if listener is not null then enable asynchronous delivery 168 // otherwise disable it 169 if (listener != null) { 170 if (_messageListener == null) { 171 // previously asynchronouse messaging was disabled 172 _listenerSetTimestamp = System.currentTimeMillis(); 173 _messageListener = listener; 174 _session.setMessageListener(this); 175 } else { 176 // asynch message deliver is enabled, just changing the 177 // client side receiving entity. 178 _messageListener = listener; 179 } 180 } else { 181 if (_messageListener != null) { 182 _session.removeMessageListener(this); 183 _messageListener = listener; 184 } 185 } 186 187 // reset the lastMessageDelivered regardless what the value 188 // of the listener is. 189 _lastMessageDelivered = null; 190 } 191 192 /*** 193 * Receive the next message produced for this consumer. 194 * This call blocks indefinitely until a message is produced or until 195 * this message consumer is closed. 196 * 197 * @return the next message produced for this consumer, or 198 * <code>null</code> if this consumer is concurrently closed 199 * @throws JMSException if the next message can't be received 200 */ 201 public Message receive() throws JMSException { 202 return retrieveMessage(0); 203 } 204 205 /*** 206 * Receive the next message that arrives within the specified 207 * timeout interval. 208 * This call blocks until a message arrives, the timeout expires, or this 209 * message consumer is closed. A timeout of zero never expires and the call 210 * blocks indefinitely. 211 * 212 * @param timeout the timeout interval, in milliseconds 213 * @return the next message produced for this consumer, or 214 * <code>null</code> if the timeout expires or the consumer concurrently 215 * closed 216 * @throws JMSException if the next message can't be received 217 */ 218 public Message receive(long timeout) throws JMSException { 219 return retrieveMessage(timeout); 220 } 221 222 /*** 223 * Receive the next message if one is immediately available 224 * 225 * @return the next message produced for this consumer, or 226 * <code>null</code> if one is not available 227 * @throws JMSException if the next message can't be received 228 */ 229 public Message receiveNoWait() throws JMSException { 230 return retrieveMessage(-1); 231 } 232 233 /*** 234 * Close the consumer. 235 * This call blocks until a receive or message listener in progress has 236 * completed. A blocked consumer receive call returns <code>null</code> 237 * when this consumer is closed. 238 * 239 * @throws JMSException if this consumer can't be closed 240 */ 241 public synchronized void close() throws JMSException { 242 _closed = true; 243 244 // wake up any blocked threads and let them complete 245 notifyAll(); 246 247 _messageListener = null; 248 _session = null; 249 _selector = null; 250 } 251 252 /*** 253 * Release all resources used by this consumer 254 * 255 * @throws JMSException if this consumer can't be destroyed 256 */ 257 public synchronized void destroy() throws JMSException { 258 _closed = true; 259 260 // wake up any blocked threads and let them complete 261 notifyAll(); 262 263 _messageListener = null; 264 _session = null; 265 _selector = null; 266 } 267 268 /*** 269 * Handles messages received asynchronously via the owning session, 270 * passing them to the registered listener 271 * 272 * @param message the message received 273 */ 274 public synchronized void onMessage(Message message) { 275 try { 276 if (_messageListener != null) { 277 // drop all messages if they were received before the listener 278 // had been set. 279 long rcvd = message.getLongProperty("JMSXRcvTimestamp"); 280 if (rcvd < _listenerSetTimestamp) { 281 return; 282 } 283 284 // According to section 4.5.2 Asynchronous Delivery messages 285 // delivered to consumers, through the MessageListener 286 // interface in a transacted session must be treated the same 287 // as synchronous delivery. 288 // Need to set this field before we actually deliver the 289 // message since the client can actually call 290 // setMessageListener in onMessage() 291 _lastMessageDelivered = ((MessageImpl) message).getId(); 292 _messageListener.onMessage(message); 293 } 294 } catch (JMSException exception) { 295 //report the exception 296 _log.error("Error in onMessage", exception); 297 } 298 } 299 300 /*** 301 * Retrieve the next message for the consumer. 302 * 303 * @param wait the maximum time to wait for a message, in milliseconds. 304 * If <code>-1</code>, don't wait, if <code>0</code> wait indefinitely, 305 * otherwise wait the specified time. 306 * @return the received message, or <code>null</code>, if no message is 307 * available 308 * @throws JMSException if an error occurs retrieving the message, 309 * the session is closed, or a message listener is set. 310 */ 311 public Message retrieveMessage(long wait) throws JMSException { 312 if (_messageListener != null) { 313 // cannot call this method when a listener is defined 314 throw new JMSException("Can't receive when listener defined"); 315 } 316 317 if (_closed) { 318 // cannot call this method when a listener is defined 319 throw new JMSException("Can't receive when session closed"); 320 } 321 322 MessageImpl message = 323 (MessageImpl) _session.retrieveMessage(_clientId, wait); 324 if (message != null) { 325 _lastMessageDelivered = message.getId(); 326 } 327 328 return message; 329 } 330 331 /*** 332 * Return the last message asynchronously delivered to the consumer 333 * 334 * @return the last message delivered 335 */ 336 public String getLastMessageDelivered() { 337 return _lastMessageDelivered; 338 } 339 340 /*** 341 * Determines if the consumer is closed 342 * 343 * @return <code>true</code> if the consumer is closed 344 */ 345 public boolean isClosed() { 346 return _closed; 347 } 348 349 /*** 350 * Returns the session that created this consumer 351 * 352 * @return the session that created this consumer 353 */ 354 protected JmsSession getSession() { 355 return _session; 356 } 357 358 }

This page was automatically generated by Maven