1 /*
2 * Copyright 2012 Olivier Godineau
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations under
12 * the License.
13 */
14 package olg.csv.bean;
15
16 import java.io.Closeable;
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.Iterator;
20
21 import olg.csv.base.IReader;
22 import olg.csv.base.IgnoreNullReader;
23 import olg.csv.base.ReaderException;
24 import olg.csv.base.Row;
25 import olg.csv.bean.loader.BeanProcessorLoader;
26 import olg.csv.bean.loader.LoadException;
27 import olg.csv.bean.parser.ParseException;
28
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33 * Class specialized in reading objects from a file. Used a {@link IReader} to
34 * read file as iterator of list of Strings. Used a BeanProcessor to transform a
35 * list of strings returned by the reader into a new object.
36 *
37 *
38 * @author Olivier Godineau
39 * @see IReader
40 * @see olg.csv.bean.impl.BeanProcessor
41 *
42 * @param <E>
43 * object this reader return
44 */
45 public class BeanReader<E> implements Iterator<E>, Closeable {
46
47 /**
48 * The class logger.
49 */
50 private static final Logger LOGGER = LoggerFactory.getLogger(BeanReader.class);
51
52 /**
53 * The reader.Allows to read file as iterator of list of Strings.
54 */
55 private IReader baseReader = null;
56
57 /**
58 * The beanProcessor. Allows to transform list of Strings into ab object
59 */
60 private IBeanProcessor<E> beanProcessor = null;
61
62 /**
63 * {@inheritDoc}
64 */
65 public void close() {
66 try {
67 baseReader.close();
68 } catch (IOException e) {
69 LOGGER.info("Error on closing IReader", e);
70 }
71
72 }
73 /**
74 * {@inheritDoc}
75 */
76 public boolean hasNext() {
77 return baseReader.hasNext();
78 }
79
80 /**
81 * {@inheritDoc}
82 */
83 public E next() throws ParseException {
84 E retour = null;
85
86 Row row = baseReader.next();
87 retour = beanProcessor.transform(row);
88
89 return retour;
90 }
91
92 /**
93 * @throws UnsupportedOperationException
94 */
95 public void remove() {
96 throw new UnsupportedOperationException();
97
98 }
99
100 /**
101 *
102 * @param configFile
103 * the file which describes how to load the transformer used to
104 * transform list of String into new object. Must be not
105 * <code>null</code>.
106 * @param reader
107 * the reader to use. allows to iterate list of Strings from the
108 * file the reader deals. Must be not <code>null</code>.
109 * @throws LoadException
110 * if an error occurs during loading transformer from file
111 */
112 public BeanReader(File configFile, IReader reader) throws LoadException {
113 this(configFile, reader, false);
114 }
115
116 /**
117 *
118 * @param configFile
119 * the file which describe how to load the transformer used to
120 * transform list of String into new object. Must be not
121 * <code>null</code>.
122 * @param reader
123 * the reader to use. allows to iterate list of Strings from the
124 * file the reader deals. Must be not <code>null</code>.
125 * @param skipEmptyRow
126 * avoids reading blank lines and skip creating beans from them
127 * @throws LoadException
128 * if an error occurs during loading transformer from file
129 */
130 public BeanReader(File configFile, IReader reader, boolean skipEmptyRow) throws LoadException {
131 super();
132 if (configFile == null) {
133 throw new IllegalArgumentException("Constructor configFile argument must be not null");
134 }
135 if (reader == null) {
136 throw new IllegalArgumentException("Constructor reader argument must be not null");
137 }
138 if (skipEmptyRow) {
139 this.baseReader = new IgnoreNullReader(reader);
140 } else {
141 this.baseReader = reader;
142 }
143
144 if (baseReader.isWithHeaders()) {
145 if (baseReader.hasNext()) {
146 baseReader.next();
147 } else {
148 throw new ReaderException("No headers");
149 }
150 }
151 this.beanProcessor = new BeanProcessorLoader<E>().load(configFile);
152 }
153
154 /**
155 * Constructs a BeanReader with a BeanProcessor and a reader.
156 *
157 * @param beanProcessor
158 * the BeanProcessor. Must be not <code>null</code>.
159 * @param reader
160 * the reader. If this reader products empty row, the Beanreader
161 * could return empty bean(use IgnoreNullReader to avoid this
162 * case). Must be not <code>null</code>.
163 */
164 public BeanReader(IBeanProcessor<E> beanProcessor, IReader reader) {
165 super();
166 if (beanProcessor == null) {
167 throw new IllegalArgumentException("Constructor beanProcessor argument must be not null");
168 }
169 if (reader == null) {
170 throw new IllegalArgumentException("Constructor reader argument must be not null");
171 }
172 this.baseReader = reader;
173 this.beanProcessor = beanProcessor;
174 if (baseReader.isWithHeaders()) {
175 if (baseReader.hasNext()) {
176 baseReader.next();
177 } else {
178 throw new ReaderException("No headers");
179 }
180 }
181 }
182
183 }