You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Gary D. Gregory (Jira)" <ji...@apache.org> on 2025/01/07 14:07:01 UTC

[jira] [Updated] (BEANUTILS-213) [beanutils] Enhancement to ResultSetDynaClass to allow case-insensitive and missing parameter bean mapping

     [ https://issues.apache.org/jira/browse/BEANUTILS-213?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary D. Gregory updated BEANUTILS-213:
--------------------------------------
    Fix Version/s: 2.0.0-M2
                       (was: 2.0.0-M1)

> [beanutils] Enhancement to ResultSetDynaClass to allow case-insensitive and missing parameter bean mapping
> ----------------------------------------------------------------------------------------------------------
>
>                 Key: BEANUTILS-213
>                 URL: https://issues.apache.org/jira/browse/BEANUTILS-213
>             Project: Commons BeanUtils
>          Issue Type: Improvement
>          Components: DynaBean
>    Affects Versions: 1.6.1
>         Environment: Operating System: other
> Platform: Other
>            Reporter: Michael Mainguy
>            Priority: Minor
>             Fix For: 2.0.0-M2
>
>         Attachments: ASF.LICENSE.NOT.GRANTED--ResultSetDynaClass.java, ASF.LICENSE.NOT.GRANTED--introspectClassJDBCDynaClass.patch
>
>
> ##This is a 1 file patch for JDBCDynaClass and ResultSetDynaClass to allow more
> ##flexibility in the mapping of variable names to bean attributes.  
> ##e.g. PROJNBR in resultset will automatically get mapped to ProjNbr or PrOjNbR
> ##in bean.  class returned by iterator will not fail if there are fewer fields
> ##in resultset than in input bean.
> --- JDBCDynaClass.orig	2003-10-14 11:40:20.000000000 -0400
> +++ JDBCDynaClass.java	2003-10-13 11:39:49.000000000 -0400
> @@ -69,11 +69,13 @@
>  import java.util.HashMap;
>  import java.util.Map;
>  
> +
>  /**
>   * <p>Provides common logic for JDBC implementations of {@link DynaClass}.</p>
>   *
>   * @author   Craig R. McClanahan
>   * @author   George Franciscus
> + * @author   Michael Mainguy
>   * @version $Revision: 1.3 $ $Date: 2003/10/09 20:43:15 $
>   */
>  
> @@ -256,6 +258,48 @@
>  
>      }
>  
> -}
>  
> +	/**
> +	 * <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
> +	 * @param resultSet The <code>DynaClass</code> whose properties we want
> +	 *  to use
> +	 * 
> +	 * @exception SQLException if an error is encountered processing the
> +	 *  result set metadata
> +	 * 
> +	 */
> +	protected void introspect(ResultSet resultSet, DynaClass dynaClass) 
> throws SQLException {
> +		HashMap propmap = new HashMap();
> +		DynaProperty[] props = dynaClass.getDynaProperties();
> +		for (int i = 0; i< props.length; i++) {
> +			propmap.put(props[i].getName().toLowerCase(), props[i]);
> +		
> +		}
> +		// 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 = (DynaProperty)propmap.get
> (metadata.getColumnName(i).toLowerCase());
> +			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]);
> +		}
> +
> +	}
> +
> +
> +}
> --- ResultSetDynaClass.orig	2003-10-14 11:39:15.000000000 -0400
> +++ ResultSetDynaClass.java	2003-10-13 11:39:47.000000000 -0400
> @@ -123,145 +123,171 @@
>   * </pre>
>   *
>   * @author Craig R. McClanahan
> + * @author Michael Mainguy
>   * @version $Revision: 1.13 $ $Date: 2003/10/09 20:43:15 $
>   */
>  
>  public class ResultSetDynaClass extends JDBCDynaClass implements DynaClass {
>  
>  
> -	// ----------------------------------------------------------- 
> Constructors
> +    // ----------------------------------------------------------- Constructors
>  
>  
> -	/**
> -	 * <p>Construct a new ResultSetDynaClass for the specified
> -	 * <code>ResultSet</code>.  The property names corresponding
> -	 * to column names in the result set will be lower cased.</p>
> -	 *
> -	 * @param resultSet The result set to be wrapped
> -	 *
> -	 * @exception NullPointerException if <code>resultSet</code>
> -	 *  is <code>null</code>
> -	 * @exception SQLException if the metadata for this result set
> -	 *  cannot be introspected
> -	 */
> -	public ResultSetDynaClass(ResultSet resultSet) throws SQLException {
>  
> -		this(resultSet, true);
>  
> -	}
> +    /**
> +     * <p>Construct a new ResultSetDynaClass for the specified
> +     * <code>ResultSet</code>.  The property names corresponding
> +     * to column names in the result set will be lower cased.</p>
> +     *
> +     * @param resultSet The result set to be wrapped
> +     *
> +     * @exception NullPointerException if <code>resultSet</code>
> +     *  is <code>null</code>
> +     * @exception SQLException if the metadata for this result set
> +     *  cannot be introspected
> +     */
> +    public ResultSetDynaClass(ResultSet resultSet) throws SQLException {
> +
> +        this(resultSet, true);
> +
> +    }
> +
> +
> +    /**
> +     * <p>Construct a new ResultSetDynaClass for the specified
> +     * <code>ResultSet</code>.  The property names corresponding
> +     * to the column names in the result set will be lower cased or not,
> +     * depending on the specified <code>lowerCase</code> value.</p>
> +     *
> +     * <p><strong>WARNING</strong> - If you specify <code>false</code>
> +     * for <code>lowerCase</code>, the returned property names will
> +     * exactly match the column names returned by your JDBC driver.
> +     * Because different drivers might return column names in different
> +     * cases, the property names seen by your application will vary
> +     * depending on which JDBC driver you are using.</p>
> +     *
> +     * @param resultSet The result set to be wrapped
> +     * @param lowerCase Should property names be lower cased?
> +     *
> +     * @exception NullPointerException if <code>resultSet</code>
> +     *  is <code>null</code>
> +     * @exception SQLException if the metadata for this result set
> +     *  cannot be introspected
> +     */
> +    public ResultSetDynaClass(ResultSet resultSet, boolean lowerCase)
> +        throws SQLException {
> +
> +        if (resultSet == null) {
> +            throw new NullPointerException();
> +        }
> +        this.resultSet = resultSet;
> +        this.lowerCase = lowerCase;
> +        introspect(resultSet);
> +
> +    }
> +
>  
> +    // ----------------------------------------------------- Instance Variables
>  
>  	/**
>  	 * <p>Construct a new ResultSetDynaClass for the specified
>  	 * <code>ResultSet</code>.  The property names corresponding
> -	 * to the column names in the result set will be lower cased or not,
> -	 * depending on the specified <code>lowerCase</code> value.</p>
> -	 *
> -	 * <p><strong>WARNING</strong> - If you specify <code>false</code>
> -	 * for <code>lowerCase</code>, the returned property names will
> -	 * exactly match the column names returned by your JDBC driver.
> -	 * Because different drivers might return column names in different
> -	 * cases, the property names seen by your application will vary
> -	 * depending on which JDBC driver you are using.</p>
> +	 * will be case insensitive compared to the properties on the 
> +	 * input dynaClass and mapped appropriately.</p>
>  	 *
>  	 * @param resultSet The result set to be wrapped
> -	 * @param lowerCase Should property names be lower cased?
> +	 * @param dynaClass The DynaClass containing the properties we want to 
> map 
>  	 *
>  	 * @exception NullPointerException if <code>resultSet</code>
>  	 *  is <code>null</code>
>  	 * @exception SQLException if the metadata for this result set
>  	 *  cannot be introspected
>  	 */
> -	public ResultSetDynaClass(ResultSet resultSet, boolean lowerCase)
> -		throws SQLException {
> +	public ResultSetDynaClass(ResultSet resultSet, DynaClass dynaClass) 
> throws SQLException {
>  
>  		if (resultSet == null) {
>  			throw new NullPointerException();
>  		}
>  		this.resultSet = resultSet;
> -		this.lowerCase = lowerCase;
> -		introspect(resultSet);
> +		introspect(resultSet, dynaClass);
>  
>  	}
>  
>  
> -	// ----------------------------------------------------- Instance 
> Variables
> +    /**
> +     * Flag defining whether column names should be lower cased when
> +     * converted to property names.
> +     */
> +    protected boolean lowerCase = true;
>  
>  
> -	/**
> -	 * Flag defining whether column names should be lower cased when
> -	 * converted to property names.
> -	 */
> -	protected boolean lowerCase = true;
> +    /**
> +     * The set of dynamic properties that are part of this DynaClass.
> +     */
> +    protected DynaProperty properties[] = null;
>  
>  
> -	/**
> -	 * The set of dynamic properties that are part of this DynaClass.
> -	 */
> -	protected DynaProperty properties[] = null;
> +    /**
> +     * The set of dynamic properties that are part of this DynaClass,
> +     * keyed by the property name.  Individual descriptor instances will
> +     * be the same instances as those in the <code>properties</code> list.
> +     */
> +    protected HashMap propertiesMap = new HashMap();
>  
>  
> -	/**
> -	 * The set of dynamic properties that are part of this DynaClass,
> -	 * keyed by the property name.  Individual descriptor instances will
> -	 * be the same instances as those in the <code>properties</code> list.
> -	 */
> -	protected HashMap propertiesMap = new HashMap();
> +    /**
> +     * <p>The <code>ResultSet</code> we are wrapping.</p>
> +     */
> +    protected ResultSet resultSet = null;
>  
>  
> -	/**
> -	 * <p>The <code>ResultSet</code> we are wrapping.</p>
> -	 */
> -	protected ResultSet resultSet = null;
> +    // --------------------------------------------------------- Public Methods
>  
>  
> -	// --------------------------------------------------------- Public 
> Methods
> +    /**
> +     * <p>Return an <code>Iterator</code> of {@link DynaBean} instances for
> +     * each row of the wrapped <code>ResultSet</code>, in "forward" order.
> +     * Unless the underlying result set supports scrolling, this method
> +     * should be called only once.</p>
> +     */
> +    public Iterator iterator() {
>  
> +        return (new ResultSetIterator(this));
>  
> -	/**
> -	 * <p>Return an <code>Iterator</code> of {@link DynaBean} instances for
> -	 * each row of the wrapped <code>ResultSet</code>, in "forward" order.
> -	 * Unless the underlying result set supports scrolling, this method
> -	 * should be called only once.</p>
> -	 */
> -	public Iterator iterator() {
> +    }
>  
> -		return (new ResultSetIterator(this));
>  
> -	}
> +    // -------------------------------------------------------- Package Methods
>  
>  
> -	// -------------------------------------------------------- Package 
> Methods
> +    /**
> +     * <p>Return the result set we are wrapping.</p>
> +     */
> +    ResultSet getResultSet() {
>  
> +        return (this.resultSet);
>  
> -	/**
> -	 * <p>Return the result set we are wrapping.</p>
> -	 */
> -	ResultSet getResultSet() {
> -
> -		return (this.resultSet);
> -
> -	}
> +    }
>  
>  
> -	// ------------------------------------------------------ Protected 
> Methods
> +    // ------------------------------------------------------ Protected Methods
>      
> -	/**
> -	 * <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 {
> -			return getClass().getClassLoader().loadClass(className);
> -		} 
> -		catch (Exception e) {
> -			throw new SQLException("Cannot load column class '" +
> -								   className 
> + "': " + e);
> -		}
> -	}
> -}
> -
> +    /**
> +     * <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 {
> +            return getClass().getClassLoader().loadClass(className);
> +        } 
> +        catch (Exception e) {
> +            throw new SQLException("Cannot load column class '" +
> +                                   className + "': " + e);
> +        }
> +    }
> +}
> \ No newline at end of file



--
This message was sent by Atlassian Jira
(v8.20.10#820010)