KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > persistence > MessageHandles


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-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42  */

43 package org.exolab.jms.persistence;
44
45 import java.sql.Connection JavaDoc;
46 import java.sql.PreparedStatement JavaDoc;
47 import java.sql.ResultSet JavaDoc;
48 import java.sql.SQLException JavaDoc;
49 import java.util.Vector JavaDoc;
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.client.JmsTopic;
56 import org.exolab.jms.messagemgr.PersistentMessageHandle;
57 import org.exolab.jms.messagemgr.MessageHandle;
58
59
60 /**
61  * This class provides persistency for MessageHandle objects
62  * in an RDBMS database
63  *
64  * @version $Revision: 1.3 $ $Date: 2005/06/09 14:39:51 $
65  * @author <a HREF="mailto:tma@netspace.net.au">Tim Anderson</a>
66  */

67 class MessageHandles {
68
69     /**
70      * prepared statement for inserting a message handle
71      */

72     private static final String JavaDoc INSERT_MSG_HANDLE_STMT =
73             "insert into message_handles (messageid, destinationid, consumerid, "
74             + "priority, acceptedtime, sequencenumber, expirytime, delivered) "
75             + "values (?,?,?,?,?,?,?,?)";
76
77     /**
78      * prepared statements for deleting message handle
79      */

80     private static final String JavaDoc DELETE_MSG_HANDLE_STMT1 =
81         "delete from message_handles where messageId=? and consumerId=?";
82     private static final String JavaDoc DELETE_MSG_HANDLE_STMT2 =
83         "delete from message_handles where messageId=? and destinationId=? " +
84         "and consumerId=?";
85
86     /**
87      * Delete all message handles with the specified message id
88      */

89     private static final String JavaDoc DELETE_MSG_HANDLES_STMT =
90         "delete from message_handles where messageId=?";
91
92     /**
93      * Update a row in the message handles table
94      */

95     private static final String JavaDoc UPDATE_MSG_HANDLE_STMT =
96         "update message_handles set delivered=? where messageId=? and " +
97         "destinationId=? and consumerId=?";
98
99     /**
100      * Delete all message handles for a destination
101      */

102     private static final String JavaDoc DELETE_MSG_HANDLES_FOR_DEST =
103         "delete from message_handles where destinationId=?";
104
105     /**
106      * Retrieve all message handles for a particular consumer
107      */

108     private static final String JavaDoc GET_MSG_HANDLES_FOR_DEST =
109         "select messageid, destinationid, consumerid, priority, acceptedtime, "
110         + "sequencenumber, expirytime, delivered from message_handles "
111         + "where consumerId=? order by acceptedTime asc";
112
113     /**
114      * Retrieve a range of message handles between the specified times
115      */

116     private static final String JavaDoc GET_MESSAGE_HANDLES_IN_RANGE =
117         "select distinct messageId from message_handles where " +
118         " acceptedTime >= ? and acceptedTime <=?";
119
120     /**
121      * Retrieve a handle with the specified id
122      */

123     private static final String JavaDoc GET_MESSAGE_HANDLE_WITH_ID =
124         "select distinct messageId from message_handles where messageId=?";
125
126     /**
127      * Return the number of messages and a specified destination and cousmer
128      */

129     private static final String JavaDoc GET_MSG_HANDLE_COUNT_FOR_DEST_AND_CONSUMER =
130         "select count(messageId) from message_handles where destinationId=? " +
131         "and consumerId=?";
132
133     /**
134      * Return the number of messages and a specified consumer
135      */

136     private static final String JavaDoc GET_MSG_HANDLE_COUNT_FOR_CONSUMER =
137         "select count(messageId) from message_handles where consumerId=?";
138
139     /**
140      * Delete all expired messages
141      */

142     private static final String JavaDoc DELETE_EXPIRED_MESSAGES =
143         "delete from message_handles where consumerId=? and expiryTime != 0 " +
144         "and expiryTime<?";
145
146     /**
147      * Singleton to this class
148      */

149     private static MessageHandles _instance;
150
151     /**
152      * Used to ensure that only one thread initialises the class
153      */

154     private static final Object JavaDoc _block = new Object JavaDoc();
155
156     /**
157      * The logger
158      */

159     private static final Log _log = LogFactory.getLog(MessageHandles.class);
160
161
162     /**
163      * Returns the singleton instance.
164      *
165      * Note that initialise() must have been invoked first for this
166      * to return a valid instance.
167      *
168      * @return MessageHandles
169      */

170     public static MessageHandles instance() {
171         return _instance;
172     }
173
174     /**
175      * Constructor
176      */

177     protected MessageHandles() {
178     }
179
180     /**
181      * Initialise the singleton _instance
182      *
183      * @return MessageHandles
184      */

185     public static MessageHandles initialise() {
186         if (_instance == null) {
187             synchronized (_block) {
188                 if (_instance == null) {
189                     _instance = new MessageHandles();
190                 }
191             }
192         }
193
194         return _instance;
195     }
196
197     /**
198      * Add the specified message handle to the database
199      *
200      * @param connection - the connection to use
201      * @param handle - message handle to add
202      * @throws PersistenceException - if add does not complete
203      */

204     public void addMessageHandle(Connection JavaDoc connection,
205                                  MessageHandle handle)
206         throws PersistenceException {
207
208         if (_log.isDebugEnabled()) {
209             _log.debug("addMessageHandle(handle=[consumer="
210                        + handle.getConsumerPersistentId()
211                        + ", destination=" + handle.getDestination()
212                        + ", id=" + handle.getMessageId() + "])");
213         }
214
215         PreparedStatement JavaDoc insert = null;
216         try {
217             // map the destination name to an actual identity
218
long destinationId = Destinations.instance().getId(
219                 handle.getDestination().getName());
220             if (destinationId == 0) {
221                 throw new PersistenceException(
222                     "Cannot add message handle id=" + handle.getMessageId() +
223                     " for destination=" + handle.getDestination().getName() +
224                     " and consumer=" + handle.getConsumerPersistentId() +
225                     " since the destination cannot be mapped to an id");
226             }
227
228             // map the consumer name ot an identity
229
long consumerId = Consumers.instance().getConsumerId(
230                 handle.getConsumerPersistentId());
231             if (consumerId == 0) {
232                 throw new PersistenceException(
233                     "Cannot add message handle id=" + handle.getMessageId() +
234                     " for destination=" + handle.getDestination().getName() +
235                     " and consumer=" + handle.getConsumerPersistentId() +
236                     " since the consumer cannot be mapped to an id");
237             }
238
239             insert = connection.prepareStatement(INSERT_MSG_HANDLE_STMT);
240             insert.setString(1, handle.getMessageId());
241             insert.setLong(2, destinationId);
242             insert.setLong(3, consumerId);
243             insert.setInt(4, handle.getPriority());
244             insert.setLong(5, handle.getAcceptedTime());
245             insert.setLong(6, handle.getSequenceNumber());
246             insert.setLong(7, handle.getExpiryTime());
247             insert.setInt(8, (handle.getDelivered()) ? 1 : 0);
248
249             // execute the insert
250
if (insert.executeUpdate() != 1) {
251                 _log.error(
252                     "Failed to execute addMessageHandle for handle="
253                     + handle.getMessageId() + ", destination Id="
254                     + destinationId);
255             }
256         } catch (SQLException JavaDoc exception) {
257             throw new PersistenceException("Failed to add message handle=" +
258                 handle, exception);
259         } finally {
260             SQLHelper.close(insert);
261         }
262     }
263
264     /**
265      * Remove the specified message handle from the database. Once the handle
266      * has been removed check to see whether there are any more message handles
267      * referencing the same message. If there are not then remove the
268      * corresponding message from the messages tables.
269      *
270      * @param connection - the connection to use
271      * @param handle - the handle to remove
272      * @throws PersistenceException - sql releated exception
273      */

274     public void removeMessageHandle(Connection JavaDoc connection,
275                                     MessageHandle handle)
276         throws PersistenceException {
277
278         if (_log.isDebugEnabled()) {
279             _log.debug("removeMessageHandle(handle=[consumer="
280                        + handle.getConsumerPersistentId()
281                        + ", destination=" + handle.getDestination()
282                        + ", id=" + handle.getMessageId() + "])");
283         }
284
285         PreparedStatement JavaDoc delete = null;
286         PreparedStatement JavaDoc select = null;
287         ResultSet JavaDoc rs = null;
288
289         try {
290             // first check to see that the consumer exists and only
291
// proceed if it non-zero.
292
long consumerId = Consumers.instance().getConsumerId(
293                 handle.getConsumerPersistentId());
294             if (consumerId != 0) {
295                 // get the message id
296
String JavaDoc id = handle.getMessageId();
297
298                 // map the destination name to an actual identity. If it is
299
// null then the destination does not currently exist but we
300
// may need to delete orphaned handles
301
long destinationId = Destinations.instance().getId(
302                     handle.getDestination().getName());
303
304                 if (destinationId == 0) {
305                     delete = connection.prepareStatement(
306                         DELETE_MSG_HANDLE_STMT1);
307                     delete.setString(1, id);
308                     delete.setLong(2, consumerId);
309
310                 } else {
311                     delete = connection.prepareStatement(
312                         DELETE_MSG_HANDLE_STMT2);
313                     delete.setString(1, id);
314                     delete.setLong(2, destinationId);
315                     delete.setLong(3, consumerId);
316                 }
317
318                 // execute the delete
319
if (delete.executeUpdate() != 1 && !handle.hasExpired()) {
320                     // only log if the message hasn't been garbage
321
// collected
322
_log.error("Failed to execute removeMessageHandle for "
323                         + "handle=" + id + " destination id="
324                         + destinationId + " consumer id=" + consumerId);
325                 }
326             }
327         } catch (SQLException JavaDoc exception) {
328             throw new PersistenceException("Failed to remove message handle=" +
329                 handle, exception);
330         } finally {
331             SQLHelper.close(rs);
332             SQLHelper.close(delete);
333             SQLHelper.close(select);
334         }
335     }
336
337     /**
338      * Update the specified message handle from the database
339      *
340      * @param connection - the connection to use
341      * @param handle - the handle to update
342      * @throws PersistenceException - sql releated exception
343      */

344     public void updateMessageHandle(Connection JavaDoc connection,
345                                     MessageHandle handle)
346         throws PersistenceException {
347         PreparedStatement JavaDoc update = null;
348
349         if (_log.isDebugEnabled()) {
350             _log.debug("updateMessageHandle(handle=[consumer="
351                        + handle.getConsumerPersistentId()
352                        + ", destination=" + handle.getDestination()
353                        + ", id=" + handle.getMessageId() + "])");
354         }
355
356         try {
357             // get the message id
358
String JavaDoc id = handle.getMessageId();
359
360             // map the destination name to an actual identity
361
long destinationId = Destinations.instance().getId(
362                 handle.getDestination().getName());
363             if (destinationId == 0) {
364                 throw new PersistenceException(
365                     "Cannot update message handle id=" +
366                     handle.getMessageId() + " for destination=" +
367                     handle.getDestination().getName() + " and consumer=" +
368                     handle.getConsumerPersistentId() +
369                     " since the destination cannot be mapped to an id");
370             }
371
372             // map the consumer name to an identity
373
long consumerId = Consumers.instance().getConsumerId(
374                 handle.getConsumerPersistentId());
375             if (consumerId == 0) {
376                 throw new PersistenceException(
377                     "Cannot update message handle id=" +
378                     handle.getMessageId() + " for destination=" +
379                     handle.getDestination().getName() + " and consumer=" +
380                     handle.getConsumerPersistentId() +
381                     " since the consumer cannot be mapped to an id");
382             }
383
384             update = connection.prepareStatement(UPDATE_MSG_HANDLE_STMT);
385             update.setInt(1, handle.getDelivered() ? 1 : 0);
386             update.setString(2, id);
387             update.setLong(3, destinationId);
388             update.setLong(4, consumerId);
389
390             // execute the delete
391
if (update.executeUpdate() != 1 && !handle.hasExpired()) {
392                 // only log if the message hasn't been garbage collected
393
_log.error(
394                     "Failed to execute updateMessageHandle for handle=" +
395                     id + ", destination id=" + destinationId +
396                     ", consumer id=" + consumerId);
397             }
398         } catch (SQLException JavaDoc exception) {
399             throw new PersistenceException("Failed to update message handle=" +
400                 handle, exception);
401         } finally {
402             SQLHelper.close(update);
403         }
404     }
405
406     /**
407      * Remove all the message handles associated with the specified destination
408      *
409      * @param connection - the connection to use
410      * @param destination the name of the destination
411      * @throws PersistenceException - sql releated exception
412      */

413     public void removeMessageHandles(Connection JavaDoc connection, String JavaDoc destination)
414         throws PersistenceException {
415
416         PreparedStatement JavaDoc delete = null;
417
418         try {
419             // map the destination name to an actual identity
420
long destinationId = Destinations.instance().getId(destination);
421             if (destinationId == 0) {
422                 throw new PersistenceException(
423                     "Cannot remove message handles for destination=" +
424                     destination + " since the destination cannot be " +
425                     "mapped to an id");
426             }
427
428             delete = connection.prepareStatement(DELETE_MSG_HANDLES_FOR_DEST);
429             delete.setLong(1, destinationId);
430             delete.executeUpdate();
431         } catch (SQLException JavaDoc exception) {
432             throw new PersistenceException(
433                 "Failed to remove message handles for destination=" +
434                 destination, exception);
435         } finally {
436             SQLHelper.close(delete);
437         }
438     }
439
440     /**
441      * Remove all the message handles for the specified messageid
442      *
443      * @param connection - the connection to use
444      * @param messageId the message identity
445      * @throws PersistenceException - sql releated exception
446      */

447     public void removeMessageHandles(Connection JavaDoc connection, long messageId)
448         throws PersistenceException {
449
450         PreparedStatement JavaDoc delete = null;
451
452         try {
453             delete = connection.prepareStatement(DELETE_MSG_HANDLES_STMT);
454             delete.setLong(1, messageId);
455             delete.executeUpdate();
456         } catch (SQLException JavaDoc exception) {
457             throw new PersistenceException(
458                 "Failed to remove message handles for message id=" + messageId,
459                 exception);
460         } finally {
461             SQLHelper.close(delete);
462         }
463     }
464
465     /**
466      * Retrieve the message handle for the specified desitation and consumer
467      * name
468      *
469      * @param connection - the connection to use
470      * @param destination - destination name
471      * @param name - consumer name
472      * @return Vector - collection of MessageHandle objects
473      * @throws PersistenceException - sql releated exception
474      */

475     public Vector JavaDoc getMessageHandles(Connection JavaDoc connection, String JavaDoc destination,
476                                     String JavaDoc name)
477         throws PersistenceException {
478
479         Vector JavaDoc result = new Vector JavaDoc();
480         PreparedStatement JavaDoc select = null;
481         ResultSet JavaDoc set = null;
482
483         // if the consumer and/or destination cannot be mapped then
484
// return an empty vector
485
long destinationId = Destinations.instance().getId(destination);
486         long consumerId = Consumers.instance().getConsumerId(name);
487         if ((consumerId == 0) ||
488             (destinationId == 0)) {
489             return result;
490         }
491
492         // all preprequisites have been met so continue processing the
493
// request.
494
try {
495             select = connection.prepareStatement(GET_MSG_HANDLES_FOR_DEST);
496             select.setLong(1, consumerId);
497
498             // iterate through the result set and construct the corresponding
499
// MessageHandles
500
set = select.executeQuery();
501             while (set.next()) {
502                 // Attempt to retrieve the corresponding destination
503
JmsDestination dest = Destinations.instance().get(
504                     set.getLong(2));
505                 if (dest == null) {
506                     throw new PersistenceException(
507                         "Cannot create persistent handle, because " +
508                         "destination mapping failed for " + set.getLong(2));
509                 }
510
511                 String JavaDoc consumer = Consumers.instance().getConsumerName(
512                     set.getLong(3));
513                 if (name == null) {
514                     throw new PersistenceException(
515                         "Cannot create persistent handle because " +
516                         "consumer mapping failed for " + set.getLong(3));
517                 }
518
519                 String JavaDoc messageId = set.getString(1);
520                 int priority = set.getInt(4);
521                 long acceptedTime = set.getLong(5);
522                 long sequenceNumber = set.getLong(6);
523                 long expiryTime = set.getLong(7);
524                 boolean delivered = (set.getInt(8) == 0) ? false : true;
525                 MessageHandle handle = new PersistentMessageHandle(
526                         messageId, priority, acceptedTime, sequenceNumber,
527                         expiryTime, dest, consumer);
528                 handle.setDelivered(delivered);
529                 result.add(handle);
530             }
531         } catch (SQLException JavaDoc exception) {
532             throw new PersistenceException(
533                 "Failed to get message handles for destination=" +
534                 destination + ", consumer=" + name, exception);
535         } finally {
536             SQLHelper.close(set);
537             SQLHelper.close(select);
538         }
539
540         return result;
541     }
542
543     /**
544      * Retrieve a distint list of message ids, in this table, between the min
545      * and max times inclusive.
546      *
547      * @param connection - the connection to use
548      * @param min - the minimum time in milliseconds
549      * @param max - the maximum time in milliseconds
550      * @return Vector - collection of String objects
551      * @throws PersistenceException - sql related exception
552      */

553     public Vector JavaDoc getMessageIds(Connection JavaDoc connection, long min, long max)
554         throws PersistenceException {
555
556         Vector JavaDoc result = new Vector JavaDoc();
557         PreparedStatement JavaDoc select = null;
558         ResultSet JavaDoc set = null;
559
560         try {
561             select = connection.prepareStatement(GET_MESSAGE_HANDLES_IN_RANGE);
562             select.setLong(1, min);
563             select.setLong(2, max);
564
565             // iterate through the result set and construct the corresponding
566
// MessageHandles
567
set = select.executeQuery();
568             while (set.next()) {
569                 result.add(set.getString(1));
570             }
571
572            
573         } catch (SQLException JavaDoc exception) {
574             throw new PersistenceException("Failed to retrieve message ids",
575                 exception);
576         } finally {
577             SQLHelper.close(set);
578             SQLHelper.close(select);
579         }
580
581         return result;
582     }
583
584     /**
585      * Check if a message with the specified messageId exists in the
586      * table
587      *
588      * @param connection - the connection to use
589      * @param messageId the message Identifier
590      * @return Vector - collection of MessageHandle objects
591      * @throws PersistenceException - sql releated exception
592      */

593     public boolean messageExists(Connection JavaDoc connection, long messageId)
594         throws PersistenceException {
595
596         boolean result = false;
597         PreparedStatement JavaDoc select = null;
598         ResultSet JavaDoc set = null;
599
600         try {
601             select = connection.prepareStatement(GET_MESSAGE_HANDLE_WITH_ID);
602             select.setLong(1, messageId);
603             set = select.executeQuery();
604
605             if (set.next()) {
606                 result = true;
607             }
608             
609         } catch (SQLException JavaDoc exception) {
610             throw new PersistenceException(
611                 "Failed to determine if message exists, id=" + messageId,
612                 exception);
613         } finally {
614             SQLHelper.close(set);
615             SQLHelper.close(select);
616         }
617         return result;
618     }
619
620     /**
621      * Returns the number of messages for the specified destination and
622      * consumer
623      *
624      * @param connection - the connection to use
625      * @param destination - destination name
626      * @param name - consumer name
627      * @return Vector - collection of MessageHandle objects
628      * @throws PersistenceException - sql releated exception
629      */

630     public int getMessageCount(Connection JavaDoc connection, String JavaDoc destination,
631                                String JavaDoc name)
632         throws PersistenceException {
633
634         int result = -1;
635         boolean destinationIsWildCard = false;
636
637         // map the destination name to an actual identity
638
long destinationId = Destinations.instance().getId(destination);
639         if (destinationId == 0) {
640             if (JmsTopic.isWildCard(destination)) {
641                 destinationIsWildCard = true;
642             } else {
643                 throw new PersistenceException(
644                     "Cannot get message handle count for destination=" +
645                     destination + " and consumer=" + name +
646                     " since the destination cannot be mapped to an id");
647             }
648         }
649
650         // map the consumer name to an identity
651
long consumerId = Consumers.instance().getConsumerId(name);
652         if (consumerId == 0) {
653             throw new PersistenceException(
654                 "Cannot get message handle count for destination=" +
655                 destination + " and consumer=" + name +
656                 " since the consumer cannot be mapped to an id");
657         }
658
659         PreparedStatement JavaDoc select = null;
660         ResultSet JavaDoc set = null;
661
662         try {
663             if (destinationIsWildCard) {
664                 select = connection.prepareStatement(
665                     GET_MSG_HANDLE_COUNT_FOR_DEST_AND_CONSUMER);
666                 select.setLong(1, destinationId);
667                 select.setLong(2, consumerId);
668             } else {
669                 select = connection.prepareStatement(
670                     GET_MSG_HANDLE_COUNT_FOR_CONSUMER);
671                 select.setLong(1, consumerId);
672             }
673
674             set = select.executeQuery();
675             if (set.next()) {
676                 result = set.getInt(1);
677             }
678         } catch (SQLException JavaDoc exception) {
679             throw new PersistenceException(
680                 "Failed to count messages for destination=" + destination +
681                 ", consumer=" + name, exception);
682         } finally {
683             SQLHelper.close(set);
684             SQLHelper.close(select);
685         }
686
687         return result;
688     }
689
690     /**
691      * Remove all expired handles for the specified consumer
692      *
693      * @param connection - the connection to use
694      * @param consumer - consumer name
695      * @throws PersistenceException - sql releated exception
696      */

697     public void removeExpiredMessageHandles(Connection JavaDoc connection,
698                                             String JavaDoc consumer)
699         throws PersistenceException {
700
701         PreparedStatement JavaDoc delete = null;
702
703         // map the consumer name ot an identity
704
long consumerId = Consumers.instance().getConsumerId(consumer);
705         if (consumerId != 0) {
706             try {
707                 delete = connection.prepareStatement(DELETE_EXPIRED_MESSAGES);
708                 delete.setLong(1, consumerId);
709                 delete.setLong(2, System.currentTimeMillis());
710                 delete.executeUpdate();
711             } catch (SQLException JavaDoc exception) {
712                 throw new PersistenceException(
713                     "Failed to remove expired message handles",
714                     exception);
715             } finally {
716                 SQLHelper.close(delete);
717             }
718         }
719     }
720
721     /**
722      * Deallocates resources owned or referenced by the instance
723      */

724     public void close() {
725         _instance = null;
726     }
727
728 }
729
Popular Tags