1 19 20 package com.sslexplorer.jdbc.hsqldb; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.io.PrintWriter ; 25 import java.io.Writer ; 26 import java.net.Socket ; 27 import java.sql.Connection ; 28 import java.sql.DriverManager ; 29 import java.sql.Statement ; 30 import java.util.ArrayList ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.hsqldb.HsqlProperties; 37 import org.hsqldb.Server; 38 import org.hsqldb.ServerConstants; 39 40 import com.sslexplorer.boot.ContextHolder; 41 import com.sslexplorer.jdbc.JDBCConnectionImpl; 42 43 59 public class EmbeddedHSQLDBServer { 60 61 private final static Log log = LogFactory.getLog(EmbeddedHSQLDBServer.class); 62 63 private HsqlProperties properties; 64 private Server server; 65 private boolean testedConnection; 66 private boolean serverMode; 67 private int dbIdx = 1; 68 private List <String > databases; 69 private boolean started; 70 71 78 public EmbeddedHSQLDBServer(boolean serverMode) throws Exception { 79 super(); 80 81 databases = new ArrayList <String >(); 82 this.serverMode = serverMode; 83 if (serverMode) { 84 properties = new HsqlProperties(); 85 } 86 } 87 88 91 public void stop() { 92 93 if (server != null) { 94 95 103 JDBCConnectionImpl.JDBCPool.getInstance().closeAll(); 104 105 for (Iterator i = databases.iterator(); i.hasNext();) { 107 String n = (String ) i.next(); 108 Connection con = null; 109 try { 110 if (log.isInfoEnabled()) 111 log.info("Compacting database " + n); 112 con = DriverManager 113 .getConnection(EmbeddedHSQLDBServer.this.serverMode ? "jdbc:hsqldb:hsql://localhost/" + n 114 : "jdbc:hsqldb:file:" + ContextHolder.getContext().getDBDirectory().getPath() 115 + "/" + n); 116 Statement s = con.createStatement(); 117 s.execute("SHUTDOWN COMPACT"); 118 if (log.isInfoEnabled()) 119 log.info("Database " + n + " compacted."); 120 } catch (Exception e) { 121 log.error("Failed to compact database."); 122 } finally { 123 if(con != null) { 124 try { 125 con.close(); 126 } 127 catch(Exception e) { 128 } 129 } 130 } 131 132 } 133 server.signalCloseAllServerConnections(); 134 server.stop(); 135 waitForServerToStop(); 136 server = null; 137 testedConnection = false; 138 } 139 started = false; 140 } 141 142 147 public void start() throws Exception { 148 if (serverMode) { 149 if (server == null) { 150 server = new Server(); 151 server.setLogWriter(log.isDebugEnabled() ? new PrintWriter (new LoggingPrintWriter()) : new PrintWriter ( 152 new SinkPrintWiter())); 153 server.setNoSystemExit(true); 154 server.setProperties(properties); 155 } 156 if (server.getState() != ServerConstants.SERVER_STATE_SHUTDOWN) { 157 throw new Exception ("Cannot start an HSQLDB server that is not shutdown."); 158 } 159 server.start(); 160 } 161 162 waitForServer(); 163 started = true; 164 } 165 166 void waitForServer() { 167 if (!testedConnection && serverMode) { 168 Socket s = null; 169 String addr = server.getAddress().equals("0.0.0.0") ? "127.0.0.1" : server.getAddress(); 170 if (log.isInfoEnabled()) 171 log.info("Waiting for HSQLDB to start accepting connections on " + addr + ":" + server.getPort()); 172 for (int i = 0; i < 30; i++) { 173 try { 174 s = new Socket (addr, server.getPort()); 175 break; 176 } catch (IOException ioe) { 177 try { 178 Thread.sleep(1000); 179 } catch (InterruptedException ie) { 180 } 181 } 182 } 183 if (s == null) { 184 throw new IllegalStateException ("The HSQLDB server is not accepting connections after 30 seconds."); 185 } else { 186 testedConnection = true; 187 if (log.isInfoEnabled()) 188 log.info("HSQLDB is now accepting connections."); 189 try { 190 s.close(); 191 } catch (IOException ioe) { 192 } 193 } 194 } 195 } 196 197 void waitForServerToStop() { 198 if (serverMode) { 199 Socket s = null; 200 String addr = server.getAddress().equals("0.0.0.0") ? "127.0.0.1" : server.getAddress(); 201 if (log.isInfoEnabled()) 202 log.info("Waiting for HSQLDB to stop accepting connections on " + addr + ":" + server.getPort()); 203 int i = 0; 204 for (; i < 30; i++) { 205 try { 206 s = new Socket (addr, server.getPort()); 207 try { 208 s.close(); 209 } catch (Exception e) { 210 e.printStackTrace(); 211 } 212 s = null; 213 try { 214 Thread.sleep(1000); 215 } catch (InterruptedException ie) { 216 } 217 } catch (IOException ioe) { 218 break; 219 } finally { 220 if (s != null) { 221 try { 222 s.close(); 223 } catch (Exception e) { 224 } 225 s = null; 226 } 227 } 228 } 229 if (i == 30) { 230 throw new IllegalStateException ("The HSQLDB server has not stopped after 30 seconds."); 231 } else { 232 if (log.isInfoEnabled()) 233 log.info("HSQLDB is now stopped."); 234 } 235 } 236 } 237 238 248 public void addDatabase(String databaseName, File file) throws Exception { 249 if (!databases.contains(databaseName)) { 250 if (serverMode) { 251 if (log.isInfoEnabled()) 252 log.info("Adding database " + databaseName + " in TCP/IP server mode, so restarting database"); 253 boolean wasStarted = started; 254 if (wasStarted) { 255 stop(); 256 } 257 databases.add(databaseName); 258 dbIdx++; 259 properties.setProperty("server.database." + dbIdx, "file:" +file.getPath()+ "/" + databaseName); 260 properties.setProperty("server.dbname." + dbIdx, databaseName); 261 start(); 262 } else { 263 if (log.isInfoEnabled()) 264 log.info("Adding database " + databaseName + " in embedded mode."); 265 databases.add(databaseName); 266 267 } 268 } 269 270 } 271 272 275 class SinkPrintWiter extends Writer { 276 public void close() throws IOException { 277 } 278 279 public void flush() throws IOException { 280 } 281 282 public void write(char[] cbuf, int off, int len) throws IOException { 283 } 284 285 } 286 287 290 class LoggingPrintWriter extends Writer { 291 292 private StringBuffer buffer = new StringBuffer (); 293 private char ch; 294 295 300 public void close() throws IOException { 301 } 303 304 309 public void flush() throws IOException { 310 } 311 312 317 public synchronized void write(char[] cbuf, int off, int len) throws IOException { 318 String s = new String (cbuf, off, len); 319 for (int i = 0; i < len; i++) { 320 ch = s.charAt(i); 321 if (ch == '\n') { 322 if (log.isInfoEnabled()) 323 log.info(buffer.toString()); 324 buffer.setLength(0); 325 } else { 326 buffer.append(ch); 327 } 328 } 329 } 330 331 } 332 333 } | Popular Tags |