001    /**
002     * Copyright 2007-2008 Arthur Blake
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *    http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     *
016     */
017    package net.sf.log4jdbc;
018    
019    import java.io.InputStream;
020    import java.io.Reader;
021    import java.math.BigDecimal;
022    import java.net.URL;
023    import java.sql.*;
024    import java.util.Calendar;
025    import java.util.Map;
026    
027    /**
028     * Wraps a CallableStatement and reports method calls, returns and exceptions.
029     *
030     * @author Arthur Blake
031     */
032    public class CallableStatementSpy extends PreparedStatementSpy implements CallableStatement
033    {
034      private final SpyLogDelegator log;
035    
036      protected void reportAllReturns(String methodCall, String msg)
037      {
038        log.methodReturned(this, methodCall, msg);
039      }
040    
041      /**
042       * The real underlying CallableStatement that this CallableStatementSpy wraps.
043       */
044      private CallableStatement realCallableStatement;
045    
046      /**
047       * Create a CallableStatementSpy (JDBC 4.0 version) to spy upon a CallableStatement.
048       *
049       * @param sql                   The SQL used for this CallableStatement
050       * @param connectionSpy         The ConnectionSpy which produced this CallableStatementSpy
051       * @param realCallableStatement The real CallableStatement that is being spied upon
052       */
053      public CallableStatementSpy(String sql, ConnectionSpy connectionSpy, CallableStatement realCallableStatement)
054      {
055        super(sql, connectionSpy, realCallableStatement);
056        this.realCallableStatement = realCallableStatement;
057        log = SpyLogFactory.getSpyLogDelegator();
058      }
059    
060      public String getClassType()
061      {
062        return "CallableStatement";
063      }
064    
065      // forwarding methods
066    
067      public Date getDate(int parameterIndex) throws SQLException
068      {
069        String methodCall = "getDate(" + parameterIndex + ")";
070        try
071        {
072          return (Date) reportReturn(methodCall, realCallableStatement.getDate(parameterIndex));
073        }
074        catch (SQLException s)
075        {
076          reportException(methodCall, s);
077          throw s;
078        }
079      }
080    
081      public Date getDate(int parameterIndex, Calendar cal) throws SQLException
082      {
083        String methodCall = "getDate(" + parameterIndex + ", " + cal + ")";
084        try
085        {
086          return (Date) reportReturn(methodCall, realCallableStatement.getDate(parameterIndex, cal));
087        }
088        catch (SQLException s)
089        {
090          reportException(methodCall, s);
091          throw s;
092        }
093      }
094    
095      public Ref getRef(String parameterName) throws SQLException
096      {
097        String methodCall = "getRef(" + parameterName + ")";
098        try
099        {
100          return (Ref) reportReturn(methodCall, realCallableStatement.getRef(parameterName));
101        }
102        catch (SQLException s)
103        {
104          reportException(methodCall, s);
105          throw s;
106        }
107      }
108    
109      public Time getTime(String parameterName) throws SQLException
110      {
111        String methodCall = "getTime(" + parameterName + ")";
112        try
113        {
114          return (Time) reportReturn(methodCall, realCallableStatement.getTime(parameterName));
115        }
116        catch (SQLException s)
117        {
118          reportException(methodCall, s);
119          throw s;
120        }
121      }
122    
123      public void setTime(String parameterName, Time x) throws SQLException
124      {
125        String methodCall = "setTime(" + parameterName + ", " + x + ")";
126        try
127        {
128          realCallableStatement.setTime(parameterName, x);
129        }
130        catch (SQLException s)
131        {
132          reportException(methodCall, s);
133          throw s;
134        }
135        reportReturn(methodCall);
136      }
137    
138      public Blob getBlob(int i) throws SQLException
139      {
140        String methodCall = "getBlob(" + i + ")";
141        try
142        {
143          return (Blob) reportReturn(methodCall, realCallableStatement.getBlob(i));
144        }
145        catch (SQLException s)
146        {
147          reportException(methodCall, s);
148          throw s;
149        }
150      }
151    
152      public Clob getClob(int i) throws SQLException
153      {
154        String methodCall = "getClob(" + i + ")";
155        try
156        {
157          return (Clob) reportReturn(methodCall, realCallableStatement.getClob(i));
158        }
159        catch (SQLException s)
160        {
161          reportException(methodCall, s);
162          throw s;
163        }
164      }
165    
166      public Array getArray(int i) throws SQLException
167      {
168        String methodCall = "getArray(" + i + ")";
169        try
170        {
171          return (Array) reportReturn(methodCall, realCallableStatement.getArray(i));
172        }
173        catch (SQLException s)
174        {
175          reportException(methodCall, s);
176          throw s;
177        }
178      }
179    
180      public byte[] getBytes(int parameterIndex) throws SQLException
181      {
182        String methodCall = "getBytes(" + parameterIndex + ")";
183        try
184        {
185          return (byte[]) reportReturn(methodCall, realCallableStatement.getBytes(parameterIndex));
186        }
187        catch (SQLException s)
188        {
189          reportException(methodCall, s);
190          throw s;
191        }
192      }
193    
194      public double getDouble(int parameterIndex) throws SQLException
195      {
196        String methodCall = "getDouble(" + parameterIndex + ")";
197        try
198        {
199          return reportReturn(methodCall, realCallableStatement.getDouble(parameterIndex));
200        }
201        catch (SQLException s)
202        {
203          reportException(methodCall, s);
204          throw s;
205        }
206      }
207    
208      public int getInt(int parameterIndex) throws SQLException
209      {
210        String methodCall = "getInt(" + parameterIndex + ")";
211        try
212        {
213          return reportReturn(methodCall, realCallableStatement.getInt(parameterIndex));
214        }
215        catch (SQLException s)
216        {
217          reportException(methodCall, s);
218          throw s;
219        }
220      }
221    
222      public boolean wasNull() throws SQLException
223      {
224        String methodCall = "wasNull()";
225        try
226        {
227          return reportReturn(methodCall, realCallableStatement.wasNull());
228        }
229        catch (SQLException s)
230        {
231          reportException(methodCall, s);
232          throw s;
233        }
234      }
235    
236      public Time getTime(int parameterIndex) throws SQLException
237      {
238        String methodCall = "getTime(" + parameterIndex + ")";
239        try
240        {
241          return (Time) reportReturn(methodCall, realCallableStatement.getTime(parameterIndex));
242        }
243        catch (SQLException s)
244        {
245          reportException(methodCall, s);
246          throw s;
247        }
248      }
249    
250      public Time getTime(int parameterIndex, Calendar cal) throws SQLException
251      {
252        String methodCall = "getTime(" + parameterIndex + ", " + cal + ")";
253        try
254        {
255          return (Time) reportReturn(methodCall, realCallableStatement.getTime(parameterIndex, cal));
256        }
257        catch (SQLException s)
258        {
259          reportException(methodCall, s);
260          throw s;
261        }
262      }
263    
264      public Timestamp getTimestamp(String parameterName) throws SQLException
265      {
266        String methodCall = "getTimestamp(" + parameterName + ")";
267        try
268        {
269          return (Timestamp) reportReturn(methodCall, realCallableStatement.getTimestamp(parameterName));
270        }
271        catch (SQLException s)
272        {
273          reportException(methodCall, s);
274          throw s;
275        }
276      }
277    
278      public void setTimestamp(String parameterName, Timestamp x) throws SQLException
279      {
280        String methodCall = "setTimestamp(" + parameterName + ", " + x + ")";
281        try
282        {
283          realCallableStatement.setTimestamp(parameterName, x);
284        }
285        catch (SQLException s)
286        {
287          reportException(methodCall, s);
288          throw s;
289        }
290        reportReturn(methodCall);
291      }
292    
293      public String getString(int parameterIndex) throws SQLException
294      {
295        String methodCall = "getString(" + parameterIndex + ")";
296        try
297        {
298          return (String) reportReturn(methodCall, realCallableStatement.getString(parameterIndex));
299        }
300        catch (SQLException s)
301        {
302          reportException(methodCall, s);
303          throw s;
304        }
305      }
306    
307      public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException
308      {
309        String methodCall = "registerOutParameter(" + parameterIndex + ", " + sqlType + ")";
310        argTraceSet(parameterIndex, null, "<OUT>");
311        try
312        {
313          realCallableStatement.registerOutParameter(parameterIndex, sqlType);
314        }
315        catch (SQLException s)
316        {
317          reportException(methodCall, s);
318          throw s;
319        }
320        reportReturn(methodCall);
321      }
322    
323      public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException
324      {
325        String methodCall = "registerOutParameter(" + parameterIndex + ", " + sqlType + ", " + scale + ")";
326        argTraceSet(parameterIndex, null, "<OUT>");
327        try
328        {
329          realCallableStatement.registerOutParameter(parameterIndex, sqlType, scale);
330        }
331        catch (SQLException s)
332        {
333          reportException(methodCall, s);
334          throw s;
335        }
336        reportReturn(methodCall);
337      }
338    
339      public void registerOutParameter(int paramIndex, int sqlType, String typeName) throws SQLException
340      {
341        String methodCall = "registerOutParameter(" + paramIndex + ", " + sqlType + ", " + typeName + ")";
342        argTraceSet(paramIndex, null, "<OUT>");
343        try
344        {
345          realCallableStatement.registerOutParameter(paramIndex, sqlType, typeName);
346        }
347        catch (SQLException s)
348        {
349          reportException(methodCall, s);
350          throw s;
351        }
352        reportReturn(methodCall);
353      }
354    
355      public byte getByte(String parameterName) throws SQLException
356      {
357        String methodCall = "getByte(" + parameterName + ")";
358        try
359        {
360          return reportReturn(methodCall, realCallableStatement.getByte(parameterName));
361        }
362        catch (SQLException s)
363        {
364          reportException(methodCall, s);
365          throw s;
366        }
367      }
368    
369      public double getDouble(String parameterName) throws SQLException
370      {
371        String methodCall = "getDouble(" + parameterName + ")";
372        try
373        {
374          return reportReturn(methodCall, realCallableStatement.getDouble(parameterName));
375        }
376        catch (SQLException s)
377        {
378          reportException(methodCall, s);
379          throw s;
380        }
381      }
382    
383      public float getFloat(String parameterName) throws SQLException
384      {
385        String methodCall = "getFloat(" + parameterName + ")";
386        try
387        {
388          return reportReturn(methodCall, realCallableStatement.getFloat(parameterName));
389        }
390        catch (SQLException s)
391        {
392          reportException(methodCall, s);
393          throw s;
394        }
395      }
396    
397      public int getInt(String parameterName) throws SQLException
398      {
399        String methodCall = "getInt(" + parameterName + ")";
400        try
401        {
402          return reportReturn(methodCall, realCallableStatement.getInt(parameterName));
403        }
404        catch (SQLException s)
405        {
406          reportException(methodCall, s);
407          throw s;
408        }
409      }
410    
411      public long getLong(String parameterName) throws SQLException
412      {
413        String methodCall = "getLong(" + parameterName + ")";
414        try
415        {
416          return reportReturn(methodCall, realCallableStatement.getLong(parameterName));
417        }
418        catch (SQLException s)
419        {
420          reportException(methodCall, s);
421          throw s;
422        }
423      }
424    
425      public short getShort(String parameterName) throws SQLException
426      {
427        String methodCall = "getShort(" + parameterName + ")";
428        try
429        {
430          return reportReturn(methodCall, realCallableStatement.getShort(parameterName));
431        }
432        catch (SQLException s)
433        {
434          reportException(methodCall, s);
435          throw s;
436        }
437      }
438    
439      public boolean getBoolean(String parameterName) throws SQLException
440      {
441        String methodCall = "getBoolean(" + parameterName + ")";
442        try
443        {
444          return reportReturn(methodCall, realCallableStatement.getBoolean(parameterName));
445        }
446        catch (SQLException s)
447        {
448          reportException(methodCall, s);
449          throw s;
450        }
451      }
452    
453      public byte[] getBytes(String parameterName) throws SQLException
454      {
455        String methodCall = "getBytes(" + parameterName + ")";
456        try
457        {
458          return (byte[]) reportReturn(methodCall, realCallableStatement.getBytes(parameterName));
459        }
460        catch (SQLException s)
461        {
462          reportException(methodCall, s);
463          throw s;
464        }
465      }
466    
467      public void setByte(String parameterName, byte x) throws SQLException
468      {
469        String methodCall = "setByte(" + parameterName + ", " + x + ")";
470        try
471        {
472          realCallableStatement.setByte(parameterName, x);
473        }
474        catch (SQLException s)
475        {
476          reportException(methodCall, s);
477          throw s;
478        }
479        reportReturn(methodCall);
480      }
481    
482      public void setDouble(String parameterName, double x) throws SQLException
483      {
484        String methodCall = "setDouble(" + parameterName + ", " + x + ")";
485        try
486        {
487          realCallableStatement.setDouble(parameterName, x);
488        }
489        catch (SQLException s)
490        {
491          reportException(methodCall, s);
492          throw s;
493        }
494        reportReturn(methodCall);
495      }
496    
497      public void setFloat(String parameterName, float x) throws SQLException
498      {
499        String methodCall = "setFloat(" + parameterName + ", " + x + ")";
500        try
501        {
502          realCallableStatement.setFloat(parameterName, x);
503        }
504        catch (SQLException s)
505        {
506          reportException(methodCall, s);
507          throw s;
508        }
509        reportReturn(methodCall);
510      }
511    
512      public void registerOutParameter(String parameterName, int sqlType) throws SQLException
513      {
514        String methodCall = "registerOutParameter(" + parameterName + ", " + sqlType + ")";
515        try
516        {
517          realCallableStatement.registerOutParameter(parameterName, sqlType);
518        }
519        catch (SQLException s)
520        {
521          reportException(methodCall, s);
522          throw s;
523        }
524        reportReturn(methodCall);
525      }
526    
527      public void setInt(String parameterName, int x) throws SQLException
528      {
529        String methodCall = "setInt(" + parameterName + ", " + x + ")";
530        try
531        {
532          realCallableStatement.setInt(parameterName, x);
533        }
534        catch (SQLException s)
535        {
536          reportException(methodCall, s);
537          throw s;
538        }
539        reportReturn(methodCall);
540      }
541    
542      public void setNull(String parameterName, int sqlType) throws SQLException
543      {
544        String methodCall = "setNull(" + parameterName + ", " + sqlType + ")";
545        try
546        {
547          realCallableStatement.setNull(parameterName, sqlType);
548        }
549        catch (SQLException s)
550        {
551          reportException(methodCall, s);
552          throw s;
553        }
554        reportReturn(methodCall);
555      }
556    
557      public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException
558      {
559        String methodCall = "registerOutParameter(" + parameterName + ", " + sqlType + ", " + scale + ")";
560        try
561        {
562          realCallableStatement.registerOutParameter(parameterName, sqlType, scale);
563        }
564        catch (SQLException s)
565        {
566          reportException(methodCall, s);
567          throw s;
568        }
569        reportReturn(methodCall);
570      }
571    
572      public void setLong(String parameterName, long x) throws SQLException
573      {
574        String methodCall = "setLong(" + parameterName + ", " + x + ")";
575        try
576        {
577          realCallableStatement.setLong(parameterName, x);
578        }
579        catch (SQLException s)
580        {
581          reportException(methodCall, s);
582          throw s;
583        }
584        reportReturn(methodCall);
585      }
586    
587      public void setShort(String parameterName, short x) throws SQLException
588      {
589        String methodCall = "setShort(" + parameterName + ", " + x + ")";
590        try
591        {
592          realCallableStatement.setShort(parameterName, x);
593        }
594        catch (SQLException s)
595        {
596          reportException(methodCall, s);
597          throw s;
598        }
599        reportReturn(methodCall);
600      }
601    
602      public void setBoolean(String parameterName, boolean x) throws SQLException
603      {
604        String methodCall = "setBoolean(" + parameterName + ", " + x + ")";
605        try
606        {
607          realCallableStatement.setBoolean(parameterName, x);
608        }
609        catch (SQLException s)
610        {
611          reportException(methodCall, s);
612          throw s;
613        }
614        reportReturn(methodCall);
615      }
616    
617      public void setBytes(String parameterName, byte[] x) throws SQLException
618      {
619        //todo: dump byte array?
620        String methodCall = "setBytes(" + parameterName + ", " + x + ")";
621        try
622        {
623          realCallableStatement.setBytes(parameterName, x);
624        }
625        catch (SQLException s)
626        {
627          reportException(methodCall, s);
628          throw s;
629        }
630        reportReturn(methodCall);
631      }
632    
633      public boolean getBoolean(int parameterIndex) throws SQLException
634      {
635        String methodCall = "getBoolean(" + parameterIndex + ")";
636        try
637        {
638          return reportReturn(methodCall, realCallableStatement.getBoolean(parameterIndex));
639        }
640        catch (SQLException s)
641        {
642          reportException(methodCall, s);
643          throw s;
644        }
645      }
646    
647      public Timestamp getTimestamp(int parameterIndex) throws SQLException
648      {
649        String methodCall = "getTimestamp(" + parameterIndex + ")";
650        try
651        {
652          return (Timestamp) reportReturn(methodCall, realCallableStatement.getTimestamp(parameterIndex));
653        }
654        catch (SQLException s)
655        {
656          reportException(methodCall, s);
657          throw s;
658        }
659      }
660    
661      public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException
662      {
663        String methodCall = "setAsciiStream(" + parameterName + ", " + x + ", " + length + ")";
664        try
665        {
666          realCallableStatement.setAsciiStream(parameterName, x, length);
667        }
668        catch (SQLException s)
669        {
670          reportException(methodCall, s);
671          throw s;
672        }
673        reportReturn(methodCall);
674      }
675    
676      public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException
677      {
678        String methodCall = "setBinaryStream(" + parameterName + ", " + x + ", " + length + ")";
679        try
680        {
681          realCallableStatement.setBinaryStream(parameterName, x, length);
682        }
683        catch (SQLException s)
684        {
685          reportException(methodCall, s);
686          throw s;
687        }
688        reportReturn(methodCall);
689      }
690    
691      public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException
692      {
693        String methodCall = "setCharacterStream(" + parameterName + ", " + reader + ", " + length + ")";
694        try
695        {
696          realCallableStatement.setCharacterStream(parameterName, reader, length);
697        }
698        catch (SQLException s)
699        {
700          reportException(methodCall, s);
701          throw s;
702        }
703        reportReturn(methodCall);
704      }
705    
706      public Object getObject(String parameterName) throws SQLException
707      {
708        String methodCall = "getObject(" + parameterName + ")";
709        try
710        {
711          return reportReturn(methodCall, realCallableStatement.getObject(parameterName));
712        }
713        catch (SQLException s)
714        {
715          reportException(methodCall, s);
716          throw s;
717        }
718      }
719    
720      public void setObject(String parameterName, Object x) throws SQLException
721      {
722        String methodCall = "setObject(" + parameterName + ", " + x + ")";
723        try
724        {
725          realCallableStatement.setObject(parameterName, x);
726        }
727        catch (SQLException s)
728        {
729          reportException(methodCall, s);
730          throw s;
731        }
732        reportReturn(methodCall);
733      }
734    
735      public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException
736      {
737        String methodCall = "setObject(" + parameterName + ", " + x + ", " + targetSqlType + ")";
738        try
739        {
740          realCallableStatement.setObject(parameterName, x, targetSqlType);
741        }
742        catch (SQLException s)
743        {
744          reportException(methodCall, s);
745          throw s;
746        }
747        reportReturn(methodCall);
748      }
749    
750      public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException
751      {
752        String methodCall = "setObject(" + parameterName + ", " + x + ", " + targetSqlType + ", " + scale + ")";
753        try
754        {
755          realCallableStatement.setObject(parameterName, x, targetSqlType, scale);
756        }
757        catch (SQLException s)
758        {
759          reportException(methodCall, s);
760          throw s;
761        }
762        reportReturn(methodCall);
763      }
764    
765      public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException
766      {
767        String methodCall = "getTimestamp(" + parameterIndex + ", " + cal + ")";
768        try
769        {
770          return (Timestamp) reportReturn(methodCall, realCallableStatement.getTimestamp(parameterIndex, cal));
771        }
772        catch (SQLException s)
773        {
774          reportException(methodCall, s);
775          throw s;
776        }
777      }
778    
779      public Date getDate(String parameterName, Calendar cal) throws SQLException
780      {
781        String methodCall = "getDate(" + parameterName + ", " + cal + ")";
782        try
783        {
784          return (Date) reportReturn(methodCall, realCallableStatement.getDate(parameterName, cal));
785        }
786        catch (SQLException s)
787        {
788          reportException(methodCall, s);
789          throw s;
790        }
791      }
792    
793      public Time getTime(String parameterName, Calendar cal) throws SQLException
794      {
795        String methodCall = "getTime(" + parameterName + ", " + cal + ")";
796        try
797        {
798          return (Time) reportReturn(methodCall, realCallableStatement.getTime(parameterName, cal));
799        }
800        catch (SQLException s)
801        {
802          reportException(methodCall, s);
803          throw s;
804        }
805      }
806    
807      public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException
808      {
809        String methodCall = "getTimestamp(" + parameterName + ", " + cal + ")";
810        try
811        {
812          return (Timestamp) reportReturn(methodCall, realCallableStatement.getTimestamp(parameterName, cal));
813        }
814        catch (SQLException s)
815        {
816          reportException(methodCall, s);
817          throw s;
818        }
819      }
820    
821      public void setDate(String parameterName, Date x, Calendar cal) throws SQLException
822      {
823        String methodCall = "setDate(" + parameterName + ", " + x + ", " + cal + ")";
824        try
825        {
826          realCallableStatement.setDate(parameterName, x, cal);
827        }
828        catch (SQLException s)
829        {
830          reportException(methodCall, s);
831          throw s;
832        }
833        reportReturn(methodCall);
834      }
835    
836      public void setTime(String parameterName, Time x, Calendar cal) throws SQLException
837      {
838        String methodCall = "setTime(" + parameterName + ", " + x + ", " + cal + ")";
839        try
840        {
841          realCallableStatement.setTime(parameterName, x, cal);
842        }
843        catch (SQLException s)
844        {
845          reportException(methodCall, s);
846          throw s;
847        }
848        reportReturn(methodCall);
849      }
850    
851      public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException
852      {
853        String methodCall = "setTimestamp(" + parameterName + ", " + x + ", " + cal + ")";
854        try
855        {
856          realCallableStatement.setTimestamp(parameterName, x, cal);
857        }
858        catch (SQLException s)
859        {
860          reportException(methodCall, s);
861          throw s;
862        }
863        reportReturn(methodCall);
864      }
865    
866      public short getShort(int parameterIndex) throws SQLException
867      {
868        String methodCall = "getShort(" + parameterIndex + ")";
869        try
870        {
871          return reportReturn(methodCall, realCallableStatement.getShort(parameterIndex));
872        }
873        catch (SQLException s)
874        {
875          reportException(methodCall, s);
876          throw s;
877        }
878      }
879    
880      public long getLong(int parameterIndex) throws SQLException
881      {
882        String methodCall = "getLong(" + parameterIndex + ")";
883        try
884        {
885          return reportReturn(methodCall, realCallableStatement.getLong(parameterIndex));
886        }
887        catch (SQLException s)
888        {
889          reportException(methodCall, s);
890          throw s;
891        }
892      }
893    
894      public float getFloat(int parameterIndex) throws SQLException
895      {
896        String methodCall = "getFloat(" + parameterIndex + ")";
897        try
898        {
899          return reportReturn(methodCall, realCallableStatement.getFloat(parameterIndex));
900        }
901        catch (SQLException s)
902        {
903          reportException(methodCall, s);
904          throw s;
905        }
906      }
907    
908      public Ref getRef(int i) throws SQLException
909      {
910        String methodCall = "getRef(" + i + ")";
911        try
912        {
913          return (Ref) reportReturn(methodCall, realCallableStatement.getRef(i));
914        }
915        catch (SQLException s)
916        {
917          reportException(methodCall, s);
918          throw s;
919        }
920      }
921    
922      /**
923       * @deprecated
924       */
925      public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException
926      {
927        String methodCall = "getBigDecimal(" + parameterIndex + ", " + scale + ")";
928        try
929        {
930          return (BigDecimal) reportReturn(methodCall, realCallableStatement.getBigDecimal(parameterIndex, scale));
931        }
932        catch (SQLException s)
933        {
934          reportException(methodCall, s);
935          throw s;
936        }
937      }
938    
939      public URL getURL(int parameterIndex) throws SQLException
940      {
941        String methodCall = "getURL(" + parameterIndex + ")";
942        try
943        {
944          return (URL) reportReturn(methodCall, realCallableStatement.getURL(parameterIndex));
945        }
946        catch (SQLException s)
947        {
948          reportException(methodCall, s);
949          throw s;
950        }
951    
952      }
953    
954      public BigDecimal getBigDecimal(int parameterIndex) throws SQLException
955      {
956        String methodCall = "getBigDecimal(" + parameterIndex + ")";
957        try
958        {
959          return (BigDecimal) reportReturn(methodCall, realCallableStatement.getBigDecimal(parameterIndex));
960        }
961        catch (SQLException s)
962        {
963          reportException(methodCall, s);
964          throw s;
965        }
966      }
967    
968      public byte getByte(int parameterIndex) throws SQLException
969      {
970        String methodCall = "getByte(" + parameterIndex + ")";
971        try
972        {
973          return reportReturn(methodCall, realCallableStatement.getByte(parameterIndex));
974        }
975        catch (SQLException s)
976        {
977          reportException(methodCall, s);
978          throw s;
979        }
980      }
981    
982      public Object getObject(int parameterIndex) throws SQLException
983      {
984        String methodCall = "getObject(" + parameterIndex + ")";
985        try
986        {
987          return reportReturn(methodCall, realCallableStatement.getObject(parameterIndex));
988        }
989        catch (SQLException s)
990        {
991          reportException(methodCall, s);
992          throw s;
993        }
994      }
995    
996      public Object getObject(int i, Map map) throws SQLException
997      {
998        String methodCall = "getObject(" + i + ", " + map + ")";
999        try
1000        {
1001          return reportReturn(methodCall, realCallableStatement.getObject(i, map));
1002        }
1003        catch (SQLException s)
1004        {
1005          reportException(methodCall, s);
1006          throw s;
1007        }
1008      }
1009    
1010      public String getString(String parameterName) throws SQLException
1011      {
1012        String methodCall = "getString(" + parameterName + ")";
1013        try
1014        {
1015          return (String) reportReturn(methodCall, realCallableStatement.getString(parameterName));
1016        }
1017        catch (SQLException s)
1018        {
1019          reportException(methodCall, s);
1020          throw s;
1021        }
1022      }
1023    
1024      public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException
1025      {
1026        String methodCall = "registerOutParameter(" + parameterName + ", " + sqlType + ", " + typeName + ")";
1027        try
1028        {
1029          realCallableStatement.registerOutParameter(parameterName, sqlType, typeName);
1030        }
1031        catch (SQLException s)
1032        {
1033          reportException(methodCall, s);
1034          throw s;
1035        }
1036        reportReturn(methodCall);
1037      }
1038    
1039      public void setNull(String parameterName, int sqlType, String typeName) throws SQLException
1040      {
1041        String methodCall = "setNull(" + parameterName + ", " + sqlType + ", " + typeName + ")";
1042        try
1043        {
1044          realCallableStatement.setNull(parameterName, sqlType, typeName);
1045        }
1046        catch (SQLException s)
1047        {
1048          reportException(methodCall, s);
1049          throw s;
1050        }
1051        reportReturn(methodCall);
1052      }
1053    
1054      public void setString(String parameterName, String x) throws SQLException
1055      {
1056        String methodCall = "setString(" + parameterName + ", " + x + ")";
1057    
1058        try
1059        {
1060          realCallableStatement.setString(parameterName, x);
1061        }
1062        catch (SQLException s)
1063        {
1064          reportException(methodCall, s);
1065          throw s;
1066        }
1067        reportReturn(methodCall);
1068      }
1069    
1070      public BigDecimal getBigDecimal(String parameterName) throws SQLException
1071      {
1072        String methodCall = "getBigDecimal(" + parameterName + ")";
1073        try
1074        {
1075          return (BigDecimal) reportReturn(methodCall, realCallableStatement.getBigDecimal(parameterName));
1076        }
1077        catch (SQLException s)
1078        {
1079          reportException(methodCall, s);
1080          throw s;
1081        }
1082      }
1083    
1084      public Object getObject(String parameterName, Map<String, Class<?>> map) throws SQLException {
1085        String methodCall = "getObject(" + parameterName + ", " + map + ")";
1086        try
1087        {
1088          return reportReturn(methodCall, realCallableStatement.getObject(parameterName, map));
1089        }
1090        catch (SQLException s)
1091        {
1092          reportException(methodCall, s);
1093          throw s;
1094        }
1095      }
1096    
1097      public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException
1098      {
1099        String methodCall = "setBigDecimal(" + parameterName + ", " + x + ")";
1100        try
1101        {
1102          realCallableStatement.setBigDecimal(parameterName, x);
1103        }
1104        catch (SQLException s)
1105        {
1106          reportException(methodCall, s);
1107          throw s;
1108        }
1109        reportReturn(methodCall);
1110      }
1111    
1112      public URL getURL(String parameterName) throws SQLException
1113      {
1114        String methodCall = "getURL(" + parameterName + ")";
1115        try
1116        {
1117          return (URL) reportReturn(methodCall, realCallableStatement.getURL(parameterName));
1118        }
1119        catch (SQLException s)
1120        {
1121          reportException(methodCall, s);
1122          throw s;
1123        }
1124      }
1125    
1126      public RowId getRowId(int parameterIndex) throws SQLException {
1127        String methodCall = "getRowId(" + parameterIndex + ")";
1128        try
1129        {
1130          return (RowId) reportReturn(methodCall, realCallableStatement.getRowId(parameterIndex));
1131        }
1132        catch (SQLException s)
1133        {
1134          reportException(methodCall, s);
1135          throw s;
1136        }
1137      }
1138    
1139      public RowId getRowId(String parameterName) throws SQLException {
1140        String methodCall = "getRowId(" + parameterName + ")";
1141        try
1142        {
1143          return (RowId) reportReturn(methodCall, realCallableStatement.getRowId(parameterName));
1144        }
1145        catch (SQLException s)
1146        {
1147          reportException(methodCall, s);
1148          throw s;
1149        }
1150      }
1151    
1152      public void setRowId(String parameterName, RowId x) throws SQLException {
1153        String methodCall = "setRowId(" + parameterName + ", " + x + ")";
1154        try
1155        {
1156          realCallableStatement.setRowId(parameterName, x);
1157        }
1158        catch (SQLException s)
1159        {
1160          reportException(methodCall, s);
1161          throw s;
1162        }
1163        reportReturn(methodCall);
1164      }
1165    
1166      public void setNString(String parameterName, String value) throws SQLException {
1167        String methodCall = "setNString(" + parameterName + ", " + value + ")";
1168        try
1169        {
1170          realCallableStatement.setNString(parameterName, value);
1171        }
1172        catch (SQLException s)
1173        {
1174          reportException(methodCall, s);
1175          throw s;
1176        }
1177        reportReturn(methodCall);
1178      }
1179    
1180      public void setNCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
1181        String methodCall = "setNCharacterStream(" + parameterName + ", " + reader + ", " + length + ")";
1182        try
1183        {
1184          realCallableStatement.setNCharacterStream(parameterName, reader, length);
1185        }
1186        catch (SQLException s)
1187        {
1188          reportException(methodCall, s);
1189          throw s;
1190        }
1191        reportReturn(methodCall);
1192      }
1193    
1194      public void setNClob(String parameterName, NClob value) throws SQLException {
1195        String methodCall = "setNClob(" + parameterName + ", " + value + ")";
1196        try
1197        {
1198          realCallableStatement.setNClob(parameterName, value);
1199        }
1200        catch (SQLException s)
1201        {
1202          reportException(methodCall, s);
1203          throw s;
1204        }
1205        reportReturn(methodCall);
1206      }
1207    
1208      public void setClob(String parameterName, Reader reader, long length) throws SQLException {
1209        String methodCall = "setClob(" + parameterName + ", " + reader + ", " + length + ")";
1210        try
1211        {
1212          realCallableStatement.setClob(parameterName, reader, length);
1213        }
1214        catch (SQLException s)
1215        {
1216          reportException(methodCall, s);
1217          throw s;
1218        }
1219        reportReturn(methodCall);
1220      }
1221    
1222      public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
1223        String methodCall = "setBlob(" + parameterName + ", " + inputStream + ", " + length + ")";
1224        try
1225        {
1226          realCallableStatement.setBlob(parameterName, inputStream, length);
1227        }
1228        catch (SQLException s)
1229        {
1230          reportException(methodCall, s);
1231          throw s;
1232        }
1233        reportReturn(methodCall);
1234      }
1235    
1236      public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
1237        String methodCall = "setNClob(" + parameterName + ", " + reader + ", " + length + ")";
1238        try
1239        {
1240          realCallableStatement.setNClob(parameterName, reader, length);
1241        }
1242        catch (SQLException s)
1243        {
1244          reportException(methodCall, s);
1245          throw s;
1246        }
1247        reportReturn(methodCall);
1248      }
1249    
1250      public NClob getNClob(int parameterIndex) throws SQLException {
1251        String methodCall = "getNClob(" + parameterIndex + ")";
1252        try
1253        {
1254          return (NClob) reportReturn(methodCall, realCallableStatement.getNClob(parameterIndex));
1255        }
1256        catch (SQLException s)
1257        {
1258          reportException(methodCall, s);
1259          throw s;
1260        }
1261      }
1262    
1263      public NClob getNClob(String parameterName) throws SQLException {
1264        String methodCall = "getNClob(" + parameterName + ")";
1265        try
1266        {
1267          return (NClob) reportReturn(methodCall, realCallableStatement.getNClob(parameterName));
1268        }
1269        catch (SQLException s)
1270        {
1271          reportException(methodCall, s);
1272          throw s;
1273        }
1274      }
1275    
1276      public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
1277        String methodCall = "setSQLXML(" + parameterName + ", " + xmlObject + ")";
1278        try
1279        {
1280          realCallableStatement.setSQLXML(parameterName, xmlObject);
1281        }
1282        catch (SQLException s)
1283        {
1284          reportException(methodCall, s);
1285          throw s;
1286        }
1287        reportReturn(methodCall);
1288      }
1289    
1290      public SQLXML getSQLXML(int parameterIndex) throws SQLException {
1291        String methodCall = "getSQLXML(" + parameterIndex + ")";
1292        try
1293        {
1294          return (SQLXML) reportReturn(methodCall, realCallableStatement.getSQLXML(parameterIndex));
1295        }
1296        catch (SQLException s)
1297        {
1298          reportException(methodCall, s);
1299          throw s;
1300        }
1301      }
1302    
1303      public SQLXML getSQLXML(String parameterName) throws SQLException {
1304        String methodCall = "getSQLXML(" + parameterName + ")";
1305        try
1306        {
1307          return (SQLXML) reportReturn(methodCall, realCallableStatement.getSQLXML(parameterName));
1308        }
1309        catch (SQLException s)
1310        {
1311          reportException(methodCall, s);
1312          throw s;
1313        }
1314    
1315      }
1316    
1317      public String getNString(int parameterIndex) throws SQLException {
1318        String methodCall = "getNString(" + parameterIndex + ")";
1319        try
1320        {
1321          return (String) reportReturn(methodCall, realCallableStatement.getNString(parameterIndex));
1322        }
1323        catch (SQLException s)
1324        {
1325          reportException(methodCall, s);
1326          throw s;
1327        }
1328      }
1329    
1330      public String getNString(String parameterName) throws SQLException {
1331        String methodCall = "getNString(" + parameterName + ")";
1332        try
1333        {
1334          return (String) reportReturn(methodCall, realCallableStatement.getNString(parameterName));
1335        }
1336        catch (SQLException s)
1337        {
1338          reportException(methodCall, s);
1339          throw s;
1340        }
1341      }
1342    
1343      public Reader getNCharacterStream(int parameterIndex) throws SQLException {
1344        String methodCall = "getNCharacterStream(" + parameterIndex + ")";
1345        try
1346        {
1347          return (Reader) reportReturn(methodCall, realCallableStatement.getNCharacterStream(parameterIndex));
1348        }
1349        catch (SQLException s)
1350        {
1351          reportException(methodCall, s);
1352          throw s;
1353        }
1354      }
1355    
1356      public Reader getNCharacterStream(String parameterName) throws SQLException {
1357        String methodCall = "getNCharacterStream(" + parameterName + ")";
1358        try
1359        {
1360          return (Reader) reportReturn(methodCall, realCallableStatement.getNCharacterStream(parameterName));
1361        }
1362        catch (SQLException s)
1363        {
1364          reportException(methodCall, s);
1365          throw s;
1366        }
1367      }
1368    
1369      public Reader getCharacterStream(int parameterIndex) throws SQLException {
1370        String methodCall = "getCharacterStream(" + parameterIndex + ")";
1371        try
1372        {
1373          return (Reader) reportReturn(methodCall, realCallableStatement.getCharacterStream(parameterIndex));
1374        }
1375        catch (SQLException s)
1376        {
1377          reportException(methodCall, s);
1378          throw s;
1379        }
1380      }
1381    
1382      public Reader getCharacterStream(String parameterName) throws SQLException {
1383        String methodCall = "getCharacterStream(" + parameterName + ")";
1384        try
1385        {
1386          return (Reader) reportReturn(methodCall, realCallableStatement.getCharacterStream(parameterName));
1387        }
1388        catch (SQLException s)
1389        {
1390          reportException(methodCall, s);
1391          throw s;
1392        }
1393      }
1394    
1395      public void setBlob(String parameterName, Blob x) throws SQLException {
1396        String methodCall = "setBlob(" + parameterName + ", " + x + ")";
1397        try
1398        {
1399          realCallableStatement.setBlob(parameterName, x);
1400        }
1401        catch (SQLException s)
1402        {
1403          reportException(methodCall, s);
1404          throw s;
1405        }
1406        reportReturn(methodCall);
1407      }
1408    
1409      public void setClob(String parameterName, Clob x) throws SQLException {
1410        String methodCall = "setClob(" + parameterName + ", " + x + ")";
1411        try
1412        {
1413          realCallableStatement.setClob(parameterName, x);
1414        }
1415        catch (SQLException s)
1416        {
1417          reportException(methodCall, s);
1418          throw s;
1419        }
1420        reportReturn(methodCall);
1421      }
1422    
1423      public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
1424        String methodCall = "setAsciiStream(" + parameterName + ", " + x + ", " + length + ")";
1425        try
1426        {
1427          realCallableStatement.setAsciiStream(parameterName, x, length);
1428        }
1429        catch (SQLException s)
1430        {
1431          reportException(methodCall, s);
1432          throw s;
1433        }
1434        reportReturn(methodCall);
1435      }
1436    
1437      public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
1438        String methodCall = "setBinaryStream(" + parameterName + ", " + x + ", " + length + ")";
1439        try
1440        {
1441          realCallableStatement.setBinaryStream(parameterName, x, length);
1442        }
1443        catch (SQLException s)
1444        {
1445          reportException(methodCall, s);
1446          throw s;
1447        }
1448        reportReturn(methodCall);
1449      }
1450    
1451      public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
1452        String methodCall = "setCharacterStream(" + parameterName + ", " + reader + ", " + length + ")";
1453        try
1454        {
1455          realCallableStatement.setCharacterStream(parameterName, reader, length);
1456        }
1457        catch (SQLException s)
1458        {
1459          reportException(methodCall, s);
1460          throw s;
1461        }
1462        reportReturn(methodCall);
1463      }
1464    
1465      public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
1466        String methodCall = "setAsciiStream(" + parameterName + ", " + x + ")";
1467        try
1468        {
1469          realCallableStatement.setAsciiStream(parameterName, x);
1470        }
1471        catch (SQLException s)
1472        {
1473          reportException(methodCall, s);
1474          throw s;
1475        }
1476        reportReturn(methodCall);
1477      }
1478    
1479      public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
1480        String methodCall = "setBinaryStream(" + parameterName + ", " + x + ")";
1481        try
1482        {
1483          realCallableStatement.setBinaryStream(parameterName, x);
1484        }
1485        catch (SQLException s)
1486        {
1487          reportException(methodCall, s);
1488          throw s;
1489        }
1490        reportReturn(methodCall);
1491      }
1492    
1493      public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
1494        String methodCall = "setCharacterStream(" + parameterName + ", " + reader + ")";
1495        try
1496        {
1497          realCallableStatement.setCharacterStream(parameterName, reader);
1498        }
1499        catch (SQLException s)
1500        {
1501          reportException(methodCall, s);
1502          throw s;
1503        }
1504        reportReturn(methodCall);
1505      }
1506    
1507      public void setNCharacterStream(String parameterName, Reader reader) throws SQLException {
1508        String methodCall = "setNCharacterStream(" + parameterName + ", " + reader + ")";
1509        try
1510        {
1511          realCallableStatement.setNCharacterStream(parameterName, reader);
1512        }
1513        catch (SQLException s)
1514        {
1515          reportException(methodCall, s);
1516          throw s;
1517        }
1518        reportReturn(methodCall);
1519      }
1520    
1521      public void setClob(String parameterName, Reader reader) throws SQLException {
1522        String methodCall = "setClob(" + parameterName + ", " + reader + ")";
1523        try
1524        {
1525          realCallableStatement.setClob(parameterName, reader);
1526        }
1527        catch (SQLException s)
1528        {
1529          reportException(methodCall, s);
1530          throw s;
1531        }
1532        reportReturn(methodCall);
1533      }
1534    
1535      public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
1536        String methodCall = "setBlob(" + parameterName + ", " + inputStream + ")";
1537        try
1538        {
1539          realCallableStatement.setBlob(parameterName, inputStream);
1540        }
1541        catch (SQLException s)
1542        {
1543          reportException(methodCall, s);
1544          throw s;
1545        }
1546        reportReturn(methodCall);
1547      }
1548    
1549      public void setNClob(String parameterName, Reader reader) throws SQLException {
1550        String methodCall = "setNClob(" + parameterName + ", " + reader + ")";
1551        try
1552        {
1553          realCallableStatement.setNClob(parameterName, reader);
1554        }
1555        catch (SQLException s)
1556        {
1557          reportException(methodCall, s);
1558          throw s;
1559        }
1560        reportReturn(methodCall);
1561      }
1562    
1563      public void setURL(String parameterName, URL val) throws SQLException
1564      {
1565        String methodCall = "setURL(" + parameterName + ", " + val + ")";
1566        try
1567        {
1568          realCallableStatement.setURL(parameterName, val);
1569        }
1570        catch (SQLException s)
1571        {
1572          reportException(methodCall, s);
1573          throw s;
1574        }
1575        reportReturn(methodCall);
1576      }
1577    
1578      public Array getArray(String parameterName) throws SQLException
1579      {
1580        String methodCall = "getURL(" + parameterName + ")";
1581        try
1582        {
1583          return (Array) reportReturn(methodCall, realCallableStatement.getArray(parameterName));
1584        }
1585        catch (SQLException s)
1586        {
1587          reportException(methodCall, s);
1588          throw s;
1589        }
1590      }
1591    
1592      public Blob getBlob(String parameterName) throws SQLException
1593      {
1594        String methodCall = "getBlob(" + parameterName + ")";
1595        try
1596        {
1597          return (Blob) reportReturn(methodCall, realCallableStatement.getBlob(parameterName));
1598        }
1599        catch (SQLException s)
1600        {
1601          reportException(methodCall, s);
1602          throw s;
1603        }
1604      }
1605    
1606      public Clob getClob(String parameterName) throws SQLException
1607      {
1608        String methodCall = "getClob(" + parameterName + ")";
1609        try
1610        {
1611          return (Clob) reportReturn(methodCall, realCallableStatement.getClob(parameterName));
1612        }
1613        catch (SQLException s)
1614        {
1615          reportException(methodCall, s);
1616          throw s;
1617        }
1618      }
1619    
1620      public Date getDate(String parameterName) throws SQLException
1621      {
1622        String methodCall = "getDate(" + parameterName + ")";
1623        try
1624        {
1625          return (Date) reportReturn(methodCall, realCallableStatement.getDate(parameterName));
1626        }
1627        catch (SQLException s)
1628        {
1629          reportException(methodCall, s);
1630          throw s;
1631        }
1632      }
1633    
1634      public void setDate(String parameterName, Date x) throws SQLException
1635      {
1636        String methodCall = "setDate(" + parameterName + ", " + x + ")";
1637        try
1638        {
1639          realCallableStatement.setDate(parameterName, x);
1640        }
1641        catch (SQLException s)
1642        {
1643          reportException(methodCall, s);
1644          throw s;
1645        }
1646        reportReturn(methodCall);
1647      }
1648    
1649      public <T> T unwrap(Class<T> iface) throws SQLException {
1650        String methodCall = "unwrap(" + (iface==null?"null":iface.getName()) + ")";
1651        try
1652        {
1653          //todo: double check this logic
1654          //NOTE: could call super.isWrapperFor to simplify this logic, but it would result in extra log output
1655          //because the super classes would be invoked, thus executing their logging methods too...
1656          return (T)reportReturn(methodCall,
1657            (iface != null && (iface == CallableStatement.class||iface==PreparedStatement.class||
1658              iface==Statement.class||iface==Spy.class))?
1659              (T)this:
1660              realCallableStatement.unwrap(iface));
1661        }
1662        catch (SQLException s)
1663        {
1664          reportException(methodCall,s);
1665          throw s;
1666        }
1667      }
1668    
1669      public boolean isWrapperFor(Class<?> iface) throws SQLException
1670      {
1671        String methodCall = "isWrapperFor(" + (iface==null?"null":iface.getName()) + ")";
1672        try
1673        {
1674          //NOTE: could call super.isWrapperFor to simplify this logic, but it would result in extra log output
1675          //when the super classes would be invoked..
1676          return reportReturn(methodCall,
1677            (iface != null && (iface == CallableStatement.class||iface==PreparedStatement.class||iface==Statement.class||iface==Spy.class)) ||
1678            realCallableStatement.isWrapperFor(iface));
1679        }
1680        catch (SQLException s)
1681        {
1682          reportException(methodCall,s);
1683          throw s;
1684        }
1685      }
1686    
1687    }