1 16 17 package org.apache.commons.dbcp; 18 19 import java.io.PrintWriter ; 20 import java.util.Properties ; 21 import java.sql.Connection ; 22 import java.sql.Driver ; 23 import java.sql.DriverManager ; 24 import java.sql.SQLException ; 25 import javax.sql.DataSource ; 26 27 import org.apache.commons.pool.impl.GenericKeyedObjectPool; 28 import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory; 29 import org.apache.commons.pool.impl.GenericObjectPool; 30 31 32 43 public class BasicDataSource implements DataSource { 44 45 47 50 protected boolean defaultAutoCommit = true; 51 52 public synchronized boolean getDefaultAutoCommit() { 53 return this.defaultAutoCommit; 54 } 55 56 public synchronized void setDefaultAutoCommit(boolean defaultAutoCommit) { 57 this.defaultAutoCommit = defaultAutoCommit; 58 this.restartNeeded = true; 59 } 60 61 62 65 protected Boolean defaultReadOnly = null; 66 67 public synchronized boolean getDefaultReadOnly() { 68 if (this.defaultReadOnly != null) { 69 return this.defaultReadOnly.booleanValue(); 70 } 71 return false; 72 } 73 74 public synchronized void setDefaultReadOnly(boolean defaultReadOnly) { 75 this.defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE; 76 this.restartNeeded = true; 77 } 78 79 82 protected int defaultTransactionIsolation = PoolableConnectionFactory.UNKNOWN_TRANSACTIONISOLATION; 83 84 public synchronized int getDefaultTransactionIsolation() { 85 return this.defaultTransactionIsolation; 86 } 87 88 public synchronized void setDefaultTransactionIsolation(int defaultTransactionIsolation) { 89 this.defaultTransactionIsolation = defaultTransactionIsolation; 90 this.restartNeeded = true; 91 } 92 93 94 97 protected String defaultCatalog = null; 98 99 public synchronized String getDefaultCatalog() { 100 return this.defaultCatalog; 101 } 102 103 public synchronized void setDefaultCatalog(String defaultCatalog) { 104 if ((defaultCatalog != null) && (defaultCatalog.trim().length() > 0)) { 105 this.defaultCatalog = defaultCatalog; 106 } 107 else { 108 this.defaultCatalog = null; 109 } 110 this.restartNeeded = true; 111 } 112 113 114 117 protected String driverClassName = null; 118 119 public synchronized String getDriverClassName() { 120 return this.driverClassName; 121 } 122 123 public synchronized void setDriverClassName(String driverClassName) { 124 if ((driverClassName != null) && (driverClassName.trim().length() > 0)) { 125 this.driverClassName = driverClassName; 126 } 127 else { 128 this.driverClassName = null; 129 } 130 this.restartNeeded = true; 131 } 132 133 134 138 protected int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE; 139 140 public synchronized int getMaxActive() { 141 return this.maxActive; 142 } 143 144 public synchronized void setMaxActive(int maxActive) { 145 this.maxActive = maxActive; 146 if (connectionPool != null) { 147 connectionPool.setMaxActive(maxActive); 148 } 149 } 150 151 152 156 protected int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;; 157 158 public synchronized int getMaxIdle() { 159 return this.maxIdle; 160 } 161 162 public synchronized void setMaxIdle(int maxIdle) { 163 this.maxIdle = maxIdle; 164 if (connectionPool != null) { 165 connectionPool.setMaxIdle(maxIdle); 166 } 167 } 168 169 173 protected int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;; 174 175 public synchronized int getMinIdle() { 176 return this.minIdle; 177 } 178 179 public synchronized void setMinIdle(int minIdle) { 180 this.minIdle = minIdle; 181 if (connectionPool != null) { 182 connectionPool.setMinIdle(minIdle); 183 } 184 } 185 186 191 protected int initialSize = 0; 192 193 public synchronized int getInitialSize() { 194 return this.initialSize; 195 } 196 197 public synchronized void setInitialSize(int initialSize) { 198 this.initialSize = initialSize; 199 this.restartNeeded = true; 200 } 201 202 207 protected long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT; 208 209 public synchronized long getMaxWait() { 210 return this.maxWait; 211 } 212 213 public synchronized void setMaxWait(long maxWait) { 214 this.maxWait = maxWait; 215 if (connectionPool != null) { 216 connectionPool.setMaxWait(maxWait); 217 } 218 } 219 220 223 protected boolean poolPreparedStatements = false; 224 225 229 public synchronized boolean isPoolPreparedStatements() { 230 return this.poolPreparedStatements; 231 } 232 233 237 public synchronized void setPoolPreparedStatements(boolean poolingStatements) { 238 this.poolPreparedStatements = poolingStatements; 239 this.restartNeeded = true; 240 } 241 242 248 protected int maxOpenPreparedStatements = GenericKeyedObjectPool.DEFAULT_MAX_TOTAL; 249 250 public synchronized int getMaxOpenPreparedStatements() { 251 return this.maxOpenPreparedStatements; 252 } 253 254 public synchronized void setMaxOpenPreparedStatements(int maxOpenStatements) { 255 this.maxOpenPreparedStatements = maxOpenStatements; 256 this.restartNeeded = true; 257 } 258 259 264 protected boolean testOnBorrow = true; 265 266 public synchronized boolean getTestOnBorrow() { 267 return this.testOnBorrow; 268 } 269 270 public synchronized void setTestOnBorrow(boolean testOnBorrow) { 271 this.testOnBorrow = testOnBorrow; 272 if (connectionPool != null) { 273 connectionPool.setTestOnBorrow(testOnBorrow); 274 } 275 } 276 277 281 protected boolean testOnReturn = false; 282 283 public synchronized boolean getTestOnReturn() { 284 return this.testOnReturn; 285 } 286 287 public synchronized void setTestOnReturn(boolean testOnReturn) { 288 this.testOnReturn = testOnReturn; 289 if (connectionPool != null) { 290 connectionPool.setTestOnReturn(testOnReturn); 291 } 292 } 293 294 295 300 protected long timeBetweenEvictionRunsMillis = 301 GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; 302 303 public synchronized long getTimeBetweenEvictionRunsMillis() { 304 return this.timeBetweenEvictionRunsMillis; 305 } 306 307 public synchronized void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { 308 this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 309 if (connectionPool != null) { 310 connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); 311 } 312 } 313 314 315 319 protected int numTestsPerEvictionRun = 320 GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN; 321 322 public synchronized int getNumTestsPerEvictionRun() { 323 return this.numTestsPerEvictionRun; 324 } 325 326 public synchronized void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) { 327 this.numTestsPerEvictionRun = numTestsPerEvictionRun; 328 if (connectionPool != null) { 329 connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun); 330 } 331 } 332 333 334 338 protected long minEvictableIdleTimeMillis = 339 GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; 340 341 public synchronized long getMinEvictableIdleTimeMillis() { 342 return this.minEvictableIdleTimeMillis; 343 } 344 345 public synchronized void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { 346 this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 347 if (connectionPool != null) { 348 connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); 349 } 350 } 351 352 357 protected boolean testWhileIdle = false; 358 359 public synchronized boolean getTestWhileIdle() { 360 return this.testWhileIdle; 361 } 362 363 public synchronized void setTestWhileIdle(boolean testWhileIdle) { 364 this.testWhileIdle = testWhileIdle; 365 if (connectionPool != null) { 366 connectionPool.setTestWhileIdle(testWhileIdle); 367 } 368 } 369 370 374 public synchronized int getNumActive() { 375 if (connectionPool != null) { 376 return connectionPool.getNumActive(); 377 } else { 378 return 0; 379 } 380 } 381 382 383 387 public synchronized int getNumIdle() { 388 if (connectionPool != null) { 389 return connectionPool.getNumIdle(); 390 } else { 391 return 0; 392 } 393 } 394 395 396 400 protected String password = null; 401 402 public synchronized String getPassword() { 403 return this.password; 404 } 405 406 public synchronized void setPassword(String password) { 407 this.password = password; 408 this.restartNeeded = true; 409 } 410 411 412 416 protected String url = null; 417 418 public synchronized String getUrl() { 419 return this.url; 420 } 421 422 public synchronized void setUrl(String url) { 423 this.url = url; 424 this.restartNeeded = true; 425 } 426 427 428 432 protected String username = null; 433 434 public synchronized String getUsername() { 435 return this.username; 436 } 437 438 public synchronized void setUsername(String username) { 439 this.username = username; 440 this.restartNeeded = true; 441 } 442 443 444 450 protected String validationQuery = null; 451 452 public synchronized String getValidationQuery() { 453 return this.validationQuery; 454 } 455 456 public synchronized void setValidationQuery(String validationQuery) { 457 if ((validationQuery != null) && (validationQuery.trim().length() > 0)) { 458 this.validationQuery = validationQuery; 459 } else { 460 this.validationQuery = null; 461 } 462 this.restartNeeded = true; 463 } 464 465 468 private boolean accessToUnderlyingConnectionAllowed = false; 469 470 475 public synchronized boolean isAccessToUnderlyingConnectionAllowed() { 476 return this.accessToUnderlyingConnectionAllowed; 477 } 478 479 486 public synchronized void setAccessToUnderlyingConnectionAllowed(boolean allow) { 487 this.accessToUnderlyingConnectionAllowed = allow; 488 this.restartNeeded = true; 489 } 490 491 493 495 private boolean restartNeeded = false; 496 497 501 private synchronized boolean isRestartNeeded() { 502 return restartNeeded; 503 } 504 505 508 protected GenericObjectPool connectionPool = null; 509 510 516 protected Properties connectionProperties = new Properties (); 517 518 523 protected DataSource dataSource = null; 524 525 528 protected PrintWriter logWriter = new PrintWriter (System.out); 529 530 531 533 534 539 public Connection getConnection() throws SQLException { 540 return createDataSource().getConnection(); 541 } 542 543 544 553 public Connection getConnection(String username, String password) throws SQLException { 554 return createDataSource().getConnection(username, password); 555 } 556 557 558 563 public int getLoginTimeout() throws SQLException { 564 return createDataSource().getLoginTimeout(); 565 } 566 567 568 573 public PrintWriter getLogWriter() throws SQLException { 574 return createDataSource().getLogWriter(); 575 } 576 577 578 585 public void setLoginTimeout(int loginTimeout) throws SQLException { 586 createDataSource().setLoginTimeout(loginTimeout); 587 } 588 589 590 597 public void setLogWriter(PrintWriter logWriter) throws SQLException { 598 createDataSource().setLogWriter(logWriter); 599 this.logWriter = logWriter; 600 } 601 602 private AbandonedConfig abandonedConfig; 603 604 615 public boolean getRemoveAbandoned() { 616 if (abandonedConfig != null) { 617 return abandonedConfig.getRemoveAbandoned(); 618 } 619 return false; 620 } 621 622 626 public void setRemoveAbandoned(boolean removeAbandoned) { 627 if (abandonedConfig == null) { 628 abandonedConfig = new AbandonedConfig(); 629 } 630 abandonedConfig.setRemoveAbandoned(removeAbandoned); 631 this.restartNeeded = true; 632 } 633 634 640 public int getRemoveAbandonedTimeout() { 641 if (abandonedConfig != null) { 642 return abandonedConfig.getRemoveAbandonedTimeout(); 643 } 644 return 300; 645 } 646 647 651 public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) { 652 if (abandonedConfig == null) { 653 abandonedConfig = new AbandonedConfig(); 654 } 655 abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout); 656 this.restartNeeded = true; 657 } 658 659 670 public boolean getLogAbandoned() { 671 if (abandonedConfig != null) { 672 return abandonedConfig.getLogAbandoned(); 673 } 674 return false; 675 } 676 677 681 public void setLogAbandoned(boolean logAbandoned) { 682 if (abandonedConfig == null) { 683 abandonedConfig = new AbandonedConfig(); 684 } 685 abandonedConfig.setLogAbandoned(logAbandoned); 686 this.restartNeeded = true; 687 } 688 689 691 700 public void addConnectionProperty(String name, String value) { 701 connectionProperties.put(name, value); 702 this.restartNeeded = true; 703 } 704 705 public void removeConnectionProperty(String name) { 706 connectionProperties.remove(name); 707 this.restartNeeded = true; 708 } 709 710 716 public synchronized void close() throws SQLException { 717 GenericObjectPool oldpool = connectionPool; 718 connectionPool = null; 719 dataSource = null; 720 try { 721 if (oldpool != null) { 722 oldpool.close(); 723 } 724 } catch(SQLException e) { 725 throw e; 726 } catch(RuntimeException e) { 727 throw e; 728 } catch(Exception e) { 729 throw new SQLNestedException("Cannot close connection pool", e); 730 } 731 } 732 733 734 736 737 749 protected synchronized DataSource createDataSource() 750 throws SQLException { 751 752 if (dataSource != null) { 754 return (dataSource); 755 } 756 757 if (driverClassName != null) { 759 try { 760 Class.forName(driverClassName); 761 } catch (Throwable t) { 762 String message = "Cannot load JDBC driver class '" + 763 driverClassName + "'"; 764 logWriter.println(message); 765 t.printStackTrace(logWriter); 766 throw new SQLNestedException(message, t); 767 } 768 } 769 770 Driver driver = null; 772 try { 773 driver = DriverManager.getDriver(url); 774 } catch (Throwable t) { 775 String message = "Cannot create JDBC driver of class '" + 776 (driverClassName != null ? driverClassName : "") + 777 "' for connect URL '" + url + "'"; 778 logWriter.println(message); 779 t.printStackTrace(logWriter); 780 throw new SQLNestedException(message, t); 781 } 782 783 if (validationQuery == null) { 785 setTestOnBorrow(false); 786 setTestOnReturn(false); 787 setTestWhileIdle(false); 788 } 789 790 if ((abandonedConfig != null) && (abandonedConfig.getRemoveAbandoned() == true)) { 792 connectionPool = new AbandonedObjectPool(null,abandonedConfig); 793 } 794 else { 795 connectionPool = new GenericObjectPool(); 796 } 797 connectionPool.setMaxActive(maxActive); 798 connectionPool.setMaxIdle(maxIdle); 799 connectionPool.setMinIdle(minIdle); 800 connectionPool.setMaxWait(maxWait); 801 connectionPool.setTestOnBorrow(testOnBorrow); 802 connectionPool.setTestOnReturn(testOnReturn); 803 connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); 804 connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun); 805 connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); 806 connectionPool.setTestWhileIdle(testWhileIdle); 807 808 GenericKeyedObjectPoolFactory statementPoolFactory = null; 810 if (isPoolPreparedStatements()) { 811 statementPoolFactory = new GenericKeyedObjectPoolFactory(null, 812 -1, GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL, 814 0, 1, maxOpenPreparedStatements); 817 } 818 819 if (username != null) { 821 connectionProperties.put("user", username); 822 } else { 823 log("DBCP DataSource configured without a 'username'"); 824 } 825 826 if (password != null) { 827 connectionProperties.put("password", password); 828 } else { 829 log("DBCP DataSource configured without a 'password'"); 830 } 831 832 DriverConnectionFactory driverConnectionFactory = 833 new DriverConnectionFactory(driver, url, connectionProperties); 834 835 PoolableConnectionFactory connectionFactory = null; 837 try { 838 connectionFactory = 839 new PoolableConnectionFactory(driverConnectionFactory, 840 connectionPool, 841 statementPoolFactory, 842 validationQuery, 843 defaultReadOnly, 844 defaultAutoCommit, 845 defaultTransactionIsolation, 846 defaultCatalog, 847 abandonedConfig); 848 if (connectionFactory == null) { 849 throw new SQLException ("Cannot create PoolableConnectionFactory"); 850 } 851 validateConnectionFactory(connectionFactory); 852 } catch (RuntimeException e) { 853 throw e; 854 } catch (Exception e) { 855 throw new SQLNestedException("Cannot create PoolableConnectionFactory (" + e.getMessage() + ")", e); 856 } 857 858 dataSource = new PoolingDataSource(connectionPool); 860 ((PoolingDataSource) dataSource).setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed()); 861 dataSource.setLogWriter(logWriter); 862 863 try { 864 for (int i = 0 ; i < initialSize ; i++) { 865 connectionPool.addObject(); 866 } 867 } catch (Exception e) { 868 throw new SQLNestedException("Error preloading the connection pool", e); 869 } 870 871 return dataSource; 872 } 873 874 private static void validateConnectionFactory(PoolableConnectionFactory connectionFactory) throws Exception { 875 Connection conn = null; 876 try { 877 conn = (Connection ) connectionFactory.makeObject(); 878 connectionFactory.activateObject(conn); 879 connectionFactory.validateConnection(conn); 880 connectionFactory.passivateObject(conn); 881 } 882 finally { 883 connectionFactory.destroyObject(conn); 884 } 885 } 886 887 private void restart() { 888 try { 889 close(); 890 } catch (SQLException e) { 891 log("Could not restart DataSource, cause: " + e.getMessage()); 892 } 893 } 894 895 private void log(String message) { 896 if (logWriter != null) { 897 logWriter.println(message); 898 } 899 } 900 } 901 | Popular Tags |