/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.welcom.outils.jdbc.wrapper; import java.io.BufferedInputStream; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Vector; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * General purpose utility methods related to ResultSets * * @version $Revision: 1.1 $ $Date: 2001/08/11 $ */ public class ResultSetUtils { /** logger */ private static Log log = LogFactory.getLog( ResultSetUtils.class ); /** Buffer */ private static final int BUFFER_SIZE = 4096; /** * Populate the properties of the specified JavaBean from the next record of the specified ResultSet, based on * matching each column name against the corresponding JavaBeans "property setter" methods in the bean's class. * Suitable conversion is done for argument types as described under <code>convert()</code>. * * @param bean The JavaBean whose properties are to be set * @param resultSet The ResultSet whose parameters are to be used to populate bean properties * @exception SQLException if an exception is thrown while setting property values or access the ResultSet */ public static void populate( final Object bean, final ResultSet resultSet ) throws SQLException { // Format pour les dates final SimpleDateFormat formatDate = new SimpleDateFormat( "dd/MM/yyyy HH:mm" ); // Build a list of relevant column properties from this resultSet final HashMap properties = new HashMap(); // Acquire resultSet MetaData final ResultSetMetaData metaData = resultSet.getMetaData(); final int cols = metaData.getColumnCount(); // Scroll to next record and pump into hashmap // if (resultSet.next()) for ( int i = 1; i <= cols; i++ ) { if ( metaData.getColumnClassName( i ).equals( "java.sql.Timestamp" ) ) { properties.put( metaData.getColumnName( i ), getFormattedDateTimeColumn( resultSet.getTimestamp( i ), formatDate ) ); } else if ( metaData.getColumnClassName( i ).equals( "oracle.sql.CLOB" ) ) { properties.put( metaData.getColumnName( i ), getFormattedClobColumn( resultSet.getAsciiStream( i ) ) ); } else { properties.put( metaData.getColumnName( i ), getFormattedStringColumn( resultSet.getString( i ) ) ); } } // Set the corresponding properties of our bean try { populateIgnoreCase( bean, properties ); } catch ( final Exception e ) { throw new SQLException( "BeanUtils.populate threw " + e.toString() ); } } /** * Formate une colonne DateTime SQL pour le populate * * @param ts : Valeur du Timestamp du resultSet * @param formatDate format de la date cf (@link SimpleDateFormat) * @return chaine formatt� */ private static String getFormattedDateTimeColumn( final Timestamp ts, final SimpleDateFormat formatDate ) { String dt = ""; if ( ts != null ) { dt = formatDate.format( new Date( ts.getTime() ) ); if ( dt == null ) { dt = ""; } } return dt; } /** * Formate une colonne Clob SQL pour le populate * * @param is : Valeur du ASCIIStream du resultSet * @return chaine formatt� */ private static String getFormattedClobColumn( final InputStream is ) { final byte b[] = new byte[BUFFER_SIZE]; final BufferedInputStream bi = new BufferedInputStream( is ); final StringBuffer sb = new StringBuffer(); try { while ( ( bi.read( b ) ) != -1 ) { sb.append( new String( b ) ); } } catch ( final Exception e ) { new SQLException( "Erreur sur la lecture du CLOB" ); } return sb.toString(); } /** * Formate une colonne String SQL pour le populate * * @param st : Valeur du resultSet de la colonne * @return chaine formatt� */ private static String getFormattedStringColumn( String st ) { if ( st == null ) { st = ""; } return st; } /** * Effectue un populate sans tenir compte de la case * * @param bean : Bean A populer * @param properties : Liste des propertie a modifier * @throws IllegalAccessException : Probleme sur l'acc�s a l'attribut pas le getter * @throws InvocationTargetException : Probleme sur le populate */ public static void populateIgnoreCase( final Object bean, final Map properties ) throws IllegalAccessException, InvocationTargetException { try { final Hashtable realName = new Hashtable(); // Recuperation de la table des correspondances final Map map = PropertyUtils.describe( bean ); Iterator it = map.keySet().iterator(); while ( it.hasNext() ) { final String element = (String) it.next(); realName.put( element.toUpperCase(), element ); } // Reaffecte les bons Noms final HashMap propertiesRealName = new HashMap(); it = properties.keySet().iterator(); while ( it.hasNext() ) { final String element = (String) it.next(); if ( realName.containsKey( element.toUpperCase() ) ) { propertiesRealName.put( realName.get( element.toUpperCase() ), properties.get( element ) ); } } BeanUtils.populate( bean, propertiesRealName ); } catch ( final IllegalAccessException e ) { log.error( e, e ); BeanUtils.populate( bean, properties ); } catch ( final InvocationTargetException e ) { log.error( e, e ); BeanUtils.populate( bean, properties ); } catch ( final NoSuchMethodException e ) { log.error( e, e ); BeanUtils.populate( bean, properties ); } } /** * Populate the properties of the specified JavaBean from the next record of the specified ResultSet, based on * matching each column name against the corresponding JavaBeans "property setter" methods in the bean's class. * Suitable conversion is done for argument types as described under <code>convert()</code>. * * @param bean The JavaBean whose properties are to be set * @param resultSet The ResultSet whose parameters are to be used to populate bean properties * @param formatDate (@link SimpleDateFormat) * @exception SQLException if an exception is thrown while setting property values or access the ResultSet */ public static void populate( final Object bean, final ResultSet resultSet, final SimpleDateFormat formatDate ) throws SQLException { // Build a list of relevant column properties from this resultSet final HashMap properties = new HashMap(); // Acquire resultSet MetaData final ResultSetMetaData metaData = resultSet.getMetaData(); final int cols = metaData.getColumnCount(); // Scroll to next record and pump into hashmap // if (resultSet.next()) for ( int i = 1; i <= cols; i++ ) { if ( metaData.getColumnClassName( i ).equals( "java.sql.Timestamp" ) ) { if ( resultSet.getTimestamp( i ) != null ) { properties.put( metaData.getColumnName( i ), formatDate.format( new Date( resultSet.getTimestamp( i ).getTime() ) ) ); } else { properties.put( metaData.getColumnName( i ), "" ); } } else { properties.put( metaData.getColumnName( i ), resultSet.getString( i ) ); } } // Set the corresponding properties of our bean try { populateIgnoreCase( bean, properties ); } catch ( final Exception e ) { throw new SQLException( "BeanUtils.populate threw " + e.toString() ); } } /** * @return Return a HashMap of the records in a resultSet as a contiguous list. * @param resultSet The ResultSet whose parameters are to be used to populate bean properties * @exception SQLException if an exception is thrown while setting property values or access the ResultSet */ public static HashMap toMap( final ResultSet resultSet ) throws SQLException { // Build a list of relevant column properties from this resultSet final HashMap properties = new HashMap(); // Acquire resultSet MetaData final ResultSetMetaData metaData = resultSet.getMetaData(); final int cols = metaData.getColumnCount(); // Scroll to next record and pump into hashmap while ( resultSet.next() ) { for ( int i = 1; i <= cols; i++ ) { properties.put( metaData.getColumnName( i ), resultSet.getString( i ) ); } } return ( properties ); } /** * Effectue un poepulate en retournant directment une liste d'objets * * @param c Classe de l'object a intancier * @param rs Resulset fournir par la query, effectue le test de nullit�, retourne une liste vide dans ce cas * @return Liste d'object de la classe */ public static Vector populateInVector( final Class c, final ResultSet rs ) { final Vector vector = new Vector(); try { if ( rs != null ) { while ( rs.next() ) { final Object o = c.newInstance(); ResultSetUtils.populate( o, rs ); vector.add( o ); } rs.close(); } } catch ( final Exception e ) { System.err.println( e.getMessage() ); } return vector; } }