Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
-
None
-
None
-
Operating System: All
Platform: All
-
17811
Description
This patch is in response to the JavaDoc "FIX ME" in RowSetDynaClass
suggesting to abstract functionality to support this class and
ResultSetDynaClass.
Modifications are made to both RowSetDynaClass and ResultSetDynaClass to
extend an abstract JDBCDynaClass. JDBCDynaClass consolidates common logic
found in both of these classes. JDBCDynaClass has package visibility since I
can't see a purpose to use it out side of BeanUtils.
I've run the build and all the tests regression very well. I inspected the
unit tests, but I don't have anything to add to what already there. Since this
is a simple refactor, nothing new is required.
When I run the cvs diff I don't see the JDBCDynaClass I created, so I I
appended after the diffs further down.
cvs diff ResultSetDynaClass.java (in directory C:\sandboxes\jakarta-
commons\beanutils\src\java\org\apache\commons\beanutils)
Index: ResultSetDynaClass.java
===================================================================
RCS file: /home/cvspublic/jakarta-
commons/beanutils/src/java/org/apache/commons/beanutils/ResultSetDynaClass.java
,v
retrieving revision 1.10
diff -r1.10 ResultSetDynaClass.java
67d66
< import java.sql.ResultSetMetaData;
69d67
< import java.util.ArrayList;
131c129
< public class ResultSetDynaClass implements DynaClass {
—
> public class ResultSetDynaClass extends JDBCDynaClass implements DynaClass {
185c183
< introspect();
—
> introspect(resultSet);
220,294d217
<
< // ------------------------------------------------------ DynaClass
Methods
<
<
<
< /**
< * Return the name of this DynaClass (analogous to the
< * <code>getName()</code> method of <code>java.lang.Class</code), which
< * allows the same <code>DynaClass</code> implementation class to support
< * different dynamic classes, with different sets of properties.
< */
< public String getName()
<
<
< /**
< * Return a property descriptor for the specified property, if it exists;
< * otherwise, return <code>null</code>.
< *
< * @param name Name of the dynamic property for which a descriptor
< * is requested
< *
< * @exception IllegalArgumentException if no property name is specified
< */
< public DynaProperty getDynaProperty(String name) {
<
< if (name == null)
< return ((DynaProperty) propertiesMap.get(name));
<
< }
<
<
< /**
< * <p>Return an array of <code>ProperyDescriptors</code> for the
properties
< * currently defined in this DynaClass. If no properties are defined, a
< * zero-length array will be returned.</p>
< *
< * <p><strong>FIXME</strong> - Should we really be implementing
< * <code>getBeanInfo()</code> instead, which returns property descriptors
< * and a bunch of other stuff?</p>
< */
< public DynaProperty[] getDynaProperties()
<
<
< /**
< * <p>Instantiate and return a new DynaBean instance, associated
< * with this DynaClass. <strong>NOTE</strong> - This operation is not
< * supported, and throws an exception. The <code>Iterator</code> that
< * is returned by <code>iterator()</code> will create DynaBean instances
< * for each row as needed.</p>
< *
< * @exception IllegalAccessException if the Class or the appropriate
< * constructor is not accessible
< * @exception InstantiationException if this Class represents an abstract
< * class, an array class, a primitive type, or void; or if instantiation
< * fails for some other reason
< */
< public DynaBean newInstance()
< throws IllegalAccessException, InstantiationException
<
<
327,335d249
< /**
< * <p>Introspect the metadata associated with our result set, and
populate
< * the <code>properties</code> and <code>propertiesMap</code> instance
< * variables.</p>
< *
< * @exception SQLException if an error is encountered processing the
< * result set metadata
< */
< protected void introspect() throws SQLException {
337,346d250
< // Accumulate an ordered list of DynaProperties
< ArrayList list = new ArrayList();
< ResultSetMetaData metadata = resultSet.getMetaData();
< int n = metadata.getColumnCount();
< for (int i = 1; i <= n; i++) { // JDBC is one-relative!
< DynaProperty dynaProperty = createDynaProperty(metadata, i);
< if (dynaProperty != null)
< }
348,353d251
< // Convert this list into the internal data structures we need
< properties =
< (DynaProperty[]) list.toArray(new DynaProperty[list.size()]);
< for (int i = 0; i < properties.length; i++)
355d252
< }
358,409d254
< /**
< * <p>Factory method to create a new DynaProperty for the given index
< * into the result set metadata.</p>
< *
< * @param metadata is the result set metadata
< * @param i is the column index in the metadata
< * @return the newly created DynaProperty instance
< */
< protected DynaProperty createDynaProperty(ResultSetMetaData metadata,
int i) throws SQLException {
<
< String name = null;
< if (lowerCase)
else
{ < name = metadata.getColumnName(i); < }< String className = null;
< try
< catch (SQLException e)
{ < // this is a patch for HsqlDb to ignore exceptions thrown by its metadata implementation < }<
< // lets default to Object type if no class name could be retrieved
from the metadata
< Class clazz = Object.class;
< if (className != null)
< return new DynaProperty(name, clazz);
<
< }
<
<
< /**
< * <p>Loads the class of the given name which by default uses the class
loader used
< * to load this library.
< * Dervations of this class could implement alternative class loading
policies such as
< * using custom ClassLoader or using the Threads's context class loader
etc.
< * </p>
< */
< protected Class loadClass(String className) throws SQLException {
<
< try
< catch (Exception e)
<
< }
****CVS exited normally with code 1****
Here's JDBCDynaClass ....
/*
- $Header: /home/cvspublic/jakarta-
commons/beanutils/src/java/org/apache/commons/beanutils/RowSetDynaClass.java,v
1.3 2003/01/15 21:59:39 rdonkin Exp $ - $Revision: 1.3 $
- $Date: 2003/01/15 21:59:39 $
* - ====================================================================
* - The Apache Software License, Version 1.1
* - Copyright (c) 1999-2003 The Apache Software Foundation. All rights
- reserved.
* - Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
* - 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
* - 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
* - 3. The end-user documentation included with the redistribution, if
- any, must include the following acknowlegement:
- "This product includes software developed by the
- Apache Software Foundation (http://www.apache.org/)."
- Alternately, this acknowlegement may appear in the software itself,
- if and wherever such third-party acknowlegements normally appear.
* - 4. The names "The Jakarta Project", "Commons", and "Apache Software
- Foundation" must not be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact apache@apache.org.
* - 5. Products derived from this software may not be called "Apache"
- nor may "Apache" appear in their names without prior written
- permission of the Apache Group.
* - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- ====================================================================
* - This software consists of voluntary contributions made by many
- individuals on behalf of the Apache Software Foundation. For more
- information on the Apache Software Foundation, please see
- <http://www.apache.org/>.
*
*/
package org.apache.commons.beanutils;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
- <p>Provides logic for JDBC classImplementation of
{@link DynaClass}.</p>
*
* @author Craig R. McClanahan
* @author George Franciscus
* @version $Revision: 1.10 $ $Date: 2003/02/08 18:49:56 $
*/
abstract class JDBCDynaClass implements DynaClass, Serializable {
// ----------------------------------------------------- Instance
Variables
/**
* <p>Flag defining whether column names should be lower cased when
* converted to property names.</p>
*/
protected boolean lowerCase = true;
/**
* <p>The set of dynamic properties that are part of this
* {@link DynaClass}.</p>
*/
protected DynaProperty properties[] = null;
/**
- <p>The set of dynamic properties that are part of this
- {@link DynaClass}
, keyed by the property name. Individual
descriptor - instances will be the same instances as those in the
- <code>properties</code> list.</p>
*/
protected Map propertiesMap = new HashMap();
// ------------------------------------------------------ DynaClass
Methods
/**
- <p>Return the name of this DynaClass (analogous to the
- <code>getName()</code> method of <code>java.lang.Class</code), which
- allows the same <code>DynaClass</code> implementation class to
support - different dynamic classes, with different sets of properties.</p>
*/
public String getName() { return (this.getClass().getName()); }
/**
- <p>Return a property descriptor for the specified property, if it
- exists; otherwise, return <code>null</code>.</p>
* - @param name Name of the dynamic property for which a descriptor
- is requested
* - @exception IllegalArgumentException if no property name is specified
*/
public DynaProperty getDynaProperty(String name) {
if (name == null)
{ throw new IllegalArgumentException("No property name specified"); }return ((DynaProperty) propertiesMap.get(name));
}
/**
- <p>Return an array of <code>ProperyDescriptors</code> for the
properties - currently defined in this DynaClass. If no properties are defined,
a - zero-length array will be returned.</p>
*/
public DynaProperty[] getDynaProperties() { return (properties); }
/**
- <p>Instantiate and return a new DynaBean instance, associated
- with this DynaClass. <strong>NOTE</strong> - This operation is not
- supported, and throws an exception.</p>
* - @exception IllegalAccessException if the Class or the appropriate
- constructor is not accessible
- @exception InstantiationException if this Class represents an
abstract - class, an array class, a primitive type, or void; or if
instantiation - fails for some other reason
*/
public DynaBean newInstance()
throws IllegalAccessException, InstantiationException { throw new UnsupportedOperationException("newInstance() not supported"); }
/**
- <p>Loads and returns the <code>Class</code> of the given name.
- By default, a load from the thread context class loader is
attempted. - If there is no such class loader, the class loader used to load this
- class will be utilized.</p>
* - @exception SQLException if an exception was thrown trying to load
- the specified class
*/
protected Class loadClass(String className) throws SQLException {
try {
ClassLoader cl = Thread.currentThread
().getContextClassLoader();
if (cl == null)
return (cl.loadClass(className));
} catch (Exception e)
}
/**
- <p>Factory method to create a new DynaProperty for the given index
- into the result set metadata.</p>
- @param metadata is the result set metadata
- @param i is the column index in the metadata
- @return the newly created DynaProperty instance
*/
protected DynaProperty createDynaProperty(
ResultSetMetaData metadata,
int i)
throws SQLException {
String name = null;
if (lowerCase)
else
{ name = metadata.getColumnName(i); } String className = null;
try
catch (SQLException e)
{ // this is a patch for HsqlDb to ignore exceptions // thrown by its metadata implementation } // Default to Object type if no class name could be retrieved
// from the metadata
Class clazz = Object.class;
if (className != null)
return new DynaProperty(name, clazz);
}
/**
- <p>Introspect the metadata associated with our result set, and
populate - the <code>properties</code> and <code>propertiesMap</code> instance
- variables.</p>
* - @param resultSet The <code>resultSet</code> whose metadata is to
- be introspected
* - @exception SQLException if an error is encountered processing the
- result set metadata
*/
protected void introspect(ResultSet resultSet) throws SQLException {
// Accumulate an ordered list of DynaProperties
ArrayList list = new ArrayList();
ResultSetMetaData metadata = resultSet.getMetaData();
int n = metadata.getColumnCount();
for (int i = 1; i <= n; i++) { // JDBC is one-relative!
DynaProperty dynaProperty = createDynaProperty
(metadata, i);
if (dynaProperty != null)
}
// Convert this list into the internal data structures we need
properties =
(DynaProperty[]) list.toArray(new DynaProperty
[list.size()]);
for (int i = 0; i < properties.length; i++)
}
}