1 22 23 24 package com.mchange.v2.c3p0.test; 25 26 import java.beans.PropertyChangeEvent ; 27 import java.beans.PropertyChangeListener ; 28 import java.io.File ; 29 import java.io.IOException ; 30 import java.io.ObjectInputStream ; 31 import java.io.ObjectOutputStream ; 32 import java.io.PrintWriter ; 33 import java.util.Properties ; 34 import java.sql.Connection ; 35 import java.sql.Driver ; 36 import java.sql.DriverManager ; 37 import java.sql.SQLException ; 38 import javax.sql.DataSource ; 39 import com.mchange.v2.sql.SqlUtils; 40 import com.mchange.v2.log.MLevel; 41 import com.mchange.v2.log.MLog; 42 import com.mchange.v2.log.MLogger; 43 import com.mchange.v2.c3p0.cfg.C3P0Config; 44 import com.mchange.v2.c3p0.impl.DriverManagerDataSourceBase; 45 46 47 public final class FreezableDriverManagerDataSource extends DriverManagerDataSourceBase implements DataSource 50 { 51 final static MLogger logger = MLog.getLogger( FreezableDriverManagerDataSource.class ); 52 53 final static File FREEZE_FILE = new File ("/tmp/c3p0_freeze_file"); 54 55 Driver driver; 57 58 boolean driver_class_loaded = false; 60 61 public FreezableDriverManagerDataSource() 62 { this( true ); } 63 64 public FreezableDriverManagerDataSource(boolean autoregister) 65 { 66 super( autoregister ); 67 68 setUpPropertyListeners(); 69 70 String user = C3P0Config.initializeStringPropertyVar("user", null); 71 String password = C3P0Config.initializeStringPropertyVar("password", null); 72 73 if (user != null) 74 this.setUser( user ); 75 76 if (password != null) 77 this.setPassword( password ); 78 } 79 80 private void waitNoFreezeFile() throws SQLException 81 { 82 try 83 { 84 while (true) 85 { 86 if (! FREEZE_FILE.exists()) 87 break; 88 Thread.sleep(1000); 89 } 90 } 91 catch (InterruptedException e) 92 { 93 logger.log(MLevel.WARNING, "Frozen cxn acquire interrupted.", e); 94 throw new SQLException ( e.toString() ); 95 } 96 } 97 98 private void setUpPropertyListeners() 99 { 100 PropertyChangeListener driverClassListener = new PropertyChangeListener () 101 { 102 public void propertyChange( PropertyChangeEvent evt ) 103 { 104 Object val = evt.getNewValue(); 105 if ( "driverClass".equals( evt.getPropertyName() ) ) 106 setDriverClassLoaded( false ); 107 } 108 }; 109 this.addPropertyChangeListener( driverClassListener ); 110 } 111 112 private synchronized boolean isDriverClassLoaded() 113 { return driver_class_loaded; } 114 115 private synchronized void setDriverClassLoaded(boolean dcl) 116 { this.driver_class_loaded = dcl; } 117 118 private void ensureDriverLoaded() throws SQLException 119 { 120 try 121 { 122 if (! isDriverClassLoaded()) 123 { 124 if (driverClass != null) 125 Class.forName( driverClass ); 126 setDriverClassLoaded( true ); 127 } 128 } 129 catch (ClassNotFoundException e) 130 { 131 if (logger.isLoggable(MLevel.WARNING)) 132 logger.log(MLevel.WARNING, "Could not load driverClass " + driverClass, e); 133 } 134 } 135 136 140 public Connection getConnection() throws SQLException 141 { 142 ensureDriverLoaded(); 143 144 waitNoFreezeFile(); 145 146 Connection out = driver().connect( jdbcUrl, properties ); 147 if (out == null) 148 throw new SQLException ("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + 149 "driver [" + driver() + "]."); 150 return out; 151 } 152 153 157 public Connection getConnection(String username, String password) throws SQLException 158 { 159 ensureDriverLoaded(); 160 161 waitNoFreezeFile(); 162 163 Connection out = driver().connect( jdbcUrl, overrideProps(username, password) ); 164 if (out == null) 165 throw new SQLException ("Apparently, jdbc URL '" + jdbcUrl + "' is not valid for the underlying " + 166 "driver [" + driver() + "]."); 167 return out; 168 } 169 170 public PrintWriter getLogWriter() throws SQLException 171 { return DriverManager.getLogWriter(); } 172 173 public void setLogWriter(PrintWriter out) throws SQLException 174 { DriverManager.setLogWriter( out ); } 175 176 public int getLoginTimeout() throws SQLException 177 { return DriverManager.getLoginTimeout(); } 178 179 public void setLoginTimeout(int seconds) throws SQLException 180 { DriverManager.setLoginTimeout( seconds ); } 181 182 public synchronized void setJdbcUrl(String jdbcUrl) 184 { 185 super.setJdbcUrl( jdbcUrl ); 188 clearDriver(); 189 } 190 191 public synchronized void setUser(String user) 193 { 194 String oldUser = this.getUser(); 195 if (! eqOrBothNull( user, oldUser )) 196 { 197 if (user != null) 198 properties.put( SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user ); 199 else 200 properties.remove( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); 201 202 pcs.firePropertyChange("user", oldUser, user); 203 } 204 } 205 206 public synchronized String getUser() 207 { 208 return properties.getProperty( SqlUtils.DRIVER_MANAGER_USER_PROPERTY ); 212 } 213 214 public synchronized void setPassword(String password) 215 { 216 String oldPass = this.getPassword(); 217 if (! eqOrBothNull( password, oldPass )) 218 { 219 if (password != null) 220 properties.put( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password ); 221 else 222 properties.remove( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); 223 224 pcs.firePropertyChange("password", oldPass, password); 225 } 226 } 227 228 public synchronized String getPassword() 229 { return properties.getProperty( SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY ); } 230 231 private final Properties overrideProps(String user, String password) 232 { 233 Properties overriding = (Properties ) properties.clone(); 235 if (user != null) 236 overriding.put(SqlUtils.DRIVER_MANAGER_USER_PROPERTY, user); 237 else 238 overriding.remove(SqlUtils.DRIVER_MANAGER_USER_PROPERTY); 239 240 if (password != null) 241 overriding.put(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY, password); 242 else 243 overriding.remove(SqlUtils.DRIVER_MANAGER_PASSWORD_PROPERTY); 244 245 return overriding; 246 } 247 248 private synchronized Driver driver() throws SQLException 249 { 250 if (driver == null) 252 driver = DriverManager.getDriver( jdbcUrl ); 253 return driver; 254 } 255 256 private synchronized void clearDriver() 257 { driver = null; } 258 259 private static boolean eqOrBothNull( Object a, Object b ) 260 { return (a == b || (a != null && a.equals(b))); } 261 262 private static final long serialVersionUID = 1; 264 private static final short VERSION = 0x0001; 265 266 private void writeObject( ObjectOutputStream oos ) throws IOException 267 { 268 oos.writeShort( VERSION ); 269 } 270 271 private void readObject( ObjectInputStream ois ) throws IOException , ClassNotFoundException 272 { 273 short version = ois.readShort(); 274 switch (version) 275 { 276 case VERSION: 277 setUpPropertyListeners(); 278 break; 279 default: 280 throw new IOException ("Unsupported Serialized Version: " + version); 281 } 282 } 283 } 284 | Popular Tags |