All Downloads are FREE. Search and download functionalities are using the official Maven repository.

liquibase.util.csv.opencsv.bean.CsvToBean Maven / Gradle / Ivy

There is a newer version: 3.6.2.5.inovus
Show newest version
package liquibase.util.csv.opencsv.bean;

/**
 Copyright 2007 Kyle Miller.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

import liquibase.util.csv.opencsv.CSVReader;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * Converts CSV data to objects.
 *
 * @param  - class to convert the objects to.
 */
public class CsvToBean extends AbstractCSVToBean {
   private Map, PropertyEditor> editorMap;

   /**
    * Default constructor.
    */
   public CsvToBean() {
   }

   /**
    * parse the values from a csvReader constructed from the passed in Reader.
    * @param mapper - mapping strategy for the bean.
    * @param reader - Reader used to construct a CSVReader
    * @return List of Objects.
    */

   public List parse(MappingStrategy mapper, Reader reader) {
      return parse(mapper, new CSVReader(reader));
   }

   /**
    * parse the values from a csvReader constructed from the passed in Reader.
    * @param mapper - mapping strategy for the bean.
    * @param reader - Reader used to construct a CSVReader
    * @param filter - CsvToBeanFilter to apply - null if no filter.
    * @return List of Objects.
    */
   public List parse(MappingStrategy mapper, Reader reader, CsvToBeanFilter filter) {
      return parse(mapper, new CSVReader(reader), filter);
   }

   /**
    * parse the values from the csvReader.
    * @param mapper - mapping strategy for the bean.
    * @param csv - CSVReader
    * @return List of Objects.
    */
   public List parse(MappingStrategy mapper, CSVReader csv) {
      return parse(mapper, csv, null);
   }

   /**
    * parse the values from the csvReader.
    * @param mapper - mapping strategy for the bean.
    * @param csv - CSVReader
    * @param filter - CsvToBeanFilter to apply - null if no filter.
    * @return List of Objects.
    */
   public List parse(MappingStrategy mapper, CSVReader csv, CsvToBeanFilter filter) {
      long lineProcessed = 0;
      String[] line = null;

      try {
         mapper.captureHeader(csv);
      } catch (Exception e) {
         throw new RuntimeException("Error capturing CSV header!", e);
      }

      try {
         List list = new ArrayList<>();
         while (null != (line = csv.readNext())) {
            lineProcessed++;
            processLine(mapper, filter, line, list);
         }
         return list;
      } catch (Exception e) {
         throw new RuntimeException("Error parsing CSV line: " + lineProcessed + " values: " + Arrays.toString(line), e);
      }
   }

   private void processLine(MappingStrategy mapper, CsvToBeanFilter filter, String[] line, List list) throws ReflectiveOperationException, IntrospectionException {
      if ((filter == null) || filter.allowLine(line)) {
         T obj = processLine(mapper, line);
         list.add(obj);
      }
   }

   /**
    * Creates a single object from a line from the csv file.
    * @param mapper - MappingStrategy
    * @param line  - array of Strings from the csv file.
    * @return - object containing the values.
    * @throws ReflectiveOperationException - thrown on error accessing bean.
    * @throws IntrospectionException - thrown on error getting the PropertyDescriptor.
    */
   protected T processLine(MappingStrategy mapper, String[] line) throws ReflectiveOperationException, IntrospectionException {
      T bean = mapper.createBean();
      for (int col = 0; col < line.length; col++) {
         if (mapper.isAnnotationDriven()) {
            processField(mapper, line, bean, col);
         } else {
            processProperty(mapper, line, bean, col);
         }
      }
      return bean;
   }

   private void processProperty(MappingStrategy mapper, String[] line, T bean, int col) throws IntrospectionException, ReflectiveOperationException {
      PropertyDescriptor prop = mapper.findDescriptor(col);
      if (null != prop) {
         String value = checkForTrim(line[col], prop);
         Object obj = convertValue(value, prop);
         prop.getWriteMethod().invoke(bean, obj);
      }
   }

   private void processField(MappingStrategy mapper, String[] line, T bean, int col) throws IllegalAccessException {
      BeanField beanField = mapper.findField(col);
      if (beanField != null) {
         String value = line[col];
         beanField.setFieldValue(bean, value);
      }
   }

   private PropertyEditor getPropertyEditorValue(Class cls) {
      if (editorMap == null) {
         editorMap = new HashMap<>();
      }

      PropertyEditor editor = editorMap.get(cls);

      if (editor == null) {
         editor = PropertyEditorManager.findEditor(cls);
         addEditorToMap(cls, editor);
      }

      return editor;
   }

   private void addEditorToMap(Class cls, PropertyEditor editor) {
      if (editor != null) {
         editorMap.put(cls, editor);
      }
   }


   /**
    * Attempt to find custom property editor on descriptor first, else try the propery editor manager.
    *
    * @param desc - PropertyDescriptor.
    * @return - the PropertyEditor for the given PropertyDescriptor.
    * @throws ReflectiveOperationException - thrown when getting the PropertyEditor for the class.
    */
   protected PropertyEditor getPropertyEditor(PropertyDescriptor desc) throws ReflectiveOperationException {
      Class cls = desc.getPropertyEditorClass();
      if (null != cls) {
         return (PropertyEditor) cls.getConstructor().newInstance();
      }
      return getPropertyEditorValue(desc.getPropertyType());
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy