Создание пользовательского компонента с помощью Super CSV

CSVBeanReader предоставляет методы для чтения bean-компонента заданного типа.

Есть ли способ передать фактический экземпляр объекта, а не тип объекта (т.е. настроить создание экземпляра компонента)?


person lku    schedule 06.02.2013    source источник


Ответы (1)


Обновление:

Я только что выпустил Super CSV 2.2.0, который позволяет CsvBeanReader и CsvDozerBeanReader для заполнения существующего компонента. Ура!


Я разработчик Super CSV. Это невозможно сделать с помощью средств чтения, поставляемых с Super CSV (CsvBeanReader и CsvDozerBeanReader), и он не пришел как запрос функции раньше. Вы можете отправить запрос функции, и мы рассмотрим возможность его добавления в следующий релиз (который я надеюсь выпустить в этом месяце).

Самое быстрое решение для вас — написать свой собственный CsvBeanReader, который позволяет это сделать — просто скопируйте исходный код CsvBeanReader в свой и измените его по мере необходимости.

Я бы начал с рефакторинга метода populateBean() в 2 метода (перегруженных, поэтому один вызывает другой).

  /**
   * Instantiates the bean (or creates a proxy if it's an interface), and maps the processed columns to the fields of
   * the bean.
   * 
   * @param clazz
   *            the bean class to instantiate (a proxy will be created if an interface is supplied), using the default
   *            (no argument) constructor
   * @param nameMapping
   *            the name mappings
   * @return the populated bean
   * @throws SuperCsvReflectionException
   *             if there was a reflection exception while populating the bean
   */
  private <T> T populateBean(final Class<T> clazz, final String[] nameMapping) {

    // instantiate the bean or proxy
    final T resultBean = instantiateBean(clazz);

    return populateBean(resultBean, nameMapping);
  }

  /**
   * Populates the bean by mapping the processed columns to the fields of the bean.
   * 
   * @param resultBean
   *            the bean to populate
   * @param nameMapping
   *            the name mappings
   * @return the populated bean
   * @throws SuperCsvReflectionException
   *             if there was a reflection exception while populating the bean
   */
  private <T> T populateBean(final T resultBean, final String[] nameMapping) {

    // map each column to its associated field on the bean
    for( int i = 0; i < nameMapping.length; i++ ) {

      final Object fieldValue = processedColumns.get(i);

      // don't call a set-method in the bean if there is no name mapping for the column or no result to store
      if( nameMapping[i] == null || fieldValue == null ) {
        continue;
      }

      // invoke the setter on the bean
      Method setMethod = cache.getSetMethod(resultBean, nameMapping[i], fieldValue.getClass());
      invokeSetter(resultBean, setMethod, fieldValue);

    }

    return resultBean;
  }

Затем вы можете написать свои собственные read() методы (на основе методов из CsvBeanReader), которые принимают экземпляры компонентов (вместо их класса), и вызывают populateBean(), который принимает экземпляр.

Я оставлю это как упражнение для вас, но если у вас есть какие-либо вопросы, просто спросите :)

person James Bassett    schedule 06.02.2013
comment
Для этого я создал запрос функции :) - person James Bassett; 24.04.2013