Package com.googlecode.jcsv.reader.internal

Source Code of com.googlecode.jcsv.reader.internal.AnnotationEntryParser

package com.googlecode.jcsv.reader.internal;

import java.lang.reflect.Field;

import com.googlecode.jcsv.annotations.MapToColumn;
import com.googlecode.jcsv.annotations.ValueProcessor;
import com.googlecode.jcsv.annotations.internal.ValueProcessorProvider;
import com.googlecode.jcsv.reader.CSVEntryParser;

/**
* Parses a csv entry, based on an annotated class.
*
* @author Eike Bergmann
*
* @param <E>
*            the type of the csv entries
*/
public class AnnotationEntryParser<E> implements CSVEntryParser<E> {

  private final Class<E> clazz;
 
  private final ValueProcessorProvider provider;

  /**
   * Constructs a AnnotationEntryParser for type E.
   *
   * @param clazz
   *            the annotated class, and the class of the csv entries
   */
  public AnnotationEntryParser(Class<E> clazz, ValueProcessorProvider provider) {
    this.clazz = clazz;
    this.provider = provider;
  }

  /**
   * {@link CSVEntryParser#parseEntry(String...)}
   */
  @Override
  public E parseEntry(String... data) {
    // create the instance
    E entry = newClassIntance();

    // fill the object with data
    fillObject(entry, data);

    return entry;
  }

  /**
   * Creates a new instance of type E.
   *
   * @throws RuntimeException
   *             thrown if the class can not be instantiated or accessed
   * @return the new instance
   */
  private E newClassIntance() {
    E entry;
    try {
      entry = clazz.newInstance();
    } catch (InstantiationException ie) {
      throw new RuntimeException(String.format("can not instantiate class %s", clazz.getName()), ie);
    } catch (IllegalAccessException iae) {
      throw new RuntimeException(String.format("can not access class %s", clazz.getName()), iae);
    }

    return entry;
  }

  /**
   * Fill the instance of E with the data of the csv row.
   *
   * This method iterates over the annotations that are present in the target
   * class and uses the appropriate value processors to set the data.
   *
   * @param entry
   *            The created instance of E
   * @param data
   *            The data that should be set
   */
  private void fillObject(E entry, String[] data) {
    for (Field field : entry.getClass().getDeclaredFields()) {
      // check if there is a MapToColumn Annotation
      MapToColumn mapAnnotation = field.getAnnotation(MapToColumn.class);
      if (mapAnnotation != null) {
        // read the annotation column
        int column = mapAnnotation.column();

        // read the annotation type. If type is Default.class, then
        // the type of the field will be used.
        Class<?> type;
        if (mapAnnotation.type().equals(MapToColumn.Default.class)) {
          // use the field type
          type = field.getType();
        } else {
          // use the annotated type
          type = mapAnnotation.type();
        }

        // load the appropriate value processor
        ValueProcessor<?> vp = provider.getValueProcessor(type);

        // use the value processor to convert the string data
        Object value = vp.processValue(data[column]);
       
        // make the field accessible and remember its state
        boolean wasAccessible = field.isAccessible();
        field.setAccessible(true);
       
        // try to set the field's value
        try {
          field.set(entry, value);
        } catch (IllegalArgumentException iae) {
          throw new RuntimeException(String.format("can not set value %s for type %s", value, type), iae);
        } catch (IllegalAccessException iae) {
          throw new RuntimeException(String.format("can not access field %s", field), iae);
        }
       
        // re-set the accessible flag
        field.setAccessible(wasAccessible);
      }
    }
  }
}
TOP

Related Classes of com.googlecode.jcsv.reader.internal.AnnotationEntryParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.