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 2005 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: AbstractConsumerMessageHandle.java,v 1.2 2005/08/30 07:26:49 tanderson Exp $ 44 */ 45 package org.exolab.jms.messagemgr; 46 47 import java.sql.Connection; 48 import javax.jms.JMSException; 49 import javax.jms.MessageConsumer; 50 51 import org.apache.commons.logging.Log; 52 import org.apache.commons.logging.LogFactory; 53 54 import org.exolab.jms.client.JmsDestination; 55 import org.exolab.jms.message.MessageImpl; 56 import org.exolab.jms.persistence.DatabaseService; 57 import org.exolab.jms.persistence.PersistenceException; 58 59 60 /*** 61 * A {@link MessageHandle} for a consumer. 62 * 63 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 64 * @version $Revision: 1.2 $ $Date: 2005/08/30 07:26:49 $ 65 */ 66 abstract class AbstractConsumerMessageHandle implements MessageHandle { 67 68 /*** 69 * The underlying handle. 70 */ 71 private final MessageHandle _handle; 72 73 /*** 74 * The consumer's identity. 75 */ 76 private long _consumerId; 77 78 /*** 79 * The consumer's persistent identity. 80 */ 81 private final String _persistentId; 82 83 /*** 84 * Detetmines if this handle is persistent. 85 */ 86 private boolean _persistent; 87 88 /*** 89 * The logger. 90 */ 91 private static final Log _log 92 = LogFactory.getLog(AbstractConsumerMessageHandle.class); 93 94 95 /*** 96 * Construct a new <code>AbstractConsumerMessageHandle</code>. 97 * 98 * @param handle the underlying handle 99 * @param consumer the consumer of the handle 100 * @throws JMSException if the underlying message can't be referenced 101 */ 102 public AbstractConsumerMessageHandle(MessageHandle handle, 103 ConsumerEndpoint consumer) 104 throws JMSException { 105 this(handle, consumer.getId(), consumer.getPersistentId()); 106 } 107 108 /*** 109 * Construct a new <code>AbstractConsumerMessageHandle</code>. 110 * 111 * @param handle the underlying handle 112 * @param persistentId the persistent identity of the consumer. May be 113 * <code>null</code> 114 * @throws JMSException if the underlying message can't be referenced 115 */ 116 public AbstractConsumerMessageHandle(MessageHandle handle, 117 String persistentId) 118 throws JMSException { 119 this(handle, -1L, persistentId); 120 } 121 122 /*** 123 * Construct a new <code>AbstractConsumerMessageHandle</code>. 124 * 125 * @param handle the underlying handle 126 * @param consumerId the consumer identifier 127 * @param persistentId the persistent identity of the consumer. May be 128 * <code>null</code> 129 * @throws JMSException if the underlying message can't be referenced 130 */ 131 protected AbstractConsumerMessageHandle(MessageHandle handle, long consumerId, 132 String persistentId) 133 throws JMSException { 134 if (handle == null) { 135 throw new IllegalArgumentException("Argument 'handle' is null"); 136 } 137 _handle = handle; 138 _consumerId = consumerId; 139 _persistentId = persistentId; 140 _handle.getMessageRef().reference(); 141 } 142 143 /*** 144 * Returns the message identifier. 145 * 146 * @return the message identifier 147 */ 148 public String getMessageId() { 149 return _handle.getMessageId(); 150 } 151 152 /*** 153 * Indicates if a message has been delivered to a {@link MessageConsumer}, 154 * but not acknowledged. 155 * 156 * @param delivered if <code>true</code> indicates that an attempt has been 157 * made to deliver the message 158 */ 159 public void setDelivered(boolean delivered) { 160 _handle.setDelivered(delivered); 161 } 162 163 /*** 164 * Returns if an attempt has already been made to deliver the message. 165 * 166 * @return <code>true</code> if delivery has been attempted 167 */ 168 public boolean getDelivered() { 169 return _handle.getDelivered(); 170 } 171 172 /*** 173 * Returns the priority of the message. 174 * 175 * @return the message priority 176 */ 177 public int getPriority() { 178 return _handle.getPriority(); 179 } 180 181 /*** 182 * Returns the time that the corresponding message was accepted, in 183 * milliseconds. 184 * 185 * @return the time that the corresponding message was accepted 186 */ 187 public long getAcceptedTime() { 188 return _handle.getAcceptedTime(); 189 } 190 191 /*** 192 * Returns the time that the message expires. 193 * 194 * @return the expiry time 195 */ 196 public long getExpiryTime() { 197 return _handle.getExpiryTime(); 198 } 199 200 /*** 201 * Determines if the message has expired. 202 * 203 * @return <code>true</code> if the message has expired, otherwise 204 * <code>false</code> 205 */ 206 public boolean hasExpired() { 207 return _handle.hasExpired(); 208 } 209 210 /*** 211 * Returns the handle's sequence number. 212 * 213 * @return the sequence number 214 */ 215 public long getSequenceNumber() { 216 return _handle.getSequenceNumber(); 217 } 218 219 /*** 220 * Returns the message destination. 221 * 222 * @return the message destination 223 */ 224 public JmsDestination getDestination() { 225 return _handle.getDestination(); 226 } 227 228 /*** 229 * Returns the consumer identity associated with the message. 230 * 231 * @return the consumer identity associated with the message, or * 232 * <code>-1</code> if the message isn't associated with a consumer 233 */ 234 public long getConsumerId() { 235 return _consumerId; 236 } 237 238 /*** 239 * Returns the name of the consumer endpoint that owns this handle. If it is 240 * set, then a consumer owns it exclusively, otherwise the handle may be 241 * shared across a number of consumers 242 * 243 * @return the consumer name, or <code>null</code> 244 */ 245 public String getConsumerPersistentId() { 246 return _persistentId; 247 } 248 249 /*** 250 * Returns the connection identity associated with the message. 251 * 252 * @return the connection identity associated with the message, or 253 * <code>-1</code> if the message isn't associated with a 254 * connection 255 */ 256 public long getConnectionId() { 257 return _handle.getConnectionId(); 258 } 259 260 /*** 261 * Determines if the handle is persistent. 262 * 263 * @return <code>true</code> if the handle is persistent; otherwise 264 * <code>false</code> 265 */ 266 public boolean isPersistent() { 267 return _persistent; 268 } 269 270 /*** 271 * Returns the message associated with this handle. 272 * 273 * @return the associated message, or <code>null</code> if the handle is no 274 * longer valid 275 * @throws JMSException for any error 276 */ 277 public MessageImpl getMessage() throws JMSException { 278 return _handle.getMessage(); 279 } 280 281 /*** 282 * Makes the handle persistent. 283 * 284 * @throws JMSException for any persistence error 285 */ 286 public void add() throws JMSException { 287 try { 288 DatabaseService service = DatabaseService.getInstance(); 289 Connection connection = service.getConnection(); 290 service.getAdapter().addMessageHandle(connection, this); 291 } catch (PersistenceException exception) { 292 final String msg = "Failed to make handle persistent"; 293 _log.error(msg, exception); 294 throw new JMSException(msg + ": " + exception.getMessage()); 295 } 296 _persistent = true; 297 } 298 299 /*** 300 * Update the persistent handle. 301 * 302 * @throws JMSException for any persistence error 303 */ 304 public void update() throws JMSException { 305 try { 306 DatabaseService service = DatabaseService.getInstance(); 307 Connection connection = service.getConnection(); 308 service.getAdapter().updateMessageHandle(connection, this); 309 } catch (PersistenceException exception) { 310 final String msg = "Failed to update persistent handle"; 311 _log.error(msg, exception); 312 throw new JMSException(msg + ": " + exception.getMessage()); 313 } 314 } 315 316 /*** 317 * Destroy this handle. If this is the last handle to reference the message, 318 * also destroys the message 319 * 320 * @throws JMSException for any error 321 */ 322 public void destroy() throws JMSException { 323 if (_persistent) { 324 try { 325 DatabaseService service = DatabaseService.getInstance(); 326 Connection connection = service.getConnection(); 327 service.getAdapter().removeMessageHandle(connection, this); 328 } catch (PersistenceException exception) { 329 final String msg = "Failed to destroy persistent handle"; 330 _log.error(msg, exception); 331 throw new JMSException(msg + ": " + exception.getMessage()); 332 } 333 } 334 _handle.destroy(); 335 _persistent = false; 336 } 337 338 /*** 339 * Release the message handle back to the cache, to recover an unsent or 340 * unacknowledged message. 341 * 342 * @throws JMSException for any error 343 */ 344 public void release() throws JMSException { 345 if (_handle instanceof AbstractMessageHandle) { 346 ((AbstractMessageHandle) _handle).release(this); 347 } else { 348 _handle.release(); 349 } 350 } 351 352 /*** 353 * Returns the message reference. 354 * 355 * @return the message reference, or <code>null</code> if none has been set 356 */ 357 public MessageRef getMessageRef() { 358 return _handle.getMessageRef(); 359 } 360 361 /*** 362 * Set the consumer identifier. 363 * 364 * @param consumerId the consumer identifier 365 */ 366 protected void setConsumerId(long consumerId) { 367 _consumerId = consumerId; 368 } 369 370 /*** 371 * Indicates if the handle is persistent. 372 * 373 * @param persistent if <code>true</code> indicates the handle is 374 * persistent 375 */ 376 protected void setPersistent(boolean persistent) { 377 _persistent = persistent; 378 } 379 380 } 381