KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > jdbcserver > TCPServer


1 /**
2  * com.mckoi.database.jdbcserver.TCPServer 21 Jul 2000
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database.jdbcserver;
26
27 import com.mckoi.database.DatabaseSystem;
28 import com.mckoi.database.Database;
29 import com.mckoi.debug.*;
30 import java.net.ServerSocket JavaDoc;
31 import java.net.Socket JavaDoc;
32 import java.net.InetAddress JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.ResourceBundle JavaDoc;
36
37 /**
38  * A TCP/IP socket server that opens a single port and allows JDBC clients
39  * to connect through the port to talk with the database.
40  *
41  * @author Tobias Downer
42  */

43
44 public final class TCPServer {
45
46   /**
47    * The parent Database object that describes everything about the
48    * database this TCP server is for.
49    */

50   private Database database;
51
52   /**
53    * The ConnectionPoolServer that polls the ServerConnection for new commands
54    * to process.
55    */

56   private ConnectionPoolServer connection_pool;
57
58   /**
59    * The ServerSocket object where the database server is bound.
60    */

61   private ServerSocket JavaDoc server_socket;
62
63   /**
64    * The InetAddress the JDBC server is bound to.
65    */

66   private InetAddress JavaDoc address;
67
68   /**
69    * The port the JDBC server is on.
70    */

71   private int port;
72
73   /**
74    * The connection pool model used for this server.
75    */

76   private String JavaDoc connection_pool_model;
77
78   /**
79    * Constructs the TCPServer over the given DatabaseSystem configuration.
80    */

81   public TCPServer(Database database) {
82     this.database = database;
83   }
84
85   /**
86    * Returns a DebugLogger object that we can log debug messages to.
87    */

88   public final DebugLogger Debug() {
89     return database.Debug();
90   }
91
92   /**
93    * Returns the port the JDBC server is on.
94    */

95   public int getJDBCPort() {
96     return port;
97   }
98
99   /**
100    * Checks to see if there's already something listening on the jdbc
101    * port. Returns true if the jdbc port in the configuration is available,
102    * otherwise returns false.
103    */

104   public boolean checkAvailable(InetAddress JavaDoc bind_address, int tcp_port) {
105     // MAJOR MAJOR HACK: We attempt to bind to the JDBC Port and if we get
106
// an error then most likely there's already a database running on this
107
// host.
108

109     int port = tcp_port;
110 // // Get information about how to set up the TCP port from the config
111
// // bundle.
112
// int port = Integer.parseInt(config.getString("jdbc_server_port"));
113

114     try {
115       // Bind the ServerSocket objects to the ports.
116
server_socket = new ServerSocket JavaDoc(port, 50, bind_address);
117       server_socket.close();
118     }
119     catch (IOException JavaDoc e) {
120       // If error then return false.
121
return false;
122     }
123
124     return true;
125   }
126
127
128   /**
129    * Starts the server running. This method returns immediately but spawns
130    * its own thread.
131    */

132   public void start(InetAddress JavaDoc bind_address, int tcp_port,
133                     String JavaDoc connection_pool_model) {
134
135     this.address = bind_address;
136     this.port = tcp_port;
137     this.connection_pool_model = connection_pool_model;
138
139 // // Get information about how to set up the TCP port from the config
140
// // bundle.
141
// port = Integer.parseInt(config.getString("jdbc_server_port"));
142
//
143
// // The 'tcp_connection_pool_thread_model' property determines the
144
// // connection pool object to use.
145
// connection_pool_model = "multi_threaded";
146
// try {
147
// String cptm = config.getString("tcp_connection_pool_thread_model");
148
// if (cptm.equalsIgnoreCase("single_threaded")) {
149
// connection_pool_model = "single_threaded";
150
// }
151
// // Multi-threaded if 'tcp_connection_pool_thread_model' is anything
152
// // other than 'single_threaded'
153
// }
154
// catch (java.util.MissingResourceException e) {
155
// // If no property in the config assume multi-threaded
156
// }
157
// Choose our connection pool implementation
158
if (connection_pool_model.equals("multi_threaded")) {
159       this.connection_pool = new MultiThreadedConnectionPoolServer(database);
160     }
161     else if (connection_pool_model.equals("single_threaded")) {
162       this.connection_pool = new SingleThreadedConnectionPoolServer(database);
163     }
164
165     try {
166       // Bind the ServerSocket object to the port.
167
server_socket = new ServerSocket JavaDoc(port, 50, bind_address);
168       server_socket.setSoTimeout(0);
169     }
170     catch (IOException JavaDoc e) {
171       Debug().writeException(e);
172       Debug().write(Lvl.ERROR, this,
173                   "Unable to start a server socket on port: " + port);
174       throw new Error JavaDoc(e.getMessage());
175     }
176
177     // This thread blocks on the server socket.
178
Thread JavaDoc listen_thread = new Thread JavaDoc() {
179       public void run() {
180         try {
181           // Accept new connections and notify when one arrives
182
while(true) {
183             Socket JavaDoc s = server_socket.accept();
184             portConnection(s);
185           }
186         }
187         catch (IOException JavaDoc e) {
188           Debug().writeException(Lvl.WARNING, e);
189           Debug().write(Lvl.WARNING, this, "Socket listen thread died.");
190         }
191       }
192     };
193
194 // listen_thread.setDaemon(true);
195
listen_thread.setName("Mckoi - TCP/IP Socket Accept");
196
197     listen_thread.start();
198
199   }
200
201   /**
202    * Called whenever a new connection has been received on the port.
203    */

204   private void portConnection(Socket JavaDoc socket) throws IOException JavaDoc {
205     // TCP connections are formatted as;
206
// 'TCP/[ip address]:[remote port]:[local port]'
207
String JavaDoc host_string = "TCP/" + socket.getInetAddress().getHostAddress() +
208                          ":" + socket.getPort() + "@" +
209                          socket.getLocalAddress().getHostAddress() + ":" +
210                          socket.getLocalPort();
211 // String host_string =
212
// "Host [" + socket.getInetAddress().getHostAddress() + "] " +
213
// "port=" + socket.getPort() + " localport=" + socket.getLocalPort();
214
// Make a new DatabaseInterface for this connection,
215
JDBCDatabaseInterface db_interface =
216                              new JDBCDatabaseInterface(database, host_string);
217     TCPJDBCServerConnection connection =
218                    new TCPJDBCServerConnection(db_interface, socket, Debug());
219     // Add the provider onto the queue of providers that are serviced by
220
// the server.
221
connection_pool.addConnection(connection);
222   }
223
224   /**
225    * Closes the JDBC Server.
226    */

227   public void close() {
228     if (server_socket != null) {
229       try {
230         server_socket.close();
231       }
232       catch (IOException JavaDoc e) {
233         Debug().write(Lvl.ERROR, this, "Error closing JDBC Server.");
234         Debug().writeException(e);
235       }
236     }
237     connection_pool.close();
238   }
239
240   /**
241    * Returns human understandable information about the server.
242    */

243   public String JavaDoc toString() {
244     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
245     buf.append("TCP JDBC Server (");
246     buf.append(connection_pool_model);
247     buf.append(") on ");
248     if (address != null) {
249       buf.append(address.getHostAddress());
250       buf.append(" ");
251     }
252     buf.append("port: ");
253     buf.append(getJDBCPort());
254     return new String JavaDoc(buf);
255   }
256
257 }
258
Popular Tags