View Javadoc
1   /*
2    * CSVeed (https://github.com/42BV/CSVeed)
3    *
4    * Copyright 2013-2023 CSVeed.
5    *
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of The Apache Software License,
8    * Version 2.0 which accompanies this distribution, and is available at
9    * https://www.apache.org/licenses/LICENSE-2.0.txt
10   */
11  package org.csveed.bean;
12  
13  import java.util.Set;
14  
15  import org.csveed.api.Header;
16  import org.csveed.api.Row;
17  import org.csveed.bean.conversion.BeanWrapper;
18  import org.csveed.bean.conversion.ConversionException;
19  import org.csveed.bean.conversion.DefaultConverters;
20  import org.csveed.common.Column;
21  import org.csveed.report.CsvException;
22  import org.csveed.report.RowError;
23  
24  /**
25   * The Class AbstractMapper.
26   *
27   * @param <T>
28   *            the generic type
29   */
30  public abstract class AbstractMapper<T> {
31  
32      /** The bean instructions. */
33      protected BeanInstructions beanInstructions;
34  
35      /** The verified. */
36      private boolean verified;
37  
38      /** The default converters. */
39      private DefaultConverters defaultConverters = new DefaultConverters();
40  
41      /**
42       * Gets the bean property.
43       *
44       * @param currentColumn
45       *            the current column
46       *
47       * @return the bean property
48       */
49      public abstract BeanProperty getBeanProperty(Column currentColumn);
50  
51      /**
52       * Keys.
53       *
54       * @return the sets the
55       */
56      protected abstract Set<Column> keys();
57  
58      /**
59       * Check key.
60       *
61       * @param header
62       *            the header
63       * @param key
64       *            the key
65       */
66      protected abstract void checkKey(Header header, Column key);
67  
68      /**
69       * Verify header.
70       *
71       * @param header
72       *            the header
73       */
74      public void verifyHeader(Header header) {
75          if (verified) {
76              return;
77          }
78          for (Column key : keys()) {
79              if (!getBeanProperty(key).isDynamicColumnProperty()) {
80                  checkKey(header, key);
81              }
82          }
83          verified = true;
84      }
85  
86      /**
87       * Gets the column.
88       *
89       * @param row
90       *            the row
91       *
92       * @return the column
93       */
94      protected abstract Column getColumn(Row row);
95  
96      /**
97       * Convert.
98       *
99       * @param bean
100      *            the bean
101      * @param row
102      *            the row
103      * @param lineNumber
104      *            the line number
105      * @param currentDynamicColumn
106      *            the current dynamic column
107      *
108      * @return the t
109      */
110     public T convert(T bean, Row row, int lineNumber, DynamicColumn currentDynamicColumn) {
111         BeanWrapper beanWrapper = new BeanWrapper(defaultConverters, bean);
112 
113         Column currentColumn = null;
114         for (String cell : row) {
115             currentColumn = currentColumn == null ? getColumn(row) : currentColumn.nextColumn();
116 
117             if (currentDynamicColumn.isDynamicColumnActive(currentColumn)) {
118                 setDynamicColumnProperties(row, lineNumber, beanWrapper, currentColumn);
119                 continue;
120             }
121 
122             BeanProperty beanProperty = getBeanProperty(currentColumn);
123             if (beanProperty == null) {
124                 continue;
125             }
126             if (beanProperty.isRequired() && (cell == null || cell.equals(""))) {
127                 throw new CsvException(new RowError(
128                         "Bean property \"" + beanProperty.getPropertyName()
129                                 + "\" is required and may not be empty or null",
130                         row.reportOnColumn(currentColumn.getColumnIndex()), lineNumber));
131             }
132             setBeanProperty(row, lineNumber, beanWrapper, currentColumn, cell, beanProperty);
133         }
134         return bean;
135     }
136 
137     /**
138      * Sets the dynamic column properties.
139      *
140      * @param row
141      *            the row
142      * @param lineNumber
143      *            the line number
144      * @param beanWrapper
145      *            the bean wrapper
146      * @param currentColumn
147      *            the current column
148      */
149     private void setDynamicColumnProperties(Row row, int lineNumber, BeanWrapper beanWrapper, Column currentColumn) {
150         BeanProperty headerNameProperty = beanInstructions.getProperties().getHeaderNameProperty();
151         if (headerNameProperty != null) {
152             String dynamicHeaderName = row.getHeader().getName(currentColumn.getColumnIndex());
153             setBeanProperty(row, lineNumber, beanWrapper, currentColumn, dynamicHeaderName, headerNameProperty);
154         }
155 
156         BeanProperty headerValueProperty = beanInstructions.getProperties().getHeaderValueProperty();
157         if (headerValueProperty != null) {
158             String dynamicHeaderValue = row.get(currentColumn.getColumnIndex());
159             setBeanProperty(row, lineNumber, beanWrapper, currentColumn, dynamicHeaderValue, headerValueProperty);
160         }
161     }
162 
163     /**
164      * Sets the bean property.
165      *
166      * @param row
167      *            the row
168      * @param lineNumber
169      *            the line number
170      * @param beanWrapper
171      *            the bean wrapper
172      * @param currentColumn
173      *            the current column
174      * @param cell
175      *            the cell
176      * @param beanProperty
177      *            the bean property
178      */
179     private void setBeanProperty(Row row, int lineNumber, BeanWrapper beanWrapper, Column currentColumn, String cell,
180             BeanProperty beanProperty) {
181         try {
182             beanWrapper.setProperty(beanProperty, cell);
183         } catch (ConversionException err) {
184             String message = err.getMessage() + " cell" + currentColumn.getColumnText() + " [" + cell + "] to "
185                     + beanProperty.getPropertyName() + ": " + err.getTypeDescription();
186             throw new CsvException(
187                     new RowError(message, row.reportOnColumn(currentColumn.getColumnIndex()), lineNumber));
188         }
189     }
190 
191     /**
192      * Sets the bean instructions.
193      *
194      * @param beanInstructions
195      *            the new bean instructions
196      */
197     public void setBeanInstructions(BeanInstructions beanInstructions) {
198         this.beanInstructions = beanInstructions;
199     }
200 
201 }