/**
* Copyright (c) 2009 Cahaya Consulting
*/
package org.supercsv.io;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.supercsv.exception.SuperCSVException;
import org.supercsv.exception.SuperCSVReflectionException;
import org.supercsv.prefs.CsvPreference;
import org.supercsv.util.BeanInterfaceProxy;
/**
* This class contains a bug fix for release 1.52 as found in revision 209.
* http://supercsv.svn.sourceforge.net/viewvc/supercsv/trunk/src/org/supercsv/io/CsvBeanReader.java?view=log
* When release 1.53 (or later is made) this class can be deleted.
*
* @author Mathew Pole
* @since May 2009
* @version ${Revision}
*/
public class BugFixCsvBeanReader extends CsvBeanReader
{
/** The private logger for this class */
private Logger myLog = LoggerFactory.getLogger (BugFixCsvBeanReader.class);
/**
* Create a csv reader with a specific preference. Note that the <tt>reader</tt> provided in the argument will be
* wrapped in a <tt>BufferedReader</tt> before accessed.
*/
public BugFixCsvBeanReader(final Reader reader, final CsvPreference preferences) {
super (reader, preferences);
}
/**
* Creates an object of the type or if it is an interface, create a proxy instance implementing the interface type.
*
* @param clazz
* the type to instantiate. If the type is a class type, an instance can be created straight away. If the
* type is an interface type, a proxy is created on the fly which acts as an implementation.
* @param nameMapping
* @return A filled object
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
<T> T fillObject(final Class<T> clazz, final String[] nameMapping) throws SuperCSVReflectionException {
try {
// create a proxy instance if an interface type is provided
final T resultBean;
if( clazz.isInterface() ) {
resultBean = (T) new BeanInterfaceProxy().createProxy(clazz);
} else {
resultBean = clazz.newInstance();
}
// map results into an object by traversing the list of nameMapping and for each non-null,
// map that name to an entry in the lineResult
// map results to the setter methods
for( int i = 0; i < nameMapping.length; i++ ) {
// don't call a set-method in the bean, if there is no result to store
// @bugfix Revision 209 (v1.53 should hopfully fix this)
if( nameMapping[i] == null || lineResult.get (i) == null) {
continue;
}
try {
// System.out.println(String.format("mapping[i]= %s, lR[%d] = %s val '%s'", nameMapping[i], i,
// lineResult
// .get(i).getClass(), lineResult.get(i)));
cache.getSetMethod(resultBean, nameMapping[i], lineResult.get(i).getClass())//
.invoke(resultBean, lineResult.get(i));
}
catch(final IllegalArgumentException e) {
throw new SuperCSVException("Method set" + nameMapping[i].substring(0, 1).toUpperCase()
+ nameMapping[i].substring(1) + "() does not accept input \"" + lineResult.get(i) + "\" of type "
+ lineResult.get(i).getClass().getName(), null, e);
}
}
return resultBean;
}
catch(final InstantiationException e) {
throw new SuperCSVReflectionException("Error while filling an object", e);
}
catch(final IllegalAccessException e) {
throw new SuperCSVReflectionException("Error while filling an object", e);
}
catch(final InvocationTargetException e) {
throw new SuperCSVReflectionException("Error while filling an object", e);
}
}
}