KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc > JDBCUtil


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.ByteArrayOutputStream JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.io.ObjectInputStream JavaDoc;
30 import java.io.ObjectOutputStream JavaDoc;
31 import java.io.Reader JavaDoc;
32
33 import java.lang.reflect.Field JavaDoc;
34 import java.lang.reflect.Method JavaDoc;
35 import java.lang.reflect.InvocationTargetException JavaDoc;
36
37 import java.rmi.MarshalledObject JavaDoc;
38 import java.rmi.RemoteException JavaDoc;
39
40 import java.sql.Connection JavaDoc;
41 import java.sql.ResultSet JavaDoc;
42 import java.sql.Statement JavaDoc;
43 import java.sql.SQLException JavaDoc;
44 import java.sql.Types JavaDoc;
45 import java.sql.CallableStatement JavaDoc;
46
47 import java.util.Map JavaDoc;
48 import java.util.HashMap JavaDoc;
49 import java.math.BigDecimal JavaDoc;
50
51 import javax.ejb.EJBObject JavaDoc;
52 import javax.ejb.Handle JavaDoc;
53
54 import org.jboss.invocation.MarshalledValue;
55 import org.jboss.logging.Logger;
56
57 /**
58  * JDBCUtil takes care of some of the more anoying JDBC tasks.
59  * It hanles safe closing of jdbc resources, setting statement
60  * parameters and loading query results.
61  *
62  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
63  * @author <a HREF="mailto:alex@jboss.org">Alex Loubyansky</a>
64  * @author Steve Coy
65  * @version $Revision: 45069 $
66  */

