You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ws...@apache.org on 2011/11/23 17:31:10 UTC

svn commit: r1205485 - in /commons/proper/dbutils/trunk: pom.xml src/changes/changes.xml src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java

Author: wspeirs
Date: Wed Nov 23 16:31:09 2011
New Revision: 1205485

URL: http://svn.apache.org/viewvc?rev=1205485&view=rev
Log:
- Added BeanMapHandler and associated test case (DBUTILS-67)
- Updated pom.xml; moved myself from contrib to dev
- Updated changes in changes.xml file

Added:
    commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
    commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
Modified:
    commons/proper/dbutils/trunk/pom.xml
    commons/proper/dbutils/trunk/src/changes/changes.xml

Modified: commons/proper/dbutils/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/pom.xml?rev=1205485&r1=1205484&r2=1205485&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/pom.xml [utf-8] (original)
+++ commons/proper/dbutils/trunk/pom.xml [utf-8] Wed Nov 23 16:31:09 2011
@@ -64,6 +64,15 @@
       </roles>
     </developer>
     <developer>
+      <name>Dan Fabulich</name>
+      <id>dfabulich</id>
+      <email>dan@fabulich.com</email>
+      <organization />
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+    <developer>
       <name>David Graham</name>
       <id>dgraham</id>
       <email>dgraham@apache.org</email>
@@ -82,28 +91,27 @@
       </roles>
     </developer>
     <developer>
-      <name>Henri Yandell</name>
-      <id>bayard</id>
-      <email>bayard@apache.org</email>
-      <organization />
+      <name>William Speirs</name>
+      <id>wspeirs</id>
+      <email>wspeirs@apache.org</email>
       <roles>
         <role>Java Developer</role>
       </roles>
     </developer>
     <developer>
-      <name>Dan Fabulich</name>
-      <id>dfabulich</id>
-      <email>dan@fabulich.com</email>
+      <name>Simone Tripodi</name>
+      <id>simonetripodi</id>
+      <email>simonetripodi at apache dot org</email>
+    </developer>
+    <developer>
+      <name>Henri Yandell</name>
+      <id>bayard</id>
+      <email>bayard@apache.org</email>
       <organization />
       <roles>
         <role>Java Developer</role>
       </roles>
     </developer>
-    <developer>
-      <name>Simone Tripodi</name>
-      <id>simonetripodi</id>
-      <email>simonetripodi at apache dot org</email>
-    </developer>
   </developers>
 
   <contributors>
@@ -173,12 +181,6 @@
         <role>Java Developer</role>
       </roles>
     </contributor>
-    <contributor>
-      <name>Bill Speirs</name>
-      <roles>
-        <role>Java Developer</role>
-      </roles>
-    </contributor>
   </contributors>
 
   <dependencies>

Modified: commons/proper/dbutils/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/changes/changes.xml?rev=1205485&r1=1205484&r2=1205485&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/src/changes/changes.xml (original)
+++ commons/proper/dbutils/trunk/src/changes/changes.xml Wed Nov 23 16:31:09 2011
@@ -38,6 +38,14 @@ The <action> type attribute can be add,u
     <title>Release Notes</title>
   </properties>
   <body>
+    <release version="1.5" date="2011-11-25" description="Bugfixes and addition of BeanMapHandler">
+      <action dev="wspeirs" type="update" issue="DBUTILS-77">
+        Updated documentation to better reflect the use of pmdKnownBroken
+      </action>
+      <action due-to="Michael Osipov" type="add" issue="DBUTILS-67">
+        Added BeanMapHandler
+      </action>
+    </release>
     <release version="1.4" date="2011-10-23" description="Bugfixes and addition of asynchronous QueryLoader">
       <action type="fix" issue="DBUTILS-81">
         DbUtils.loadDriver() uses Class.forName()
@@ -54,7 +62,7 @@ The <action> type attribute can be add,u
       <action type="update" issue="DBUTILS-75">
         efficient usage from findbugs
       </action>
-      <action type="add" issue="DBUTILS-78">
+      <action dev="wspeirs" type="add" issue="DBUTILS-78">
         Add asynchronous batch, query, and update calls
       </action>
     </release>

