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: HttpJmsSessionSender.java,v 1.11 2003/08/30 08:00:54 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * $Date	    jimm    Created
47   */
48  
49  
50  package org.exolab.jms.server.http;
51  
52  import java.util.Vector;
53  
54  import javax.jms.Message;
55  
56  import org.apache.commons.logging.Log;
57  import org.apache.commons.logging.LogFactory;
58  
59  import org.exolab.core.http.HttpClient;
60  import org.exolab.jms.client.JmsMessageListener;
61  import org.exolab.jms.message.MessageImpl;
62  import org.exolab.jms.server.ClientDisconnectionException;
63  import org.exolab.jms.server.JmsServerSession;
64  
65  
66  /***
67   * This class contains the http connection to a receiver or subscriber
68   * for passing messages.
69   *
70   * @version     $Revision: 1.11 $ $Date: 2003/08/30 08:00:54 $
71   * @author      <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
72   * @see         org.exolab.jms.server.JmsServerSession
73   * @see         org.exolab.core.http.HttpClient
74   */
75  public class HttpJmsSessionSender implements JmsMessageListener {
76  
77      /***
78       * The session connection
79       */
80      private HttpJmsSessionConnection _connection;
81  
82      /***
83       * The connection to the client servlet
84       */
85      private HttpClient _client;
86  
87      /***
88       * The session instance
89       */
90      private JmsServerSession _session;
91  
92      /***
93       * The host the client session runs on
94       */
95      private String _host;
96  
97      /***
98       * The port the client session is listening on
99       */
100     private String _port;
101 
102     /***
103      * Pinger used to ping subscribers and detect disconnections
104      */
105     private HttpJmsSessionPinger _pinger;
106 
107     /***
108      * The logger
109      */
110     private static final Log _log = LogFactory.getLog(
111         HttpJmsSessionSender.class);
112 
113 
114     /***
115      * Create a connection to the client listener for sending JmsMessages.
116      *
117      * @param connection the session connection
118      * @param client the connection to the client.
119      * @param session the session this connection belongs to
120      * @param host the host the client session runs on
121      * @param port the port the client session is listening on
122      */
123     public HttpJmsSessionSender(HttpJmsSessionConnection connection,
124                                 HttpClient client, JmsServerSession session,
125                                 String host, String port) {
126         _connection = connection;
127         _client = client;
128         _session = session;
129         _host = host;
130         _port = port;
131         session.setMessageListener(this);
132         _pinger = new HttpJmsSessionPinger(this);
133         new Thread(_pinger).start();
134     }
135 
136     /***
137      * Send a message to a listener.
138      *
139      * @param message The message to send.
140      */
141     public void onMessage(Message message) {
142         try {
143             if (_client != null) {
144                 Vector v = new Vector(2);
145                 v.add(_session.getSessionId());
146                 v.add((MessageImpl) message);
147                 _pinger.reset();
148                 synchronized (_client) {
149                     _client.send(v, _host, _port);
150                     Vector reply = (Vector) _client.receive();
151                 }
152             }
153         } catch (Exception err) {
154             _log.debug("Failed to send message to client", err);
155             throw new ClientDisconnectionException(err.getMessage());
156         }
157     }
158 
159     /***
160      * Send the collection of messages to the client. This is used for async
161      * message delivery.
162      *
163      * @param messages - collection of MessageImpl objects
164      */
165     public void onMessages(Vector messages) {
166         try {
167             if (_client != null) {
168                 Vector v = new Vector(2);
169                 v.add(_session.getSessionId());
170                 v.add(messages);
171                 _pinger.reset();
172                 synchronized (_client) {
173                     _client.send(v, _host, _port);
174                     Vector reply = (Vector) _client.receive();
175                 }
176             }
177         } catch (Exception err) {
178             _log.debug("Failed to send messages to client", err);
179             throw new ClientDisconnectionException(err.getMessage());
180         }
181     }
182 
183     /***
184      * Notify the specified client that a message avaiable.
185      *
186      * @param clinet - the client identity
187      */
188     public void onMessageAvailable(long clientId) {
189         try {
190             if (_client != null) {
191                 Vector v = new Vector(2);
192                 v.add(_session.getSessionId());
193                 v.add(new Long(clientId));
194                 _pinger.reset();
195                 _client.send(v, _host, _port);
196                 Vector reply = (Vector) _client.receive();
197             }
198         } catch (Exception err) {
199             _log.debug("Failed to notify client", err);
200             throw new ClientDisconnectionException(err.getMessage());
201         }
202     }
203 
204     /***
205      * Ping the client to see if its still active.
206      */
207     protected void ping() {
208         try {
209             if (_client != null) {
210                 Vector v = new Vector(1);
211                 v.add(_session.getSessionId());
212                 synchronized (_client) {
213                     _client.send(v, _host, _port);
214                     Vector reply = (Vector) _client.receive();
215                 }
216             }
217         } catch (Exception err) {
218             _log.debug("Failed to ping client", err);
219             throw new ClientDisconnectionException(err.getMessage());
220         }
221     }
222 
223     /***
224      * Remove the callback from the JmsServerSession.
225      */
226     public void close() {
227         HttpClient client = _client;
228         if (client != null) {
229             synchronized (client) {
230                 try {
231                     client.send("close", _host, _port);
232                 } catch (Exception ignore) {
233                 }
234             }
235         }
236         
237         JmsServerSession session = _session;
238         _session = null;
239         if (session != null) {            
240             session.setMessageListener(null);
241             _connection.disconnect(session);
242             _pinger.close();
243             _pinger = null;
244         }
245         _host = null;
246         _port = null;
247         _client = null;
248     }
249 
250 } //-- HttpJmsSessionSender