You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by bu...@apache.org on 2003/11/26 01:21:36 UTC

DO NOT REPLY [Bug 24997] New: - [Patch]Implements Pluggable Adaptors to Make BeanHandler Smarter

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24997>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=24997

[Patch]Implements Pluggable Adaptors to Make BeanHandler Smarter

           Summary: [Patch]Implements Pluggable Adaptors to Make BeanHandler
                    Smarter
           Product: Commons
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Enhancement
          Priority: Other
         Component: DbUtils
        AssignedTo: commons-dev@jakarta.apache.org
        ReportedBy: cepage@yahoo.com


diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/BasicRowProcessor.java 
src/java/org/apache/commons/dbutils/BasicRowProcessor.java
5c5
<  * 
---
>  *
82c82
<  * 
---
>  *
84c84
<  * 
---
>  *
88a89
>  * @author Corby Page
93,94c94,95
<      * Set a bean's primitive properties to these defaults when SQL NULL 
<      * is returned.  These are the same as the defaults that ResultSet get* 
---
>      * Set a bean's primitive properties to these defaults when SQL NULL
>      * is returned.  These are the same as the defaults that ResultSet get*
139c140
<      * This implementation copies column values into the array in the same 
---
>      * This implementation copies column values into the array in the same
158,160c159,161
<      * Convert a <code>ResultSet</code> row into a JavaBean.  This 
<      * implementation uses reflection and <code>BeanInfo</code> classes to 
<      * match column names to bean property names.  Properties are matched to 
---
>      * Convert a <code>ResultSet</code> row into a JavaBean.  This
>      * implementation uses reflection and <code>BeanInfo</code> classes to
>      * match column names to bean property names.  Properties are matched to
168c169
<      * 
---
>      *
170c171
<      *     The property's set method parameter type matches the column 
---
>      *     The property's set method parameter type matches the column
174c175
<      * 
---
>      *
178c179
<      * and booleans are set to false.  Object bean properties are set to 
---
>      * and booleans are set to false.  Object bean properties are set to
182,183c183,184
<      * 
<      * @see org.apache.commons.dbutils.RowProcessor#toBean
(java.sql.ResultSet, java.lang.Class)
---
>      *
>      * @see org.apache.commons.dbutils.RowProcessor#toBean
(java.sql.ResultSet, java.lang.Class, org.apache.commons.dbutils.ColumnAdaptor)
185c186
<     public Object toBean(ResultSet rs, Class type) throws SQLException {
---
>     public Object toBean(ResultSet rs, Class type, ColumnAdaptor adaptor) 
throws SQLException {
195c196
<         return this.createBean(rs, type, props, columnToProperty, cols);
---
>         return this.createBean(rs, type, props, columnToProperty, cols, 
adaptor);
199,201c200,202
<      * Convert a <code>ResultSet</code> into a <code>List</code> of 
JavaBeans.  
<      * This implementation uses reflection and <code>BeanInfo</code> classes 
to 
<      * match column names to bean property names. Properties are matched to 
---
>      * Convert a <code>ResultSet</code> into a <code>List</code> of JavaBeans.
>      * This implementation uses reflection and <code>BeanInfo</code> classes 
to
>      * match column names to bean property names. Properties are matched to
209c210
<      * 
---
>      *
211c212
<      *     The property's set method parameter type matches the column 
---
>      *     The property's set method parameter type matches the column
215c216
<      * 
---
>      *
219c220
<      * and booleans are set to false.  Object bean properties are set to 
---
>      * and booleans are set to false.  Object bean properties are set to
223,224c224,225
<      * 
<      * @see org.apache.commons.dbutils.RowProcessor#toBeanList
(java.sql.ResultSet, java.lang.Class)
---
>      *
>      * @see org.apache.commons.dbutils.RowProcessor#toBeanList
(java.sql.ResultSet, java.lang.Class, org.apache.commons.dbutils.ColumnAdaptor)
226c227
<     public List toBeanList(ResultSet rs, Class type) throws SQLException {
---
>     public List toBeanList(ResultSet rs, Class type, ColumnAdaptor adaptor) 
throws SQLException {
239c240
<             results.add(this.createBean(rs, type, props, columnToProperty, 
cols));
---
>             results.add(this.createBean(rs, type, props, columnToProperty, 
cols, adaptor));
262c263,264
<         int cols)
---
>         int cols,
>         ColumnAdaptor adaptor )
272,273d273
<             
<             Object value = rs.getObject(i);
277a278,279
>             Object value = adaptor.getValue( rs, i, propType );
> 
290c292
<      * stored at each position represent the index in the PropertyDescriptor
[] 
---
>      * stored at each position represent the index in the PropertyDescriptor[]
293c295
<      * 
---
>      *
296c298
<      * @return An int[] with column index to property index mappings.  The 
0th 
---
>      * @return An int[] with column index to property index mappings.  The 0th
298c300
<      * 
---
>      *
327c329
<      * Convert a <code>ResultSet</code> row into a <code>Map</code>.  This 
---
>      * Convert a <code>ResultSet</code> row into a <code>Map</code>.  This
329c331
<      * names as keys.  Calls to <code>map.get("COL")</code> and 
---
>      * names as keys.  Calls to <code>map.get("COL")</code> and
367c369
<             // Don't call setter if the value object isn't the right type 
---
>             // Don't call setter if the value object isn't the right type
392c394
<      * 
---
>      *
481,482c483,484
<      * lookups.  This is needed for the toMap() implementation because 
<      * databases don't consistenly handle the casing of column names. 
---
>      * lookups.  This is needed for the toMap() implementation because
>      * databases don't consistenly handle the casing of column names.
520c522
<          * @see java.util.Map#remove(java.lang.ObjecT)
---
>          * @see java.util.Map#remove(java.lang.Object)
526c528
<     
---
> 
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/ColumnAdaptor.java 
src/java/org/apache/commons/dbutils/ColumnAdaptor.java
0a1,31
> package org.apache.commons.dbutils;
> 
> import java.sql.SQLException;
> import java.sql.ResultSet;
> 
> /**
>  * Implementations of this interface adapt result-set columns to a bean 
property
>  *
>  * @author Corby Page
>  */
> public interface ColumnAdaptor
> {
>     /**
>      * Adapts the <code>ResultSet</code> column to a type that is compatible
>      * with the JavaBean property that the columns will be mapped to.
>      *
>      * @param rs the supplied ResultSet
>      *
>      * @param index the current column index of the ResultSet
>      *
>      * @param propType the datatype of the JavaBean property that we will be 
adapting
>      * the ResultSet column to.
>      *
>      * @return The resultSet column, adapted to a datatype that is intended
>      * to be compatible with the supplied property type.
>      *
>      * @throws java.sql.SQLException
>      */
>     public Object getValue( ResultSet rs, int index, Class propType ) throws 
SQLException;
> 
> }
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/RowProcessor.java 
src/java/org/apache/commons/dbutils/RowProcessor.java
95c95
<     public Object toBean(ResultSet rs, Class type) throws SQLException;
---
>     public Object toBean(ResultSet rs, Class type, ColumnAdaptor adaptor) 
throws SQLException;
105c105
<     public List toBeanList(ResultSet rs, Class type) throws SQLException;
---
>     public List toBeanList(ResultSet rs, Class type, ColumnAdaptor adaptor) 
throws SQLException;
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/adaptors/DriverAdaptor.java 
src/java/org/apache/commons/dbutils/adaptors/DriverAdaptor.java
0a1,63
> package org.apache.commons.dbutils.adaptors;
> 
> import java.sql.ResultSet;
> import java.sql.SQLException;
> 
> import org.apache.commons.dbutils.ColumnAdaptor;
> 
> /**
>  * <code>ColumnAdaptor</code> implementation that delegates to the JDBC
>  * driver to perform the adaption. Will call type-specific method on the 
driver
>  * (such as getDouble, getInt, etc.) depending on the supplied datatype for 
the
>  * JavaBean property
>  *
>  * @see org.apache.commons.dbutils.ColumnAdaptor
>  *
>  * @author Corby Page
>  */
> public class DriverAdaptor implements ColumnAdaptor {
> 
>     /**
>      * The Singleton instance of this class.
>      */
>     private static final DriverAdaptor instance = new DriverAdaptor();
> 
>     /**
>      * Returns the Singleton instance of this class.
>      *
>      * @return The single instance of this class.
>      */
>     public static DriverAdaptor instance() {
>         return instance;
>     }
> 
>     public Object getValue( ResultSet rs, int index, Class propType ) throws 
SQLException {
>         Object value;
>         if ( propType.equals( Double.TYPE ) || propType.equals( 
Double.class ) ) {
>             value = new Double( rs.getDouble( index ) );
>         }
>         else if ( propType.equals( Float.TYPE ) || propType.equals( 
Float.class ) ) {
>             value = new Float( rs.getFloat( index ) );
>         }
>         else if ( propType.equals( Integer.TYPE ) || propType.equals( 
Integer.class ) ) {
>             value = new Integer( rs.getInt( index ) );
>         }
>         else if ( propType.equals( Long.TYPE ) || propType.equals( 
Long.class ) ) {
>             value = new Long( rs.getLong( index ) );
>         }
>         else if ( propType.equals( Short.TYPE ) || propType.equals( 
Short.class ) ) {
>             value = new Short( rs.getShort( index ) );
>         }
>         else if ( propType.equals( Boolean.TYPE ) || propType.equals( 
Boolean.class ) ) {
>             value = new Boolean( rs.getBoolean( index ) );
>         }
>         else if ( propType.equals( Byte.TYPE ) || propType.equals( 
Byte.class ) ) {
>             value = new Byte( rs.getByte( index ) );
>         }
>         else {
>             value = rs.getObject( index );
>         }
> 
>         return value;
>     }
> }
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/adaptors/SimpleAdaptor.java 
src/java/org/apache/commons/dbutils/adaptors/SimpleAdaptor.java
0a1,36
> package org.apache.commons.dbutils.adaptors;
> 
> import java.sql.ResultSet;
> import java.sql.SQLException;
> 
> import org.apache.commons.dbutils.ColumnAdaptor;
> 
> /**
>  * <code>ColumnAdaptor</code> implementation that does no real work,
>  * but performs quite well. Simply returns the result of a getObject() call on
>  * the <code>ResultSet</code>
>  *
>  * @see org.apache.commons.dbutils.ColumnAdaptor
>  *
>  * @author Corby Page
>  */
> public class SimpleAdaptor implements ColumnAdaptor
> {
>     /**
>      * The Singleton instance of this class.
>      */
>     private static final SimpleAdaptor instance = new SimpleAdaptor();
> 
>     /**
>      * Returns the Singleton instance of this class.
>      *
>      * @return The single instance of this class.
>      */
>     public static SimpleAdaptor instance() {
>         return instance;
>     }
> 
>     public Object getValue( ResultSet rs, int index, Class propType ) throws 
SQLException {
>         return rs.getObject( index );
>     }
> }
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/handlers/BeanHandler.java 
src/java/org/apache/commons/dbutils/handlers/BeanHandler.java
68a69,70
> import org.apache.commons.dbutils.ColumnAdaptor;
> import org.apache.commons.dbutils.adaptors.SimpleAdaptor;
77a80
>  * @author Corby Page
92c95,101
<     /** 
---
>     /**
>      * The ColumnAdaptor implementation to use when adapting
>      * columns to bean properties.
>      */
>     private ColumnAdaptor adaptor = SimpleAdaptor.instance();
> 
>     /**
115a125,140
>      * Creates a new instance of BeanHandler.
>      *
>      * @param type The Class that objects returned from <code>handle()</code>
>      * are created from.
>      * @param convert The <code>RowProcessor</code> implementation
>      * to use when converting rows into beans.
>      * @param adaptor The <code>ColumnAdaptor</code> implementation to use 
when adapting
>      * columns to bean properties.
>      */
>     public BeanHandler(Class type, RowProcessor convert, ColumnAdaptor 
adaptor ) {
>         this.type = type;
>         this.convert = convert;
>         this.adaptor = adaptor;
>     }
> 
>     /**
126c151
<         return rs.next() ? this.convert.toBean(rs, this.type) : null;
---
>         return rs.next() ? this.convert.toBean(rs, this.type, adaptor ) : 
null;
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/java/org/apache/commons/dbutils/handlers/BeanListHandler.java 
src/java/org/apache/commons/dbutils/handlers/BeanListHandler.java
69a70,71
> import org.apache.commons.dbutils.ColumnAdaptor;
> import org.apache.commons.dbutils.adaptors.SimpleAdaptor;
94c96,102
<     /** 
---
>     /**
>      * The ColumnAdaptor implementation to use when adapting
>      * columns to bean properties.
>      */
>     private ColumnAdaptor adaptor = SimpleAdaptor.instance();
> 
>     /**
117a126,141
>      * Creates a new instance of BeanListHandler.
>      *
>      * @param type The Class that objects returned from <code>handle()</code>
>      * are created from.
>      * @param convert The <code>RowProcessor</code> implementation
>      * to use when converting rows into beans.
>      * @param adaptor The <code>ColumnAdaptor</code> implementation to use 
when adapting
>      * columns to bean properties.
>      */
>     public BeanListHandler(Class type, RowProcessor convert, ColumnAdaptor 
adaptor ) {
>         this.type = type;
>         this.convert = convert;
>         this.adaptor = adaptor;
>     }
> 
>     /**
128c152
<         return this.convert.toBeanList(rs, type);
---
>         return this.convert.toBeanList(rs, type, adaptor );
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/test/org/apache/commons/dbutils/BaseTestCase.java 
src/test/org/apache/commons/dbutils/BaseTestCase.java
63a64
> import java.math.BigDecimal;
67a69,73
> import org.apache.commons.dbutils.adaptors.DriverAdaptorTest;
> import org.apache.commons.dbutils.handlers.*;
> import org.apache.commons.dbutils.wrappers.SqlNullCheckedResultSetTest;
> import org.apache.commons.dbutils.wrappers.StringTrimmedResultSetTest;
> 
72,81d77
< import org.apache.commons.dbutils.handlers.ArrayHandlerTest;
< import org.apache.commons.dbutils.handlers.ArrayListHandlerTest;
< import org.apache.commons.dbutils.handlers.BeanHandlerTest;
< import org.apache.commons.dbutils.handlers.BeanListHandlerTest;
< import org.apache.commons.dbutils.handlers.MapHandlerTest;
< import org.apache.commons.dbutils.handlers.MapListHandlerTest;
< import org.apache.commons.dbutils.handlers.ScalarHandlerTest;
< import org.apache.commons.dbutils.wrappers.SqlNullCheckedResultSetTest;
< import org.apache.commons.dbutils.wrappers.StringTrimmedResultSetTest;
< 
100c96,97
<             "notDate" };
---
>             "notDate",
>             "doubleTest"};
120c117,118
<             new Date()};
---
>             new Date(),
>             new BigDecimal( 5 )};
132c130,131
<             new Date()};
---
>             new Date(),
>             new BigDecimal( 6 )};
192a192
>         suite.addTestSuite(DriverAdaptorTest.class);
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/test/org/apache/commons/dbutils/BasicRowProcessorTest.java 
src/test/org/apache/commons/dbutils/BasicRowProcessorTest.java
67a68,69
> import org.apache.commons.dbutils.adaptors.SimpleAdaptor;
> 
106c108
<             b = (TestBean) processor.toBean(this.rs, TestBean.class);
---
>             b = (TestBean) processor.toBean(this.rs, TestBean.class, 
SimpleAdaptor.instance());
125c127
<         List list = processor.toBeanList(this.rs, TestBean.class);
---
>         List list = processor.toBeanList(this.rs, TestBean.class, 
SimpleAdaptor.instance());
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/test/org/apache/commons/dbutils/MockResultSet.java 
src/test/org/apache/commons/dbutils/MockResultSet.java
71a72
> import java.math.BigDecimal;
155c156,176
< 		} else if (methodName.equals("wasNull")) {
---
> 		} else if (methodName.equals("getInt")) {
>             Integer result = null;
>             if ( args[0] instanceof Integer ) {
>                 int col = ((Integer) args[0]).intValue();
>                 result = this.getInt(col);
> 
>             } else if (args[0] instanceof String) {
>                 result = this.getInt((String) args[0]);
>             }
>             return (result == null) ? new Integer( 0 ) : result;
> 		} else if (methodName.equals("getDouble")) {
>             Double result = null;
>             if ( args[0] instanceof Integer ) {
>                 int col = ((Integer) args[0]).intValue();
>                 result = this.getDouble(col);
> 
>             } else if (args[0] instanceof String) {
>                 result = this.getDouble((String) args[0]);
>             }
>             return (result == null) ? new Double( 0 ) : result;
>         } else if (methodName.equals("wasNull")) {
217a239,298
>     /**
>      * Gets the Double at the given column index.
>      * @param columnIndex A 1 based index.
>      * @throws SQLException
>      */
>     protected Integer getInt(int columnIndex) throws SQLException {
>         Object obj = this.getObject(columnIndex);
>         if ( obj == null ) {
>             return null;
>         }
>         if ( obj instanceof Integer ) {
>             return (Integer)obj;
>         }
>         throw new SQLException( "Column could not be mapped to integer 
type" );
>     }
> 
>     protected Integer getInt(String columnName) throws SQLException {
>         Object obj = this.getObject(this.findColumnIndex(columnName));
>         if ( obj == null ) {
>             return null;
>         }
>         if ( obj instanceof Integer ) {
>             return (Integer)obj;
>         }
>         throw new SQLException( "Column could not be mapped to integer 
type" );
>     }
> 
>     /**
>      * Gets the Double at the given column index.
>      * @param columnIndex A 1 based index.
>      * @throws SQLException
>      */
>     protected Double getDouble(int columnIndex) throws SQLException {
>         Object obj = this.getObject(columnIndex);
>         if ( obj == null ) {
>             return null;
>         }
>         if ( obj instanceof Double ) {
>             return (Double)obj;
>         }
>         if ( obj instanceof BigDecimal ) {
>             return new Double(((BigDecimal)obj).doubleValue());
>         }
>         throw new SQLException( "Column could not be mapped to double type" );
>     }
> 
>     protected Double getDouble(String columnName) throws SQLException {
>         Object obj = this.getObject(this.findColumnIndex(columnName));
>         if ( obj == null ) {
>             return null;
>         }
>         if ( obj instanceof Double ) {
>             return (Double)obj;
>         }
>         if ( obj instanceof BigDecimal ) {
>             return new Double(((BigDecimal)obj).doubleValue());
>         }
>         throw new SQLException( "Column could not be mapped to double type" );
>     }
> 
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/test/org/apache/commons/dbutils/TestBean.java 
src/test/org/apache/commons/dbutils/TestBean.java
82a83,84
>     private double doubleTest = 0;
> 
180a183,189
>     public double getDoubleTest() {
>         return doubleTest;
>     }
> 
>     public void setDoubleTest( double d ) {
>         doubleTest = d;
>     }
diff -rN /cygdrive/c/Java/commons-dbutils-
1.0/src/test/org/apache/commons/dbutils/adaptors/DriverAdaptorTest.java 
src/test/org/apache/commons/dbutils/adaptors/DriverAdaptorTest.java
0a1,39
> package org.apache.commons.dbutils.adaptors;
> 
> import java.sql.SQLException;
> 
> import org.apache.commons.dbutils.BaseTestCase;
> import org.apache.commons.dbutils.ResultSetHandler;
> import org.apache.commons.dbutils.TestBean;
> import org.apache.commons.dbutils.BasicRowProcessor;
> import org.apache.commons.dbutils.handlers.BeanHandler;
> 
> import junit.textui.TestRunner;
> 
> /**
>  * BeanHandlerTest
>  *
>  * @author Corby Page
>  */
> public class DriverAdaptorTest extends BaseTestCase
> {
>     /**
>      * Constructor for DriverAdaptorTest.
>      */
>     public DriverAdaptorTest( String name ) {
>         super( name );
>     }
> 
>     public void testDriverAdaptor() throws SQLException {
>         ResultSetHandler h = new BeanHandler(TestBean.class, 
BasicRowProcessor.instance(),
>                 DriverAdaptor.instance());
>         TestBean results = (TestBean) h.handle(this.rs);
> 
>         assertNotNull(results);
>         assertEquals("1", results.getOne());
>         assertEquals("2", results.getTwo());
>         assertEquals("3", results.getThree());
>         assertEquals("not set", results.getDoNotSet());
>         assertEquals( 5, results.getDoubleTest(), 0 );
>     }
> }

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org