KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > messagemgr > DefaultMessageCache


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: DefaultMessageCache.java,v 1.1 2005/03/18 03:58:39 tanderson Exp $
44  *
45  * Date Author Changes
46  * 3/1/2001 jima Created
47  */

48 package org.exolab.jms.messagemgr;
49
50 import java.sql.Connection JavaDoc;
51 import java.util.Collections JavaDoc;
52 import java.util.HashMap JavaDoc;
53 import java.util.Map JavaDoc;
54 import javax.jms.JMSException JavaDoc;
55
56 import org.apache.commons.logging.Log;
57 import org.apache.commons.logging.LogFactory;
58
59 import org.exolab.jms.message.MessageImpl;
60 import org.exolab.jms.persistence.DatabaseService;
61 import org.exolab.jms.persistence.PersistenceAdapter;
62 import org.exolab.jms.persistence.SQLHelper;
63
64
65 /**
66  * Default implementation of the {@link MessageCache} interface.
67  *
68  * @author <a HREF="mailto:jima@comware.com.au">Jim Alateras</a>
69  * @author <a HREF="mailto:tma@netspace.net.au">Tim Anderson</a>
70  * @version $Revision: 1.1 $ $Date: 2005/03/18 03:58:39 $
71  */

72 final class DefaultMessageCache implements MessageCache {
73
74     /**
75      * Maintains the pool of transient messages.
76      */

77     private final Map JavaDoc _transient = Collections.synchronizedMap(
78             new HashMap JavaDoc(1023));
79
80     /**
81      * Maintains the pool of persistent messages.
82      */

83     private final Map JavaDoc _persistent = Collections.synchronizedMap(
84             new HashMap JavaDoc(1023));
85
86     /**
87      * Maintains the references to messages.
88      */

89     private final Map JavaDoc _references = Collections.synchronizedMap(
90             new HashMap JavaDoc(1023));
91
92     /**
93      * The logger.
94      */

95     private static final Log _log = LogFactory.getLog(
96             DefaultMessageCache.class);
97
98
99     /**
100      * Add a reference and its corresponding message to the cache.
101      *
102      * @param reference the reference to the message
103      * @param message the message
104      */

105     public void addMessage(MessageRef reference, MessageImpl message) {
106         String JavaDoc messageId = reference.getMessageId();
107         if (reference.isPersistent()) {
108             _persistent.put(messageId, message);
109         } else {
110             _transient.put(messageId, message);
111         }
112         addMessageRef(messageId, reference);
113     }
114
115     /**
116      * Adds a message reference to the cache.
117      *
118      * @param reference the message reference to add
119      */

120     public void addMessageRef(MessageRef reference) {
121         addMessageRef(reference.getMessageId(), reference);
122     }
123
124     /**
125      * Returns a message reference, given its identifier.
126      *
127      * @param messageId the message identifier
128      * @return the message reference associated with <code>messageId</code>, or
129      * <code>null</code> if none exists
130      */

131     public MessageRef getMessageRef(String JavaDoc messageId) {
132         return (MessageRef) _references.get(messageId);
133     }
134
135     /**
136      * Returns the message corresponding to the specified reference.
137      *
138      * @param reference the message reference
139      * @return the associated message, or <code>null</code> if none exists
140      * @throws JMSException for any error
141      */

142     public MessageImpl getMessage(MessageRef reference) throws JMSException JavaDoc {
143         MessageImpl message = null;
144         final String JavaDoc messageId = reference.getMessageId();
145
146         if (reference.isPersistent()) {
147             message = (MessageImpl) _persistent.get(messageId);
148
149             // if the message is not cached then try and retrieve it from the
150
// database and cache it.
151
if (message == null) {
152                 // fault in at least the next message from the database
153
PersistenceAdapter adapter = DatabaseService.getAdapter();
154                 Connection JavaDoc connection = null;
155                 try {
156                     connection = DatabaseService.getConnection();
157                     message = adapter.getMessage(connection, messageId);
158                     connection.commit();
159                 } catch (Exception JavaDoc exception) {
160                     SQLHelper.rollback(connection);
161                     _log.error("Failed to retrieve message", exception);
162                     throw new JMSException JavaDoc("Failed to retrieve message: "
163                                            + exception.getMessage());
164                 } finally {
165                     SQLHelper.close(connection);
166                 }
167
168                 // add the message to the persistent cache once it has been
169
// retrieved from the datastore
170
if (message != null) {
171                     _persistent.put(messageId, message);
172                 }
173             }
174         } else {
175             message = (MessageImpl) _transient.get(messageId);
176         }
177
178         if (message != null && !message.getReadOnly()) {
179             // mark the message as read-only
180
message.setReadOnly(true);
181         }
182
183         return message;
184     }
185
186     /**
187      * Destroys the message corresponding to the reference.
188      *
189      * @throws JMSException for any error
190      */

191     public void destroy(MessageRef reference) throws JMSException JavaDoc {
192         if (reference.isPersistent()) {
193             Connection JavaDoc connection = null;
194             try {
195                 connection = DatabaseService.getConnection();
196                 destroy(reference, connection);
197                 connection.commit();
198             } catch (JMSException JavaDoc exception) {
199                 SQLHelper.rollback(connection);
200                 throw exception;
201             } catch (Exception JavaDoc exception) {
202                 SQLHelper.rollback(connection);
203                 _log.error("Failed to remove message", exception);
204                 throw new JMSException JavaDoc("Failed to remove message: "
205                                        + exception.getMessage());
206             } finally {
207                 SQLHelper.close(connection);
208             }
209         } else {
210             final String JavaDoc messageId = reference.getMessageId();
211             _transient.remove(messageId);
212             _references.remove(messageId);
213         }
214     }
215
216     /**
217      * Destroys the message corresponding to the reference.
218      *
219      * @param connection the database connection to use
220      * @throws JMSException for any error
221      */

222     public void destroy(MessageRef reference, Connection JavaDoc connection)
223             throws JMSException JavaDoc {
224         final String JavaDoc messageId = reference.getMessageId();
225
226         if (reference.isPersistent()) {
227             try {
228                 PersistenceAdapter adapter = DatabaseService.getAdapter();
229                 adapter.removeMessage(connection, messageId);
230             } catch (Exception JavaDoc exception) {
231                 _log.error("Failed to remove message", exception);
232                 throw new JMSException JavaDoc("Failed to remove message: "
233                                        + exception.getMessage());
234             }
235             _persistent.remove(messageId);
236         } else {
237             _transient.remove(messageId);
238         }
239         _references.remove(messageId);
240     }
241
242     /**
243      * Clear the persistent and non-persistent message cache.
244      */

245     public void clear() {
246         _transient.clear();
247         _persistent.clear();
248         _references.clear();
249     }
250
251     /**
252      * Clear only the persistent messages in the cache.
253      */

254     public void clearPersistentMessages() {
255         _persistent.clear();
256     }
257
258     /**
259      * Clear only the transient messages in the cache.
260      */

261     public void clearTransientMessages() {
262         _transient.clear();
263     }
264
265     /**
266      * Return the number of messages in the transient cache.
267      *
268      * @return the number of messages in the transient cache
269      */

270     public int getTransientCount() {
271         return _transient.size();
272     }
273
274     /**
275      * Return the number of messages in the persistent cache.
276      *
277      * @return the number of messages in the persistent cache
278      */

279     public int getPersistentCount() {
280         return _persistent.size();
281     }
282
283     /**
284      * Return the number of message references in the cache.
285      *
286      * @return the number of message references in the cache
287      */

288     public int getMessageCount() {
289         return _references.size();
290     }
291
292     /**
293      * Add a message reference to the cache.
294      *
295      * @param messageId the message identifier
296      * @param reference the message reference
297      */

298     private void addMessageRef(String JavaDoc messageId, MessageRef reference) {
299         _references.put(messageId, reference);
300     }
301
302 }
303
304
Popular Tags