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 2001-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: TransientMessageHandle.java,v 1.14 2003/08/17 01:32:25 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * 3/1/2001     jima    Created
47   */
48  package org.exolab.jms.messagemgr;
49  
50  import java.io.IOException;
51  import java.io.ObjectInput;
52  import java.io.ObjectOutput;
53  
54  import javax.jms.DeliveryMode;
55  import javax.jms.JMSException;
56  import javax.jms.Message;
57  
58  import org.exolab.jms.client.JmsDestination;
59  import org.exolab.jms.message.MessageHandle;
60  import org.exolab.jms.message.MessageId;
61  import org.exolab.jms.message.MessageImpl;
62  
63  
64  /***
65   * A message handle is used to indirectly reference a message in
66   * the message manager.
67   *
68   * @version     $Revision: 1.14 $ $Date: 2003/08/17 01:32:25 $
69   * @author      <a href="mailto:jima@exoffice.com">Jim Alateras</a>
70   */
71  public class TransientMessageHandle
72      implements MessageHandle {
73  
74      /***
75       * Used for serialization
76       */
77      static final long serialVersionUID = 2;
78  
79      /***
80       * Stores the message identity of the message. This can always be
81       * resolved through the {@link MessageManager}
82       */
83      private MessageId _id = null;
84  
85      /***
86       * This attribute indicates that the message associated with this
87       * handle has already been delivered, but not acked.
88       */
89      private boolean _delivered = false;
90  
91      /***
92       * Holds the priority of the corresponding message
93       */
94      private int _priority = Message.DEFAULT_PRIORITY;
95  
96      /***
97       * This is the time that the corresponding message was accepted by the
98       * server. It is expressed as a long
99       */
100     private long _acceptedTime;
101 
102     /***
103      * a transient attribute, to associate this handle with an endpoint
104      */
105     private transient long _clientId = -1;
106 
107     /***
108      * This is the sequence number, which is assigned to it once the message
109      * has been tagged by the message manager. It also allows us to overcome
110      * the millisecond resolution problem of _acceptedTime
111      */
112     private long _sequenceNumber;
113 
114     /***
115      * This is the time that associated message expires
116      */
117     private long _expiryTime;
118 
119     /***
120      * The destination that this handle belongs too
121      */
122     private JmsDestination _destination;
123 
124     /***
125      * If the consumer name is set then it implies that the endpoint with the
126      * specified id has exclusive access to this handle. This is primarily
127      * used for topics
128      */
129     private String _consumerName;
130 
131     /***
132      * Indicates if the associated message is persistent or not
133      * NOTE: this is not serialized.  @todo - clean up semantics for
134      * persistent and transient message handles. A persistent message
135      * handle should be solely for those messages which can be evicted,
136      * and recovered
137      */
138     private boolean _persistent = false;
139 
140 
141     /***
142      * Default constructor required to support Serialization
143      */
144     public TransientMessageHandle() {
145     }
146 
147     /***
148      * Create a handle for a particular message. Handles are transient
149      * objects.
150      *
151      * @param message the message for which handle is created
152      * @throws JMSException if the handle  cannot be constructed
153      */
154     TransientMessageHandle(MessageImpl message) throws JMSException {
155         _id = message.getMessageId();
156         _priority = message.getJMSPriority();
157         _acceptedTime = message.getAcceptedTime();
158         _delivered = message.getJMSRedelivered();
159         _sequenceNumber = message.getSequenceNumber();
160         _expiryTime = message.getJMSExpiration();
161         _destination = (JmsDestination) message.getJMSDestination();
162         _clientId = message.getClientId();
163         if (message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT) {
164             _persistent = true;
165         }
166     }
167 
168     /***
169      * Return the message id
170      *
171      * @return MessgeId
172      */
173     public MessageId getMessageId() {
174         return _id;
175     }
176 
177     /***
178      * Set the message identity
179      *
180      * @param id - the message identity
181      */
182     public void setMessageId(MessageId id) {
183         _id = id;
184     }
185 
186     /***
187      * Set the message, corresponding to this handle, has already been
188      * delivered once before
189      */
190     public void setDelivered() {
191         _delivered = true;
192     }
193 
194     /***
195      * Set the state of the delivered flag to the specified value
196      *
197      * @param boolean value
198      */
199     public void setDelivered(boolean value) {
200         _delivered = value;
201     }
202 
203     /***
204      * Check whether an attempt has already been made to deliver the message
205      * before.
206      *
207      * @return boolean - true implies redelivery attempted
208      */
209     public boolean getDelivered() {
210         return _delivered;
211     }
212 
213     /***
214      * Set the message priority
215      *
216      * @param int - the message priority
217      */
218     public void setPriority(int priority) {
219         _priority = priority;
220     }
221 
222     /***
223      * Return the priority of the underlying message
224      *
225      * @return int - message priority
226      */
227     public int getPriority() {
228         return _priority;
229     }
230 
231     /***
232      * Set the time that the message was accepted by the server
233      *
234      * @param time - accepted time
235      */
236     public void setAcceptedTime(long time) {
237         _acceptedTime = time;
238     }
239 
240     /***
241      * Return time that the corresponding message was accepted.
242      *
243      * @return long - the accepted time.
244      */
245     public long getAcceptedTime() {
246         return _acceptedTime;
247     }
248 
249     /***
250      * Set the message expiry time
251      *
252      * @long time - time in ms since epoch
253      */
254     public void setExpiryTime(long time) {
255         _expiryTime = time;
256     }
257 
258     /***
259      * Return the message expiry time
260      *
261      * @return long - time in ms since epoch
262      */
263     public long getExpiryTime() {
264         return _expiryTime;
265     }
266 
267     /***
268      * Set the message's sequence number
269      *
270      * @param seq - sequence time
271      */
272     public void setSequenceNumber(long seq) {
273         _sequenceNumber = seq;
274     }
275 
276     /***
277      * Return message's sequence number
278      *
279      * @return long - the sequence number
280      */
281     public long getSequenceNumber() {
282         return _sequenceNumber;
283     }
284 
285     /***
286      * Set the destination that owns this handle
287      *
288      * @param destination - the destination
289      */
290     public void setDestination(JmsDestination destination) {
291         _destination = destination;
292     }
293 
294     /***
295      * Return the destination for this handle
296      *
297      * @return JmsDestination
298      */
299     public JmsDestination getDestination() {
300         return _destination;
301     }
302 
303     /***
304      * Set the client id, that owns this handle
305      *
306      * @param clientId - client identity
307      */
308     public void setClientId(long clientId) {
309         _clientId = clientId;
310     }
311 
312     /***
313      * Retrieve the client identity associated with this handle
314      *
315      * @return long
316      */
317     public long getClientId() {
318         return _clientId;
319     }
320 
321     // implementation of MessageHandle.setConsumerName
322     public void setConsumerName(String name) {
323         _consumerName = name;
324     }
325 
326     // implementation of MessageHandle.getConsumerName
327     public String getConsumerName() {
328         return _consumerName;
329     }
330 
331 
332     /***
333      * Return the associated message or null if it is invalid
334      *
335      * @return  MessageImpl
336      */
337     public MessageImpl getMessage() {
338         return (MessageImpl) MessageMgr.instance().getMessage(this);
339     }
340 
341     /***
342      * Return a stringified version of the handle
343      *
344      * @return String
345      */
346     public String toString() {
347         return "Handle : " + _priority + ":" + getAcceptedTime() +
348             ":" + getSequenceNumber() + ":" + _id;
349     }
350 
351     /***
352      * Clear the message handle
353      */
354     public void clear() {
355         _id = null;
356     }
357 
358     // implementation of MessageHandle.isPersistent
359     public boolean isPersistent() {
360         return _persistent;
361     }
362 
363     /***
364      * Destroy this handle
365      */
366     public void destroy() {
367         // notify the message manager
368         MessageMgr.instance().handleDestroyed(this);
369     }
370 
371     // override the definition of equals
372     public boolean equals(Object object) {
373 
374         if ((object != null) &&
375             (object instanceof TransientMessageHandle)) {
376             return _id.equals(((TransientMessageHandle) object)._id);
377         }
378 
379         return false;
380     }
381 
382     // override the definition of hashCode
383     public int hashCode() {
384         return _id.hashCode();
385     }
386 
387     // implementation of Externalizable.writeExternal
388     public void writeExternal(ObjectOutput stream)
389         throws IOException {
390         stream.writeLong(serialVersionUID);
391         stream.writeObject(_id);
392         stream.writeInt(_priority);
393         stream.writeBoolean(_delivered);
394         stream.writeLong(_acceptedTime);
395         stream.writeLong(_sequenceNumber);
396         stream.writeLong(_expiryTime);
397         stream.writeObject(_destination);
398     }
399 
400     // implementation of Externalizable.writeExternal
401     public void readExternal(ObjectInput stream)
402         throws IOException, ClassNotFoundException {
403         long version = stream.readLong();
404         if (version == serialVersionUID) {
405             _id = (MessageId) stream.readObject();
406             _priority = stream.readInt();
407             _delivered = stream.readBoolean();
408             _acceptedTime = stream.readLong();
409             _sequenceNumber = stream.readLong();
410             _expiryTime = stream.readLong();
411             _destination = (JmsDestination) stream.readObject();
412         } else if (version == 1) {
413             _id = (MessageId) stream.readObject();
414             _priority = stream.readInt();
415             _delivered = stream.readBoolean();
416             _acceptedTime = stream.readLong();
417             _sequenceNumber = stream.readLong();
418             _expiryTime = stream.readLong();
419             _destination = null;
420         } else {
421             throw new IOException("TransientMessageHandle with version " +
422                 version + " is not supported.");
423         }
424     }
425 
426 } //-- TransientMessageHandle