View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2018 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.qa.glnm.configuration;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.lang.reflect.InvocationTargetException;
25  import java.nio.charset.Charset;
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Map;
29  
30  import org.apache.commons.beanutils.BeanUtils;
31  import org.apache.commons.csv.CSVFormat;
32  import org.apache.commons.csv.CSVParser;
33  import org.apache.commons.csv.CSVRecord;
34  import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  import io.wcm.qa.glnm.exceptions.GaleniumException;
39  
40  /**
41   * Utility methods to parse CSV files.
42   *
43   * @since 1.0.0
44   */
45  public final class CsvUtil {
46  
47    private static final Charset CHARSET_UTF8 = Charset.forName("utf-8");
48    private static final CSVFormat FORMAT = CSVFormat.DEFAULT.withQuote(null).withHeader(new String[] {});
49  
50    private static final Logger LOG = LoggerFactory.getLogger(CsvUtil.class);
51  
52    private CsvUtil() {
53      // do not instantiate
54    }
55  
56    /**
57     * Get a parser for CSV file.
58     *
59     * @param csvFile to get parser for
60     * @return parser to access data in CSV file
61     * @since 3.0.0
62     */
63    public static CSVParser parse(File csvFile) {
64      return parse(csvFile, false);
65    }
66  
67    /**
68     * Get a parser for CSV file.
69     *
70     * @param csvFile to get parser for
71     * @param skipHeaderRecord whether to skip header record while parsing
72     * @return parser to access data in CSV file
73     * @since 3.0.0
74     */
75    public static CSVParser parse(File csvFile, boolean skipHeaderRecord) {
76      if (csvFile == null) {
77        throw new GaleniumException("error when checking CSV input: file is null");
78      }
79      if (!csvFile.isFile()) {
80        throw new GaleniumException("error when reading CSV file: '" + csvFile.getPath() + "'");
81      }
82      try {
83        CSVFormat format = FORMAT.withSkipHeaderRecord(skipHeaderRecord);
84        return CSVParser.parse(csvFile, CHARSET_UTF8, format);
85      }
86      catch (IOException ex) {
87        throw new GaleniumException("error when parsing CSV file: '" + csvFile.getPath() + "'", ex);
88      }
89    }
90  
91    /**
92     * Get a parser for CSV file.
93     *
94     * @param csvFilePath path to file to get parser for
95     * @return parser to access data in CSV file
96     * @since 3.0.0
97     */
98    public static CSVParser parse(String csvFilePath) {
99      return parse(new File(csvFilePath));
100   }
101 
102   /**
103    * Populate beans with CSV data.
104    *
105    * @param csvFile to get input data from
106    * @param beanClass type of bean to populate
107    * @param <T> type of bean as generic to create typed collection
108    * @return collection with one bean per row in CSV
109    * @since 3.0.0
110    */
111   public static <T> Collection<T> parseToBeans(File csvFile, Class<T> beanClass) {
112     Collection<T> result = new ArrayList<>();
113     CSVParser parse = parse(csvFile);
114     for (CSVRecord csvRecord : parse) {
115       Map<String, String> map = csvRecord.toMap();
116       LOG.debug("from csv: " + csvRecord);
117       LOG.debug("from csv: " + ReflectionToStringBuilder.toString(csvRecord));
118       LOG.debug("map from csv: " + ReflectionToStringBuilder.toString(map));
119       try {
120         T newInstance = beanClass.newInstance();
121         BeanUtils.populate(newInstance, map);
122         LOG.debug("populated: " + newInstance);
123         result.add(newInstance);
124       }
125       catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) {
126         throw new GaleniumException("error when constructing bean from CSV: '" + csvFile.getPath() + "'", ex);
127       }
128     }
129     return result;
130   }
131 
132 }