Added: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java?rev=1205485&view=auto
==============================================================================
--- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java (added)
+++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java Wed Nov 23 16:31:09 2011
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbutils.handlers;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.commons.dbutils.RowProcessor;
+
+/**
+ * <p>
+ * <code>ResultSetHandler</code> implementation that returns a Map of Beans.
+ * <code>ResultSet</code> rows are converted into Beans which are then stored in
+ * a Map under the given key.
+ * </p>
+ * <p>
+ * If you had a Person table with a primary key column called ID, you could
+ * retrieve rows from the table like this:
+ *
+ * <pre>
+ * ResultSetHandler&lt;Map&lt;Long, Person&gt;&gt; h = new BeanMapdHandler&lt;Long, Person&gt;(Person.class, &quot;id&quot;);
+ * Map&amp;ltLong, Person&gt; found = queryRunner.query(&quot;select id, name, age from person&quot;, h);
+ * Person jane = found.get(1L); // jane's id is 1
+ * String janesName = jane.getName();
+ * Integer janesAge = jane.getAge();
+ * </pre>
+ *
+ * Note that the "id" passed to BeanMapHandler can be in any case. The data type
+ * returned for id is dependent upon how your JDBC driver converts SQL column
+ * types from the Person table into Java types. The "name" and "age" columns are
+ * converted according to their property descriptors by DbUtils.
+ * </p>
+ * <p>
+ * This class is thread safe.
+ * </p>
+ *
+ * @param <K>
+ *            the type of keys maintained by the returned map
+ * @param <V>
+ *            the type of the bean
+ * @see org.apache.commons.dbutils.ResultSetHandler
+ * @since DbUtils 1.5
+ */
+public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
+
+    /**
+     * The Class of beans produced by this handler.
+     */
+    private Class<V> type;
+
+    /**
+     * The RowProcessor implementation to use when converting rows into Objects.
+     */
+    private RowProcessor convert;
+
+    /**
+     * The column index to retrieve key values from. Defaults to 1.
+     */
+    private int columnIndex;
+
+    /**
+     * The column name to retrieve key values from. Either columnName or
+     * columnIndex will be used but never both.
+     */
+    private String columnName;
+
+    /**
+     * Creates a new instance of BeanMapHandler. The value of the first column
+     * of each row will be a key in the Map.
+     *
+     * @param type
+     *            The Class that objects returned from <code>createRow()</code>
+     *            are created from.
+     */
+    public BeanMapHandler(Class<V> type) {
+        this(type, ArrayHandler.ROW_PROCESSOR, 1, null);
+    }
+
+    /**
+     * Creates a new instance of BeanMapHandler. The value of the first column
+     * of each row will be a key in the Map.
+     *
+     * @param type
+     *            The Class that objects returned from <code>createRow()</code>
+     *            are created from.
+     * @param convert
+     *            The <code>RowProcessor</code> implementation to use when
+     *            converting rows into Beans
+     */
+    public BeanMapHandler(Class<V> type, RowProcessor convert) {
+        this(type, convert, 1, null);
+    }
+
+    /**
+     * Creates a new instance of BeanMapHandler.
+     *
+     * @param type
+     *            The Class that objects returned from <code>createRow()</code>
+     *            are created from.
+     * @param columnIndex
+     *            The values to use as keys in the Map are retrieved from the
+     *            column at this index.
+     */
+    public BeanMapHandler(Class<V> type, int columnIndex) {
+        this(type, ArrayHandler.ROW_PROCESSOR, columnIndex, null);
+    }
+
+    /**
+     * Creates a new instance of BeanMapHandler.
+     *
+     * @param type
+     *            The Class that objects returned from <code>createRow()</code>
+     *            are created from.
+     * @param columnName
+     *            The values to use as keys in the Map are retrieved from the
+     *            column with this name.
+     */
+    public BeanMapHandler(Class<V> type, String columnName) {
+        this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName);
+    }
+
+    /**
+     * Private Helper
+     *
+     * @param convert
+     *            The <code>RowProcessor</code> implementation to use when
+     *            converting rows into Beans
+     * @param columnIndex
+     *            The values to use as keys in the Map are retrieved from the
+     *            column at this index.
+     * @param columnName
+     *            The values to use as keys in the Map are retrieved from the
+     *            column with this name.
+     */
+    private BeanMapHandler(Class<V> type, RowProcessor convert,
+            int columnIndex, String columnName) {
+        super();
+        this.type = type;
+        this.convert = convert;
+        this.columnIndex = columnIndex;
+        this.columnName = columnName;
+    }
+
+    @Override
+    protected K createKey(ResultSet rs) throws SQLException {
+        return (columnName == null) ? (K) rs.getObject(columnIndex) : (K) rs
+                .getObject(columnName);
+    }
+
+    @Override
+    protected V createRow(ResultSet rs) throws SQLException {
+        // TODO Auto-generated method stub
+        return this.convert.toBean(rs, type);
+    }
+
+}

