rdonkin 2003/03/13 10:45:38 Modified: beanutils/src/java/org/apache/commons/beanutils ResultSetDynaClass.java RowSetDynaClass.java Added: beanutils/src/java/org/apache/commons/beanutils JDBCDynaClass.java Log: Applied patch for enhancement #17811. This refactors the common code in ResultSetDynaClass and RowSetDynaClass into a common superclass. Submitted by George Franciscus Revision Changes Path 1.11 +7 -153 jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/ResultSetDynaClass.java Index: ResultSetDynaClass.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/ResultSetDynaClass.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- ResultSetDynaClass.java 8 Feb 2003 18:49:56 -0000 1.10 +++ ResultSetDynaClass.java 13 Mar 2003 18:45:38 -0000 1.11 @@ -64,9 +64,7 @@ import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -128,7 +126,7 @@ * @version $Revision$ $Date$ */ -public class ResultSetDynaClass implements DynaClass { +public class ResultSetDynaClass extends JDBCDynaClass implements DynaClass { // ----------------------------------------------------------- Constructors @@ -182,7 +180,7 @@ } this.resultSet = resultSet; this.lowerCase = lowerCase; - introspect(); + introspect(resultSet); } @@ -217,81 +215,6 @@ protected ResultSet resultSet = null; - - // ------------------------------------------------------ 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 (this.getClass().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) { - 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> - * - * <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() { - - 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. 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 { - - throw new UnsupportedOperationException("newInstance() not supported"); - - } - - // --------------------------------------------------------- Public Methods @@ -322,73 +245,7 @@ // ------------------------------------------------------ Protected Methods - - - /** - * <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 { - - // 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) { - list.add(dynaProperty); - } - } - - // 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++) { - propertiesMap.put(properties[i].getName(), properties[i]); - } - - } - - - /** - * <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) { - name = metadata.getColumnName(i).toLowerCase(); - } else { - name = metadata.getColumnName(i); - } - String className = null; - try { - className = metadata.getColumnClassName(i); - } - 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) { - clazz = loadClass(className); - } - 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. @@ -405,8 +262,5 @@ throw new SQLException("Cannot load column class '" + className + "': " + e); } - } - - } 1.4 +6 -209 jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/RowSetDynaClass.java Index: RowSetDynaClass.java =================================================================== RCS file: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/RowSetDynaClass.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- RowSetDynaClass.java 15 Jan 2003 21:59:39 -0000 1.3 +++ RowSetDynaClass.java 13 Mar 2003 18:45:38 -0000 1.4 @@ -65,12 +65,9 @@ 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.List; -import java.util.Map; /** @@ -109,17 +106,11 @@ * convenient mechanism for transporting data sets to remote Java-based * application components.</p> * - * <p><strong>FIXME</strong> - This class shares a lot of behavior with - * <code>ResultSetDynaClass</code>. We could not simply subclass it, - * because the existence of the <code>resultSet</code> instance variable - * would cause serializability problems. The common features should be - * factored out so that they can be shared.</p> - * * @author Craig R. McClanahan * @version $Revision$ $Date$ */ -public class RowSetDynaClass implements DynaClass, Serializable { +public class RowSetDynaClass extends JDBCDynaClass implements DynaClass, Serializable { // ----------------------------------------------------------- Constructors @@ -178,33 +169,7 @@ } - // ----------------------------------------------------- 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 - * [EMAIL PROTECTED] DynaClass}.</p> - */ - protected DynaProperty properties[] = null; - - - /** - * <p>The set of dynamic properties that are part of this - * [EMAIL PROTECTED] 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(); - - - /** + /** * <p>The list of [EMAIL PROTECTED] DynaBean}s representing the contents of * the original <code>ResultSet</code> on which this * [EMAIL PROTECTED] RowSetDynaClass} was based.</p> @@ -212,77 +177,6 @@ protected List rows = new ArrayList(); - // ------------------------------------------------------ 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"); - - } - - - // --------------------------------------------------------- Public Methods - - /** * <p>Return a <code>List</code> containing the [EMAIL PROTECTED] DynaBean}s that * represent the contents of each <code>Row</code> from the @@ -327,102 +221,5 @@ } } - - - /** - * <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) { - list.add(dynaProperty); - } - } - - // 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++) { - propertiesMap.put(properties[i].getName(), properties[i]); - } - - } - - - /** - * <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) { - name = metadata.getColumnName(i).toLowerCase(); - } else { - name = metadata.getColumnName(i); - } - String className = null; - try { - className = metadata.getColumnClassName(i); - } - 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) { - clazz = loadClass(className); - } - return new DynaProperty(name, clazz); - - } - - - /** - * <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) { - cl = this.getClass().getClassLoader(); - } - return (cl.loadClass(className)); - } catch (Exception e) { - throw new SQLException("Cannot load column class '" + - className + "': " + e); - } - - } - } 1.1 jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/JDBCDynaClass.java Index: JDBCDynaClass.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/JDBCDynaClass.java,v 1.1 2003/03/13 18:45:38 rdonkin Exp $ * $Revision: 1.1 $ * $Date: 2003/03/13 18:45:38 $ * * ==================================================================== * * 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 [EMAIL PROTECTED] * * 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 common logic for JDBC implementations of [EMAIL PROTECTED] DynaClass}.</p> * * @author Craig R. McClanahan * @author George Franciscus * @version $Revision: 1.1 $ $Date: 2003/03/13 18:45:38 $ */ 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 * [EMAIL PROTECTED] DynaClass}.</p> */ protected DynaProperty properties[] = null; /** * <p>The set of dynamic properties that are part of this * [EMAIL PROTECTED] 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) { cl = this.getClass().getClassLoader(); } return (cl.loadClass(className)); } catch (Exception e) { throw new SQLException( "Cannot load column class '" + className + "': " + 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) { name = metadata.getColumnName(i).toLowerCase(); } else { name = metadata.getColumnName(i); } String className = null; try { className = metadata.getColumnClassName(i); } 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) { clazz = loadClass(className); } 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) { list.add(dynaProperty); } } // 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++) { propertiesMap.put(properties[i].getName(), properties[i]); } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]