KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > presumo > jms > plugin > implementation > transport > tcp > ServerTransportImpl


1 /**
2  * This file is part of Presumo.
3  *
4  * Presumo is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * Presumo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Presumo; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  *
19  * Copyright 2001 Dan Greff
20  */

21 package com.presumo.jms.plugin.implementation.transport.tcp;
22
23 import java.util.Vector JavaDoc;
24
25 import java.net.InetAddress JavaDoc;
26 import java.net.Socket JavaDoc;
27 import java.net.ServerSocket JavaDoc;
28
29 import java.io.InterruptedIOException JavaDoc;
30 import java.io.IOException JavaDoc;
31 import javax.jms.JMSException JavaDoc;
32
33 import com.presumo.jms.plugin.transport.ServerTransport;
34 import com.presumo.jms.resources.Resources;
35 import com.presumo.jms.router.ConnectionListener;
36 import com.presumo.jms.router.Router;
37 import com.presumo.jms.router.RemoteSession;
38
39 import com.presumo.util.config.Preferences;
40 import com.presumo.util.log.Logger;
41 import com.presumo.util.log.LoggerFactory;
42
43 /**
44  * Reference implementation of the ServerTransport interface using
45  * TCP/IP.
46  *
47  * @author Dan Greff
48  */

49 public class ServerTransportImpl
50        implements ServerTransport, ConnectionListener, Runnable JavaDoc
51 {
52   public static final int DEFAULT_PORT = 2323;
53   public static final String JavaDoc DEFAULT_HOST = "localhost";
54   public static final int DEFAULT_SO_TIMEOUT = 5000;
55   public static final int DEFAULT_ACCEPT_BACKLOG = 10;
56   public static final String JavaDoc ACCEPT_BACKLOG_KEY = "AcceptBacklog";
57   public static final String JavaDoc CLASSNAME_KEY = "ServerTransportClass";
58   
59   private String JavaDoc host;
60   private int port;
61   private int acceptBacklog;
62   
63   private Router router;
64
65   private ServerSocket JavaDoc serverSocket;
66
67   private Thread JavaDoc acceptThread;
68   
69   private volatile boolean closed = false;
70   
71   private Vector JavaDoc connections;
72
73
74     ///////////////////////////////////////////////////////////////////////////
75
// Constructors //
76
///////////////////////////////////////////////////////////////////////////
77

78   /**
79    * Default Consturctor. Needed so that the JMS implementation can
80    * instantiate your plugin via reflection.
81    */

82   public ServerTransportImpl()
83   {
84   }
85
86
87     ///////////////////////////////////////////////////////////////////////////
88
// Public Methods //
89
///////////////////////////////////////////////////////////////////////////
90

91   /**
92    *
93    */

94   public void setURL(String JavaDoc url)
95   {
96     logger.entry("setURL: " + url);
97     
98     host = "localhost";
99     port = DEFAULT_PORT;
100
101     try {
102       host = getHost(url);
103       port = getPort(url);
104     } catch (JMSException JavaDoc jmsex) {
105       logger.exception(jmsex);
106     }
107     
108     logger.exit("setURL");
109   }
110   
111   /**
112    *
113    */

114   public void setPreferences(Preferences prefs)
115   {
116     logger.entry("setPreferences");
117     
118     String JavaDoc temp = prefs.get(ACCEPT_BACKLOG_KEY);
119     if (temp != null) {
120       try {
121         acceptBacklog = Integer.parseInt(temp);
122       } catch (java.lang.NumberFormatException JavaDoc nfe) {
123         logger.exception(nfe);
124         acceptBacklog = DEFAULT_ACCEPT_BACKLOG;
125       }
126     } else {
127       acceptBacklog = DEFAULT_ACCEPT_BACKLOG;
128     }
129     logger.exit("setPreferences");
130   }
131
132   public void setRouter(Router r)
133   {
134     logger.entry("setRouter", r);
135     
136     router = r;
137
138     logger.exit("setRouter");
139   }
140
141   /**
142    *
143    */

144   public synchronized void start() throws JMSException JavaDoc
145   {
146     logger.entry("start");
147       
148     if (closed)
149       throw new JMSException JavaDoc("start() called on a closed server transport.");
150
151     try {
152       serverSocket = new ServerSocket JavaDoc(port, acceptBacklog, InetAddress.getByName(host));
153       serverSocket.setSoTimeout(DEFAULT_SO_TIMEOUT);
154     } catch (IOException JavaDoc ioe) {
155       JMSException JavaDoc jmse = new JMSException JavaDoc(Resources.getResourceString("PJMSE0001"));
156       jmse.setLinkedException(ioe);
157       throw jmse;
158     }
159     
160     acceptThread = new Thread JavaDoc(this, "JMS_TCP/IP_ServerSocket_Listener");
161     acceptThread.start();
162  
163     logger.exit("start");
164   }
165
166   
167   /**
168    *
169    */

170   public synchronized void close()
171   {
172     logger.entry("close");
173     
174     if (! closed) {
175       
176       closed = true;
177       try {
178         serverSocket.close();
179        
180       } catch(IOException JavaDoc ioe) {
181         logger.exception(ioe);
182       }
183       
184       try {
185         acceptThread.join();
186       } catch (InterruptedException JavaDoc ie) {}
187       if (connections != null) {
188         for (int i=0; i < connections.size(); i++) {
189           RemoteSession session = (RemoteSession) connections.get(i);
190           session.close();
191         }
192       }
193
194     }
195     
196     logger.exit("close");
197   }
198
199   /**
200    * Simply blocks until a client attempts to connect. Upon connection
201    * the connection listener will be called which should handle all additional
202    * setup procedures using the given TransportImpl.
203    */

204   public void run()
205   {
206     logger.entry("run");
207     
208     logger.info("PJMSI5001", host + ":" + port);
209     while(! closed) {
210
211       try {
212         Socket JavaDoc connection = serverSocket.accept();
213         
214         if (closed) continue; // don't allow any connections while we our shutting
215
// down.
216
try {
217           logger.debug("Connection accepted from: " + connection.toString());
218           
219           TransportImpl client = new TransportImpl(connection);
220           RemoteSession session = new RemoteSession(router, client, this);
221  
222           if (connections == null)
223             connections = new Vector JavaDoc();
224           connections.add(session);
225           
226         } catch (Exception JavaDoc jmse) {
227           logger.exception(jmse);
228           connection.close();
229         }
230       } catch (InterruptedIOException JavaDoc iioe) {
231       } catch (IOException JavaDoc ioe) {
232         
233         // Report an error only if we are not closed. Closing the socket during
234
// an accept should throw an harmless exception. Using an SO_TIMEOUT will
235
// cause polling
236
if (! closed) {
237           logger.exception(ioe);
238         }
239       }
240     }
241     
242     logger.exit("run");
243   }
244
245   /**
246    * Called when a RemoteSession looses connectivity.
247    */

248   public void connectionLost(RemoteSession session)
249   {
250     session.close();
251     connections.remove(session);
252   }
253
254
255
256     ///////////////////////////////////////////////////////////////////////////
257
// Private Methods //
258
///////////////////////////////////////////////////////////////////////////
259

260   private String JavaDoc getHost(String JavaDoc url) throws JMSException JavaDoc
261   {
262     logger.entry("getHost", url);
263     
264     int loc = url.lastIndexOf('/');
265     int loc2 = url.lastIndexOf(':');
266     
267     if (loc == -1 || loc2 == -1) {
268       throw new JMSException JavaDoc("Malformed URL: " + url);
269     }
270
271     String JavaDoc retval = url.substring(loc+1, loc2);
272     logger.exit("getHost", retval);
273     return retval;
274   }
275
276   private int getPort(String JavaDoc url) throws JMSException JavaDoc
277   {
278     logger.entry("getPort", url);
279
280     int loc = url.lastIndexOf(':');
281     if (loc == -1) {
282       throw new JMSException JavaDoc("Malformed URL: " + url);
283     }
284     
285     int retval = 0;
286     try {
287       retval = Integer.parseInt(url.substring(loc+1));
288     } catch (NumberFormatException JavaDoc nfe) {
289       JMSException JavaDoc jmsex = new JMSException JavaDoc("Malformed URL: " + url);
290       jmsex.setLinkedException(nfe);
291       throw jmsex;
292     }
293     
294     logger.exit("getPort", new Integer JavaDoc(retval));
295     return retval;
296   }
297
298   
299   ///////////////////////////// Misc stuff /////////////////////////////////
300
private static Logger logger =
301    LoggerFactory.getLogger(ServerTransportImpl.class, Resources.getBundle());
302   ///////////////////////////////////////////////////////////////////////////
303

304 }
305
Popular Tags