View Javadoc

1   package com.leonarduk.clearcheckbook.file;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.FileReader;
7   import java.io.IOException;
8   import java.io.PrintWriter;
9   import java.io.UnsupportedEncodingException;
10  import java.util.HashMap;
11  import java.util.Iterator;
12  import java.util.LinkedList;
13  import java.util.List;
14  import java.util.Map;
15  
16  import org.apache.log4j.Logger;
17  
18  import com.google.common.base.Joiner;
19  import com.google.common.base.Splitter;
20  import com.leonarduk.clearcheckbook.ClearcheckbookException;
21  import com.leonarduk.clearcheckbook.dto.AbstractDataType;
22  import com.leonarduk.clearcheckbook.dto.AccountDataType;
23  import com.leonarduk.clearcheckbook.dto.CategoryDataType;
24  import com.leonarduk.clearcheckbook.dto.LimitDataType;
25  import com.leonarduk.clearcheckbook.dto.ReminderDataType;
26  import com.leonarduk.clearcheckbook.dto.TransactionDataType;
27  
28  public class ClearCheckBookFileHandler {
29  
30  	private static final Logger _logger = Logger
31  			.getLogger(ClearCheckBookFileHandler.class);
32  
33  	public ClearCheckBookFileHandler() {
34  		// TODO Auto-generated constructor stub
35  	}
36  
37  	/***
38  	 * 
39  	 * @param fileName
40  	 * @param accounts
41  	 * @return
42  	 * @throws ClearcheckbookException
43  	 */
44  	public File exportAccounts(String fileName, List<AccountDataType> accounts)
45  			throws ClearcheckbookException {
46  		_logger.debug("exportAccounts: " + fileName + " " + accounts);
47  		Enum<?>[] headers = AccountDataType.Fields.values();
48  		return exportToFile(fileName, headers, accounts);
49  	}
50  
51  	/***
52  	 * 
53  	 * @param fileName
54  	 * @param categories
55  	 * @return
56  	 * @throws ClearcheckbookException
57  	 */
58  	public File exportCategories(String fileName,
59  			List<CategoryDataType> categories) throws ClearcheckbookException {
60  		_logger.debug("exportCategories: " + fileName + " " + categories);
61  		Enum<?>[] headers = CategoryDataType.Fields.values();
62  		return exportToFile(fileName, headers, categories);
63  	}
64  
65  	/***
66  	 * 
67  	 * @param fileName
68  	 * @param limits
69  	 * @return
70  	 * @throws ClearcheckbookException
71  	 */
72  	public File exportLimits(String fileName, List<LimitDataType> limits)
73  			throws ClearcheckbookException {
74  		_logger.debug("exportLimits: " + fileName + " " + limits);
75  		Enum<?>[] headers = LimitDataType.Fields.values();
76  		return exportToFile(fileName, headers, limits);
77  	}
78  
79  	/***
80  	 * 
81  	 * @param fileName
82  	 * @param reminders
83  	 * @return
84  	 * @throws ClearcheckbookException
85  	 */
86  	public File exportReminders(String fileName,
87  			List<ReminderDataType> reminders) throws ClearcheckbookException {
88  		_logger.debug("exportReminders: " + fileName + " " + reminders);
89  		Enum<?>[] headers = ReminderDataType.Fields.values();
90  		return exportToFile(fileName, headers, reminders);
91  	}
92  
93  	/***
94  	 * 
95  	 * @param fileName
96  	 * @param headers
97  	 * @param dataTypes
98  	 * @return
99  	 * @throws ClearcheckbookException
100 	 */
101 	private File exportToFile(String fileName, Enum<?>[] headers,
102 			List<? extends AbstractDataType> dataTypes)
103 			throws ClearcheckbookException {
104 		PrintWriter writer;
105 		try {
106 			File file = new File(fileName);
107 			writer = new PrintWriter(file, "UTF-8");
108 			String separator = "\",\"";
109 			writer.println("\"" + Joiner.on(separator).join(headers) + "\"");
110 			for (Iterator<? extends AbstractDataType> iterator = dataTypes
111 					.iterator(); iterator.hasNext();) {
112 				AbstractDataType<?> dataType = iterator.next();
113 				writer.println("\""
114 						+ Joiner.on(separator).join(dataType.getValues())
115 						+ "\"");
116 			}
117 			writer.close();
118 			return file;
119 		} catch (FileNotFoundException | UnsupportedEncodingException e) {
120 			throw new ClearcheckbookException(
121 					"Failed to export to " + fileName, e);
122 		}
123 
124 	}
125 
126 	/***
127 	 * 
128 	 * @param fileName
129 	 * @param transactions
130 	 * @return
131 	 * @throws ClearcheckbookException
132 	 */
133 	public File exportTransactions(String fileName,
134 			List<TransactionDataType> transactions)
135 			throws ClearcheckbookException {
136 		_logger.debug("exportTransactions: " + fileName + " " + transactions);
137 		Enum<?>[] headers = TransactionDataType.getFileFields();
138 		return exportToFile(fileName, headers, transactions);
139 	}
140 
141 	public List<AccountDataType> importAccounts(String fileName)
142 			throws ClearcheckbookException {
143 		_logger.debug("importTransactions: " + fileName);
144 		return importFromFile(fileName, AccountDataType.class);
145 	}
146 
147 	public List<CategoryDataType> importCategories(String fileName)
148 			throws ClearcheckbookException {
149 		_logger.debug("importTransactions: " + fileName);
150 		return importFromFile(fileName, CategoryDataType.class);
151 	}
152 
153 	/***
154 	 * 
155 	 * @param fileName
156 	 * @return
157 	 * @throws ClearcheckbookException
158 	 */
159 	public <D extends AbstractDataType<?>> List<D> importFromFile(
160 			String fileName, Class<D> c) throws ClearcheckbookException {
161 		return importFromFile(fileName, c, new TransactionFilePreprocessor());
162 	}
163 
164 	public <D extends AbstractDataType<?>> List<D> importFromFile(
165 			String fileName, Class<D> class1, FilePreProcessor processor)
166 			throws ClearcheckbookException {
167 
168 		String separator = ",";
169 		List<D> dataItems = new LinkedList<>();
170 
171 		try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
172 
173 			// Ignore some rows
174 			for (int i = 0; i < processor.getRowsToSkip(); i++) {
175 				br.readLine();
176 			}
177 			String line = br.readLine();
178 			List<String> headerFields = processor.processHeaderRow(separator, line);
179 
180 			// first data line
181 			line = br.readLine();
182 
183 			while (line != null) {
184 				Map<String, String> fieldsMap = new HashMap<>();
185 				Iterable<String> fields = Splitter.on(separator).trimResults()
186 						.split(line);
187 				Iterator<String> headerIter = headerFields.iterator();
188 				for (String field : fields) {
189 					String headerName = headerIter.next();
190 					_logger.debug(headerName + "=" + field.replace("\"", ""));
191 					fieldsMap.put(headerName.toLowerCase(),
192 							field.replace("\"", ""));
193 				}
194 				Map<String, String> processedMap = processor
195 						.processRow(fieldsMap);
196 				try {
197 					D newElem = class1.getDeclaredConstructor(Map.class)
198 							.newInstance(processedMap);
199 					dataItems.add(newElem);
200 				} catch (Exception e) {
201 					throw new ClearcheckbookException("Failed to import file",
202 							e);
203 				}
204 
205 				line = br.readLine();
206 			}
207 			return dataItems;
208 		} catch (IOException e) {
209 			throw new ClearcheckbookException("Failed to import file", e);
210 		}
211 	}
212 
213 	public List<LimitDataType> importLimits(String fileName)
214 			throws ClearcheckbookException {
215 		_logger.debug("importTransactions: " + fileName);
216 		return importFromFile(fileName, LimitDataType.class);
217 	}
218 
219 	public List<ReminderDataType> importReminders(String fileName)
220 			throws ClearcheckbookException {
221 		_logger.debug("importTransactions: " + fileName);
222 		return importFromFile(fileName, ReminderDataType.class);
223 	}
224 
225 	public List<TransactionDataType> importTransactions(String fileName,
226 			FilePreProcessor processor) throws ClearcheckbookException {
227 		_logger.debug("importTransactions: " + fileName);
228 		return importFromFile(fileName, TransactionDataType.class, processor);
229 	}
230 
231 }