67 public final class JDBCUtil
68 {
69    private static final Logger log = Logger.getLogger(JDBCUtil.class.getName());
70
71    public static void safeClose(Connection JavaDoc con)
72    {
73       if(con != null)
74       {
75          try
76          {
77             con.close();
78          }
79          catch(Exception JavaDoc e)
80          {
81             log.error(SQL_ERROR, e);
82          }
83       }
84    }
85
86    public static void safeClose(ResultSet JavaDoc rs)
87    {
88       if(rs != null)
89       {
90          try
91          {
92             rs.close();
93          }
94          catch(Exception JavaDoc e)
95          {
96             log.error(SQL_ERROR, e);
97          }
98       }
99    }
100
101    public static void safeClose(Statement JavaDoc statement)
102    {
103       if(statement != null)
104       {
105          try
106          {
107             statement.close();
108          }
109          catch(Exception JavaDoc e)
110          {
111             log.error(SQL_ERROR, e);
112          }
113       }
114    }
115
116    public static void safeClose(InputStream JavaDoc in)
117    {
118       if(in != null)
119       {
120          try
121          {
122             in.close();
123          }
124          catch(Exception JavaDoc e)
125          {
126             log.error(SQL_ERROR, e);
127          }
128       }
129    }
130
131    public static void safeClose(OutputStream JavaDoc out)
132    {
133       if(out != null)
134       {
135          try
136          {
137             out.close();
138          }
139          catch(Exception JavaDoc e)
140          {
141             log.error(SQL_ERROR, e);
142          }
143       }
144    }
145
146    public static void safeClose(Reader JavaDoc reader)
147    {
148       if(reader != null)
149       {
150          try
151          {
152             reader.close();
153          }
154          catch(Exception JavaDoc e)
155          {
156             log.error(SQL_ERROR, e);
157          }
158       }
159    }
160
161    /**
162     * Coerces the input value into the correct type for the specified
163     * jdbcType.
164     *
165     * @param jdbcType the jdbc type to which the value will be assigned
166     * @param value the value to coerce
167     * @return the corrected object
168     */

169    public static Object JavaDoc coerceToSQLType(int jdbcType, Object JavaDoc value)
170    {
171       if(value.getClass() == java.util.Date JavaDoc.class)
172       {
173          if(jdbcType == Types.DATE)
174          {
175             return new java.sql.Date JavaDoc(((java.util.Date JavaDoc)value).getTime());
176          }
177          else if(jdbcType == Types.TIME)
178          {
179             return new java.sql.Time JavaDoc(((java.util.Date JavaDoc)value).getTime());
180          }
181          else if(jdbcType == Types.TIMESTAMP)
182          {
183             return new java.sql.Timestamp JavaDoc(((java.util.Date JavaDoc)value).getTime());
184          }
185       }
186       else if(value.getClass() == Character JavaDoc.class && jdbcType == Types.VARCHAR)
187       {
188          value = value.toString();
189       }
190       return value;
191    }
192
193    /**
194     * Coverts the value into a byte array.
195     * @param value the value to convert into a byte array
196     * @return the byte representation of the value
197     * @throws SQLException if a problem occures in the conversion
198     */

199    public static byte[] convertObjectToByteArray(Object JavaDoc value)
200       throws SQLException JavaDoc
201    {
202       // Do we already have a byte array?
203
if(value instanceof byte[])
204       {
205          return (byte[])value;
206       }
207
208       ByteArrayOutputStream JavaDoc baos = null;
209       ObjectOutputStream JavaDoc oos = null;
210       try
211       {
212          // ejb-reference: store the handle
213
if(value instanceof EJBObject JavaDoc)
214          {
215             value = ((EJBObject JavaDoc)value).getHandle();
216          }
217
218          // Marshall the object using MashalledValue to handle classloaders
219
value = new MarshalledValue(value);
220
221          // return the serialize the value
222
baos = new ByteArrayOutputStream JavaDoc();
223          oos = new ObjectOutputStream JavaDoc(baos);
224          oos.writeObject(value);
225          return baos.toByteArray();
226       }
227       catch(RemoteException JavaDoc e)
228       {
229          throw new SQLException JavaDoc("Cannot get Handle of EJBObject: " + e);
230       }
231       catch(IOException JavaDoc e)
232       {
233          throw new SQLException JavaDoc("Can't serialize binary object: " + e);
234       }
235       finally
236       {
237          safeClose(oos);
238          safeClose(baos);
239       }
240    }
241
242    /**
243     * Coverts the input into an object.
244     * @param input the bytes to convert
245     * @return the object repsentation of the input stream
246     * @throws SQLException if a problem occures in the conversion
247     */

248    public static Object JavaDoc convertToObject(byte[] input)
249       throws SQLException JavaDoc
250    {
251       ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(input);
252       try
253       {
254          return convertToObject(bais);
255       }
256       finally
257       {
258          safeClose(bais);
259       }
260    }
261
262
263    /**
264     * Coverts the input into an object.
265     * @param input the bytes to convert
266     * @return the object repsentation of the input stream
267     * @throws SQLException if a problem occures in the conversion
268     */

269    public static Object JavaDoc convertToObject(InputStream JavaDoc input)
270       throws SQLException JavaDoc
271    {
272       Object JavaDoc value = null;
273       if(input != null)
274       {
275          ObjectInputStream JavaDoc ois = null;
276          try
277          {
278             // deserialize result
279
ois = new ObjectInputStream JavaDoc(input);
280             value = ois.readObject();
281
282             // de-marshall value if possible
283
if(value instanceof MarshalledValue)
284             {
285                value = ((MarshalledValue)value).get();
286             }
287             else if(value instanceof MarshalledObject JavaDoc)
288             {
289                value = ((MarshalledObject JavaDoc)value).get();
290             }
291
292             // ejb-reference: get the object back from the handle
293
if(value instanceof Handle JavaDoc)
294             {
295                value = ((Handle JavaDoc)value).getEJBObject();
296             }
297
298          }
299          catch(RemoteException JavaDoc e)
300          {
301             throw new SQLException JavaDoc("Unable to load EJBObject back from Handle: " + e);
302          }
303          catch(IOException JavaDoc e)
304          {
305             throw new SQLException JavaDoc("Unable to load to deserialize result: " + e);
306          }
307          catch(ClassNotFoundException JavaDoc e)
308          {
309             throw new SQLException JavaDoc("Unable to load to deserialize result: " + e);
310          }
311          finally
312          {
313             // ois will close the input stream it wraps
314
safeClose(ois);
315          }
316       }
317       return value;
318    }
319
320    /**
321     * Get the indicated result set parameter as a character stream and return
322     * it's entire content as a String.
323     *
324     * @param rs the <code>ResultSet</code> from which a result is
325     * being retrieved.
326     * @param index index of the result column.
327     * @return a String containing the content of the result column
328     */

329    public static String JavaDoc getLongString(ResultSet JavaDoc rs, int index)
330       throws SQLException JavaDoc
331    {
332       String JavaDoc value;
333       Reader JavaDoc textData = rs.getCharacterStream(index);
334       if(textData != null)
335       {
336          try
337          {
338             // Use a modest buffer here to reduce function call overhead
339
// when reading extremely large data.
340
StringBuffer JavaDoc textBuffer = new StringBuffer JavaDoc();
341             char[] tmpBuffer = new char[1000];
342             int charsRead;
343             while((charsRead = textData.read(tmpBuffer)) != -1)
344                textBuffer.append(tmpBuffer, 0, charsRead);
345             value = textBuffer.toString();
346          }
347          catch(java.io.IOException JavaDoc ioException)
348          {
349             throw new SQLException JavaDoc(ioException.getMessage());
350          }
351          finally
352          {
353             safeClose(textData);
354          }
355       }
356       else
357          value = null;
358       return value;
359    }
360
361
362    /**
363     * Read the entire input stream provided and return its content as a byte
364     * array.
365     * The method closes the passed in input stream!
366     *
367     * @param input the <code>InputStream</code> from which a result is
368     * being retrieved.
369     * @return a byte array containing the content of the input stream
370     */

371    public static byte[] getByteArray(InputStream JavaDoc input)
372       throws SQLException JavaDoc
373    {
374       ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
375       try
376       {
377          // Use a modest buffer here to reduce function call overhead
378
// when reading extremely large data.
379
byte[] tmpBuffer = new byte[1000];
380          int bytesRead;
381          while((bytesRead = input.read(tmpBuffer)) != -1)
382             baos.write(tmpBuffer, 0, bytesRead);
383          return baos.toByteArray();
384       }
385       catch(java.io.IOException JavaDoc ioException)
386       {
387          throw new SQLException JavaDoc(ioException.getMessage());
388       }
389       finally
390       {
391          safeClose(baos);
392          safeClose(input);
393       }
394    }
395
396    // Inner
397

398    public static JDBCResultSetReader getResultSetReader(int jdbcType, Class JavaDoc destination)
399    {
400       JDBCResultSetReader reader;
401       switch(jdbcType)
402       {
403          case Types.CLOB:
404             reader = JDBCResultSetReader.CLOB_READER;
405             break;
406          case Types.LONGVARCHAR:
407             reader = JDBCResultSetReader.LONGVARCHAR_READER;
408             break;
409          case Types.BINARY:
410             reader = JDBCResultSetReader.BINARY_READER;
411             break;
412          case Types.VARBINARY:
413             reader = JDBCResultSetReader.VARBINARY_READER;
414             break;
415          case Types.BLOB:
416             reader = JDBCResultSetReader.BLOB_READER;
417             break;
418          case Types.LONGVARBINARY:
419             reader = JDBCResultSetReader.LONGVARBINARY_READER;
420             break;
421          case Types.JAVA_OBJECT:
422             reader = JDBCResultSetReader.JAVA_OBJECT_READER;
423             break;
424          case Types.STRUCT:
425             reader = JDBCResultSetReader.STRUCT_READER;
426             break;
427          case Types.ARRAY:
428             reader = JDBCResultSetReader.ARRAY_READER;
429             break;
430          case Types.OTHER:
431             reader = JDBCResultSetReader.OTHER_READER;
432             break;
433          default:
434             {
435                reader = getResultReaderByType(destination);
436             }
437       }
438       return reader;
439    }
440
441    public static JDBCResultSetReader getResultReaderByType(Class JavaDoc destination)
442    {
443       JDBCResultSetReader reader;
444       if(destination == java.util.Date JavaDoc.class)
445       {
446          reader = JDBCResultSetReader.JAVA_UTIL_DATE_READER;
447       }
448       else if(destination == java.sql.Date JavaDoc.class)
449       {
450          reader = JDBCResultSetReader.JAVA_SQL_DATE_READER;
451       }
452       else if(destination == java.sql.Time JavaDoc.class)
453       {
454          reader = JDBCResultSetReader.JAVA_SQL_TIME_READER;
455       }
456       else if(destination == java.sql.Timestamp JavaDoc.class)
457       {
458          reader = JDBCResultSetReader.JAVA_SQL_TIMESTAMP_READER;
459       }
460       else if(destination == BigDecimal JavaDoc.class)
461       {
462          reader = JDBCResultSetReader.BIGDECIMAL_READER;
463       }
464       else if(destination == java.sql.Ref JavaDoc.class)
465       {
466          reader = JDBCResultSetReader.REF_READER;
467       }
468       else if(destination == String JavaDoc.class)
469       {
470          reader = JDBCResultSetReader.STRING_READER;
471       }
472       else if(destination == Boolean JavaDoc.class || destination == Boolean.TYPE)
473       {
474          reader = JDBCResultSetReader.BOOLEAN_READER;
475       }
476       else if(destination == Byte JavaDoc.class || destination == Byte.TYPE)
477       {
478          reader = JDBCResultSetReader.BYTE_READER;
479       }
480       else if(destination == Character JavaDoc.class || destination == Character.TYPE)
481       {
482          reader = JDBCResultSetReader.CHARACTER_READER;
483       }
484       else if(destination == Short JavaDoc.class || destination == Short.TYPE)
485       {
486          reader = JDBCResultSetReader.SHORT_READER;
487       }
488       else if(destination == Integer JavaDoc.class || destination == Integer.TYPE)
489       {
490          reader = JDBCResultSetReader.INT_READER;
491       }
492       else if(destination == Long JavaDoc.class || destination == Long.TYPE)
493       {
494          reader = JDBCResultSetReader.LONG_READER;
495       }
496       else if(destination == Float JavaDoc.class || destination == Float.TYPE)
497       {
498          reader = JDBCResultSetReader.FLOAT_READER;
499       }
500       else if(destination == Double JavaDoc.class || destination == Double.TYPE)
501       {
502          reader = JDBCResultSetReader.DOUBLE_READER;
503       }
504       else
505       {
506          reader = JDBCResultSetReader.OBJECT_READER;
507       }
508       return reader;
509    }
510
511    public static JDBCParameterSetter getParameterSetter(int jdbcType, Class JavaDoc javaType)
512    {
513       JDBCParameterSetter ps;
514
515       switch(jdbcType)
516       {
517          case Types.CLOB:
518          case Types.LONGVARCHAR:
519             ps = JDBCParameterSetter.CLOB;
520             break;
521
522          case Types.BINARY:
523          case Types.VARBINARY:
524             ps = JDBCParameterSetter.BINARY;
525             break;
526
527          case Types.BLOB:
528          case Types.LONGVARBINARY:
529             ps = JDBCParameterSetter.BLOB;
530             break;
531
532          case Types.DECIMAL:
533          case Types.NUMERIC:
534             ps = JDBCParameterSetter.NUMERIC;
535             break;
536
537          case Types.JAVA_OBJECT:
538          case Types.OTHER:
539          case Types.STRUCT:
540
541          default:
542             ps = JDBCParameterSetter.OBJECT;
543             break;
544       }
545
546       return ps;
547    }
548
549    //
550
// All the above is used only for Oracle specific entity create command
551
// and could be refactored/optimized.
552
//
553

554    private static final Map JavaDoc jdbcTypeNames;
555    private final static Map JavaDoc csTypes;
556
557    /**
558     * Gets the JDBC type name corresponding to the given type code.
559     * Only used in debug log messages.
560     *
561     * @param jdbcType the integer JDBC type code.
562     * @return the JDBC type name.
563     * @see Types
564     */

565    public static String JavaDoc getJDBCTypeName(int jdbcType)
566    {
567       return (String JavaDoc)jdbcTypeNames.get(new Integer JavaDoc(jdbcType));
568    }
569
570    private static final String JavaDoc SQL_ERROR = "SQL error";
571    private static final String JavaDoc GET_TIMESTAMP = "getTimestamp";
572    private static final String JavaDoc GET_DATE = "getDate";
573    private static final String JavaDoc GET_TIME = "getTime";
574    private static final String JavaDoc GET_BIGDECIMAL = "getBigDecimal";
575    private static final String JavaDoc GET_REF = "getRef";
576    private static final String JavaDoc GET_STRING = "getString";
577    private static final String JavaDoc GET_BOOLEAN = "getBoolean";
578    private static final String JavaDoc GET_BYTE = "getByte";
579    private static final String JavaDoc GET_SHORT = "getShort";
580    private static final String JavaDoc GET_INT = "getInt";
581    private static final String JavaDoc GET_LONG = "getLong";
582    private static final String JavaDoc GET_FLOAT = "getFloat";
583    private static final String JavaDoc GET_DOUBLE = "getDouble";
584    private static final String JavaDoc GET_BYTES = "getBytes";
585
586    static
587    {
588       Class JavaDoc[] arg = new Class JavaDoc[]{Integer.TYPE};
589
590       // Initialize the mapping between non-binary java result set
591
// types and the method on CallableStatement that is used to retrieve
592
// a value of the java type.
593
csTypes = new HashMap JavaDoc();
594       try
595       {
596          // java.util.Date
597
csTypes.put(java.util.Date JavaDoc.class.getName(),
598             CallableStatement JavaDoc.class.getMethod(GET_TIMESTAMP, arg));
599          // java.sql.Date
600
csTypes.put(java.sql.Date JavaDoc.class.getName(),
601             CallableStatement JavaDoc.class.getMethod(GET_DATE, arg));
602          // Time
603
csTypes.put(java.sql.Time JavaDoc.class.getName(),
604             CallableStatement JavaDoc.class.getMethod(GET_TIME, arg));
605          // Timestamp
606
csTypes.put(java.sql.Timestamp JavaDoc.class.getName(),
607             CallableStatement JavaDoc.class.getMethod(GET_TIMESTAMP, arg));
608          // BigDecimal
609
csTypes.put(java.math.BigDecimal JavaDoc.class.getName(),
610             CallableStatement JavaDoc.class.getMethod(GET_BIGDECIMAL, arg));
611          // java.sql.Ref Does this really work?
612
csTypes.put(java.sql.Ref JavaDoc.class.getName(),
613             CallableStatement JavaDoc.class.getMethod(GET_REF, arg));
614          // String
615
csTypes.put(java.lang.String JavaDoc.class.getName(),
616             CallableStatement JavaDoc.class.getMethod(GET_STRING, arg));
617          // Boolean
618
csTypes.put(java.lang.Boolean JavaDoc.class.getName(),
619             CallableStatement JavaDoc.class.getMethod(GET_BOOLEAN, arg));
620          // boolean
621
csTypes.put(Boolean.TYPE.getName(),
622             CallableStatement JavaDoc.class.getMethod(GET_BOOLEAN, arg));
623          // Byte
624
csTypes.put(java.lang.Byte JavaDoc.class.getName(),
625             CallableStatement JavaDoc.class.getMethod(GET_BYTE, arg));
626          // byte
627
csTypes.put(Byte.TYPE.getName(),
628             CallableStatement JavaDoc.class.getMethod(GET_BYTE, arg));
629          // Character
630
csTypes.put(java.lang.Character JavaDoc.class.getName(),
631             CallableStatement JavaDoc.class.getMethod(GET_STRING, arg));
632          // char
633
csTypes.put(Character.TYPE.getName(),
634             CallableStatement JavaDoc.class.getMethod(GET_STRING, arg));
635          // Short
636
csTypes.put(java.lang.Short JavaDoc.class.getName(),
637             CallableStatement JavaDoc.class.getMethod(GET_SHORT, arg));
638          // short
639
csTypes.put(Short.TYPE.getName(),
640             CallableStatement JavaDoc.class.getMethod(GET_SHORT, arg));
641          // Integer
642
csTypes.put(java.lang.Integer JavaDoc.class.getName(),
643             CallableStatement JavaDoc.class.getMethod(GET_INT, arg));
644          // int
645
csTypes.put(Integer.TYPE.getName(),
646             CallableStatement JavaDoc.class.getMethod(GET_INT, arg));
647          // Long
648
csTypes.put(java.lang.Long JavaDoc.class.getName(),
649             CallableStatement JavaDoc.class.getMethod(GET_LONG, arg));
650          // long
651
csTypes.put(Long.TYPE.getName(),
652             CallableStatement JavaDoc.class.getMethod(GET_LONG, arg));
653          // Float
654
csTypes.put(java.lang.Float JavaDoc.class.getName(),
655             CallableStatement JavaDoc.class.getMethod(GET_FLOAT, arg));
656          // float
657
csTypes.put(Float.TYPE.getName(),
658             CallableStatement JavaDoc.class.getMethod(GET_FLOAT, arg));
659          // Double
660
csTypes.put(java.lang.Double JavaDoc.class.getName(),
661             CallableStatement JavaDoc.class.getMethod(GET_DOUBLE, arg));
662          // double
663
csTypes.put(Double.TYPE.getName(),
664             CallableStatement JavaDoc.class.getMethod(GET_DOUBLE, arg));
665          // byte[] (scoy: I expect that this will no longer be invoked)
666
csTypes.put("[B",
667             CallableStatement JavaDoc.class.getMethod(GET_BYTES, arg));
668       }
669       catch(NoSuchMethodException JavaDoc e)
670       {
671          // Should never happen
672
log.error(SQL_ERROR, e);
673       }
674
675       // Initializes the map between jdbcType (int) and the name of the type.
676
// This map is used to print meaningful debug and error messages.
677
jdbcTypeNames = new HashMap JavaDoc();
678       Field JavaDoc[] fields = Types JavaDoc.class.getFields();
679       for(int i = 0; i < fields.length; i++)
680       {
681          try
682          {
683             jdbcTypeNames.put(fields[i].get(null), fields[i].getName());
684          }
685          catch(IllegalAccessException JavaDoc e)
686          {
687             // Should never happen
688
log.error(SQL_ERROR, e);
689          }
690       }
691    }
692
693    /**
694     * Used for all retrieval of parameters from <code>CallableStatement</code>s.
695     * Implements tracing, and allows some tweaking of returned types.
696     *
697     * @param log where to log to
698     * @param cs the <code>CallableStatement</code> from which an out parameter is being retrieved
699     * @param index index of the result column.
700     * @param jdbcType a {@link java.sql.Types} constant used to determine the
701     * most appropriate way to extract the data from rs.
702     * @param destination The class of the variable this is going into
703     * @return the value
704     */

705    public static Object JavaDoc getParameter(Logger log, CallableStatement JavaDoc cs, int index, int jdbcType, Class JavaDoc destination) throws SQLException JavaDoc
706    {
707       Object JavaDoc value = null;
708       switch(jdbcType)
709       {
710          //
711
// Large types
712
//
713
case Types.CLOB:
714          case Types.LONGVARCHAR:
715          case Types.BLOB:
716          case Types.LONGVARBINARY:
717             throw new UnsupportedOperationException JavaDoc();
718
719             //
720
// Small binary types
721
//
722
case Types.BINARY:
723          case Types.VARBINARY:
724             {
725                byte[] bytes = cs.getBytes(index);
726                if(!cs.wasNull())
727                {
728                   if(destination == byte[].class)
729                      value = bytes;
730                   else
731                      value = convertToObject(bytes);
732                }
733                if(log.isTraceEnabled())
734                {
735                   log.trace("Get result: index=" + index +
736                      ", javaType=" + destination.getName() +
737                      ", Binary, value=" + value);
738                }
739             }
740             break;
741
742             //
743
// Specialist types that the
744
// driver should handle
745
//
746
case Types.JAVA_OBJECT:
747          case Types.STRUCT:
748          case Types.ARRAY:
749          case Types.OTHER:
750             {
751                value = cs.getObject(index);
752                if(log.isTraceEnabled())
753                {
754                   log.trace("Get result: index=" + index +
755                      ", javaType=" + destination.getName() +
756                      ", Object, value=" + value);
757                }
758             }
759             break;
760
761             //
762
// Non-binary types
763
//
764
default:
765             Method JavaDoc method = (Method JavaDoc)csTypes.get(destination.getName());
766             if(method != null)
767             {
768                try
769                {
770                   value = method.invoke(cs, new Object JavaDoc[]{new Integer JavaDoc(index)});
771                   if(cs.wasNull())
772                   {
773                      value = null;
774                   }
775
776                   if(log.isTraceEnabled())
777                   {
778                      log.trace("Get result: index=" + index +
779                         ", javaType=" + destination.getName() +
780                         ", Simple, value=" + value);
781                   }
782                }
783                catch(IllegalAccessException JavaDoc e)
784                {
785                   // Whatever, I guess non-binary will not work for this field.
786
}
787                catch(InvocationTargetException JavaDoc e)
788                {
789                   // Whatever, I guess non-binary will not work for this field.
790
}
791             }
792             else
793             {
794                value = cs.getObject(index);
795                if(log.isTraceEnabled())
796                {
797                   log.trace("Get result: index=" + index +
798                      ", javaType=" + destination.getName() +
799                      ", Object, value=" + value);
800                }
801             }
802       }
803       return coerceToJavaType(value, destination);
804    }
805
806    private static Object JavaDoc coerceToJavaType(
807       Object JavaDoc value,
808       Class JavaDoc destination) throws SQLException JavaDoc
809    {
810       try
811       {
812          //
813
// null
814
//
815
if(value == null)
816          {
817             return null;
818          }
819
820          //
821
// java.rmi.MarshalledObject
822
//
823
// get unmarshalled value
824
if(value instanceof MarshalledObject JavaDoc && !destination.equals(MarshalledObject JavaDoc.class))
825          {
826             value = ((MarshalledObject JavaDoc)value).get();
827          }
828
829          //
830
// javax.ejb.Handle
831
//
832
// get the object back from the handle
833
if(value instanceof Handle JavaDoc)
834          {
835             value = ((Handle JavaDoc)value).getEJBObject();
836          }
837
838          //
839
// Primitive wrapper classes
840
//
841
// We have a primitive wrapper and we want a real primitive
842
// just return the wrapper and the vm will convert it at the proxy
843
if(destination.isPrimitive())
844          {
845             if(value == null)
846                throw new IllegalStateException JavaDoc("Loaded NULL value for a field of a primitive type.");
847             if((destination.equals(Byte.TYPE) && value instanceof Byte JavaDoc) ||
848                (destination.equals(Short.TYPE) && value instanceof Short JavaDoc) ||
849                (destination.equals(Character.TYPE) && value instanceof Character JavaDoc) ||
850                (destination.equals(Boolean.TYPE) && value instanceof Boolean JavaDoc) ||
851                (destination.equals(Integer.TYPE) && value instanceof Integer JavaDoc) ||
852                (destination.equals(Long.TYPE) && value instanceof Long JavaDoc) ||
853                (destination.equals(Float.TYPE) && value instanceof Float JavaDoc) ||
854                (destination.equals(Double.TYPE) && value instanceof Double JavaDoc)
855             )
856             {
857                return value;
858             }
859          }
860
861          //
862
// java.util.Date
863
//
864
// make new copy as sub types have problems in comparions
865
if(destination == java.util.Date JavaDoc.class && value instanceof java.util.Date JavaDoc)
866          {
867             // handle timestamp special becauses it hoses the milisecond values
868
if(value instanceof java.sql.Timestamp JavaDoc)
869             {
870                java.sql.Timestamp JavaDoc ts = (java.sql.Timestamp JavaDoc)value;
871
872                // Timestamp returns whole seconds from getTime and partial
873
// seconds are retrieved from getNanos()
874
// Adrian Brock: Not in 1.4 it doesn't
875
long temp = ts.getTime();
876                if(temp % 1000 == 0)
877                   temp += ts.getNanos() / 1000000;
878                return new java.util.Date JavaDoc(temp);
879             }
880             else
881             {
882                return new java.util.Date JavaDoc(((java.util.Date JavaDoc)value).getTime());
883             }
884          }
885
886          //
887
// java.sql.Time
888
//
889
// make a new copy object; you never know what a driver will return
890
if(destination == java.sql.Time JavaDoc.class && value instanceof java.sql.Time JavaDoc)
891          {
892             return new java.sql.Time JavaDoc(((java.sql.Time JavaDoc)value).getTime());
893          }
894
895          //
896
// java.sql.Date
897
//
898
// make a new copy object; you never know what a driver will return
899
if(destination == java.sql.Date JavaDoc.class && value instanceof java.sql.Date JavaDoc)
900          {
901             return new java.sql.Date JavaDoc(((java.sql.Date JavaDoc)value).getTime());
902          }
903
904          //
905
// java.sql.Timestamp
906
//
907
// make a new copy object; you never know what a driver will return
908
if(destination == java.sql.Timestamp JavaDoc.class && value instanceof java.sql.Timestamp JavaDoc)
909          {
910             // make a new Timestamp object; you never know
911
// what a driver will return
912
java.sql.Timestamp JavaDoc orignal = (java.sql.Timestamp JavaDoc)value;
913             java.sql.Timestamp JavaDoc copy = new java.sql.Timestamp JavaDoc(orignal.getTime());
914             copy.setNanos(orignal.getNanos());
915             return copy;
916          }
917
918          //
919
// java.lang.String --> java.lang.Character or char
920
//
921
// just grab first character
922
if(value instanceof String JavaDoc && (destination == Character JavaDoc.class || destination == Character.TYPE))
923          {
924             return new Character JavaDoc(((String JavaDoc)value).charAt(0));
925          }
926
927          // Did we get the desired result?
928
if(destination.isAssignableFrom(value.getClass()))
929          {
930             return value;
931          }
932
933          if(destination == java.math.BigInteger JavaDoc.class && value.getClass() == java.math.BigDecimal JavaDoc.class)
934          {
935             return ((java.math.BigDecimal JavaDoc)value).toBigInteger();
936          }
937
938          // oops got the wrong type - nothing we can do
939
throw new SQLException JavaDoc("Got a " + value.getClass().getName() + "[cl=" +
940             System.identityHashCode(value.getClass().getClassLoader()) +
941             ", value=" + value + "] while looking for a " +
942             destination.getName() + "[cl=" +
943             System.identityHashCode(destination) + "]");
944       }
945       catch(RemoteException JavaDoc e)
946       {
947          throw new SQLException JavaDoc("Unable to load EJBObject back from Handle: "
948             + e);
949       }
950       catch(IOException JavaDoc e)
951       {
952          throw new SQLException JavaDoc("Unable to load to deserialize result: " + e);
953       }
954       catch(ClassNotFoundException JavaDoc e)
955       {
956          throw new SQLException JavaDoc("Unable to load to deserialize result: " + e);
957       }
958    }
959 }
960
Popular Tags