1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.dbcp2;
18
19 import java.sql.Connection;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.sql.SQLWarning;
23 import java.sql.Statement;
24 import java.util.ArrayList;
25 import java.util.List;
26
27
28
29
30
31
32
33
34
35
36
37
38 public class DelegatingStatement extends AbandonedTrace implements Statement {
39
40
41 private Statement statement;
42
43
44 private DelegatingConnection<?> connection;
45
46 private boolean closed;
47
48
49
50
51
52
53
54
55
56
57 public DelegatingStatement(final DelegatingConnection<?> connection, final Statement statement) {
58 super(connection);
59 this.statement = statement;
60 this.connection = connection;
61 }
62
63
64
65
66
67
68
69 public void activate() throws SQLException {
70 if (statement instanceof DelegatingStatement) {
71 ((DelegatingStatement) statement).activate();
72 }
73 }
74
75 @Override
76 public void addBatch(final String sql) throws SQLException {
77 checkOpen();
78 try {
79 statement.addBatch(sql);
80 } catch (final SQLException e) {
81 handleException(e);
82 }
83 }
84
85 @Override
86 public void cancel() throws SQLException {
87 checkOpen();
88 try {
89 statement.cancel();
90 } catch (final SQLException e) {
91 handleException(e);
92 }
93 }
94
95 protected void checkOpen() throws SQLException {
96 if (isClosed()) {
97 throw new SQLException(this.getClass().getName() + " with address: \"" + this.toString() + "\" is closed.");
98 }
99 }
100
101 @Override
102 public void clearBatch() throws SQLException {
103 checkOpen();
104 try {
105 statement.clearBatch();
106 } catch (final SQLException e) {
107 handleException(e);
108 }
109 }
110
111 @Override
112 public void clearWarnings() throws SQLException {
113 checkOpen();
114 try {
115 statement.clearWarnings();
116 } catch (final SQLException e) {
117 handleException(e);
118 }
119 }
120
121
122
123
124 @Override
125 public void close() throws SQLException {
126 if (isClosed()) {
127 return;
128 }
129 final List<Exception> thrownList = new ArrayList<>();
130 try {
131 if (connection != null) {
132 connection.removeTrace(this);
133 connection = null;
134 }
135
136
137
138
139
140 final List<AbandonedTrace> traceList = getTrace();
141 if (traceList != null) {
142 traceList.forEach(trace -> trace.close(e -> {
143 if (connection != null) {
144
145 connection.handleExceptionNoThrow(e);
146 }
147 thrownList.add(e);
148 }));
149 clearTrace();
150 }
151 Utils.close(statement, e -> {
152 if (connection != null) {
153
154 connection.handleExceptionNoThrow(e);
155 }
156 thrownList.add(e);
157 });
158 } finally {
159 closed = true;
160 statement = null;
161 if (!thrownList.isEmpty()) {
162 throw new SQLExceptionList(thrownList);
163 }
164 }
165 }
166
167 @Override
168 public void closeOnCompletion() throws SQLException {
169 checkOpen();
170 try {
171 Jdbc41Bridge.closeOnCompletion(statement);
172 } catch (final SQLException e) {
173 handleException(e);
174 }
175 }
176
177 @Override
178 public boolean execute(final String sql) throws SQLException {
179 checkOpen();
180 setLastUsedInParent();
181 try {
182 return statement.execute(sql);
183 } catch (final SQLException e) {
184 handleException(e);
185 return false;
186 }
187 }
188
189 @Override
190 public boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException {
191 checkOpen();
192 setLastUsedInParent();
193 try {
194 return statement.execute(sql, autoGeneratedKeys);
195 } catch (final SQLException e) {
196 handleException(e);
197 return false;
198 }
199 }
200
201 @Override
202 public boolean execute(final String sql, final int[] columnIndexes) throws SQLException {
203 checkOpen();
204 setLastUsedInParent();
205 try {
206 return statement.execute(sql, columnIndexes);
207 } catch (final SQLException e) {
208 handleException(e);
209 return false;
210 }
211 }
212
213 @Override
214 public boolean execute(final String sql, final String[] columnNames) throws SQLException {
215 checkOpen();
216 setLastUsedInParent();
217 try {
218 return statement.execute(sql, columnNames);
219 } catch (final SQLException e) {
220 handleException(e);
221 return false;
222 }
223 }
224
225 @Override
226 public int[] executeBatch() throws SQLException {
227 checkOpen();
228 setLastUsedInParent();
229 try {
230 return statement.executeBatch();
231 } catch (final SQLException e) {
232 handleException(e);
233 throw new AssertionError();
234 }
235 }
236
237
238
239
240 @Override
241 public long[] executeLargeBatch() throws SQLException {
242 checkOpen();
243 setLastUsedInParent();
244 try {
245 return statement.executeLargeBatch();
246 } catch (final SQLException e) {
247 handleException(e);
248 return null;
249 }
250 }
251
252
253
254
255 @Override
256 public long executeLargeUpdate(final String sql) throws SQLException {
257 checkOpen();
258 setLastUsedInParent();
259 try {
260 return statement.executeLargeUpdate(sql);
261 } catch (final SQLException e) {
262 handleException(e);
263 return 0;
264 }
265 }
266
267
268
269
270 @Override
271 public long executeLargeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
272 checkOpen();
273 setLastUsedInParent();
274 try {
275 return statement.executeLargeUpdate(sql, autoGeneratedKeys);
276 } catch (final SQLException e) {
277 handleException(e);
278 return 0;
279 }
280 }
281
282
283
284
285 @Override
286 public long executeLargeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
287 checkOpen();
288 setLastUsedInParent();
289 try {
290 return statement.executeLargeUpdate(sql, columnIndexes);
291 } catch (final SQLException e) {
292 handleException(e);
293 return 0;
294 }
295 }
296
297
298
299
300 @Override
301 public long executeLargeUpdate(final String sql, final String[] columnNames) throws SQLException {
302 checkOpen();
303 setLastUsedInParent();
304 try {
305 return statement.executeLargeUpdate(sql, columnNames);
306 } catch (final SQLException e) {
307 handleException(e);
308 return 0;
309 }
310 }
311
312 @SuppressWarnings("resource")
313 @Override
314 public ResultSet executeQuery(final String sql) throws SQLException {
315 checkOpen();
316 setLastUsedInParent();
317 try {
318 return DelegatingResultSet.wrapResultSet(this, statement.executeQuery(sql));
319 } catch (final SQLException e) {
320 handleException(e);
321 throw new AssertionError();
322 }
323 }
324
325 @Override
326 public int executeUpdate(final String sql) throws SQLException {
327 checkOpen();
328 setLastUsedInParent();
329 try {
330 return statement.executeUpdate(sql);
331 } catch (final SQLException e) {
332 handleException(e);
333 return 0;
334 }
335 }
336
337 @Override
338 public int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
339 checkOpen();
340 setLastUsedInParent();
341 try {
342 return statement.executeUpdate(sql, autoGeneratedKeys);
343 } catch (final SQLException e) {
344 handleException(e);
345 return 0;
346 }
347 }
348
349 @Override
350 public int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
351 checkOpen();
352 setLastUsedInParent();
353 try {
354 return statement.executeUpdate(sql, columnIndexes);
355 } catch (final SQLException e) {
356 handleException(e);
357 return 0;
358 }
359 }
360
361 @Override
362 public int executeUpdate(final String sql, final String[] columnNames) throws SQLException {
363 checkOpen();
364 setLastUsedInParent();
365 try {
366 return statement.executeUpdate(sql, columnNames);
367 } catch (final SQLException e) {
368 handleException(e);
369 return 0;
370 }
371 }
372
373 @Override
374 protected void finalize() throws Throwable {
375
376
377
378
379
380
381
382
383 close();
384 super.finalize();
385 }
386
387 @Override
388 public Connection getConnection() throws SQLException {
389 checkOpen();
390 return getConnectionInternal();
391 }
392
393 protected DelegatingConnection<?> getConnectionInternal() {
394 return connection;
395 }
396
397
398
399
400
401
402
403 public Statement getDelegate() {
404 return statement;
405 }
406
407 @Override
408 public int getFetchDirection() throws SQLException {
409 checkOpen();
410 try {
411 return statement.getFetchDirection();
412 } catch (final SQLException e) {
413 handleException(e);
414 return 0;
415 }
416 }
417
418 @Override
419 public int getFetchSize() throws SQLException {
420 checkOpen();
421 try {
422 return statement.getFetchSize();
423 } catch (final SQLException e) {
424 handleException(e);
425 return 0;
426 }
427 }
428
429 @SuppressWarnings("resource")
430 @Override
431 public ResultSet getGeneratedKeys() throws SQLException {
432 checkOpen();
433 try {
434 return DelegatingResultSet.wrapResultSet(this, statement.getGeneratedKeys());
435 } catch (final SQLException e) {
436 handleException(e);
437 throw new AssertionError();
438 }
439 }
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 @SuppressWarnings("resource")
457 public Statement getInnermostDelegate() {
458 Statement stmt = statement;
459 while (stmt instanceof DelegatingStatement) {
460 stmt = ((DelegatingStatement) stmt).getDelegate();
461 if (this == stmt) {
462 return null;
463 }
464 }
465 return stmt;
466 }
467
468
469
470
471 @Override
472 public long getLargeMaxRows() throws SQLException {
473 checkOpen();
474 try {
475 return statement.getLargeMaxRows();
476 } catch (final SQLException e) {
477 handleException(e);
478 return 0;
479 }
480 }
481
482
483
484
485 @Override
486 public long getLargeUpdateCount() throws SQLException {
487 checkOpen();
488 try {
489 return statement.getLargeUpdateCount();
490 } catch (final SQLException e) {
491 handleException(e);
492 return 0;
493 }
494 }
495
496 @Override
497 public int getMaxFieldSize() throws SQLException {
498 checkOpen();
499 try {
500 return statement.getMaxFieldSize();
501 } catch (final SQLException e) {
502 handleException(e);
503 return 0;
504 }
505 }
506
507 @Override
508 public int getMaxRows() throws SQLException {
509 checkOpen();
510 try {
511 return statement.getMaxRows();
512 } catch (final SQLException e) {
513 handleException(e);
514 return 0;
515 }
516 }
517
518 @Override
519 public boolean getMoreResults() throws SQLException {
520 checkOpen();
521 try {
522 return statement.getMoreResults();
523 } catch (final SQLException e) {
524 handleException(e);
525 return false;
526 }
527 }
528
529 @Override
530 public boolean getMoreResults(final int current) throws SQLException {
531 checkOpen();
532 try {
533 return statement.getMoreResults(current);
534 } catch (final SQLException e) {
535 handleException(e);
536 return false;
537 }
538 }
539
540 @Override
541 public int getQueryTimeout() throws SQLException {
542 checkOpen();
543 try {
544 return statement.getQueryTimeout();
545 } catch (final SQLException e) {
546 handleException(e);
547 return 0;
548 }
549 }
550
551 @SuppressWarnings("resource")
552 @Override
553 public ResultSet getResultSet() throws SQLException {
554 checkOpen();
555 try {
556 return DelegatingResultSet.wrapResultSet(this, statement.getResultSet());
557 } catch (final SQLException e) {
558 handleException(e);
559 throw new AssertionError();
560 }
561 }
562
563 @Override
564 public int getResultSetConcurrency() throws SQLException {
565 checkOpen();
566 try {
567 return statement.getResultSetConcurrency();
568 } catch (final SQLException e) {
569 handleException(e);
570 return 0;
571 }
572 }
573
574 @Override
575 public int getResultSetHoldability() throws SQLException {
576 checkOpen();
577 try {
578 return statement.getResultSetHoldability();
579 } catch (final SQLException e) {
580 handleException(e);
581 return 0;
582 }
583 }
584
585 @Override
586 public int getResultSetType() throws SQLException {
587 checkOpen();
588 try {
589 return statement.getResultSetType();
590 } catch (final SQLException e) {
591 handleException(e);
592 return 0;
593 }
594 }
595
596 @Override
597 public int getUpdateCount() throws SQLException {
598 checkOpen();
599 try {
600 return statement.getUpdateCount();
601 } catch (final SQLException e) {
602 handleException(e);
603 return 0;
604 }
605 }
606
607 @Override
608 public SQLWarning getWarnings() throws SQLException {
609 checkOpen();
610 try {
611 return statement.getWarnings();
612 } catch (final SQLException e) {
613 handleException(e);
614 throw new AssertionError();
615 }
616 }
617
618 protected void handleException(final SQLException e) throws SQLException {
619 if (connection == null) {
620 throw e;
621 }
622 connection.handleException(e);
623 }
624
625
626
627
628 @Override
629 public boolean isClosed() throws SQLException {
630 return closed;
631 }
632
633 protected boolean isClosedInternal() {
634 return closed;
635 }
636
637 @Override
638 public boolean isCloseOnCompletion() throws SQLException {
639 checkOpen();
640 try {
641 return Jdbc41Bridge.isCloseOnCompletion(statement);
642 } catch (final SQLException e) {
643 handleException(e);
644 return false;
645 }
646 }
647
648 @Override
649 public boolean isPoolable() throws SQLException {
650 checkOpen();
651 try {
652 return statement.isPoolable();
653 } catch (final SQLException e) {
654 handleException(e);
655 return false;
656 }
657 }
658
659 @Override
660 public boolean isWrapperFor(final Class<?> iface) throws SQLException {
661 if (iface.isAssignableFrom(getClass())) {
662 return true;
663 }
664 if (iface.isAssignableFrom(statement.getClass())) {
665 return true;
666 }
667 return statement.isWrapperFor(iface);
668 }
669
670
671
672
673
674
675
676 public void passivate() throws SQLException {
677 if (statement instanceof DelegatingStatement) {
678 ((DelegatingStatement) statement).passivate();
679 }
680 }
681
682 protected void setClosedInternal(final boolean closed) {
683 this.closed = closed;
684 }
685
686 @Override
687 public void setCursorName(final String name) throws SQLException {
688 checkOpen();
689 try {
690 statement.setCursorName(name);
691 } catch (final SQLException e) {
692 handleException(e);
693 }
694 }
695
696
697
698
699
700
701
702 public void setDelegate(final Statement statement) {
703 this.statement = statement;
704 }
705
706 @Override
707 public void setEscapeProcessing(final boolean enable) throws SQLException {
708 checkOpen();
709 try {
710 statement.setEscapeProcessing(enable);
711 } catch (final SQLException e) {
712 handleException(e);
713 }
714 }
715
716 @Override
717 public void setFetchDirection(final int direction) throws SQLException {
718 checkOpen();
719 try {
720 statement.setFetchDirection(direction);
721 } catch (final SQLException e) {
722 handleException(e);
723 }
724 }
725
726 @Override
727 public void setFetchSize(final int rows) throws SQLException {
728 checkOpen();
729 try {
730 statement.setFetchSize(rows);
731 } catch (final SQLException e) {
732 handleException(e);
733 }
734 }
735
736
737
738
739 @Override
740 public void setLargeMaxRows(final long max) throws SQLException {
741 checkOpen();
742 try {
743 statement.setLargeMaxRows(max);
744 } catch (final SQLException e) {
745 handleException(e);
746 }
747 }
748
749 private void setLastUsedInParent() {
750 if (connection != null) {
751 connection.setLastUsed();
752 }
753 }
754
755 @Override
756 public void setMaxFieldSize(final int max) throws SQLException {
757 checkOpen();
758 try {
759 statement.setMaxFieldSize(max);
760 } catch (final SQLException e) {
761 handleException(e);
762 }
763 }
764
765 @Override
766 public void setMaxRows(final int max) throws SQLException {
767 checkOpen();
768 try {
769 statement.setMaxRows(max);
770 } catch (final SQLException e) {
771 handleException(e);
772 }
773 }
774
775 @Override
776 public void setPoolable(final boolean poolable) throws SQLException {
777 checkOpen();
778 try {
779 statement.setPoolable(poolable);
780 } catch (final SQLException e) {
781 handleException(e);
782 }
783 }
784
785 @Override
786 public void setQueryTimeout(final int seconds) throws SQLException {
787 checkOpen();
788 try {
789 statement.setQueryTimeout(seconds);
790 } catch (final SQLException e) {
791 handleException(e);
792 }
793 }
794
795
796
797
798
799
800 @Override
801 public synchronized String toString() {
802 return statement == null ? "NULL" : statement.toString();
803 }
804
805 @Override
806 public <T> T unwrap(final Class<T> iface) throws SQLException {
807 if (iface.isAssignableFrom(getClass())) {
808 return iface.cast(this);
809 }
810 if (iface.isAssignableFrom(statement.getClass())) {
811 return iface.cast(statement);
812 }
813 return statement.unwrap(iface);
814 }
815 }