001package io.ebean.datasource; 002 003import java.sql.Connection; 004import java.util.ArrayList; 005import java.util.LinkedHashMap; 006import java.util.List; 007import java.util.Map; 008import java.util.Properties; 009 010/** 011 * Configuration information for a DataSource. 012 */ 013public class DataSourceConfig { 014 015 private static final String POSTGRES = "postgres"; 016 017 private InitDatabase initDatabase; 018 019 private String readOnlyUrl; 020 021 private String url; 022 023 private String username; 024 025 private String password; 026 027 private String schema; 028 029 /** 030 * The name of the database platform (for use with ownerUsername and InitDatabase). 031 */ 032 private String platform; 033 034 /** 035 * The optional database owner username (for running InitDatabase). 036 */ 037 private String ownerUsername; 038 039 /** 040 * The optional database owner password (for running InitDatabase). 041 */ 042 private String ownerPassword; 043 044 private String driver; 045 046 private int minConnections = 2; 047 048 private int maxConnections = 200; 049 050 private int isolationLevel = Connection.TRANSACTION_READ_COMMITTED; 051 052 private boolean autoCommit; 053 054 private boolean readOnly; 055 056 private String heartbeatSql; 057 058 private int heartbeatFreqSecs = 30; 059 060 private int heartbeatTimeoutSeconds = 3; 061 062 private boolean captureStackTrace; 063 064 private int maxStackTraceSize = 5; 065 066 private int leakTimeMinutes = 30; 067 068 private int maxInactiveTimeSecs = 300; 069 070 private int maxAgeMinutes = 0; 071 072 private int trimPoolFreqSecs = 59; 073 074 private int pstmtCacheSize = 50; 075 076 private int cstmtCacheSize = 20; 077 078 private int waitTimeoutMillis = 1000; 079 080 private String poolListener; 081 082 private boolean offline; 083 084 private boolean failOnStart = true; 085 086 private Map<String, String> customProperties; 087 088 private List<String> initSql; 089 090 091 private DataSourceAlert alert; 092 093 private DataSourcePoolListener listener; 094 095 /** 096 * Return a copy of the DataSourceConfig. 097 */ 098 public DataSourceConfig copy() { 099 100 DataSourceConfig copy = new DataSourceConfig(); 101 copy.initDatabase = initDatabase; 102 copy.url = url; 103 copy.readOnlyUrl = readOnlyUrl; 104 copy.username = username; 105 copy.password = password; 106 copy.schema = schema; 107 copy.platform = platform; 108 copy.ownerUsername = ownerUsername; 109 copy.ownerPassword = ownerPassword; 110 copy.driver = driver; 111 copy.minConnections = minConnections; 112 copy.maxConnections = maxConnections; 113 copy.isolationLevel = isolationLevel; 114 copy.autoCommit = autoCommit; 115 copy.readOnly = readOnly; 116 copy.heartbeatSql = heartbeatSql; 117 copy.heartbeatFreqSecs = heartbeatFreqSecs; 118 copy.heartbeatTimeoutSeconds = heartbeatTimeoutSeconds; 119 copy.captureStackTrace = captureStackTrace; 120 copy.maxStackTraceSize = maxStackTraceSize; 121 copy.leakTimeMinutes = leakTimeMinutes; 122 copy.maxInactiveTimeSecs = maxInactiveTimeSecs; 123 copy.maxAgeMinutes = maxAgeMinutes; 124 copy.trimPoolFreqSecs = trimPoolFreqSecs; 125 copy.pstmtCacheSize = pstmtCacheSize; 126 copy.cstmtCacheSize = cstmtCacheSize; 127 copy.waitTimeoutMillis = waitTimeoutMillis; 128 copy.poolListener = poolListener; 129 copy.offline = offline; 130 copy.failOnStart = failOnStart; 131 if (customProperties != null) { 132 copy.customProperties = new LinkedHashMap<>(customProperties); 133 } 134 copy.initSql = initSql; 135 copy.alert = alert; 136 copy.listener = listener; 137 138 return copy; 139 } 140 141 /** 142 * Default the values for driver, url, username and password from another config if 143 * they have not been set. 144 */ 145 public DataSourceConfig setDefaults(DataSourceConfig other) { 146 if (driver == null) { 147 driver = other.driver; 148 } 149 if (url == null) { 150 url = other.url; 151 } 152 if (username == null) { 153 username = other.username; 154 } 155 if (password == null) { 156 password = other.password; 157 } 158 if (schema == null) { 159 schema = other.schema; 160 } 161 if (customProperties == null && other.customProperties != null) { 162 customProperties = new LinkedHashMap<>(other.customProperties); 163 } 164 return this; 165 } 166 167 /** 168 * Return true if there are no values set for any of url, driver, username and password. 169 */ 170 public boolean isEmpty() { 171 return url == null 172 && driver == null 173 && username == null 174 && password == null; 175 } 176 177 /** 178 * Return the read-only URL to use for creating a matching read only DataSource.. 179 */ 180 public String getReadOnlyUrl() { 181 return readOnlyUrl; 182 } 183 184 /** 185 * Set the connection URL to use for a matching read-only connection pool. 186 */ 187 public DataSourceConfig setReadOnlyUrl(String readOnlyUrl) { 188 this.readOnlyUrl = readOnlyUrl; 189 return this; 190 } 191 192 /** 193 * Return the connection URL. 194 */ 195 public String getUrl() { 196 return url; 197 } 198 199 /** 200 * Set the connection URL. 201 */ 202 public DataSourceConfig setUrl(String url) { 203 this.url = url; 204 return this; 205 } 206 207 /** 208 * Return the database username. 209 */ 210 public String getUsername() { 211 return username; 212 } 213 214 /** 215 * Set the database username. 216 */ 217 public DataSourceConfig setUsername(String username) { 218 this.username = username; 219 return this; 220 } 221 222 /** 223 * Return the database password. 224 */ 225 public String getPassword() { 226 return password; 227 } 228 229 /** 230 * Set the database password. 231 */ 232 public DataSourceConfig setPassword(String password) { 233 this.password = password; 234 return this; 235 } 236 237 /** 238 * Return the database username. 239 */ 240 public String getSchema() { 241 return schema; 242 } 243 244 /** 245 * Set the default database schema to use. 246 */ 247 public DataSourceConfig setSchema(String schema) { 248 this.schema = schema; 249 return this; 250 } 251 252 /** 253 * Return the database driver. 254 */ 255 public String getDriver() { 256 return driver; 257 } 258 259 /** 260 * Set the database driver. 261 */ 262 public DataSourceConfig setDriver(String driver) { 263 this.driver = driver; 264 return this; 265 } 266 267 /** 268 * Return the transaction isolation level. 269 */ 270 public int getIsolationLevel() { 271 return isolationLevel; 272 } 273 274 /** 275 * Set the transaction isolation level. 276 */ 277 public DataSourceConfig setIsolationLevel(int isolationLevel) { 278 this.isolationLevel = isolationLevel; 279 return this; 280 } 281 282 /** 283 * Return autoCommit setting. 284 */ 285 public boolean isAutoCommit() { 286 return autoCommit; 287 } 288 289 /** 290 * Set to true to turn on autoCommit. 291 */ 292 public DataSourceConfig setAutoCommit(boolean autoCommit) { 293 this.autoCommit = autoCommit; 294 return this; 295 } 296 297 /** 298 * Return the read only setting. 299 */ 300 public boolean isReadOnly() { 301 return readOnly; 302 } 303 304 /** 305 * Set to true to for read only. 306 */ 307 public DataSourceConfig setReadOnly(boolean readOnly) { 308 this.readOnly = readOnly; 309 return this; 310 } 311 312 /** 313 * Return the minimum number of connections the pool should maintain. 314 */ 315 public int getMinConnections() { 316 return minConnections; 317 } 318 319 /** 320 * Set the minimum number of connections the pool should maintain. 321 */ 322 public DataSourceConfig setMinConnections(int minConnections) { 323 this.minConnections = minConnections; 324 return this; 325 } 326 327 /** 328 * Return the maximum number of connections the pool can reach. 329 */ 330 public int getMaxConnections() { 331 return maxConnections; 332 } 333 334 /** 335 * Set the maximum number of connections the pool can reach. 336 */ 337 public DataSourceConfig setMaxConnections(int maxConnections) { 338 this.maxConnections = maxConnections; 339 return this; 340 } 341 342 /** 343 * Return the alert implementation to use. 344 */ 345 public DataSourceAlert getAlert() { 346 return alert; 347 } 348 349 /** 350 * Set the alert implementation to use. 351 */ 352 public DataSourceConfig setAlert(DataSourceAlert alert) { 353 this.alert = alert; 354 return this; 355 } 356 357 /** 358 * Return the listener to use. 359 */ 360 public DataSourcePoolListener getListener() { 361 return listener; 362 } 363 364 /** 365 * Set the listener to use. 366 */ 367 public DataSourceConfig setListener(DataSourcePoolListener listener) { 368 this.listener = listener; 369 return this; 370 } 371 372 /** 373 * Return a SQL statement used to test the database is accessible. 374 * <p> 375 * Note that if this is not set then it can get defaulted from the 376 * DatabasePlatform. 377 * </p> 378 */ 379 public String getHeartbeatSql() { 380 return heartbeatSql; 381 } 382 383 /** 384 * Set a SQL statement used to test the database is accessible. 385 * <p> 386 * Note that if this is not set then it can get defaulted from the 387 * DatabasePlatform. 388 * </p> 389 */ 390 public DataSourceConfig setHeartbeatSql(String heartbeatSql) { 391 this.heartbeatSql = heartbeatSql; 392 return this; 393 } 394 395 /** 396 * Return the heartbeat frequency in seconds. 397 * <p> 398 * This is the expected frequency in which the DataSource should be checked to 399 * make sure it is healthy and trim idle connections. 400 * </p> 401 */ 402 public int getHeartbeatFreqSecs() { 403 return heartbeatFreqSecs; 404 } 405 406 /** 407 * Set the expected heartbeat frequency in seconds. 408 */ 409 public DataSourceConfig setHeartbeatFreqSecs(int heartbeatFreqSecs) { 410 this.heartbeatFreqSecs = heartbeatFreqSecs; 411 return this; 412 } 413 414 /** 415 * Return the heart beat timeout in seconds. 416 */ 417 public int getHeartbeatTimeoutSeconds() { 418 return heartbeatTimeoutSeconds; 419 } 420 421 /** 422 * Set the heart beat timeout in seconds. 423 */ 424 public DataSourceConfig setHeartbeatTimeoutSeconds(int heartbeatTimeoutSeconds) { 425 this.heartbeatTimeoutSeconds = heartbeatTimeoutSeconds; 426 return this; 427 } 428 429 /** 430 * Return true if a stack trace should be captured when obtaining a connection 431 * from the pool. 432 * <p> 433 * This can be used to diagnose a suspected connection pool leak. 434 * </p> 435 * <p> 436 * Obviously this has a performance overhead. 437 * </p> 438 */ 439 public boolean isCaptureStackTrace() { 440 return captureStackTrace; 441 } 442 443 /** 444 * Set to true if a stack trace should be captured when obtaining a connection 445 * from the pool. 446 * <p> 447 * This can be used to diagnose a suspected connection pool leak. 448 * </p> 449 * <p> 450 * Obviously this has a performance overhead. 451 * </p> 452 */ 453 public DataSourceConfig setCaptureStackTrace(boolean captureStackTrace) { 454 this.captureStackTrace = captureStackTrace; 455 return this; 456 } 457 458 /** 459 * Return the max size for reporting stack traces on busy connections. 460 */ 461 public int getMaxStackTraceSize() { 462 return maxStackTraceSize; 463 } 464 465 /** 466 * Set the max size for reporting stack traces on busy connections. 467 */ 468 public DataSourceConfig setMaxStackTraceSize(int maxStackTraceSize) { 469 this.maxStackTraceSize = maxStackTraceSize; 470 return this; 471 } 472 473 /** 474 * Return the time in minutes after which a connection could be considered to 475 * have leaked. 476 */ 477 public int getLeakTimeMinutes() { 478 return leakTimeMinutes; 479 } 480 481 /** 482 * Set the time in minutes after which a connection could be considered to 483 * have leaked. 484 */ 485 public DataSourceConfig setLeakTimeMinutes(int leakTimeMinutes) { 486 this.leakTimeMinutes = leakTimeMinutes; 487 return this; 488 } 489 490 /** 491 * Return the size of the PreparedStatement cache (per connection). 492 */ 493 public int getPstmtCacheSize() { 494 return pstmtCacheSize; 495 } 496 497 /** 498 * Set the size of the PreparedStatement cache (per connection). 499 */ 500 public DataSourceConfig setPstmtCacheSize(int pstmtCacheSize) { 501 this.pstmtCacheSize = pstmtCacheSize; 502 return this; 503 } 504 505 /** 506 * Return the size of the CallableStatement cache (per connection). 507 */ 508 public int getCstmtCacheSize() { 509 return cstmtCacheSize; 510 } 511 512 /** 513 * Set the size of the CallableStatement cache (per connection). 514 */ 515 public DataSourceConfig setCstmtCacheSize(int cstmtCacheSize) { 516 this.cstmtCacheSize = cstmtCacheSize; 517 return this; 518 } 519 520 /** 521 * Return the time in millis to wait for a connection before timing out once 522 * the pool has reached its maximum size. 523 */ 524 public int getWaitTimeoutMillis() { 525 return waitTimeoutMillis; 526 } 527 528 /** 529 * Set the time in millis to wait for a connection before timing out once the 530 * pool has reached its maximum size. 531 */ 532 public DataSourceConfig setWaitTimeoutMillis(int waitTimeoutMillis) { 533 this.waitTimeoutMillis = waitTimeoutMillis; 534 return this; 535 } 536 537 /** 538 * Return the time in seconds a connection can be idle after which it can be 539 * trimmed from the pool. 540 * <p> 541 * This is so that the pool after a busy period can trend over time back 542 * towards the minimum connections. 543 * </p> 544 */ 545 public int getMaxInactiveTimeSecs() { 546 return maxInactiveTimeSecs; 547 } 548 549 /** 550 * Return the maximum age a connection is allowed to be before it is closed. 551 * <p> 552 * This can be used to close really old connections. 553 * </p> 554 */ 555 public int getMaxAgeMinutes() { 556 return maxAgeMinutes; 557 } 558 559 /** 560 * Set the maximum age a connection can be in minutes. 561 */ 562 public DataSourceConfig setMaxAgeMinutes(int maxAgeMinutes) { 563 this.maxAgeMinutes = maxAgeMinutes; 564 return this; 565 } 566 567 /** 568 * Set the time in seconds a connection can be idle after which it can be 569 * trimmed from the pool. 570 * <p> 571 * This is so that the pool after a busy period can trend over time back 572 * towards the minimum connections. 573 * </p> 574 */ 575 public DataSourceConfig setMaxInactiveTimeSecs(int maxInactiveTimeSecs) { 576 this.maxInactiveTimeSecs = maxInactiveTimeSecs; 577 return this; 578 } 579 580 581 /** 582 * Return the minimum time gap between pool trim checks. 583 * <p> 584 * This defaults to 59 seconds meaning that the pool trim check will run every 585 * minute assuming the heart beat check runs every 30 seconds. 586 * </p> 587 */ 588 public int getTrimPoolFreqSecs() { 589 return trimPoolFreqSecs; 590 } 591 592 /** 593 * Set the minimum trim gap between pool trim checks. 594 */ 595 public DataSourceConfig setTrimPoolFreqSecs(int trimPoolFreqSecs) { 596 this.trimPoolFreqSecs = trimPoolFreqSecs; 597 return this; 598 } 599 600 /** 601 * Return the pool listener. 602 */ 603 public String getPoolListener() { 604 return poolListener; 605 } 606 607 /** 608 * Set a pool listener. 609 */ 610 public DataSourceConfig setPoolListener(String poolListener) { 611 this.poolListener = poolListener; 612 return this; 613 } 614 615 /** 616 * Return true if the DataSource should be left offline. 617 * <p> 618 * This is to support DDL generation etc without having a real database. 619 * </p> 620 */ 621 public boolean isOffline() { 622 return offline; 623 } 624 625 /** 626 * Return true (default) if the DataSource should be fail on start. 627 * <p> 628 * This enables to initialize the Ebean-Server if the db-server is not yet up. 629 * ({@link DataSourceAlert#dataSourceUp(javax.sql.DataSource)} is fired when DS gets up later.) 630 * </p> 631 */ 632 public boolean isFailOnStart() { 633 return failOnStart; 634 } 635 636 /** 637 * Set to false, if DataSource should not fail on start. (e.g. DataSource is not available) 638 */ 639 public DataSourceConfig setFailOnStart(boolean failOnStart) { 640 this.failOnStart = failOnStart; 641 return this; 642 } 643 644 /** 645 * Set to true if the DataSource should be left offline. 646 */ 647 public DataSourceConfig setOffline(boolean offline) { 648 this.offline = offline; 649 return this; 650 } 651 652 /** 653 * Return a map of custom properties for the jdbc driver connection. 654 */ 655 public Map<String, String> getCustomProperties() { 656 return customProperties; 657 } 658 659 /** 660 * Return a list of init queries, that are executed after a connection is opened. 661 */ 662 public List<String> getInitSql() { 663 return initSql; 664 } 665 666 /** 667 * Set custom init queries for each query. 668 */ 669 public DataSourceConfig setInitSql(List<String> initSql) { 670 this.initSql = initSql; 671 return this; 672 } 673 674 /** 675 * Set custom properties for the jdbc driver connection. 676 */ 677 public DataSourceConfig setCustomProperties(Map<String, String> customProperties) { 678 this.customProperties = customProperties; 679 return this; 680 } 681 682 /** 683 * Add an additional driver property. 684 * <pre>{@code 685 * 686 * config.addProperty("useSSL", false); 687 * 688 * }</pre> 689 */ 690 public DataSourceConfig addProperty(String key, String value) { 691 if (customProperties == null) { 692 customProperties = new LinkedHashMap<>(); 693 } 694 customProperties.put(key, value); 695 return this; 696 } 697 698 /** 699 * Add an additional driver property. 700 * <pre>{@code 701 * 702 * config.addProperty("useSSL", false); 703 * 704 * }</pre> 705 */ 706 public DataSourceConfig addProperty(String key, boolean value) { 707 return addProperty(key, Boolean.toString(value)); 708 } 709 710 /** 711 * Add an additional driver property. 712 * <pre>{@code 713 * 714 * config.addProperty("useSSL", false); 715 * 716 * }</pre> 717 */ 718 public DataSourceConfig addProperty(String key, int value) { 719 return addProperty(key, Integer.toString(value)); 720 } 721 722 /** 723 * Return the database owner username. 724 */ 725 public String getOwnerUsername() { 726 return ownerUsername; 727 } 728 729 /** 730 * Set the database owner username (used to create connection for use with InitDatabase). 731 */ 732 public DataSourceConfig setOwnerUsername(String ownerUsername) { 733 this.ownerUsername = ownerUsername; 734 return this; 735 } 736 737 /** 738 * Return the database owner password. 739 */ 740 public String getOwnerPassword() { 741 return ownerPassword; 742 } 743 744 /** 745 * Set the database owner password (used to create connection for use with InitDatabase). 746 */ 747 public DataSourceConfig setOwnerPassword(String ownerPassword) { 748 this.ownerPassword = ownerPassword; 749 return this; 750 } 751 752 /** 753 * Return the database platform. 754 */ 755 public String getPlatform() { 756 return platform; 757 } 758 759 /** 760 * Set the database platform (for use with ownerUsername and InitDatabase. 761 */ 762 public DataSourceConfig setPlatform(String platform) { 763 this.platform = platform; 764 if (initDatabase != null) { 765 setInitDatabaseForPlatform(platform); 766 } 767 return this; 768 } 769 770 /** 771 * Return the InitDatabase to use with ownerUsername. 772 */ 773 public InitDatabase getInitDatabase() { 774 return initDatabase; 775 } 776 777 /** 778 * Set the InitDatabase to use with ownerUsername. 779 */ 780 public DataSourceConfig setInitDatabase(InitDatabase initDatabase) { 781 this.initDatabase = initDatabase; 782 return this; 783 } 784 785 /** 786 * Set InitDatabase based on the database platform. 787 */ 788 public DataSourceConfig setInitDatabaseForPlatform(String platform) { 789 if (platform != null) { 790 switch (platform.toLowerCase()) { 791 case POSTGRES: 792 initDatabase = new PostgresInitDatabase(); 793 break; 794 } 795 } 796 return this; 797 } 798 799 /** 800 * Return true if InitDatabase should be used (when the pool initialises and a connection can't be obtained). 801 * 802 * @return True to obtain a connection using ownerUsername and run InitDatabase. 803 */ 804 public boolean useInitDatabase() { 805 if (ownerUsername != null && ownerPassword != null) { 806 if (initDatabase == null) { 807 // default to postgres 808 initDatabase = new PostgresInitDatabase(); 809 } 810 return true; 811 } 812 return false; 813 } 814 815 /** 816 * Load the settings from the properties supplied. 817 * <p> 818 * You can use this when you have your own properties to use for configuration. 819 * </p> 820 * 821 * @param properties the properties to configure the dataSource 822 * @param serverName the name of the specific dataSource (optional) 823 */ 824 public DataSourceConfig loadSettings(Properties properties, String serverName) { 825 ConfigPropertiesHelper dbProps = new ConfigPropertiesHelper("datasource", serverName, properties); 826 loadSettings(dbProps); 827 return this; 828 } 829 830 /** 831 * Load the settings from the PropertiesWrapper. 832 */ 833 private void loadSettings(ConfigPropertiesHelper properties) { 834 835 username = properties.get("username", username); 836 password = properties.get("password", password); 837 schema = properties.get("schema", schema); 838 platform = properties.get("platform", platform); 839 ownerUsername = properties.get("ownerUsername", ownerUsername); 840 ownerPassword = properties.get("ownerPassword", ownerPassword); 841 if (initDatabase == null && platform != null) { 842 setInitDatabaseForPlatform(platform); 843 } 844 845 driver = properties.get("driver", properties.get("databaseDriver", driver)); 846 readOnlyUrl = properties.get("readOnlyUrl", readOnlyUrl); 847 url = properties.get("url", properties.get("databaseUrl", url)); 848 autoCommit = properties.getBoolean("autoCommit", autoCommit); 849 readOnly = properties.getBoolean("readOnly", readOnly); 850 captureStackTrace = properties.getBoolean("captureStackTrace", captureStackTrace); 851 maxStackTraceSize = properties.getInt("maxStackTraceSize", maxStackTraceSize); 852 leakTimeMinutes = properties.getInt("leakTimeMinutes", leakTimeMinutes); 853 maxInactiveTimeSecs = properties.getInt("maxInactiveTimeSecs", maxInactiveTimeSecs); 854 trimPoolFreqSecs = properties.getInt("trimPoolFreqSecs", trimPoolFreqSecs); 855 maxAgeMinutes = properties.getInt("maxAgeMinutes", maxAgeMinutes); 856 857 minConnections = properties.getInt("minConnections", minConnections); 858 maxConnections = properties.getInt("maxConnections", maxConnections); 859 pstmtCacheSize = properties.getInt("pstmtCacheSize", pstmtCacheSize); 860 cstmtCacheSize = properties.getInt("cstmtCacheSize", cstmtCacheSize); 861 862 waitTimeoutMillis = properties.getInt("waitTimeout", waitTimeoutMillis); 863 864 heartbeatSql = properties.get("heartbeatSql", heartbeatSql); 865 heartbeatTimeoutSeconds = properties.getInt("heartbeatTimeoutSeconds", heartbeatTimeoutSeconds); 866 poolListener = properties.get("poolListener", poolListener); 867 offline = properties.getBoolean("offline", offline); 868 869 String isoLevel = properties.get("isolationLevel", getTransactionIsolationLevel(isolationLevel)); 870 this.isolationLevel = getTransactionIsolationLevel(isoLevel); 871 872 this.initSql = parseSql(properties.get("initSql", null)); 873 this.failOnStart = properties.getBoolean("failOnStart", failOnStart); 874 875 String customProperties = properties.get("customProperties", null); 876 if (customProperties != null && customProperties.length() > 0) { 877 this.customProperties = parseCustom(customProperties); 878 } 879 } 880 881 private List<String> parseSql(String sql) { 882 List<String> ret = new ArrayList<>(); 883 if (sql != null) { 884 String[] queries = sql.split(";"); 885 for (String query : queries) { 886 query = query.trim(); 887 if (!query.isEmpty()) { 888 ret.add(query); 889 } 890 } 891 } 892 return ret; 893 } 894 895 Map<String, String> parseCustom(String customProperties) { 896 897 Map<String, String> propertyMap = new LinkedHashMap<String, String>(); 898 String[] pairs = customProperties.split(";"); 899 for (String pair : pairs) { 900 String[] split = pair.split("="); 901 if (split.length == 2) { 902 propertyMap.put(split[0], split[1]); 903 } 904 } 905 return propertyMap; 906 } 907 908 /** 909 * Return the isolation level description from the associated Connection int value. 910 */ 911 private String getTransactionIsolationLevel(int level) { 912 switch (level) { 913 case Connection.TRANSACTION_NONE: 914 return "NONE"; 915 case Connection.TRANSACTION_READ_COMMITTED: 916 return "READ_COMMITTED"; 917 case Connection.TRANSACTION_READ_UNCOMMITTED: 918 return "READ_UNCOMMITTED"; 919 case Connection.TRANSACTION_REPEATABLE_READ: 920 return "REPEATABLE_READ"; 921 case Connection.TRANSACTION_SERIALIZABLE: 922 return "SERIALIZABLE"; 923 default: 924 throw new RuntimeException("Transaction Isolation level [" + level + "] is not known."); 925 } 926 } 927 928 /** 929 * Return the isolation level for a given string description. 930 */ 931 private int getTransactionIsolationLevel(String level) { 932 level = level.toUpperCase(); 933 if (level.startsWith("TRANSACTION")) { 934 level = level.substring("TRANSACTION".length()); 935 } 936 level = level.replace("_", ""); 937 if ("NONE".equalsIgnoreCase(level)) { 938 return Connection.TRANSACTION_NONE; 939 } 940 if ("READCOMMITTED".equalsIgnoreCase(level)) { 941 return Connection.TRANSACTION_READ_COMMITTED; 942 } 943 if ("READUNCOMMITTED".equalsIgnoreCase(level)) { 944 return Connection.TRANSACTION_READ_UNCOMMITTED; 945 } 946 if ("REPEATABLEREAD".equalsIgnoreCase(level)) { 947 return Connection.TRANSACTION_REPEATABLE_READ; 948 } 949 if ("SERIALIZABLE".equalsIgnoreCase(level)) { 950 return Connection.TRANSACTION_SERIALIZABLE; 951 } 952 953 throw new RuntimeException("Transaction Isolation level [" + level + "] is not known."); 954 } 955}