View Javadoc
1   package org.csveed.bean;
2   
3   import java.io.Reader;
4   import java.util.ArrayList;
5   import java.util.List;
6   
7   import org.csveed.api.Header;
8   import org.csveed.api.Row;
9   import org.csveed.report.CsvException;
10  import org.csveed.report.GeneralError;
11  import org.csveed.row.RowReader;
12  import org.csveed.row.RowReaderImpl;
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  
16  public class BeanReaderImpl<T> implements BeanReader<T> {
17  
18      private static final Logger logger = LoggerFactory.getLogger(BeanReaderImpl.class);
19  
20      private final RowReader rowReader;
21  
22      private final BeanInstructions beanInstructions;
23  
24      private AbstractMapper<T> mapper;
25  
26      private final DynamicColumn currentDynamicColumn;
27  
28      private Row unmappedRow;
29  
30      public BeanReaderImpl(Reader reader, Class<T> beanClass) {
31          this(reader, new BeanParser().getBeanInstructions(beanClass));
32      }
33  
34      public BeanReaderImpl(Reader reader, BeanInstructions beanInstructions) {
35          this.beanInstructions = beanInstructions;
36          this.rowReader = new RowReaderImpl(reader, this.beanInstructions.getRowInstructions());
37          this.currentDynamicColumn = new DynamicColumn(this.beanInstructions.getStartIndexDynamicColumns());
38      }
39  
40      public AbstractMapper<T> getMapper() {
41          if (this.mapper == null) {
42              this.mapper = this.createMappingStrategy();
43              mapper.setBeanInstructions(this.beanInstructions);
44          }
45          return mapper;
46      }
47  
48      @Override
49      public List<T> readBeans() {
50          List<T> beans = new ArrayList<>();
51          while (!isFinished()) {
52              T bean = readBean();
53              if (bean != null) {
54                  beans.add(bean);
55              }
56          }
57          return beans;
58      }
59  
60      @Override
61      public T readBean() {
62          logSettings();
63  
64          if (this.beanInstructions.useHeader()) {
65              getMapper().verifyHeader(getHeader());
66          }
67  
68          currentDynamicColumn.checkForReset(((RowReaderImpl) rowReader).getMaxNumberOfColumns());
69          if (currentDynamicColumn.atFirstDynamicColumn()) {
70              unmappedRow = rowReader.readRow();
71          }
72          if (unmappedRow == null) {
73              return null;
74          }
75  
76          T bean = getMapper().convert(instantiateBean(), unmappedRow, getCurrentLine(), currentDynamicColumn);
77          currentDynamicColumn.advanceDynamicColumn();
78          return bean;
79      }
80  
81      protected void logSettings() {
82          this.beanInstructions.logSettings();
83      }
84  
85      protected Header getHeader() {
86          if (this.beanInstructions.useHeader()) {
87              return rowReader.getHeader();
88          }
89          return null;
90      }
91  
92      @Override
93      public Header readHeader() {
94          return rowReader.readHeader();
95      }
96  
97      @Override
98      public int getCurrentLine() {
99          return this.rowReader.getCurrentLine();
100     }
101 
102     @Override
103     public boolean isFinished() {
104         return rowReader.isFinished();
105     }
106 
107     @Override
108     public RowReader getRowReader() {
109         return this.rowReader;
110     }
111 
112     private T instantiateBean() {
113         try {
114             return this.getBeanClass().newInstance();
115         } catch (Exception err) {
116             throw new CsvException(new GeneralError(
117                     "Unable to instantiate the bean class " + this.getBeanClass().getName() +
118                             ". Does it have a no-arg public constructor?"
119                     ));
120         }
121     }
122 
123     @SuppressWarnings("unchecked")
124     public Class<T> getBeanClass() {
125         return this.beanInstructions.getBeanClass();
126     }
127 
128     @SuppressWarnings("unchecked")
129     public AbstractMapper<T> createMappingStrategy() {
130         try {
131             return this.beanInstructions.getMappingStrategy().newInstance();
132         } catch (Exception e) {
133             logger.trace("", e);
134             throw new CsvException(new GeneralError(
135                     "Unable to instantiate the mapping strategy"
136                     ));
137         }
138     }
139 
140     @Override
141     public BeanInstructions getBeanInstructions() {
142         return this.beanInstructions;
143     }
144 
145 }