KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > tools > Server


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.tools;
6
7 import java.sql.Connection JavaDoc;
8 import java.sql.DriverManager JavaDoc;
9 import java.sql.PreparedStatement JavaDoc;
10 import java.sql.SQLException JavaDoc;
11
12 import org.h2.engine.Constants;
13 import org.h2.message.Message;
14 import org.h2.message.TraceSystem;
15 import org.h2.server.OdbcServer;
16 import org.h2.server.Service;
17 import org.h2.server.TcpServer;
18 import org.h2.server.ftp.FtpServer;
19 import org.h2.server.web.WebServer;
20 import org.h2.util.JdbcUtils;
21 import org.h2.util.MathUtils;
22 import org.h2.util.StartBrowser;
23
24 /**
25  * This tool can be used to start various database servers (listeners).
26  */

27 public class Server implements Runnable JavaDoc {
28     
29     private String JavaDoc name;
30     private Service service;
31     
32     private void showUsage() {
33         System.out.println("java "+getClass().getName() + " [options]");
34         System.out.println("By default, -tcp, -web, -browser and -odbc are started");
35         System.out.println("-tcp (start the TCP Server)");
36         System.out.println("-tcpPort <port> (default: " + TcpServer.DEFAULT_PORT+")");
37         System.out.println("-tcpSSL [true|false]");
38         System.out.println("-tcpAllowOthers [true|false]");
39         System.out.println("-tcpPassword {password} (the password for shutting down a TCP Server)");
40         System.out.println("-tcpShutdown {url} (shutdown the TCP Server, URL example: tcp://localhost:9094)");
41         System.out.println("-tcpShutdownForce [true|false] (don't wait for other connections to close)");
42
43         System.out.println("-web (start the Web Server)");
44         System.out.println("-webPort <port> (default: " + Constants.DEFAULT_HTTP_PORT+")");
45         System.out.println("-webSSL [true|false}");
46         System.out.println("-webAllowOthers [true|false}");
47         System.out.println("-browser (start a browser)");
48
49         System.out.println("-odbc (start the ODBC Server)");
50         System.out.println("-odbcPort <port> (default: " + OdbcServer.DEFAULT_PORT+")");
51         System.out.println("-odbcAllowOthers [true|false]");
52
53         System.out.println("-ftp (start the FTP Server)");
54         System.out.println("-ftpPort <port> (default: " + Constants.DEFAULT_FTP_PORT+")");
55         System.out.println("-ftpDir <directory> (default: " + FtpServer.DEFAULT_ROOT+", use jdbc:... to access a database)");
56         System.out.println("-ftpRead <readUserName> (default: " + FtpServer.DEFAULT_READ+")");
57         System.out.println("-ftpWrite <writeUserName> (default: " + FtpServer.DEFAULT_WRITE+")");
58         System.out.println("-ftpWritePassword <password> (default: " + FtpServer.DEFAULT_WRITE_PASSWORD+")");
59
60         System.out.println("-log [true|false]");
61         System.out.println("-baseDir <directory>");
62         System.out.println("-ifExists [true|false] (only existing databases may be opened)");
63     }
64     
65     private Server() {
66     }
67     
68     /**
69      * The command line interface for this tool.
70      * The options must be split into strings like this: "-baseDir", "/temp/data",...
71      * By default, -tcp, -web, -browser and -odbc are started.
72      * The following options are supported:
73      * <ul>
74      * <li>-help or -? (print the list of options)
75      * <li>-web (start the Web Server)
76      * <li>-tcp (start the TCP Server)
77      * <li>-tcpShutdown {url} (shutdown the running TCP Server, URL example: tcp://localhost:9094)
78      * <li>-odbc (start the ODBC Server)
79      * <li>-browser (start a browser and open a page to connect to the Web Server)
80      * <li>-log [true|false] (enable or disable logging)
81      * <li>-baseDir {directory} (sets the base directory for database files)
82      * <li>-ifExists [true|false] (only existing databases may be opened)
83      * <li>-ftp (start the FTP Server)
84      * </ul>
85      * For each Server, there are additional options available:
86      * <ul>
87      * <li>-webPort {port} (the port of Web Server, default: 8082)
88      * <li>-webSSL [true|false] (if SSL should be used)
89      * <li>-webAllowOthers [true|false] (enable/disable remote connections)
90      * <li>-tcpPort {port} (the port of TCP Server, default: 9092)
91      * <li>-tcpSSL [true|false] (if SSL should be used)
92      * <li>-tcpAllowOthers [true|false] (enable/disable remote connections)
93      * <li>-tcpPassword {password} (the password for shutting down a TCP Server)
94      * <li>-tcpShutdownForce [true|false] (don't wait for other connections to close)
95      * <li>-odbcPort {port} (the port of ODBC Server, default: 9083)
96      * <li>-odbcAllowOthers [true|false] (enable/disable remote connections)
97      * <li>-ftpPort {port}
98      * <li>-ftpDir {directory}
99      * <li>-ftpRead {readUserName}
100      * <li>-ftpWrite {writeUserName}
101      * <li>-ftpWritePassword {password}
102      * </ul>
103      *
104      * @param args the command line arguments
105      * @throws SQLException
106      */

107     public static void main(String JavaDoc[] args) throws SQLException JavaDoc {
108         new Server().run(args);
109     }
110
111     private void run(String JavaDoc[] args) throws SQLException JavaDoc {
112         boolean tcpStart = false, odbcStart = false, webStart = false, ftpStart = false;
113         boolean browserStart = false;
114         boolean tcpShutdown = false, tcpShutdownForce = false;
115         String JavaDoc tcpPassword = "";
116         String JavaDoc tcpShutdownServer = "";
117         boolean startDefaultServers = true;
118         for(int i=0; args != null && i<args.length; i++) {
119             String JavaDoc a = args[i];
120             if(a.equals("-?") || a.equals("-help")) {
121                 showUsage();
122                 return;
123             } else if(a.equals("-web")) {
124                 startDefaultServers = false;
125                 webStart = true;
126             } else if(a.equals("-odbc")) {
127                 startDefaultServers = false;
128                 odbcStart = true;
129             } else if(a.equals("-tcp")) {
130                 startDefaultServers = false;
131                 tcpStart = true;
132             } else if(a.equals("-ftp")) {
133                 startDefaultServers = false;
134                 ftpStart = true;
135             } else if(a.equals("-tcpShutdown")) {
136                 startDefaultServers = false;
137                 tcpShutdown = true;
138                 tcpShutdownServer = args[++i];
139             } else if(a.equals("-tcpPassword")) {
140                 tcpPassword = args[++i];
141             } else if(a.equals("-tcpShutdownForce")) {
142                 tcpShutdownForce = true;
143             } else if(a.equals("-browser")) {
144                 startDefaultServers = false;
145                 browserStart = true;
146             }
147         }
148         if(startDefaultServers) {
149             tcpStart = true;
150             odbcStart = true;
151             webStart = true;
152             browserStart = true;
153         }
154         // TODO server: maybe use one single properties file?
155
if(tcpShutdown) {
156             System.out.println("Shutting down TCP Server at " + tcpShutdownServer);
157             shutdownTcpServer(tcpShutdownServer, tcpPassword, tcpShutdownForce);
158         }
159         if(tcpStart) {
160             Server tcp = createTcpServer(args);
161             try {
162                 tcp.start();
163             } catch(SQLException JavaDoc e) {
164                 // ignore (status is displayed)
165
e.printStackTrace();
166             }
167             System.out.println(tcp.getStatus());
168         }
169         if(odbcStart) {
170             Server odbc = createOdbcServer(args);
171             try {
172                 odbc.start();
173             } catch(SQLException JavaDoc e) {
174                 // ignore (status is displayed)
175
e.printStackTrace();
176             }
177             System.out.println(odbc.getStatus());
178         }
179         if(webStart) {
180             Server web = createWebServer(args);
181             try {
182                 web.start();
183             } catch(SQLException JavaDoc e) {
184                 // ignore (status is displayed)
185
e.printStackTrace();
186             }
187             System.out.println(web.getStatus());
188             // start browser anyway (even if the server is already running)
189
// because some people don't look at the output,
190
// but are wondering why nothing happens
191
if(browserStart) {
192                 StartBrowser.openURL(web.getURL());
193             }
194         }
195         if(ftpStart) {
196             Server ftp = createFtpServer(args);
197             try {
198                 ftp.start();
199             } catch(SQLException JavaDoc e) {
200                 // ignore (status is displayed)
201
e.printStackTrace();
202             }
203             System.out.println(ftp.getStatus());
204         }
205     }
206     
207     /**
208      * Shutdown a TCP server.
209      *
210      * @param url example: tcp://localhost:9094
211      * @param password the password to use ("" for no password)
212      * @param force the shutdown (don't wait)
213      * @throws ClassNotFoundException
214      * @throws SQLException
215      */

216     public static void shutdownTcpServer(String JavaDoc url, String JavaDoc password, boolean force) throws SQLException JavaDoc {
217         int port = Constants.DEFAULT_SERVER_PORT;
218         int idx = url.indexOf(':', "jdbc:h2:".length());
219         if(idx >= 0) {
220             String JavaDoc p = url.substring(idx+1);
221             idx = p.indexOf('/');
222             if(idx >= 0) {
223                 p = p.substring(0, idx);
224             }
225             port = MathUtils.decodeInt(p);
226         }
227         String JavaDoc db = TcpServer.getManagementDbName(port);
228         try {
229             org.h2.Driver.load();
230         } catch(Throwable JavaDoc e) {
231             throw Message.convert(e);
232         }
233         for(int i=0; i<2; i++) {
234             Connection JavaDoc conn = null;
235             PreparedStatement JavaDoc prep = null;
236             try {
237                 conn = DriverManager.getConnection("jdbc:h2:" + url + "/" + db, "sa", password);
238                 prep = conn.prepareStatement("CALL STOP_SERVER(?, ?, ?)");
239                 prep.setInt(1, port);
240                 prep.setString(2, password);
241                 prep.setInt(3, force ? TcpServer.SHUTDOWN_FORCE : TcpServer.SHUTDOWN_NORMAL);
242                 try {
243                     prep.execute();
244                 } catch(SQLException JavaDoc e) {
245                     if(force) {
246                         // ignore
247
} else {
248                         throw e;
249                     }
250                 }
251                 break;
252             } catch(SQLException JavaDoc e) {
253                 if(i == 1) {
254                     throw e;
255                 }
256             } finally {
257                 JdbcUtils.closeSilently(prep);
258                 JdbcUtils.closeSilently(conn);
259             }
260         }
261     }
262     
263     private String JavaDoc getStatus() {
264         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
265         if(isRunning()) {
266              buff.append(service.getType());
267              buff.append(" server running on ");
268              buff.append(service.getURL());
269              buff.append(" (");
270              if(service.getAllowOthers()) {
271                  buff.append("others can connect");
272              } else {
273                  buff.append("only local connections");
274              }
275              buff.append(")");
276         } else {
277             buff.append("Port is in use, maybe another " + service.getType() + " server already running on ");
278             buff.append(service.getURL());
279         }
280         return buff.toString();
281     }
282
283     /**
284      * Create a new web server, but does not start it yet.
285      * @param args
286      * @return the server
287      */

288     public static Server createWebServer(String JavaDoc[] args) throws SQLException JavaDoc {
289         return new Server("H2 Console Server", new WebServer(), args);
290     }
291
292     /**
293      * Create a new ftp server, but does not start it yet.
294      * @param args
295      * @return the server
296      */

297     public static Server createFtpServer(String JavaDoc[] args) throws SQLException JavaDoc {
298         return new Server("H2 FTP Server", new FtpServer(), args);
299     }
300
301     /**
302      * Create a new TCP server, but does not start it yet.
303      * @param args
304      * @return the server
305      */

306     public static Server createTcpServer(String JavaDoc[] args) throws SQLException JavaDoc {
307         return new Server("H2 TCP Server", new TcpServer(), args);
308     }
309     
310     /**
311      * Create a new TCP server, but does not start it yet.
312      * @param args
313      * @return the server
314      */

315     public static Server createOdbcServer(String JavaDoc[] args) throws SQLException JavaDoc {
316         return new Server("H2 ODBC Server", new OdbcServer(), args);
317     }
318     
319     /**
320      * Tries to start the server.
321      * @return the server if successfull
322      * @throws SQLException if the server could not be started
323      */

324     public Server start() throws SQLException JavaDoc {
325         service.start();
326         Thread JavaDoc t = new Thread JavaDoc(this);
327         t.setName(name);
328         t.start();
329         for(int i=1; i<64; i+=i) {
330             wait(i);
331             if(isRunning()) {
332                 return this;
333             }
334         }
335         throw Message.getSQLException(Message.CONNECTION_BROKEN);
336     }
337     
338     private static void wait(int i) {
339         try {
340             // sleep at most 4096 ms
341
long sleep = (long)i * (long)i;
342             Thread.sleep(sleep);
343         } catch (InterruptedException JavaDoc e) {
344             // ignore
345
}
346     }
347
348     /**
349      * Checks if the server is running.
350      *
351      * @return if the server is running
352      */

353     public boolean isRunning() {
354         return service.isRunning();
355     }
356
357     /**
358      * Stops the server.
359      */

360     public void stop() {
361         service.stop();
362     }
363     
364     /**
365      * Gets the URL of this server.
366      * @return the url
367      */

368     public String JavaDoc getURL() {
369         return service.getURL();
370     }
371
372     private Server(String JavaDoc name, Service service, String JavaDoc[] args) throws SQLException JavaDoc {
373         this.name = name;
374         this.service = service;
375         try {
376             service.init(args);
377         } catch(Exception JavaDoc e) {
378             throw Message.convert(e);
379         }
380     }
381
382     /**
383      * INTERNAL
384      */

385     public void run() {
386         try {
387             service.listen();
388         } catch (Exception JavaDoc e) {
389             TraceSystem.traceThrowable(e);
390         }
391     }
392 }
393
Popular Tags