1 16 17 package org.apache.commons.dbcp.datasources; 18 19 import java.sql.Connection ; 20 import java.sql.ResultSet ; 21 import java.sql.SQLException ; 22 import java.sql.Statement ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 import java.util.WeakHashMap ; 26 27 import javax.sql.ConnectionEvent ; 28 import javax.sql.ConnectionEventListener ; 29 import javax.sql.ConnectionPoolDataSource ; 30 import javax.sql.PooledConnection ; 31 32 import org.apache.commons.dbcp.SQLNestedException; 33 import org.apache.commons.pool.ObjectPool; 34 import org.apache.commons.pool.PoolableObjectFactory; 35 36 43 class CPDSConnectionFactory 44 implements PoolableObjectFactory, ConnectionEventListener { 45 46 private static final String NO_KEY_MESSAGE 47 = "close() was called on a Connection, but " 48 + "I have no record of the underlying PooledConnection."; 49 50 protected ConnectionPoolDataSource _cpds = null; 51 protected String _validationQuery = null; 52 protected ObjectPool _pool = null; 53 protected String _username = null; 54 protected String _password = null; 55 private Map validatingMap = new HashMap (); 56 private WeakHashMap pcMap = new WeakHashMap (); 57 58 70 public CPDSConnectionFactory(ConnectionPoolDataSource cpds, 71 ObjectPool pool, 72 String validationQuery, 73 String username, 74 String password) { 75 _cpds = cpds; 76 _pool = pool; 77 _pool.setFactory(this); 78 _validationQuery = validationQuery; 79 _username = username; 80 _password = password; 81 } 82 83 89 public synchronized void setCPDS(ConnectionPoolDataSource cpds) { 90 _cpds = cpds; 91 } 92 93 101 public synchronized void setValidationQuery(String validationQuery) { 102 _validationQuery = validationQuery; 103 } 104 105 110 public synchronized void setPool(ObjectPool pool) throws SQLException { 111 if (null != _pool && pool != _pool) { 112 try { 113 _pool.close(); 114 } catch (RuntimeException e) { 115 throw e; 116 } catch (Exception e) { 117 throw new SQLNestedException("Cannot set the pool on this factory", e); 118 } 119 } 120 _pool = pool; 121 } 122 123 public ObjectPool getPool() { 124 return _pool; 125 } 126 127 public synchronized Object makeObject() { 128 Object obj; 129 try { 130 PooledConnection pc = null; 131 if (_username == null) { 132 pc = _cpds.getPooledConnection(); 133 } else { 134 pc = _cpds.getPooledConnection(_username, _password); 135 } 136 pc.addConnectionEventListener(this); 139 obj = new PooledConnectionAndInfo(pc, _username, _password); 140 pcMap.put(pc, obj); 141 } catch (SQLException e) { 142 throw new RuntimeException (e.getMessage()); 143 } 144 return obj; 145 } 146 147 public void destroyObject(Object obj) throws Exception { 148 if (obj instanceof PooledConnectionAndInfo) { 149 ((PooledConnectionAndInfo) obj).getPooledConnection().close(); 150 } 151 } 152 153 public boolean validateObject(Object obj) { 154 boolean valid = false; 155 if (obj instanceof PooledConnectionAndInfo) { 156 PooledConnection pconn = 157 ((PooledConnectionAndInfo) obj).getPooledConnection(); 158 String query = _validationQuery; 159 if (null != query) { 160 Connection conn = null; 161 Statement stmt = null; 162 ResultSet rset = null; 163 validatingMap.put(pconn, null); 168 try { 169 conn = pconn.getConnection(); 170 stmt = conn.createStatement(); 171 rset = stmt.executeQuery(query); 172 if (rset.next()) { 173 valid = true; 174 } else { 175 valid = false; 176 } 177 } catch (Exception e) { 178 valid = false; 179 } finally { 180 try { 181 rset.close(); 182 } catch (Throwable t) { 183 } 185 try { 186 stmt.close(); 187 } catch (Throwable t) { 188 } 190 try { 191 conn.close(); 192 } catch (Throwable t) { 193 } 195 validatingMap.remove(pconn); 196 } 197 } else { 198 valid = true; 199 } 200 } else { 201 valid = false; 202 } 203 return valid; 204 } 205 206 public void passivateObject(Object obj) { 207 } 208 209 public void activateObject(Object obj) { 210 } 211 212 216 222 public void connectionClosed(ConnectionEvent event) { 223 PooledConnection pc = (PooledConnection ) event.getSource(); 224 if (!validatingMap.containsKey(pc)) { 227 Object info = pcMap.get(pc); 228 if (info == null) { 229 throw new IllegalStateException (NO_KEY_MESSAGE); 230 } 231 232 try { 233 _pool.returnObject(info); 234 } catch (Exception e) { 235 System.err.println("CLOSING DOWN CONNECTION AS IT COULD " 236 + "NOT BE RETURNED TO THE POOL"); 237 try { 238 destroyObject(info); 239 } catch (Exception e2) { 240 System.err.println("EXCEPTION WHILE DESTROYING OBJECT " 241 + info); 242 e2.printStackTrace(); 243 } 244 } 245 } 246 } 247 248 252 public void connectionErrorOccurred(ConnectionEvent event) { 253 PooledConnection pc = (PooledConnection )event.getSource(); 254 try { 255 if (null != event.getSQLException()) { 256 System.err.println( 257 "CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR (" 258 + event.getSQLException() + ")"); 259 } 260 pc.removeConnectionEventListener(this); 263 } catch (Exception ignore) { 264 } 266 267 Object info = pcMap.get(pc); 268 if (info == null) { 269 throw new IllegalStateException (NO_KEY_MESSAGE); 270 } 271 try { 272 destroyObject(info); 273 } catch (Exception e) { 274 System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info); 275 e.printStackTrace(); 276 } 277 } 278 279 } 280 | Popular Tags |