1 package com.opencsv.bean;
2
3 /*
4 * Copyright 2015 Bytecode Pty Ltd.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 import com.opencsv.CSVReader;
20 import com.opencsv.ICSVParser;
21 import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
22 import org.apache.commons.lang3.ObjectUtils;
23
24 import java.beans.IntrospectionException;
25 import java.io.IOException;
26 import java.lang.reflect.InvocationTargetException;
27 import java.util.Iterator;
28 import java.util.Locale;
29 import java.util.NoSuchElementException;
30 import java.util.ResourceBundle;
31
32 /**
33 * Converts CSV strings to objects.
34 * Unlike CsvToBean it returns a single record at a time.
35 *
36 * @param <T> Class to convert the objects to.
37 * @deprecated Use {@link CsvToBean#iterator()} instead.
38 */
39 @Deprecated
40 public class IterableCSVToBean<T> implements Iterable<T> {
41 private final MappingStrategy<T> strategy;
42 private final CSVReader csvReader;
43 private final CsvToBeanFilter filter;
44 private boolean hasHeader;
45 private Locale errorLocale = Locale.getDefault();
46
47 /**
48 * IterableCSVToBean constructor
49 *
50 * @param csvReader CSVReader. Should not be null.
51 * @param strategy MappingStrategy used to map CSV data to the bean. Should not be null.
52 * @param filter Optional CsvToBeanFilter used remove unwanted data from reads.
53 */
54 public IterableCSVToBean(CSVReader csvReader, MappingStrategy<T> strategy, CsvToBeanFilter filter) {
55 this.csvReader = csvReader;
56 this.strategy = strategy;
57 this.filter = filter;
58 this.hasHeader = false;
59 }
60
61 /**
62 * Retrieves the MappingStrategy.
63 * @return The MappingStrategy being used by the IterableCSVToBean.
64 */
65 protected MappingStrategy<T> getStrategy() {
66 return strategy;
67 }
68
69 /**
70 * Retrieves the CSVReader.
71 * @return The CSVReader being used by the IterableCSVToBean.
72 */
73 protected CSVReader getCSVReader() {
74 return csvReader;
75 }
76
77 /**
78 * Retrieves the CsvToBeanFilter
79 *
80 * @return The CsvToBeanFilter being used by the IterableCSVToBean.
81 */
82 protected CsvToBeanFilter getFilter() {
83 return filter;
84 }
85
86 /**
87 * Reads and processes a single line.
88 * @return Object of type T with the requested information or null if there
89 * are no more lines to process.
90 * @throws IllegalAccessException Thrown if there is a failure in introspection.
91 * @throws InstantiationException Thrown when getting the PropertyDescriptor for the class.
92 * @throws IOException Thrown when there is an unexpected error reading the file.
93 * @throws IntrospectionException Thrown if there is a failure in introspection.
94 * @throws InvocationTargetException Thrown if there is a failure in introspection.
95 * @throws CsvRequiredFieldEmptyException If a field is required, but the
96 * header or column position for the field is not present in the input
97 */
98 public T nextLine() throws IllegalAccessException, InstantiationException,
99 IOException, IntrospectionException, InvocationTargetException,
100 CsvRequiredFieldEmptyException {
101 if (!hasHeader) {
102 strategy.captureHeader(csvReader);
103 hasHeader = true;
104 }
105 T bean = null;
106 String[] line;
107 do {
108 line = csvReader.readNext();
109 } while (line != null && (filter != null && !filter.allowLine(line)));
110 if (line != null) {
111 bean = strategy.populateNewBeanWithIntrospection(line);
112 }
113 return bean;
114 }
115
116 /**
117 * Sets the locale to be used for error messages.
118 * @param errorLocale The locale to be used for all error messages. If null,
119 * the default locale is used.
120 * @since 4.0
121 */
122 public void setErrorLocale(Locale errorLocale) {
123 this.errorLocale = ObjectUtils.defaultIfNull(errorLocale, Locale.getDefault());
124 }
125
126 @Override
127 public Iterator<T> iterator() {
128 return iterator(this);
129 }
130
131 private Iterator<T> iterator(final IterableCSVToBean<T> bean) {
132 return new Iterator<T>() {
133 private T nextBean;
134
135 @Override
136 public boolean hasNext() {
137 if (nextBean != null) {
138 return true;
139 }
140
141 try {
142 nextBean = bean.nextLine();
143 } catch (IllegalAccessException | InstantiationException
144 | IOException | IntrospectionException
145 | InvocationTargetException
146 | CsvRequiredFieldEmptyException e) {
147 e.printStackTrace();
148 }
149
150 return nextBean != null;
151 }
152
153 @Override
154 public T next() {
155 if (!hasNext()) {
156 throw new NoSuchElementException();
157 }
158
159 T holder = nextBean;
160 nextBean = null;
161 return holder;
162 }
163
164 @Override
165 public void remove() {
166 throw new UnsupportedOperationException(ResourceBundle.getBundle(ICSVParser.DEFAULT_BUNDLE_NAME, errorLocale).getString("read.only.iterator"));
167 }
168 };
169 }
170 }