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.lang.annotation.Annotation;
14  import java.lang.reflect.Field;
15  import java.util.Locale;
16  
17  import org.csveed.annotations.CsvCell;
18  import org.csveed.annotations.CsvConverter;
19  import org.csveed.annotations.CsvDate;
20  import org.csveed.annotations.CsvFile;
21  import org.csveed.annotations.CsvHeaderName;
22  import org.csveed.annotations.CsvHeaderValue;
23  import org.csveed.annotations.CsvIgnore;
24  import org.csveed.annotations.CsvLocalizedNumber;
25  import org.csveed.common.Column;
26  
27  /**
28   * The Class BeanParser.
29   */
30  public class BeanParser {
31  
32      /** The bean instructions. */
33      private BeanInstructions beanInstructions;
34  
35      /** The current column. */
36      private Column currentColumn = new Column();
37  
38      /**
39       * Gets the bean instructions.
40       *
41       * @param beanClass
42       *            the bean class
43       *
44       * @return the bean instructions
45       */
46      public BeanInstructions getBeanInstructions(Class beanClass) {
47  
48          this.beanInstructions = new BeanInstructionsImpl(beanClass);
49  
50          Annotation[] annotations = beanClass.getAnnotations();
51          for (Annotation annotation : annotations) {
52              if (annotation instanceof CsvFile) {
53                  parseCsvFile((CsvFile) annotation);
54              }
55          }
56  
57          for (BeanProperty beanProperty : beanInstructions.getProperties()) {
58              checkForAnnotations(beanProperty);
59          }
60  
61          return this.beanInstructions;
62      }
63  
64      /**
65       * Check for annotations.
66       *
67       * @param beanProperty
68       *            the bean property
69       */
70      public void checkForAnnotations(BeanProperty beanProperty) {
71  
72          Field currentField = beanProperty.getField();
73          Annotation[] annotations = currentField.getDeclaredAnnotations();
74          String propertyName = beanProperty.getPropertyName();
75          String columnName = propertyName;
76          for (Annotation annotation : annotations) {
77              if (annotation instanceof CsvCell) {
78                  columnName = parseCsvCell(propertyName, (CsvCell) annotation);
79              } else if (annotation instanceof CsvConverter) {
80                  parseCsvConverter(propertyName, (CsvConverter) annotation);
81              } else if (annotation instanceof CsvDate) {
82                  parseCsvDate(propertyName, (CsvDate) annotation);
83              } else if (annotation instanceof CsvLocalizedNumber) {
84                  parseCsvLocalizedNumber(propertyName, (CsvLocalizedNumber) annotation);
85              } else if (annotation instanceof CsvHeaderName) {
86                  this.beanInstructions.setHeaderNameToProperty(propertyName);
87              } else if (annotation instanceof CsvHeaderValue) {
88                  this.beanInstructions.setHeaderValueToProperty(propertyName);
89              } else if (annotation instanceof CsvIgnore) {
90                  this.beanInstructions.ignoreProperty(propertyName);
91                  return;
92              }
93          }
94          this.beanInstructions.mapColumnNameToProperty(columnName, propertyName);
95          this.beanInstructions.mapColumnIndexToProperty(currentColumn.getColumnIndex(), propertyName);
96          currentColumn = currentColumn.nextColumn();
97      }
98  
99      /**
100      * Parses the csv localized number.
101      *
102      * @param propertyName
103      *            the property name
104      * @param annotation
105      *            the annotation
106      */
107     private void parseCsvLocalizedNumber(String propertyName, CsvLocalizedNumber annotation) {
108         final Locale locale;
109         if (annotation.country().isEmpty()) {
110             locale = new Locale(annotation.language());
111         } else if (annotation.variant().isEmpty()) {
112             locale = new Locale(annotation.language(), annotation.country());
113         } else {
114             locale = new Locale(annotation.language(), annotation.country(), annotation.variant());
115         }
116         this.beanInstructions.setLocalizedNumber(propertyName, locale);
117     }
118 
119     /**
120      * Parses the csv file.
121      *
122      * @param csvFile
123      *            the csv file
124      */
125     private void parseCsvFile(CsvFile csvFile) {
126 
127         this.beanInstructions.setEscape(csvFile.escape()).setQuote(csvFile.quote())
128                 .setQuotingEnabled(csvFile.quotingEnabled()).setSeparator(csvFile.separator())
129                 .setComment(csvFile.comment()).setEndOfLine(csvFile.endOfLine()).setMapper(csvFile.mappingStrategy())
130                 .setStartRow(csvFile.startRow()).setUseHeader(csvFile.useHeader())
131                 .skipEmptyLines(csvFile.skipEmptyLines()).skipCommentLines(csvFile.skipCommentLines())
132                 .setStartIndexDynamicColumns(csvFile.startIndexDynamicColumns());
133     }
134 
135     /**
136      * Parses the csv date.
137      *
138      * @param propertyName
139      *            the property name
140      * @param csvDate
141      *            the csv date
142      */
143     private void parseCsvDate(String propertyName, CsvDate csvDate) {
144         this.beanInstructions.setDate(propertyName, csvDate.format());
145     }
146 
147     /**
148      * Parses the csv converter.
149      *
150      * @param propertyName
151      *            the property name
152      * @param csvConverter
153      *            the csv converter
154      */
155     private void parseCsvConverter(String propertyName, CsvConverter csvConverter) {
156         try {
157             this.beanInstructions.setConverter(propertyName,
158                     csvConverter.converter().getDeclaredConstructor().newInstance());
159         } catch (Exception err) {
160             throw new RuntimeException(err);
161         }
162     }
163 
164     /**
165      * Parses the csv cell.
166      *
167      * @param propertyName
168      *            the property name
169      * @param csvCell
170      *            the csv cell
171      *
172      * @return the string
173      */
174     private String parseCsvCell(String propertyName, CsvCell csvCell) {
175         String columnName = csvCell.columnName() == null || csvCell.columnName().isEmpty() ? propertyName
176                 : csvCell.columnName();
177         this.beanInstructions.setRequired(propertyName, csvCell.required());
178         currentColumn = csvCell.columnIndex() != -1 ? new Column(csvCell.columnIndex()) : currentColumn;
179         return columnName;
180     }
181 
182 }