1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbcp2.datasources;
18
19 import java.io.OutputStreamWriter;
20 import java.io.PrintWriter;
21 import java.io.Serializable;
22 import java.nio.charset.StandardCharsets;
23 import java.sql.Connection;
24 import java.sql.SQLException;
25 import java.sql.SQLFeatureNotSupportedException;
26 import java.time.Duration;
27 import java.util.Properties;
28 import java.util.logging.Logger;
29
30 import javax.naming.Context;
31 import javax.naming.InitialContext;
32 import javax.naming.Referenceable;
33 import javax.sql.ConnectionPoolDataSource;
34 import javax.sql.DataSource;
35 import javax.sql.PooledConnection;
36
37 import org.apache.commons.dbcp2.Utils;
38 import org.apache.commons.pool2.impl.BaseObjectPoolConfig;
39 import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
40 import org.apache.commons.pool2.impl.GenericObjectPool;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public abstract class InstanceKeyDataSource implements DataSource, Referenceable, Serializable, AutoCloseable {
78
79 private static final long serialVersionUID = -6819270431752240878L;
80
81 private static final String GET_CONNECTION_CALLED = "A Connection was already requested from this source, "
82 + "further initialization is not allowed.";
83 private static final String BAD_TRANSACTION_ISOLATION = "The requested TransactionIsolation level is invalid.";
84
85
86
87
88 protected static final int UNKNOWN_TRANSACTIONISOLATION = -1;
89
90
91 private volatile boolean getConnectionCalled;
92
93
94 private ConnectionPoolDataSource dataSource;
95
96
97 private String dataSourceName;
98
99
100 private String description;
101
102
103 private Properties jndiEnvironment;
104
105
106 private Duration loginTimeoutDuration = Duration.ZERO;
107
108
109 private PrintWriter logWriter;
110
111
112 private String instanceKey;
113
114
115 private boolean defaultBlockWhenExhausted = BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
116 private String defaultEvictionPolicyClassName = BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
117 private boolean defaultLifo = BaseObjectPoolConfig.DEFAULT_LIFO;
118 private int defaultMaxIdle = GenericKeyedObjectPoolConfig.DEFAULT_MAX_IDLE_PER_KEY;
119 private int defaultMaxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
120 private Duration defaultMaxWaitDuration = BaseObjectPoolConfig.DEFAULT_MAX_WAIT;
121 private Duration defaultMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_DURATION;
122 private int defaultMinIdle = GenericKeyedObjectPoolConfig.DEFAULT_MIN_IDLE_PER_KEY;
123 private int defaultNumTestsPerEvictionRun = BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
124 private Duration defaultSoftMinEvictableIdleDuration = BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_DURATION;
125 private boolean defaultTestOnCreate = BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
126 private boolean defaultTestOnBorrow = BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
127 private boolean defaultTestOnReturn = BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
128 private boolean defaultTestWhileIdle = BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
129 private Duration defaultDurationBetweenEvictionRuns = BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS;
130
131
132 private String validationQuery;
133 private Duration validationQueryTimeoutDuration = Duration.ofSeconds(-1);
134 private boolean rollbackAfterValidation;
135 private Duration maxConnDuration = Duration.ofMillis(-1);
136
137
138 private Boolean defaultAutoCommit;
139 private int defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
140 private Boolean defaultReadOnly;
141
142
143
144
145 public InstanceKeyDataSource() {
146 }
147
148
149
150
151
152
153 protected void assertInitializationAllowed() throws IllegalStateException {
154 if (getConnectionCalled) {
155 throw new IllegalStateException(GET_CONNECTION_CALLED);
156 }
157 }
158
159
160
161
162 @Override
163 public abstract void close() throws SQLException;
164
165 private void closeDueToException(final PooledConnectionAndInfo info) {
166 if (info != null) {
167 try {
168 info.getPooledConnection().getConnection().close();
169 } catch (final Exception e) {
170
171
172
173 getLogWriter().println("[ERROR] Could not return connection to pool during exception handling. " + e.getMessage());
174 }
175 }
176 }
177
178
179
180
181 @Override
182 public Connection getConnection() throws SQLException {
183 return getConnection(null, null);
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 @Override
198 public Connection getConnection(final String userName, final String userPassword) throws SQLException {
199 if (instanceKey == null) {
200 throw new SQLException("Must set the ConnectionPoolDataSource "
201 + "through setDataSourceName or setConnectionPoolDataSource" + " before calling getConnection.");
202 }
203 getConnectionCalled = true;
204 PooledConnectionAndInfo info = null;
205 try {
206 info = getPooledConnectionAndInfo(userName, userPassword);
207 } catch (final RuntimeException | SQLException e) {
208 closeDueToException(info);
209 throw e;
210 } catch (final Exception e) {
211 closeDueToException(info);
212 throw new SQLException("Cannot borrow connection from pool", e);
213 }
214
215
216 if (!(null == userPassword ? null == info.getPassword() : userPassword.equals(info.getPassword()))) {
217 try {
218 testCPDS(userName, userPassword);
219 } catch (final SQLException ex) {
220
221 closeDueToException(info);
222 throw new SQLException(
223 "Given password did not match password used" + " to create the PooledConnection.", ex);
224 } catch (final javax.naming.NamingException ne) {
225 throw new SQLException("NamingException encountered connecting to database", ne);
226 }
227
228
229
230
231 final UserPassKey upkey = info.getUserPassKey();
232 final PooledConnectionManager manager = getConnectionManager(upkey);
233
234 manager.invalidate(info.getPooledConnection());
235
236 manager.setPassword(upkey.getPassword());
237 info = null;
238 for (int i = 0; i < 10; i++) {
239 try {
240 info = getPooledConnectionAndInfo(userName, userPassword);
241 } catch (final RuntimeException | SQLException e) {
242 closeDueToException(info);
243 throw e;
244 } catch (final Exception e) {
245 closeDueToException(info);
246 throw new SQLException("Cannot borrow connection from pool", e);
247 }
248 if (info != null && userPassword != null && userPassword.equals(info.getPassword())) {
249 break;
250 }
251 if (info != null) {
252 manager.invalidate(info.getPooledConnection());
253 }
254 info = null;
255 }
256 if (info == null) {
257 throw new SQLException("Cannot borrow connection from pool - password change failure.");
258 }
259 }
260
261 final Connection connection = info.getPooledConnection().getConnection();
262 try {
263 setupDefaults(connection, userName);
264 connection.clearWarnings();
265 return connection;
266 } catch (final SQLException ex) {
267 Utils.close(connection, e -> getLogWriter().println("ignoring exception during close: " + e));
268 throw ex;
269 }
270 }
271
272 protected abstract PooledConnectionManager getConnectionManager(UserPassKey upkey);
273
274
275
276
277
278
279
280 public ConnectionPoolDataSource getConnectionPoolDataSource() {
281 return dataSource;
282 }
283
284
285
286
287
288
289
290 public String getDataSourceName() {
291 return dataSourceName;
292 }
293
294
295
296
297
298
299
300 public boolean getDefaultBlockWhenExhausted() {
301 return this.defaultBlockWhenExhausted;
302 }
303
304
305
306
307
308
309
310 public Duration getDefaultDurationBetweenEvictionRuns() {
311 return this.defaultDurationBetweenEvictionRuns;
312 }
313
314
315
316
317
318
319
320
321 public String getDefaultEvictionPolicyClassName() {
322 return this.defaultEvictionPolicyClassName;
323 }
324
325
326
327
328
329
330 public boolean getDefaultLifo() {
331 return this.defaultLifo;
332 }
333
334
335
336
337
338
339 public int getDefaultMaxIdle() {
340 return this.defaultMaxIdle;
341 }
342
343
344
345
346
347
348 public int getDefaultMaxTotal() {
349 return this.defaultMaxTotal;
350 }
351
352
353
354
355
356
357
358 public Duration getDefaultMaxWait() {
359 return this.defaultMaxWaitDuration;
360 }
361
362
363
364
365
366
367
368 @Deprecated
369 public long getDefaultMaxWaitMillis() {
370 return getDefaultMaxWait().toMillis();
371 }
372
373
374
375
376
377
378
379
380
381 public Duration getDefaultMinEvictableIdleDuration() {
382 return this.defaultMinEvictableIdleDuration;
383 }
384
385
386
387
388
389
390
391
392
393 @Deprecated
394 public long getDefaultMinEvictableIdleTimeMillis() {
395 return this.defaultMinEvictableIdleDuration.toMillis();
396 }
397
398
399
400
401
402
403 public int getDefaultMinIdle() {
404 return this.defaultMinIdle;
405 }
406
407
408
409
410
411
412
413
414 public int getDefaultNumTestsPerEvictionRun() {
415 return this.defaultNumTestsPerEvictionRun;
416 }
417
418
419
420
421
422
423
424
425
426 public Duration getDefaultSoftMinEvictableIdleDuration() {
427 return this.defaultSoftMinEvictableIdleDuration;
428 }
429
430
431
432
433
434
435
436
437
438 @Deprecated
439 public long getDefaultSoftMinEvictableIdleTimeMillis() {
440 return this.defaultSoftMinEvictableIdleDuration.toMillis();
441 }
442
443
444
445
446
447
448
449
450 public boolean getDefaultTestOnBorrow() {
451 return this.defaultTestOnBorrow;
452 }
453
454
455
456
457
458
459
460
461 public boolean getDefaultTestOnCreate() {
462 return this.defaultTestOnCreate;
463 }
464
465
466
467
468
469
470
471
472 public boolean getDefaultTestOnReturn() {
473 return this.defaultTestOnReturn;
474 }
475
476
477
478
479
480
481
482
483 public boolean getDefaultTestWhileIdle() {
484 return this.defaultTestWhileIdle;
485 }
486
487
488
489
490
491
492
493 @Deprecated
494 public long getDefaultTimeBetweenEvictionRunsMillis() {
495 return this.defaultDurationBetweenEvictionRuns.toMillis();
496 }
497
498
499
500
501
502
503
504
505 public int getDefaultTransactionIsolation() {
506 return defaultTransactionIsolation;
507 }
508
509
510
511
512
513
514
515 public String getDescription() {
516 return description;
517 }
518
519
520
521
522
523
524 protected String getInstanceKey() {
525 return instanceKey;
526 }
527
528
529
530
531
532
533
534
535
536 public String getJndiEnvironment(final String key) {
537 String value = null;
538 if (jndiEnvironment != null) {
539 value = jndiEnvironment.getProperty(key);
540 }
541 return value;
542 }
543
544
545
546
547
548
549
550 @Deprecated
551 @Override
552 public int getLoginTimeout() {
553 return (int) loginTimeoutDuration.getSeconds();
554 }
555
556
557
558
559
560
561
562 public Duration getLoginTimeoutDuration() {
563 return loginTimeoutDuration;
564 }
565
566
567
568
569
570
571 @Override
572 public PrintWriter getLogWriter() {
573 if (logWriter == null) {
574 logWriter = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
575 }
576 return logWriter;
577 }
578
579
580
581
582
583
584
585
586
587 public Duration getMaxConnDuration() {
588 return maxConnDuration;
589 }
590
591
592
593
594
595
596
597
598
599 @Deprecated
600 public Duration getMaxConnLifetime() {
601 return maxConnDuration;
602 }
603
604
605
606
607
608
609
610
611
612 @Deprecated
613 public long getMaxConnLifetimeMillis() {
614 return maxConnDuration.toMillis();
615 }
616
617 @Override
618 public Logger getParentLogger() throws SQLFeatureNotSupportedException {
619 throw new SQLFeatureNotSupportedException();
620 }
621
622
623
624
625
626
627
628
629
630
631 protected abstract PooledConnectionAndInfo getPooledConnectionAndInfo(String userName, String userPassword)
632 throws SQLException;
633
634
635
636
637
638
639
640
641
642 public String getValidationQuery() {
643 return this.validationQuery;
644 }
645
646
647
648
649
650
651
652 @Deprecated
653 public int getValidationQueryTimeout() {
654 return (int) validationQueryTimeoutDuration.getSeconds();
655 }
656
657
658
659
660
661
662 public Duration getValidationQueryTimeoutDuration() {
663 return validationQueryTimeoutDuration;
664 }
665
666
667
668
669
670
671
672
673 public Boolean isDefaultAutoCommit() {
674 return defaultAutoCommit;
675 }
676
677
678
679
680
681
682
683
684 public Boolean isDefaultReadOnly() {
685 return defaultReadOnly;
686 }
687
688
689
690
691
692
693
694 public boolean isRollbackAfterValidation() {
695 return this.rollbackAfterValidation;
696 }
697
698 @Override
699 public boolean isWrapperFor(final Class<?> iface) throws SQLException {
700 return iface.isInstance(this);
701 }
702
703
704
705
706
707
708
709
710 public void setConnectionPoolDataSource(final ConnectionPoolDataSource dataSource) {
711 assertInitializationAllowed();
712 if (dataSourceName != null) {
713 throw new IllegalStateException("Cannot set the DataSource, if JNDI is used.");
714 }
715 if (this.dataSource != null) {
716 throw new IllegalStateException("The CPDS has already been set. It cannot be altered.");
717 }
718 this.dataSource = dataSource;
719 instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this);
720 }
721
722
723
724
725
726
727
728
729 public void setDataSourceName(final String dataSourceName) {
730 assertInitializationAllowed();
731 if (dataSource != null) {
732 throw new IllegalStateException("Cannot set the JNDI name for the DataSource, if already "
733 + "set using setConnectionPoolDataSource.");
734 }
735 if (this.dataSourceName != null) {
736 throw new IllegalStateException("The DataSourceName has already been set. " + "It cannot be altered.");
737 }
738 this.dataSourceName = dataSourceName;
739 instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this);
740 }
741
742
743
744
745
746
747
748
749
750 public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
751 assertInitializationAllowed();
752 this.defaultAutoCommit = defaultAutoCommit;
753 }
754
755
756
757
758
759
760
761
762 public void setDefaultBlockWhenExhausted(final boolean blockWhenExhausted) {
763 assertInitializationAllowed();
764 this.defaultBlockWhenExhausted = blockWhenExhausted;
765 }
766
767
768
769
770
771
772
773
774 public void setDefaultDurationBetweenEvictionRuns(final Duration defaultDurationBetweenEvictionRuns) {
775 assertInitializationAllowed();
776 this.defaultDurationBetweenEvictionRuns = defaultDurationBetweenEvictionRuns;
777 }
778
779
780
781
782
783
784
785
786
787 public void setDefaultEvictionPolicyClassName(final String evictionPolicyClassName) {
788 assertInitializationAllowed();
789 this.defaultEvictionPolicyClassName = evictionPolicyClassName;
790 }
791
792
793
794
795
796
797
798 public void setDefaultLifo(final boolean lifo) {
799 assertInitializationAllowed();
800 this.defaultLifo = lifo;
801 }
802
803
804
805
806
807
808
809 public void setDefaultMaxIdle(final int maxIdle) {
810 assertInitializationAllowed();
811 this.defaultMaxIdle = maxIdle;
812 }
813
814
815
816
817
818
819
820 public void setDefaultMaxTotal(final int maxTotal) {
821 assertInitializationAllowed();
822 this.defaultMaxTotal = maxTotal;
823 }
824
825
826
827
828
829
830
831
832 public void setDefaultMaxWait(final Duration maxWaitMillis) {
833 assertInitializationAllowed();
834 this.defaultMaxWaitDuration = maxWaitMillis;
835 }
836
837
838
839
840
841
842
843
844 @Deprecated
845 public void setDefaultMaxWaitMillis(final long maxWaitMillis) {
846 setDefaultMaxWait(Duration.ofMillis(maxWaitMillis));
847 }
848
849
850
851
852
853
854
855
856
857
858 public void setDefaultMinEvictableIdle(final Duration defaultMinEvictableIdleDuration) {
859 assertInitializationAllowed();
860 this.defaultMinEvictableIdleDuration = defaultMinEvictableIdleDuration;
861 }
862
863
864
865
866
867
868
869
870
871
872 @Deprecated
873 public void setDefaultMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
874 assertInitializationAllowed();
875 this.defaultMinEvictableIdleDuration = Duration.ofMillis(minEvictableIdleTimeMillis);
876 }
877
878
879
880
881
882
883
884 public void setDefaultMinIdle(final int minIdle) {
885 assertInitializationAllowed();
886 this.defaultMinIdle = minIdle;
887 }
888
889
890
891
892
893
894
895
896
897 public void setDefaultNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
898 assertInitializationAllowed();
899 this.defaultNumTestsPerEvictionRun = numTestsPerEvictionRun;
900 }
901
902
903
904
905
906
907
908
909
910 public void setDefaultReadOnly(final Boolean defaultReadOnly) {
911 assertInitializationAllowed();
912 this.defaultReadOnly = defaultReadOnly;
913 }
914
915
916
917
918
919
920
921
922
923
924 public void setDefaultSoftMinEvictableIdle(final Duration defaultSoftMinEvictableIdleDuration) {
925 assertInitializationAllowed();
926 this.defaultSoftMinEvictableIdleDuration = defaultSoftMinEvictableIdleDuration;
927 }
928
929
930
931
932
933
934
935
936
937
938 @Deprecated
939 public void setDefaultSoftMinEvictableIdleTimeMillis(final long softMinEvictableIdleTimeMillis) {
940 assertInitializationAllowed();
941 this.defaultSoftMinEvictableIdleDuration = Duration.ofMillis(softMinEvictableIdleTimeMillis);
942 }
943
944
945
946
947
948
949
950
951
952 public void setDefaultTestOnBorrow(final boolean testOnBorrow) {
953 assertInitializationAllowed();
954 this.defaultTestOnBorrow = testOnBorrow;
955 }
956
957
958
959
960
961
962
963
964
965 public void setDefaultTestOnCreate(final boolean testOnCreate) {
966 assertInitializationAllowed();
967 this.defaultTestOnCreate = testOnCreate;
968 }
969
970
971
972
973
974
975
976
977
978 public void setDefaultTestOnReturn(final boolean testOnReturn) {
979 assertInitializationAllowed();
980 this.defaultTestOnReturn = testOnReturn;
981 }
982
983
984
985
986
987
988
989
990
991 public void setDefaultTestWhileIdle(final boolean testWhileIdle) {
992 assertInitializationAllowed();
993 this.defaultTestWhileIdle = testWhileIdle;
994 }
995
996
997
998
999
1000
1001
1002
1003 @Deprecated
1004 public void setDefaultTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
1005 assertInitializationAllowed();
1006 this.defaultDurationBetweenEvictionRuns = Duration.ofMillis(timeBetweenEvictionRunsMillis);
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) {
1018 assertInitializationAllowed();
1019 switch (defaultTransactionIsolation) {
1020 case Connection.TRANSACTION_NONE:
1021 case Connection.TRANSACTION_READ_COMMITTED:
1022 case Connection.TRANSACTION_READ_UNCOMMITTED:
1023 case Connection.TRANSACTION_REPEATABLE_READ:
1024 case Connection.TRANSACTION_SERIALIZABLE:
1025 break;
1026 default:
1027 throw new IllegalArgumentException(BAD_TRANSACTION_ISOLATION);
1028 }
1029 this.defaultTransactionIsolation = defaultTransactionIsolation;
1030 }
1031
1032
1033
1034
1035
1036
1037
1038
1039 public void setDescription(final String description) {
1040 this.description = description;
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050 void setJndiEnvironment(final Properties properties) {
1051 if (jndiEnvironment == null) {
1052 jndiEnvironment = new Properties();
1053 } else {
1054 jndiEnvironment.clear();
1055 }
1056 jndiEnvironment.putAll(properties);
1057 }
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068 public void setJndiEnvironment(final String key, final String value) {
1069 if (jndiEnvironment == null) {
1070 jndiEnvironment = new Properties();
1071 }
1072 jndiEnvironment.setProperty(key, value);
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082 public void setLoginTimeout(final Duration loginTimeout) {
1083 this.loginTimeoutDuration = loginTimeout;
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093 @Deprecated
1094 @Override
1095 public void setLoginTimeout(final int loginTimeout) {
1096 this.loginTimeoutDuration = Duration.ofSeconds(loginTimeout);
1097 }
1098
1099
1100
1101
1102
1103
1104
1105 @Override
1106 public void setLogWriter(final PrintWriter logWriter) {
1107 this.logWriter = logWriter;
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123 public void setMaxConnLifetime(final Duration maxConnLifetimeMillis) {
1124 this.maxConnDuration = maxConnLifetimeMillis;
1125 }
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 @Deprecated
1141 public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
1142 setMaxConnLifetime(Duration.ofMillis(maxConnLifetimeMillis));
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 public void setRollbackAfterValidation(final boolean rollbackAfterValidation) {
1154 assertInitializationAllowed();
1155 this.rollbackAfterValidation = rollbackAfterValidation;
1156 }
1157
1158 protected abstract void setupDefaults(Connection connection, String userName) throws SQLException;
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169 public void setValidationQuery(final String validationQuery) {
1170 assertInitializationAllowed();
1171 this.validationQuery = validationQuery;
1172 }
1173
1174
1175
1176
1177
1178
1179
1180 public void setValidationQueryTimeout(final Duration validationQueryTimeoutDuration) {
1181 this.validationQueryTimeoutDuration = validationQueryTimeoutDuration;
1182 }
1183
1184
1185
1186
1187
1188
1189
1190
1191 @Deprecated
1192 public void setValidationQueryTimeout(final int validationQueryTimeoutSeconds) {
1193 this.validationQueryTimeoutDuration = Duration.ofSeconds(validationQueryTimeoutSeconds);
1194 }
1195
1196 protected ConnectionPoolDataSource testCPDS(final String userName, final String userPassword)
1197 throws javax.naming.NamingException, SQLException {
1198
1199 ConnectionPoolDataSource cpds = this.dataSource;
1200 if (cpds == null) {
1201 Context ctx = null;
1202 if (jndiEnvironment == null) {
1203 ctx = new InitialContext();
1204 } else {
1205 ctx = new InitialContext(jndiEnvironment);
1206 }
1207 final Object ds = ctx.lookup(dataSourceName);
1208 if (!(ds instanceof ConnectionPoolDataSource)) {
1209 throw new SQLException("Illegal configuration: " + "DataSource " + dataSourceName + " ("
1210 + ds.getClass().getName() + ")" + " doesn't implement javax.sql.ConnectionPoolDataSource");
1211 }
1212 cpds = (ConnectionPoolDataSource) ds;
1213 }
1214
1215
1216 PooledConnection conn = null;
1217 try {
1218 if (userName != null) {
1219 conn = cpds.getPooledConnection(userName, userPassword);
1220 } else {
1221 conn = cpds.getPooledConnection();
1222 }
1223 if (conn == null) {
1224 throw new SQLException("Cannot connect using the supplied userName/password");
1225 }
1226 } finally {
1227 if (conn != null) {
1228 try {
1229 conn.close();
1230 } catch (final SQLException ignored) {
1231
1232 }
1233 }
1234 }
1235 return cpds;
1236 }
1237
1238
1239
1240
1241 @Override
1242 public synchronized String toString() {
1243 final StringBuilder builder = new StringBuilder(super.toString());
1244 builder.append('[');
1245 toStringFields(builder);
1246 builder.append(']');
1247 return builder.toString();
1248 }
1249
1250 protected void toStringFields(final StringBuilder builder) {
1251 builder.append("getConnectionCalled=");
1252 builder.append(getConnectionCalled);
1253 builder.append(", dataSource=");
1254 builder.append(dataSource);
1255 builder.append(", dataSourceName=");
1256 builder.append(dataSourceName);
1257 builder.append(", description=");
1258 builder.append(description);
1259 builder.append(", jndiEnvironment=");
1260 builder.append(jndiEnvironment);
1261 builder.append(", loginTimeoutDuration=");
1262 builder.append(loginTimeoutDuration);
1263 builder.append(", logWriter=");
1264 builder.append(logWriter);
1265 builder.append(", instanceKey=");
1266 builder.append(instanceKey);
1267 builder.append(", defaultBlockWhenExhausted=");
1268 builder.append(defaultBlockWhenExhausted);
1269 builder.append(", defaultEvictionPolicyClassName=");
1270 builder.append(defaultEvictionPolicyClassName);
1271 builder.append(", defaultLifo=");
1272 builder.append(defaultLifo);
1273 builder.append(", defaultMaxIdle=");
1274 builder.append(defaultMaxIdle);
1275 builder.append(", defaultMaxTotal=");
1276 builder.append(defaultMaxTotal);
1277 builder.append(", defaultMaxWaitDuration=");
1278 builder.append(defaultMaxWaitDuration);
1279 builder.append(", defaultMinEvictableIdleDuration=");
1280 builder.append(defaultMinEvictableIdleDuration);
1281 builder.append(", defaultMinIdle=");
1282 builder.append(defaultMinIdle);
1283 builder.append(", defaultNumTestsPerEvictionRun=");
1284 builder.append(defaultNumTestsPerEvictionRun);
1285 builder.append(", defaultSoftMinEvictableIdleDuration=");
1286 builder.append(defaultSoftMinEvictableIdleDuration);
1287 builder.append(", defaultTestOnCreate=");
1288 builder.append(defaultTestOnCreate);
1289 builder.append(", defaultTestOnBorrow=");
1290 builder.append(defaultTestOnBorrow);
1291 builder.append(", defaultTestOnReturn=");
1292 builder.append(defaultTestOnReturn);
1293 builder.append(", defaultTestWhileIdle=");
1294 builder.append(defaultTestWhileIdle);
1295 builder.append(", defaultDurationBetweenEvictionRuns=");
1296 builder.append(defaultDurationBetweenEvictionRuns);
1297 builder.append(", validationQuery=");
1298 builder.append(validationQuery);
1299 builder.append(", validationQueryTimeoutDuration=");
1300 builder.append(validationQueryTimeoutDuration);
1301 builder.append(", rollbackAfterValidation=");
1302 builder.append(rollbackAfterValidation);
1303 builder.append(", maxConnDuration=");
1304 builder.append(maxConnDuration);
1305 builder.append(", defaultAutoCommit=");
1306 builder.append(defaultAutoCommit);
1307 builder.append(", defaultTransactionIsolation=");
1308 builder.append(defaultTransactionIsolation);
1309 builder.append(", defaultReadOnly=");
1310 builder.append(defaultReadOnly);
1311 }
1312
1313 @Override
1314 @SuppressWarnings("unchecked")
1315 public <T> T unwrap(final Class<T> iface) throws SQLException {
1316 if (isWrapperFor(iface)) {
1317 return (T) this;
1318 }
1319 throw new SQLException(this + " is not a wrapper for " + iface);
1320 }
1321 }