Added: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java?rev=1205485&view=auto
==============================================================================
--- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java (added)
+++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java Wed Nov 23 16:31:09 2011
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbutils.handlers;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.when;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.util.Map;
+
+import org.apache.commons.dbutils.RowProcessor;
+import org.apache.commons.dbutils.TestBean;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class BeanMapHandlerTest {
+	
+	private BeanMapHandler<Long, TestBean> bmh;
+	private Map<Long, TestBean> res;
+	@Mock private ResultSet rs;
+	@Mock private ResultSetMetaData rsmd;
+	@Mock private RowProcessor rp;
+	
+	@Before
+	public void setUp() throws Exception {
+		MockitoAnnotations.initMocks(this);
+
+		when(rs.next()).thenReturn(true, false);
+		when(rs.getObject(1)).thenReturn(23L);
+		when(rs.getObject(2)).thenReturn(23L);
+		when(rs.getObject("id")).thenReturn(23L);
+		when(rs.getMetaData()).thenReturn(rsmd);
+		when(rp.toBean(rs, TestBean.class)).thenReturn(new TestBean());
+	}
+
+	private void handle() throws Exception {
+		res = bmh.handle(rs);
+		assertNotNull(res.get(23L));
+	}
+	
+	@Test
+	public void testBeanMapHandlerClassOfV() throws Exception {
+		bmh = new BeanMapHandler<Long, TestBean>(TestBean.class);
+		handle();
+	}
+
+	@Test
+	public void testBeanMapHandlerClassOfVRowProcessor() throws Exception {
+		bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, rp);
+		handle();
+	}
+
+	@Test
+	public void testBeanMapHandlerClassOfVInt() throws Exception {
+		bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, 2);
+		handle();
+	}
+
+	@Test
+	public void testBeanMapHandlerClassOfVString() throws Exception {
+		bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, "id");
+		handle();
+	}
+	
+	@Test
+	public void testEmptyResultSet() throws Exception {
+		when(rs.next()).thenReturn(false);
+		bmh = new BeanMapHandler<Long, TestBean>(TestBean.class);
+		res = bmh.handle(rs);
+		assertNull(res.get(23L));
+	}
+
+}



Re: svn commit: r1205485 - in /commons/proper/dbutils/trunk: pom.xml src/changes/changes.xml src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java

