1 5 package org.h2.server; 6 7 import java.io.IOException ; 8 import java.net.ServerSocket ; 9 import java.net.Socket ; 10 import java.sql.Connection ; 11 import java.sql.DriverManager ; 12 import java.sql.SQLException ; 13 import java.sql.Statement ; 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 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 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 serverSocket; 40 private HashSet running = new HashSet (); 41 private String baseDir; 42 private String url; 43 private boolean allowOthers; 44 private boolean ifExists; 45 private Connection managementDb; 46 private String managementPassword = ""; 47 private static HashMap servers = new HashMap (); 48 49 public static String getManagementDbName(int port) { 50 return "mem:" + Constants.MANAGEMENT_DB_PREFIX + port; 51 } 52 53 private void initManagementDb() throws SQLException { 54 Connection conn = DriverManager.getConnection("jdbc:h2:" + getManagementDbName(port), "sa", managementPassword); 55 managementDb = conn; 56 Statement 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 e) { 72 TraceSystem.traceThrowable(e); 73 } 74 managementDb = null; 75 } 76 } 77 } 78 79 public void init(String [] args) throws Exception { 80 port = DEFAULT_PORT; 81 for (int i = 0; i < args.length; i++) { 82 String 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 getURL() { 104 return url; 105 } 106 107 boolean allow(Socket socket) { 108 if(allowOthers) { 109 return true; 110 } 111 return NetUtils.isLoopbackAddress(socket); 112 } 113 114 public void start() throws SQLException { 115 synchronized(TcpServer.class) { 116 serverSocket = NetUtils.createServerSocket(port, ssl); 117 initManagementDb(); 118 } 119 } 120 121 public void listen() { 122 String threadName = Thread.currentThread().getName(); 123 try { 124 while (!stop) { 125 Socket s = serverSocket.accept(); 126 TcpServerThread c = new TcpServerThread(s, this); 127 running.add(c); 128 Thread thread = new Thread (c); 129 thread.setName(threadName+" thread"); 130 c.setThread(thread); 131 thread.start(); 132 } 133 } catch (Exception 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 s = NetUtils.createLoopbackSocket(port, ssl); 147 s.close(); 148 return true; 149 } catch(Exception e) { 150 return false; 151 } 152 } 153 154 public synchronized void stop() { 155 if(!stop) { 157 stopManagementDb(); 158 stop = true; 159 if(serverSocket != null) { 160 try { 161 serverSocket.close(); 162 } catch (IOException e) { 163 TraceSystem.traceThrowable(e); 164 } 165 serverSocket = null; 166 } 167 } 168 ArrayList list = new ArrayList (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 e) { 176 TraceSystem.traceThrowable(e); 177 } 178 } 179 servers.remove(""+port); 180 } 181 182 public static synchronized void stopServer(int port, String 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 s = new Socket ("localhost", port); 195 s.close(); 196 } catch (Exception e) { 197 } 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 getBaseDir() { 213 return baseDir; 214 } 215 216 void log(String s) { 217 if (log) { 219 System.out.println(s); 220 } 221 } 222 223 void logError(Throwable e) { 224 if (log) { 225 e.printStackTrace(); 226 } 227 } 228 229 public boolean getAllowOthers() { 230 return allowOthers; 231 } 232 233 public String getType() { 234 return "TCP"; 235 } 236 237 public void logInternalError(String string) { 238 if(TcpServer.LOG_INTERNAL_ERRORS) { 239 System.out.println(string); 240 new Error (string).printStackTrace(); 241 } 242 } 243 244 public boolean getIfExists() { 245 return ifExists; 246 } 247 248 } 249 | Popular Tags |