KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > server > TcpServer


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.server;
6
7 import java.io.IOException JavaDoc;
8 import java.net.ServerSocket JavaDoc;
9 import java.net.Socket JavaDoc;
10 import java.sql.Connection JavaDoc;
11 import java.sql.DriverManager JavaDoc;
12 import java.sql.SQLException JavaDoc;
13 import java.sql.Statement JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17
18 import org.h2.engine.Constants;
19 import org.h2.message.TraceSystem;
20 import org.h2.util.JdbcUtils;
21 import org.h2.util.MathUtils;
22 import org.h2.util.NetUtils;
23
24 public class TcpServer implements Service {
25     
26     // TODO new feature: implement automatic client / server mode if 'socket' file locking is used
27
// TODO make the kernel multi-threaded
28
// TODO better exception message if the port is already in use, maybe automatically use the next free port?
29

30     public static final int DEFAULT_PORT = 9092;
31     public static final int SHUTDOWN_NORMAL = 0;
32     public static final int SHUTDOWN_FORCE = 1;
33     public static boolean LOG_INTERNAL_ERRORS;
34     
35     private int port;
36     private boolean log;
37     private boolean ssl;
38     private boolean stop;
39     private ServerSocket JavaDoc serverSocket;
40     private HashSet JavaDoc running = new HashSet JavaDoc();
41     private String JavaDoc baseDir;
42     private String JavaDoc url;
43     private boolean allowOthers;
44     private boolean ifExists;
45     private Connection JavaDoc managementDb;
46     private String JavaDoc managementPassword = "";
47     private static HashMap JavaDoc servers = new HashMap JavaDoc();
48     
49     public static String JavaDoc getManagementDbName(int port) {
50         return "mem:" + Constants.MANAGEMENT_DB_PREFIX + port;
51     }
52     
53     private void initManagementDb() throws SQLException JavaDoc {
54         Connection JavaDoc conn = DriverManager.getConnection("jdbc:h2:" + getManagementDbName(port), "sa", managementPassword);
55         managementDb = conn;
56         Statement JavaDoc stat = null;
57         try {
58             stat = conn.createStatement();
59             stat.execute("CREATE ALIAS IF NOT EXISTS STOP_SERVER FOR \"" + TcpServer.class.getName() +".stopServer\"");
60         } finally {
61             JdbcUtils.closeSilently(stat);
62         }
63         servers.put(""+port, this);
64     }
65     
66     private void stopManagementDb() {
67         synchronized(TcpServer.class) {
68             if(managementDb != null) {
69                 try {
70                     managementDb.close();
71                 } catch (SQLException JavaDoc e) {
72                     TraceSystem.traceThrowable(e);
73                 }
74                 managementDb = null;
75             }
76         }
77     }
78
79     public void init(String JavaDoc[] args) throws Exception JavaDoc {
80         port = DEFAULT_PORT;
81         for (int i = 0; i < args.length; i++) {
82             String JavaDoc a = args[i];
83             if (a.equals("-log")) {
84                 log = Boolean.valueOf(args[++i]).booleanValue();
85             } else if (a.equals("-tcpSSL")) {
86                 ssl = Boolean.valueOf(args[++i]).booleanValue();
87             } else if (a.equals("-tcpPort")) {
88                 port = MathUtils.decodeInt(args[++i]);
89             } else if (a.equals("-tcpPassword")) {
90                 managementPassword= args[++i];
91             } else if (a.equals("-baseDir")) {
92                 baseDir = args[++i];
93             } else if (a.equals("-tcpAllowOthers")) {
94                 allowOthers = Boolean.valueOf(args[++i]).booleanValue();
95             } else if (a.equals("-ifExists")) {
96                 ifExists = Boolean.valueOf(args[++i]).booleanValue();
97             }
98         }
99         org.h2.Driver.load();
100         url = (ssl ? "ssl" : "tcp") + "://localhost:" + port;
101     }
102     
103     public String JavaDoc getURL() {
104         return url;
105     }
106     
107     boolean allow(Socket JavaDoc socket) {
108         if(allowOthers) {
109             return true;
110         }
111         return NetUtils.isLoopbackAddress(socket);
112     }
113     
114     public void start() throws SQLException JavaDoc {
115         synchronized(TcpServer.class) {
116             serverSocket = NetUtils.createServerSocket(port, ssl);
117             initManagementDb();
118         }
119     }
120     
121     public void listen() {
122         String JavaDoc threadName = Thread.currentThread().getName();
123         try {
124             while (!stop) {
125                 Socket JavaDoc s = serverSocket.accept();
126                 TcpServerThread c = new TcpServerThread(s, this);
127                 running.add(c);
128                 Thread JavaDoc thread = new Thread JavaDoc(c);
129                 thread.setName(threadName+" thread");
130                 c.setThread(thread);
131                 thread.start();
132             }
133         } catch (Exception JavaDoc e) {
134             if(!stop) {
135                 TraceSystem.traceThrowable(e);
136             }
137         }
138         stopManagementDb();
139     }
140
141     public boolean isRunning() {
142         if(serverSocket == null) {
143             return false;
144         }
145         try {
146             Socket JavaDoc s = NetUtils.createLoopbackSocket(port, ssl);
147             s.close();
148             return true;
149         } catch(Exception JavaDoc e) {
150             return false;
151         }
152     }
153     
154     public synchronized void stop() {
155         // TODO server: share code between web and tcp servers
156
if(!stop) {
157             stopManagementDb();
158             stop = true;
159             if(serverSocket != null) {
160                 try {
161                     serverSocket.close();
162                 } catch (IOException JavaDoc e) {
163                     TraceSystem.traceThrowable(e);
164                 }
165                 serverSocket = null;
166             }
167         }
168         // TODO server: using a boolean 'now' argument? a timeout?
169
ArrayList JavaDoc list = new ArrayList JavaDoc(running);
170         for(int i=0; i<list.size(); i++) {
171             TcpServerThread c = (TcpServerThread) list.get(i);
172             c.close();
173             try {
174                 c.getThread().join(100);
175             } catch(Exception JavaDoc e) {
176                 TraceSystem.traceThrowable(e);
177             }
178         }
179         servers.remove(""+port);
180     }
181
182     public static synchronized void stopServer(int port, String JavaDoc password, int shutdownMode) {
183         TcpServer server = (TcpServer) servers.get("" + port);
184         if(server == null) {
185             return;
186         }
187         if(!server.managementPassword.equals(password)) {
188             return;
189         }
190         if(shutdownMode == TcpServer.SHUTDOWN_NORMAL) {
191             server.stopManagementDb();
192             server.stop = true;
193             try {
194                 Socket JavaDoc s = new Socket JavaDoc("localhost", port);
195                 s.close();
196             } catch (Exception JavaDoc e) {
197                 // try to connect - so that accept returns
198
}
199         } else if(shutdownMode == TcpServer.SHUTDOWN_FORCE) {
200             server.stop();
201         }
202     }
203
204     synchronized void remove(TcpServerThread t) {
205         running.remove(t);
206     }
207
208     boolean getLog() {
209         return log;
210     }
211     
212     String JavaDoc getBaseDir() {
213         return baseDir;
214     }
215
216     void log(String JavaDoc s) {
217         // TODO log: need concept for server log
218
if (log) {
219             System.out.println(s);
220         }
221     }
222
223     void logError(Throwable JavaDoc e) {
224         if (log) {
225             e.printStackTrace();
226         }
227     }
228     
229     public boolean getAllowOthers() {
230         return allowOthers;
231     }
232
233     public String JavaDoc getType() {
234         return "TCP";
235     }
236
237     public void logInternalError(String JavaDoc string) {
238         if(TcpServer.LOG_INTERNAL_ERRORS) {
239             System.out.println(string);
240             new Error JavaDoc(string).printStackTrace();
241         }
242     }
243
244     public boolean getIfExists() {
245         return ifExists;
246     }
247
248 }
249
Popular Tags