Posted by sebb <se...@gmail.com>.
On 23 November 2011 17:45, Bill Speirs <bi...@gmail.com> wrote:
> These are good questions/points...
>
> On Wed, Nov 23, 2011 at 12:35 PM, sebb <se...@gmail.com> wrote:
>
>> > +
>> > +    /**
>> > +     * The Class of beans produced by this handler.
>> > +     */
>> > +    private Class<V> type;
>> > +
>> > +    /**
>> > +     * The RowProcessor implementation to use when converting rows into
>> Objects.
>> > +     */
>> > +    private RowProcessor convert;
>> > +
>> > +    /**
>> > +     * The column index to retrieve key values from. Defaults to 1.
>> > +     */
>> > +    private int columnIndex;
>> > +
>> > +    /**
>> > +     * The column name to retrieve key values from. Either columnName or
>> > +     * columnIndex will be used but never both.
>> > +     */
>> > +    private String columnName;
>> > +
>>
>> Looks like the class fields could all be final.
>>
>
> I agree... will change. Good catch!
>
>
>> > +    @Override
>> > +    protected K createKey(ResultSet rs) throws SQLException {
>> > +        return (columnName == null) ? (K) rs.getObject(columnIndex) :
>> (K) rs
>> > +                .getObject(columnName);
>>
>> This generates a warning: "Unchecked cast from Object to K".
>>
>> Is it safe to ignore this warning? If so why?
>>
>
> This same type of things pops up in a few other pieces of code where I'm
> changing things to make them generic. I'm not 100% sure what the "best
> practice" is here.
>
> I'm thinking these are safe to ignore (add @*SuppressWarnings*("*unchecked*"))
> because if the type is wrong, it will throw a cast exception and that
> should immediately alert the developer to the root cause of the issue.

In this case, yes, ignoring the warning will result in an immediate CCE.

However, there are some generics warnings that don't result in an
immediate warning.
For example, with lists, ignoring a warning may result in allowing an
incorrect entry which only appears as a CCE much later.

> Othewise, there is no way I'm aware of in java to say something like
> if(object instanceof K) where K is a generic, because it's all washed away
> with type erasure at compile time. Any thoughts here?

If the cast should work, then suppress the warning with a suitable
comment, and document that there can be a CCE.

If there is no way of knowing whether the cast should work or not,
then perhaps the addition of generics has not been done correctly or
is not appropriate.

>>
>> > +    }
>> > +
>> > +    @Override
>> > +    protected V createRow(ResultSet rs) throws SQLException {
>> > +        // TODO Auto-generated method stub
>>
>> ??? is this still TODO?
>>
>
> Nope... will remove.
>
>
>>
> Thanks for the review/feedback... always appreciated!
>
> Bill-
>

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


Re: svn commit: r1205485 - in /commons/proper/dbutils/trunk: pom.xml src/changes/changes.xml src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java

Posted by Bill Speirs <bi...@gmail.com>.
These are good questions/points...

On Wed, Nov 23, 2011 at 12:35 PM, sebb <se...@gmail.com> wrote:

> > +
> > +    /**
> > +     * The Class of beans produced by this handler.
> > +     */
> > +    private Class<V> type;
> > +
> > +    /**
> > +     * The RowProcessor implementation to use when converting rows into
> Objects.
> > +     */
> > +    private RowProcessor convert;
> > +
> > +    /**
> > +     * The column index to retrieve key values from. Defaults to 1.
> > +     */
> > +    private int columnIndex;
> > +
> > +    /**
> > +     * The column name to retrieve key values from. Either columnName or
> > +     * columnIndex will be used but never both.
> > +     */
> > +    private String columnName;
> > +
>
> Looks like the class fields could all be final.
>

I agree... will change. Good catch!


> > +    @Override
> > +    protected K createKey(ResultSet rs) throws SQLException {
> > +        return (columnName == null) ? (K) rs.getObject(columnIndex) :
> (K) rs
> > +                .getObject(columnName);
>
> This generates a warning: "Unchecked cast from Object to K".
>
> Is it safe to ignore this warning? If so why?
>

This same type of things pops up in a few other pieces of code where I'm
changing things to make them generic. I'm not 100% sure what the "best
practice" is here.

I'm thinking these are safe to ignore (add @*SuppressWarnings*("*unchecked*"))
because if the type is wrong, it will throw a cast exception and that
should immediately alert the developer to the root cause of the issue.
Othewise, there is no way I'm aware of in java to say something like
if(object instanceof K) where K is a generic, because it's all washed away
with type erasure at compile time. Any thoughts here?

>
> > +    }
> > +
> > +    @Override
> > +    protected V createRow(ResultSet rs) throws SQLException {
> > +        // TODO Auto-generated method stub
>
> ??? is this still TODO?
>

Nope... will remove.


>
Thanks for the review/feedback... always appreciated!

Bill-

Re: svn commit: r1205485 - in /commons/proper/dbutils/trunk: pom.xml src/changes/changes.xml src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java

Posted by sebb <se...@gmail.com>.
On 23 November 2011 16:31,  <ws...@apache.org> wrote:
> Author: wspeirs
> Date: Wed Nov 23 16:31:09 2011
> New Revision: 1205485
>
> URL: http://svn.apache.org/viewvc?rev=1205485&view=rev
> Log:
> - Added BeanMapHandler and associated test case (DBUTILS-67)
> - Updated pom.xml; moved myself from contrib to dev
> - Updated changes in changes.xml file
>
> Added:
>    commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
>    commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
> Modified:
>    commons/proper/dbutils/trunk/pom.xml
>    commons/proper/dbutils/trunk/src/changes/changes.xml
>
> Modified: commons/proper/dbutils/trunk/pom.xml
> URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/pom.xml?rev=1205485&r1=1205484&r2=1205485&view=diff
> ==============================================================================
> --- commons/proper/dbutils/trunk/pom.xml [utf-8] (original)
> +++ commons/proper/dbutils/trunk/pom.xml [utf-8] Wed Nov 23 16:31:09 2011
> @@ -64,6 +64,15 @@
>       </roles>
>     </developer>
>     <developer>
> +      <name>Dan Fabulich</name>
> +      <id>dfabulich</id>
> +      <email>dan@fabulich.com</email>
> +      <organization />
> +      <roles>
> +        <role>Java Developer</role>
> +      </roles>
> +    </developer>
> +    <developer>
>       <name>David Graham</name>
>       <id>dgraham</id>
>       <email>dgraham@apache.org</email>
> @@ -82,28 +91,27 @@
>       </roles>
>     </developer>
>     <developer>
> -      <name>Henri Yandell</name>
> -      <id>bayard</id>
> -      <email>bayard@apache.org</email>
> -      <organization />
> +      <name>William Speirs</name>
> +      <id>wspeirs</id>
> +      <email>wspeirs@apache.org</email>
>       <roles>
>         <role>Java Developer</role>
>       </roles>
>     </developer>
>     <developer>
> -      <name>Dan Fabulich</name>
> -      <id>dfabulich</id>
> -      <email>dan@fabulich.com</email>
> +      <name>Simone Tripodi</name>
> +      <id>simonetripodi</id>
> +      <email>simonetripodi at apache dot org</email>
> +    </developer>
> +    <developer>
> +      <name>Henri Yandell</name>
> +      <id>bayard</id>
> +      <email>bayard@apache.org</email>
>       <organization />
>       <roles>
>         <role>Java Developer</role>
>       </roles>
>     </developer>
> -    <developer>
> -      <name>Simone Tripodi</name>
> -      <id>simonetripodi</id>
> -      <email>simonetripodi at apache dot org</email>
> -    </developer>
>   </developers>
>
>   <contributors>
> @@ -173,12 +181,6 @@
>         <role>Java Developer</role>
>       </roles>
>     </contributor>
> -    <contributor>
> -      <name>Bill Speirs</name>
> -      <roles>
> -        <role>Java Developer</role>
> -      </roles>
> -    </contributor>
>   </contributors>
>
>   <dependencies>
>
> Modified: commons/proper/dbutils/trunk/src/changes/changes.xml
> URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/changes/changes.xml?rev=1205485&r1=1205484&r2=1205485&view=diff
> ==============================================================================
> --- commons/proper/dbutils/trunk/src/changes/changes.xml (original)
> +++ commons/proper/dbutils/trunk/src/changes/changes.xml Wed Nov 23 16:31:09 2011
> @@ -38,6 +38,14 @@ The <action> type attribute can be add,u
>     <title>Release Notes</title>
>   </properties>
>   <body>
> +    <release version="1.5" date="2011-11-25" description="Bugfixes and addition of BeanMapHandler">
> +      <action dev="wspeirs" type="update" issue="DBUTILS-77">
> +        Updated documentation to better reflect the use of pmdKnownBroken
> +      </action>
> +      <action due-to="Michael Osipov" type="add" issue="DBUTILS-67">
> +        Added BeanMapHandler
> +      </action>
> +    </release>
>     <release version="1.4" date="2011-10-23" description="Bugfixes and addition of asynchronous QueryLoader">
>       <action type="fix" issue="DBUTILS-81">
>         DbUtils.loadDriver() uses Class.forName()
> @@ -54,7 +62,7 @@ The <action> type attribute can be add,u
>       <action type="update" issue="DBUTILS-75">
>         efficient usage from findbugs
>       </action>
> -      <action type="add" issue="DBUTILS-78">
> +      <action dev="wspeirs" type="add" issue="DBUTILS-78">
>         Add asynchronous batch, query, and update calls
>       </action>
>     </release>
>
> Added: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java
> URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java?rev=1205485&view=auto
> ==============================================================================
> --- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java (added)
> +++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java Wed Nov 23 16:31:09 2011
> @@ -0,0 +1,170 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.dbutils.handlers;
> +
> +import java.sql.ResultSet;
> +import java.sql.SQLException;
> +
> +import org.apache.commons.dbutils.RowProcessor;
> +
> +/**
> + * <p>
> + * <code>ResultSetHandler</code> implementation that returns a Map of Beans.
> + * <code>ResultSet</code> rows are converted into Beans which are then stored in
> + * a Map under the given key.
> + * </p>
> + * <p>
> + * If you had a Person table with a primary key column called ID, you could
> + * retrieve rows from the table like this:
> + *
> + * <pre>
> + * ResultSetHandler&lt;Map&lt;Long, Person&gt;&gt; h = new BeanMapdHandler&lt;Long, Person&gt;(Person.class, &quot;id&quot;);
> + * Map&amp;ltLong, Person&gt; found = queryRunner.query(&quot;select id, name, age from person&quot;, h);
> + * Person jane = found.get(1L); // jane's id is 1
> + * String janesName = jane.getName();
> + * Integer janesAge = jane.getAge();
> + * </pre>
> + *
> + * Note that the "id" passed to BeanMapHandler can be in any case. The data type
> + * returned for id is dependent upon how your JDBC driver converts SQL column
> + * types from the Person table into Java types. The "name" and "age" columns are
> + * converted according to their property descriptors by DbUtils.
> + * </p>
> + * <p>
> + * This class is thread safe.
> + * </p>
> + *
> + * @param <K>
> + *            the type of keys maintained by the returned map
> + * @param <V>
> + *            the type of the bean
> + * @see org.apache.commons.dbutils.ResultSetHandler
> + * @since DbUtils 1.5
> + */
> +public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
> +
> +    /**
> +     * The Class of beans produced by this handler.
> +     */
> +    private Class<V> type;
> +
> +    /**
> +     * The RowProcessor implementation to use when converting rows into Objects.
> +     */
> +    private RowProcessor convert;
> +
> +    /**
> +     * The column index to retrieve key values from. Defaults to 1.
> +     */
> +    private int columnIndex;
> +
> +    /**
> +     * The column name to retrieve key values from. Either columnName or
> +     * columnIndex will be used but never both.
> +     */
> +    private String columnName;
> +

Looks like the class fields could all be final.

> +    /**
> +     * Creates a new instance of BeanMapHandler. The value of the first column
> +     * of each row will be a key in the Map.
> +     *
> +     * @param type
> +     *            The Class that objects returned from <code>createRow()</code>
> +     *            are created from.
> +     */
> +    public BeanMapHandler(Class<V> type) {
> +        this(type, ArrayHandler.ROW_PROCESSOR, 1, null);
> +    }
> +
> +    /**
> +     * Creates a new instance of BeanMapHandler. The value of the first column
> +     * of each row will be a key in the Map.
> +     *
> +     * @param type
> +     *            The Class that objects returned from <code>createRow()</code>
> +     *            are created from.
> +     * @param convert
> +     *            The <code>RowProcessor</code> implementation to use when
> +     *            converting rows into Beans
> +     */
> +    public BeanMapHandler(Class<V> type, RowProcessor convert) {
> +        this(type, convert, 1, null);
> +    }
> +
> +    /**
> +     * Creates a new instance of BeanMapHandler.
> +     *
> +     * @param type
> +     *            The Class that objects returned from <code>createRow()</code>
> +     *            are created from.
> +     * @param columnIndex
> +     *            The values to use as keys in the Map are retrieved from the
> +     *            column at this index.
> +     */
> +    public BeanMapHandler(Class<V> type, int columnIndex) {
> +        this(type, ArrayHandler.ROW_PROCESSOR, columnIndex, null);
> +    }
> +
> +    /**
> +     * Creates a new instance of BeanMapHandler.
> +     *
> +     * @param type
> +     *            The Class that objects returned from <code>createRow()</code>
> +     *            are created from.
> +     * @param columnName
> +     *            The values to use as keys in the Map are retrieved from the
> +     *            column with this name.
> +     */
> +    public BeanMapHandler(Class<V> type, String columnName) {
> +        this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName);
> +    }
> +
> +    /**
> +     * Private Helper
> +     *
> +     * @param convert
> +     *            The <code>RowProcessor</code> implementation to use when
> +     *            converting rows into Beans
> +     * @param columnIndex
> +     *            The values to use as keys in the Map are retrieved from the
> +     *            column at this index.
> +     * @param columnName
> +     *            The values to use as keys in the Map are retrieved from the
> +     *            column with this name.
> +     */
> +    private BeanMapHandler(Class<V> type, RowProcessor convert,
> +            int columnIndex, String columnName) {
> +        super();
> +        this.type = type;
> +        this.convert = convert;
> +        this.columnIndex = columnIndex;
> +        this.columnName = columnName;
> +    }
> +
> +    @Override
> +    protected K createKey(ResultSet rs) throws SQLException {
> +        return (columnName == null) ? (K) rs.getObject(columnIndex) : (K) rs
> +                .getObject(columnName);

This generates a warning: "Unchecked cast from Object to K".

Is it safe to ignore this warning? If so why?

> +    }
> +
> +    @Override
> +    protected V createRow(ResultSet rs) throws SQLException {
> +        // TODO Auto-generated method stub

??? is this still TODO?

> +        return this.convert.toBean(rs, type);
> +    }
> +
> +}
>
> Added: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java?rev=1205485&view=auto
> ==============================================================================
> --- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java (added)
> +++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java Wed Nov 23 16:31:09 2011
> @@ -0,0 +1,90 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.dbutils.handlers;
> +
> +import static org.junit.Assert.*;
> +import static org.mockito.Mockito.when;
> +
> +import java.sql.ResultSet;
> +import java.sql.ResultSetMetaData;
> +import java.util.Map;
> +
> +import org.apache.commons.dbutils.RowProcessor;
> +import org.apache.commons.dbutils.TestBean;
> +import org.junit.Before;
> +import org.junit.Test;
> +import org.mockito.Mock;
> +import org.mockito.MockitoAnnotations;
> +
> +public class BeanMapHandlerTest {
> +
> +       private BeanMapHandler<Long, TestBean> bmh;
> +       private Map<Long, TestBean> res;
> +       @Mock private ResultSet rs;
> +       @Mock private ResultSetMetaData rsmd;
> +       @Mock private RowProcessor rp;
> +
> +       @Before
> +       public void setUp() throws Exception {
> +               MockitoAnnotations.initMocks(this);
> +
> +               when(rs.next()).thenReturn(true, false);
> +               when(rs.getObject(1)).thenReturn(23L);
> +               when(rs.getObject(2)).thenReturn(23L);
> +               when(rs.getObject("id")).thenReturn(23L);
> +               when(rs.getMetaData()).thenReturn(rsmd);
> +               when(rp.toBean(rs, TestBean.class)).thenReturn(new TestBean());
> +       }
> +
> +       private void handle() throws Exception {
> +               res = bmh.handle(rs);
> +               assertNotNull(res.get(23L));
> +       }
> +
> +       @Test
> +       public void testBeanMapHandlerClassOfV() throws Exception {
> +               bmh = new BeanMapHandler<Long, TestBean>(TestBean.class);
> +               handle();
> +       }
> +
> +       @Test
> +       public void testBeanMapHandlerClassOfVRowProcessor() throws Exception {
> +               bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, rp);
> +               handle();
> +       }
> +
> +       @Test
> +       public void testBeanMapHandlerClassOfVInt() throws Exception {
> +               bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, 2);
> +               handle();
> +       }
> +
> +       @Test
> +       public void testBeanMapHandlerClassOfVString() throws Exception {
> +               bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, "id");
> +               handle();
> +       }
> +
> +       @Test
> +       public void testEmptyResultSet() throws Exception {
> +               when(rs.next()).thenReturn(false);
> +               bmh = new BeanMapHandler<Long, TestBean>(TestBean.class);
> +               res = bmh.handle(rs);
> +               assertNull(res.get(23L));
> +       }
> +
> +}
>
>
>

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