Open Source Repository

Home /csv/supercsv-1.52 | Repository Home



org/supercsv/io/CsvBeanReader.java
package org.supercsv.io;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.exception.SuperCSVException;
import org.supercsv.exception.SuperCSVReflectionException;
import org.supercsv.prefs.CsvPreference;
import org.supercsv.util.BeanInterfaceProxy;
import org.supercsv.util.MethodCache;
import org.supercsv.util.Util;

/**
 * This class reads a line from a csv file, instantiates a bean and populate its fields.
 
 @author Kasper B. Graversen
 */
public class CsvBeanReader extends AbstractCsvReader implements ICsvBeanReader {
/**
 * object used for storing intermediate result of a processing of cell processors and before put into maps/objects etc..
 * due to the typing, we cannot use super.line
 */
protected List<? super Object> lineResult = new ArrayList<Object>();
protected MethodCache cache = new MethodCache();

/**
 * 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 CsvBeanReader(final Reader reader, final CsvPreference preferences) {
  setPreferences(preferences);
  setInput(reader);
}

/**
 * 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[] nameMappingthrows SuperCSVReflectionException {
  try {
    // create a proxy instance if an interface type is provided
    final T resultBean;
    ifclazz.isInterface() ) {
      resultBean = (Tnew 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
    forint i = 0; i < nameMapping.length; i++ ) {
      // don't call a set-method in the bean, if there is no result to store
      ifnameMapping[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(01).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);
  }
}

/**
 * {@inheritDoc}
 */
public <T> T read(final Class<T> clazz, final String... nameMappingthrows IOException, SuperCSVReflectionException {
  iftokenizer.readStringList(super.line) ) {
    lineResult.clear();
    lineResult.addAll(super.line);
    return fillObject(clazz, nameMapping);
  }
  return null// EOF
}

/**
 * {@inheritDoc}
 */
public <T> T read(final Class<T> clazz, final String[] nameMapping, final CellProcessor[] processors)
  throws IOException, SuperCSVReflectionException, SuperCSVException {
  iftokenizer.readStringList(super.line) ) {
    Util.processStringList(lineResult, super.line, processors, tokenizer.getLineNumber());
    return fillObject(clazz, nameMapping);
  }
  return null// EOF
}
}