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-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: RmiJmsServerSession.java,v 1.30 2003/08/07 13:33:10 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * 04/07/2000   jima    Created
47   */
48  package org.exolab.jms.server.rmi;
49  
50  import java.rmi.RemoteException;
51  import java.rmi.server.UnicastRemoteObject;
52  import java.util.Vector;
53  
54  import javax.jms.JMSException;
55  import javax.jms.Message;
56  import javax.transaction.xa.XAException;
57  import javax.transaction.xa.XAResource;
58  import javax.transaction.xa.Xid;
59  
60  import org.exolab.jms.client.JmsMessageListener;
61  import org.exolab.jms.client.JmsQueue;
62  import org.exolab.jms.client.JmsTopic;
63  import org.exolab.jms.client.rmi.RemoteJmsMessageListenerIfc;
64  import org.exolab.jms.server.ClientDisconnectionException;
65  import org.exolab.jms.server.JmsServerSession;
66  
67  
68  /***
69   * This is an implementation of the RemoteJmsServerSessionIfc which delegates
70   * all requests to the JmsServerSession class. Actually, an instsnce of this
71   * class cannot be created without a JmsServerSession object.
72   *
73   * @version     $Revision: 1.30 $ $Date: 2003/08/07 13:33:10 $
74   * @author      <a href="mailto:jima@exoffice.com">Jim Alateras</a>
75   * @see         org.exolab.jms.server.JmsServerSession
76   * @see         org.exolab.jms.server.rmi.RemoteJmsServerConnectionIfc
77   **/
78  public class RmiJmsServerSession
79      extends UnicastRemoteObject
80      implements RemoteJmsServerSessionIfc, JmsMessageListener {
81  
82      /***
83       * This instance attribute maintains a reference to the delegate. The
84       * delegate must be assigned during object construction
85       */
86      private JmsServerSession _delegate = null;
87  
88      /***
89       * This is the message listener to the remote object. This is how all the
90       * messages are pushed down to the client
91       */
92      private RemoteJmsMessageListenerIfc _listener = null;
93  
94  
95      /***
96       * Instantiate an instance of this class given a JmsServerSession.
97       * object. If the session object is null then throw the JMSException
98       * exception
99       *
100      * @param       session
101      * @exception   JMSException
102      * @exception   RemoteException
103      */
104     public RmiJmsServerSession(JmsServerSession session)
105         throws JMSException, RemoteException {
106         if (session != null) {
107             _delegate = session;
108         } else {
109             throw new JMSException(
110                 "Cannot create RmiJmsServerSession with null session");
111         }
112     }
113 
114     /***
115      * Return a reference to the client id.
116      *
117      * @return      String      client id
118      * @exception   RemoteException
119      */
120     public synchronized String getClientId()
121         throws RemoteException {
122         return _delegate.getClientId();
123     }
124 
125     /***
126      * Return a reference to the session id
127      *
128      * @return      String      session id
129      * @exception   RemoteException
130      */
131     public synchronized String getSessionId()
132         throws JMSException, RemoteException {
133         return _delegate.getSessionId();
134     }
135 
136     /***
137      * Close and release any resource allocated to this session. Throw the
138      * JMSException exception is a problem is encountered
139      *
140      * @exception   JMSException
141      * @exception   RemoteException
142      */
143     public synchronized void close()
144         throws JMSException, RemoteException {
145         _listener = null;
146         _delegate.close();
147         _delegate = null;
148     }
149 
150     /***
151      * Acknowledge that the message id for the specified client identity. If
152      * the acknowledgement faisl then throw JMSException
153      *
154      * @param       clientId            the client identity.
155      * @param       messageId           identity of the message
156      * @exception   JMSException        if method does not complete
157      * @exception   RemoteException
158      */
159     public synchronized void acknowledgeMessage(long clientId, String messageId)
160         throws JMSException, RemoteException {
161         _delegate.acknowledgeMessage(clientId, messageId);
162     }
163 
164     /***
165      * Send the specified message to the server. If there is any problem
166      * then throw the JMSException exception
167      *
168      * @param       message             message to send
169      * @exception   JMSException
170      * @exception   RemoteException
171      */
172     public synchronized void sendMessage(Message message)
173         throws JMSException, RemoteException {
174         _delegate.sendMessage(message);
175     }
176 
177     /***
178      * Send the specified messages to the server. If there is any problem
179      * then throw the JMSException exception
180      *
181      * @param       messages            messages to send
182      * @exception   JMSException
183      * @exception   RemoteException
184      */
185     public synchronized void sendMessages(Vector messages)
186         throws JMSException, RemoteException {
187         _delegate.sendMessages(messages);
188     }
189 
190     /***
191      * Return the next message for the specified client. The <code>wait</code>
192      * parameter indicates how long many milliseconds to wait for a message
193      * before returning. If <code>wait</code> is 0 then do not wait at all. If
194      * <code>wait</code> is -1 then wait indefinitely for the next message
195      *
196      * @param       clientId            the client identity
197      * @param       wait                number of ms to wait
198      * @return      Message             the next message or null
199      * @exception   JMSException        if there is an app level problem
200      * @exception   RemoteException     if there is a RMI based exception.
201      */
202     public Message receiveMessage(long clientId, long wait)
203         throws JMSException, RemoteException {
204         return _delegate.receiveMessage(clientId, wait);
205     }
206 
207     // implementation of RemoteJmsServerSessionIfc.receiveMessages
208     public Vector receiveMessages(long clientId, int count)
209         throws JMSException, RemoteException {
210         return _delegate.receiveMessages(clientId, count);
211     }
212 
213     /***
214      * Create a queue with the specified name. If the queue already exists
215      * then simply return a reference to it. If the queue does not exist
216      * then create it. If it cannot create the queue then throw the
217      * JMSException exception
218      *
219      * @param       queue               queue to create
220      * @exception   JMSException
221      * @exception   RemoteException
222      */
223     public synchronized void createQueue(JmsQueue queue)
224         throws JMSException, RemoteException {
225         _delegate.createQueue(queue);
226     }
227 
228     /***
229      * Create a topic with the specified name. If the topic already exists
230      * then simply return a reference to it. If the topic does not exist
231      * then create it. If it cannot create the topic then throw the
232      * JMSException exception
233      *
234      * @param       topic               topic to create
235      * @exception   JMSException
236      * @exception   RemoteException
237      */
238     public synchronized void createTopic(JmsTopic topic)
239         throws JMSException, RemoteException {
240         _delegate.createTopic(topic);
241     }
242 
243     /***
244      * Create a receiver endpoint for this session. A reciever is a message
245      * consumer specific to the queue message model. The receiver is
246      * associated with a queue.
247      * <p>
248      * You cannot create more than one receiver for the same destination
249      *
250      * @param       queue               receiver destination
251      * @param       clientId            the session allocated identifier of
252      *                                  this consumer
253      * @param       selector            the selector to filter messages.
254      *                                  This may be null.
255      * @exception   JMSException.
256      * @exception   RemoteException
257      */
258     public synchronized void createReceiver(JmsQueue queue, long clientId, String selector)
259         throws JMSException, RemoteException {
260         _delegate.createReceiver(queue, clientId, selector);
261     }
262 
263     /***
264      * Create a sender endpoint for this session. A sender is a message
265      * publisher specific to the queue message model. The sender is associated
266      * with a queue.
267      * <p>
268      * You cannot create more than one receiver for the same destination
269      *
270      * @param       queue               receiver destination
271      * @exception   JMSException.
272      * @exception   RemoteException
273      */
274     public synchronized void createSender(JmsQueue queue)
275         throws JMSException, RemoteException {
276         _delegate.createSender(queue);
277     }
278 
279     /***
280      * Create a queue browser for this session. This allows clients to browse
281      * a queue without removing any messages.
282      * <p>
283      *
284      * You cannot create more than one queue browser for the same queue
285      * in a single session.
286      *
287      * @param       queue               queue to browse
288      * @param       clientId            the client identity
289      * @param       selector            message selector. This may be null
290      * @exception   JMSException
291      */
292     public synchronized void createBrowser(JmsQueue queue, long clientId, String selector)
293         throws JMSException {
294         _delegate.createBrowser(queue, clientId, selector);
295     }
296 
297     /***
298      * Delete the receiver for the specified queue. If the receiver does
299      * not exist or cannot be deleted throw JMSException
300      *
301      * @param       id                  identity of receiver
302      * @exception   JMSException.
303      * @exception   RemoteException
304      */
305     public synchronized void deleteReceiver(long clientId)
306         throws JMSException, RemoteException {
307         _delegate.deleteReceiver(clientId);
308     }
309 
310     /***
311      * Delete the sender for the specified queue. If the sender does not
312      * exist or the sender cannot be deleted then throw JMSException
313      *
314      * @param       clientId            identity of client to delete
315      * @exception   JMSException.
316      * @exception   RemoteException
317      */
318     public synchronized void deleteSender(long clientId)
319         throws JMSException, RemoteException {
320         _delegate.deleteSender(clientId);
321     }
322 
323     /***
324      * Delete the queue browser associated with the specified queue from
325      * the session.
326      * If the corresponding queue does not exist or it cannot be deleted,
327      * then throw a JMSException.
328      *
329      * @param       clientId            the identity of the client
330      * @exception   JMSException
331      */
332     public synchronized void deleteBrowser(long clientId)
333         throws JMSException {
334         _delegate.deleteBrowser(clientId);
335     }
336 
337     /***
338      * Create a subscriber endpoint for this session. A subscriber is a message
339      * consumer specific to the topic message model. The subscriber is
340      * associated with a topic. The consumer name must be specfied for
341      * persistent delivery but can be null otherwise
342      * <p>
343      * You cannot create more than one subscriber for the same destination
344      *
345      * @param       topic               subscriber destination
346      * @param       name                name of the cnsumer; can be null
347      * @param       clientId            the session allocated identifier of
348      *                                  this consumer
349      * @param       selector            the selector to filter messages.
350      *                                  This may be null.
351      * @param       noLocal             inhibit consuming messages on same
352      *                                  connection.
353      * @return                          the unique consumer identifier
354      * @exception   JMSException
355      * @exception   RemoteException
356      */
357     public synchronized void createSubscriber(JmsTopic topic, String name, long clientId,
358                                               String selector, boolean noLocal)
359         throws JMSException, RemoteException {
360         _delegate.createSubscriber(topic, name, clientId, selector, noLocal);
361     }
362 
363     /***
364      * Create a publisher endpoint for this session. A publisher is a message
365      * publisher specific to the topic message model. The publisher is
366      * associated with a topic.
367      * <p>
368      * You cannot create more than one publisher for the same destination
369      *
370      * @param       topic               receiver destination
371      * @exception   JMSException.
372      * @exception   RemoteException
373      */
374     public synchronized void createPublisher(JmsTopic topic)
375         throws JMSException, RemoteException {
376         _delegate.createPublisher(topic);
377     }
378 
379     /***
380      * Delete the subscriber for the specified topic. If this subscriber
381      * does not exist or the cannot be deleted then throw JMSException.
382      *
383      * @param       clientId            the identity of the client
384      * @exception   JMSException.
385      */
386     public synchronized void deleteSubscriber(long clientId)
387         throws JMSException, RemoteException {
388         _delegate.deleteSubscriber(clientId);
389     }
390 
391     /***
392      * Delete the publisher for the specified topic. If the publisher does
393      * not exist or cannot be deleted then throw JMSException
394      *
395      * @param       topic               topic object
396      * @exception   JMSException.
397      * @exception   RemoteException.
398      */
399     public synchronized void deletePublisher(JmsTopic topic)
400         throws JMSException, RemoteException {
401         _delegate.deletePublisher(topic);
402     }
403 
404     /***
405      * Unsubscribe a durable subscription
406      *
407      * @param       name                the name used to identify the
408      *                                  subscription
409      * @exception   JMSException        if the subscription cannot be removed
410      */
411     public synchronized void unsubscribe(String name)
412         throws JMSException {
413         _delegate.unsubscribe(name);
414     }
415 
416     /***
417      * Stop message delivery to this session. If there are any problems
418      * completing the request then throw the JMSException exception
419      *
420      * @exception   JMSException
421      * @exception   RemoteException.
422      */
423     public synchronized void stopMessageDelivery()
424         throws JMSException, RemoteException {
425         _delegate.stopMessageDelivery();
426     }
427 
428     /***
429      * Start message delivery to this session. If there are any problems
430      * completing this request then throw the JMSException exception
431      *
432      * @exception   JMSException
433      * @exception   RemoteException.
434      */
435     public synchronized void startMessageDelivery()
436         throws JMSException, RemoteException {
437         _delegate.startMessageDelivery();
438     }
439 
440     /***
441      * Recover the session
442      *
443      * @exception   JMSException
444      * @exception   RemoteException.
445      */
446     public synchronized void recover()
447         throws JMSException, RemoteException {
448         _delegate.recover();
449     }
450 
451     /***
452      * Commit the session
453      *
454      * @exception   JMSException
455      * @exception   RemoteException.
456      */
457     public synchronized void commit()
458         throws JMSException, RemoteException {
459         _delegate.commit();
460     }
461 
462     /***
463      * Rollback the session
464      *
465      * @exception   JMSException
466      * @exception   RemoteException.
467      */
468     public synchronized void rollback()
469         throws JMSException, RemoteException {
470         _delegate.rollback();
471     }
472 
473     // implementation of RmiJmsServerSessionIfc.commit
474     public void commit(Xid xid, boolean onePhase)
475         throws XAException, RemoteException {
476         _delegate.commit(xid, onePhase);
477     }
478 
479     // implementation of RmiJmsServerSessionIfc.end
480     public void end(Xid xid, int flags)
481         throws XAException, RemoteException {
482         _delegate.end(xid, flags);
483     }
484 
485     // implementation of RmiJmsServerSessionIfc.forget
486     public void forget(Xid xid)
487         throws XAException, RemoteException {
488         _delegate.forget(xid);
489     }
490 
491     // implementation of RmiJmsServerSessionIfc.getTransactionTimeout
492     public int getTransactionTimeout()
493         throws XAException, RemoteException {
494         return _delegate.getTransactionTimeout();
495     }
496 
497     // implementation of RmiJmsServerSessionIfc.prepare
498     public int prepare(Xid xid)
499         throws XAException, RemoteException {
500         return _delegate.prepare(xid);
501     }
502 
503     // implementation of RmiJmsServerSessionIfc.recover
504     public Xid[] recover(int flag)
505         throws XAException, RemoteException {
506         return _delegate.recover(flag);
507     }
508 
509     // implementation of RmiJmsServerSessionIfc.rollback
510     public void rollback(Xid xid)
511         throws XAException, RemoteException {
512         _delegate.rollback(xid);
513     }
514 
515     // implementation of RmiJmsServerSessionIfc.setTransactionTimeout
516     public boolean setTransactionTimeout(int seconds)
517         throws XAException, RemoteException {
518         return _delegate.setTransactionTimeout(seconds);
519     }
520 
521     // implementation of RmiJmsServerSessionIfc.start
522     public void start(Xid xid, int flags)
523         throws XAException, RemoteException {
524         _delegate.start(xid, flags);
525     }
526 
527     // implementation of RmiJmsServerSessionIfc.getResourceManageRId
528     public String getResourceManagerId() throws XAException, RemoteException {
529         return _delegate.getResourceManagerId();
530     }
531 
532     /***
533      * All server side sessions register with the consumer manager for
534      * message consumption (i.e push-model). When a message arrives this
535      * server-side instance will send it down to the client side stub for
536      * further processing.
537      * <p>
538      * If the listener is null then throw JMSException
539      *
540      * @param       listener            listener to delivery messages too.
541      * @exception   JMSException
542      * @exception   RemoteException.
543      */
544     public synchronized void setMessageListener(RemoteJmsMessageListenerIfc listener)
545         throws JMSException, RemoteException {
546         _listener = listener;
547         _delegate.setMessageListener(this);
548     }
549 
550     /***
551      * Enable or disable asynchronous message delivery for a particular
552      * consumer
553      *
554      * @param clientId - the id of the client to check
555      * @param id - the last message asynchronously delivered to consumer
556      * @param enable - true to enable; false to disable
557      */
558     public void enableAsynchronousDelivery(long clientId, String id,
559                                            boolean enable)
560         throws JMSException, RemoteException {
561         _delegate.enableAsynchronousDelivery(clientId, id, enable);
562     }
563 
564     // implementation of MessageListener.onMessage
565     // throws unchecked exception ClientDisconnectionException
566     public void onMessage(Message message) {
567         if (_listener != null) {
568             try {
569                 _listener.onMessage(message);
570             } catch (RemoteException exception) {
571                 // rethrow
572                 throw new ClientDisconnectionException("Failed in onMessage " +
573                     exception);
574             }
575         } else {
576             // throw a ClientDisconnectException
577             throw new ClientDisconnectionException(
578                 "No listener registered for this session");
579         }
580     }
581 
582     // implementation of MessageListener.onMessage
583     // throws unchecked exception ClientDisconnectionException
584     public void onMessages(Vector messages) {
585         if (_listener != null) {
586             try {
587                 _listener.onMessages(messages);
588             } catch (RemoteException exception) {
589                 exception.printStackTrace();
590                 // rethrow
591                 throw new ClientDisconnectionException("Failed in onMessages " +
592                     exception);
593             }
594         } else {
595             // throw a ClientDisconnectException
596             throw new ClientDisconnectionException(
597                 "No listener registered for this session");
598         }
599     }
600 
601     // implementation of MessageListener.onMessage
602     // throws unchecked exception ClientDisconnectionException
603     public void onMessageAvailable(long clientId) {
604         if (_listener != null) {
605             try {
606                 _listener.onMessageAvailable(clientId);
607             } catch (RemoteException exception) {
608                 // rethrow
609                 throw new ClientDisconnectionException("Failed in onMessageAvailable " +
610                     exception);
611             }
612         } else {
613             // throw a ClientDisconnectException
614             throw new ClientDisconnectionException(
615                 "No listener registered for this session");
616         }
617     }
618 }