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.KeyedObjectPool; 34 import org.apache.commons.pool.KeyedPoolableObjectFactory; 35 36 43 class KeyedCPDSConnectionFactory 44 implements KeyedPoolableObjectFactory, 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 KeyedObjectPool _pool = null; 53 private Map validatingMap = new HashMap (); 54 private WeakHashMap pcMap = new WeakHashMap (); 55 56 62 public KeyedCPDSConnectionFactory(ConnectionPoolDataSource cpds, 63 KeyedObjectPool pool, 64 String validationQuery) { 65 _cpds = cpds; 66 _pool = pool; 67 _pool.setFactory(this); 68 _validationQuery = validationQuery; 69 } 70 71 75 synchronized public void setCPDS(ConnectionPoolDataSource cpds) { 76 _cpds = cpds; 77 } 78 79 85 synchronized public void setValidationQuery(String validationQuery) { 86 _validationQuery = validationQuery; 87 } 88 89 93 synchronized public void setPool(KeyedObjectPool pool) 94 throws SQLException { 95 if (null != _pool && pool != _pool) { 96 try { 97 _pool.close(); 98 } catch (RuntimeException e) { 99 throw e; 100 } catch (Exception e) { 101 throw new SQLNestedException("Cannot set the pool on this factory", e); 102 } 103 } 104 _pool = pool; 105 } 106 107 public KeyedObjectPool getPool() { 108 return _pool; 109 } 110 111 116 public synchronized Object makeObject(Object key) throws Exception { 117 Object obj = null; 118 UserPassKey upkey = (UserPassKey)key; 119 120 PooledConnection pc = null; 121 String username = upkey.getUsername(); 122 String password = upkey.getPassword(); 123 if (username == null) { 124 pc = _cpds.getPooledConnection(); 125 } else { 126 pc = _cpds.getPooledConnection(username, password); 127 } 128 pc.addConnectionEventListener(this); 131 obj = new PooledConnectionAndInfo(pc, username, password); 132 pcMap.put(pc, obj); 133 134 return obj; 135 } 136 137 public void destroyObject(Object key, Object obj) throws Exception { 138 if (obj instanceof PooledConnectionAndInfo) { 139 PooledConnection pc = ((PooledConnectionAndInfo)obj).getPooledConnection(); 140 pcMap.remove(pc); 141 pc.close(); 142 } 143 } 144 145 public boolean validateObject(Object key, Object obj) { 146 boolean valid = false; 147 if (obj instanceof PooledConnectionAndInfo) { 148 PooledConnection pconn = 149 ((PooledConnectionAndInfo)obj).getPooledConnection(); 150 String query = _validationQuery; 151 if (null != query) { 152 Connection conn = null; 153 Statement stmt = null; 154 ResultSet rset = null; 155 validatingMap.put(pconn, null); 160 try { 161 conn = pconn.getConnection(); 162 stmt = conn.createStatement(); 163 rset = stmt.executeQuery(query); 164 if (rset.next()) { 165 valid = true; 166 } else { 167 valid = false; 168 } 169 } catch(Exception e) { 170 valid = false; 171 } finally { 172 try { 173 rset.close(); 174 } catch (Throwable t) { 175 } 177 try { 178 stmt.close(); 179 } catch (Throwable t) { 180 } 182 try { 183 conn.close(); 184 } catch (Throwable t) { 185 } 187 validatingMap.remove(pconn); 188 } 189 } else { 190 valid = true; 191 } 192 } else { 193 valid = false; 194 } 195 return valid; 196 } 197 198 public void passivateObject(Object key, Object obj) { 199 } 200 201 public void activateObject(Object key, Object obj) { 202 } 203 204 208 214 public void connectionClosed(ConnectionEvent event) { 215 PooledConnection pc = (PooledConnection )event.getSource(); 216 if (!validatingMap.containsKey(pc)) { 219 PooledConnectionAndInfo info = 220 (PooledConnectionAndInfo) pcMap.get(pc); 221 if (info == null) { 222 throw new IllegalStateException (NO_KEY_MESSAGE); 223 } 224 try { 225 _pool.returnObject(info.getUserPassKey(), info); 226 } catch (Exception e) { 227 System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + 228 "NOT BE RETURNED TO THE POOL"); 229 try { 230 destroyObject(info.getUserPassKey(), info); 231 } catch (Exception e2) { 232 System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + 233 info); 234 e2.printStackTrace(); 235 } 236 } 237 } 238 } 239 240 244 public void connectionErrorOccurred(ConnectionEvent event) { 245 PooledConnection pc = (PooledConnection )event.getSource(); 246 try { 247 if (null != event.getSQLException()) { 248 System.err 249 .println("CLOSING DOWN CONNECTION DUE TO INTERNAL ERROR (" + 250 event.getSQLException() + ")"); 251 } 252 pc.removeConnectionEventListener(this); 255 } catch (Exception ignore) { 256 } 258 259 PooledConnectionAndInfo info = (PooledConnectionAndInfo) pcMap.get(pc); 260 if (info == null) { 261 throw new IllegalStateException (NO_KEY_MESSAGE); 262 } 263 try { 264 destroyObject(info.getUserPassKey(), info); 265 } catch (Exception e) { 266 System.err.println("EXCEPTION WHILE DESTROYING OBJECT " + info); 267 e.printStackTrace(); 268 } 269 } 270 } 271 | Popular Tags |