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: JmsQueueBrowser.java,v 1.15 2004/01/20 14:14:21 tanderson Exp $
44   */
45  package org.exolab.jms.client;
46  
47  import java.util.Enumeration;
48  import java.util.LinkedList;
49  import java.util.Vector;
50  
51  import javax.jms.InvalidDestinationException;
52  import javax.jms.JMSException;
53  import javax.jms.Message;
54  import javax.jms.Queue;
55  import javax.jms.QueueBrowser;
56  
57  import org.apache.commons.logging.Log;
58  import org.apache.commons.logging.LogFactory;
59  
60  
61  /***
62   * Client implementation of the <code>javax.jms.QueueBrowser</code> interface
63   *
64   * @version     $Revision: 1.15 $ $Date: 2004/01/20 14:14:21 $
65   * @author      <a href="mailto:jima@comware.com.au">Jim Alateras</a>
66   * @author      <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
67   */
68  class JmsQueueBrowser
69      extends JmsMessageConsumer
70      implements QueueBrowser, Enumeration {
71  
72      /***
73       * The queue to browse
74       */
75      private JmsQueue _queue = null;
76  
77      /***
78       * Caches a collection of messages, which are used during enumeration
79       */
80      private LinkedList _messages = new LinkedList();
81  
82      /***
83       * The logger
84       */
85      private static final Log _log = LogFactory.getLog(JmsQueueBrowser.class);
86  
87  
88      /***
89       * Construct a new <code>QueueBrowser</code>
90       *
91       * @param session the session that created this instance
92       * @param clientId the session allocated client identity
93       * @param queue the queue to browse
94       * @param selector the message selector. May be <code>null</code>
95       * @throws InvalidDestinationException if <code>queue</code> is null
96       */
97      public JmsQueueBrowser(JmsQueueSession session, long clientId,
98                             JmsQueue queue, String selector)
99          throws InvalidDestinationException {
100         super(session, clientId, selector);
101 
102         if (queue == null) {
103             throw new InvalidDestinationException("Argument 'queue' is null");
104         }
105         _queue = queue;
106     }
107 
108     /***
109      * Returns the queue associated with this browser
110      *
111      * @return the queue associated with this browser
112      */
113     public Queue getQueue() {
114         return _queue;
115     }
116 
117     /***
118      * Returns an enumeration for browsing the current queue messages in the
119      * order they would be received
120      *
121      * @return an enumeration for browsing the messages
122      */
123     public Enumeration getEnumeration() {
124         return this;
125     }
126 
127     /***
128      * Close this browser
129      *
130      * @throws JMSException if the browser can't be closed
131      */
132     public void close() throws JMSException {
133         if (!isClosed()) {
134             // unregister this browser from the session before closing, and
135             // then call the base class method.
136             JmsQueueSession session = (JmsQueueSession) getSession();
137             session.removeBrowser(this);
138             _queue = null;
139 
140             _messages.clear();
141             _messages = null;
142 
143             super.close();
144         }
145     }
146 
147     /***
148      * Releases all resources used by this browser
149      *
150      * @throws JMSException if this browser can't be destroyed
151      */
152     public synchronized void destroy() throws JMSException {
153         _queue = null;
154         _messages.clear();
155         _messages = null;
156         super.destroy();
157     }
158 
159     /***
160      * Handle asynchronous messages. It is invalid to call this method -
161      * doing so results in a <code>RuntimeException</code>
162      *
163      * @param message the message received
164      */
165     public void onMessage(Message message) {
166         throw new RuntimeException(
167             "JmsQueueBrowsder.onMessage() has been called");
168     }
169 
170     /***
171      * Determines if there are more messages to browse
172      *
173      * @return <code>true</code> if there are more messages to browse
174      */
175     public boolean hasMoreElements() {
176         return !isEmpty();
177     }
178 
179     /***
180      * Returns the next message
181      *
182      * @return the next message
183      */
184     public synchronized Object nextElement() {
185         if (!isEmpty()) {
186             return _messages.removeFirst();
187         }
188 
189         return null;
190     }
191 
192     /***
193      * If there are no more messages on the server, bring across another
194      * batch of them. If there are no more then return false.
195      * <p>
196      * Return a max of 20 at a time..although we should make it configurable
197      *
198      * @return <code>true</code> is empty; <code>false</code> oherwise
199      */
200     private boolean isEmpty() {
201         final int count = 20;
202         // check that the local cache is not empty first
203         if (!_messages.isEmpty()) {
204             return false;
205         }
206 
207         // now try and retrieve a batch of messages from the server. If there
208         // are no messages in place then return true otherwise retrieve the
209         // messages, place them in the local cache and return not empty.
210         Vector messages = null;
211         try {
212             messages = getSession().retrieveMessages(getClientId(), count);
213         } catch (JMSException exception) {
214             _log.error("Error in JmsQueueBrowser.isEmpty", exception);
215         }
216 
217         if (messages != null && messages.size() > 0) {
218             while (messages.size() > 0) {
219                 _messages.addLast(messages.remove(0));
220             }
221         }
222 
223         return _messages.isEmpty();
224     }
225 
226 }