View Javadoc

1   package com.leonarduk.clearcheckbook;
2   
3   import java.io.BufferedReader;
4   import java.io.IOException;
5   import java.io.InputStreamReader;
6   import java.util.Iterator;
7   import java.util.List;
8   import java.util.Map;
9   
10  import org.apache.log4j.Logger;
11  
12  import com.leonarduk.clearcheckbook.dto.AccountDataType;
13  import com.leonarduk.clearcheckbook.dto.TransactionDataType;
14  import com.leonarduk.clearcheckbook.file.AMEXFilePreprocessor;
15  import com.leonarduk.clearcheckbook.file.FilePreProcessor;
16  import com.leonarduk.clearcheckbook.file.NationwideFilePreprocessor;
17  import com.leonarduk.clearcheckbook.file.TransactionFilePreprocessor;
18  import com.leonarduk.utils.Config;
19  
20  /***
21   * A simple Command line Interface to use the API.
22   * 
23   * @author Stephen Leonard
24   * @since 6 Feb 2014
25   * 
26   * @version $Author:: $: Author of last commit
27   * @version $Rev:: $: Revision of last commit
28   * @version $Date:: $: Date of last commit
29   * 
30   */
31  public class ClearCheckBookCLI {
32  
33  	private static final String ALL_TRANSACTIONS_CSV = "all_transactions.csv";
34  
35  	private static final String ACCOUNTS_CSV = "accounts.csv";
36  
37  	private static final Logger _logger = Logger
38  			.getLogger(ClearCheckBookCLI.class);
39  
40  	/***
41  	 * 
42  	 * @param args
43  	 * @throws ClearcheckbookException
44  	 */
45  	public static void main(String[] args) throws ClearcheckbookException {
46  		Config config = new Config();
47  
48  		String userName = config
49  				.getMandatoryPropertyValue("clearcheckbook.user");
50  		String password = config
51  				.getMandatoryPropertyValue("clearcheckbook.password");
52  
53  		String command = config
54  				.getOptionalPropertyValue("clearcheckbook.command");
55  
56  		ClearCheckBookCLI cli = new ClearCheckBookCLI(userName, password);
57  		if (null == command) {
58  			// There is an option to quit, so iterate till then
59  			while (true) {
60  				cli.getMenu();
61  			}
62  		}
63  
64  	}
65  
66  	private ClearCheckBookHelper helper;
67  
68  	private Map<Long, AccountDataType> accountsMap = null;
69  
70  	public ClearCheckBookCLI(String userName, String password) {
71  		helper = new ClearCheckBookHelper(userName, password);
72  		System.out.println("Clearcheckbook Tools - connecting as " + userName);
73  	}
74  
75  	private AccountDataType chooseAccount(String zeroOption)
76  			throws ClearcheckbookException {
77  		List<AccountDataType> accounts = fetchAccounts();
78  		AccountDataType account = null;
79  		for (int i = 0; i < accounts.size(); i++) {
80  			AccountDataType accountDataType = accounts.get(i);
81  			System.out.println((i + 1) + " " + accountDataType.getId() + " "
82  					+ accountDataType.getName() + " "
83  					+ accountDataType.getCurrentBalance());
84  		}
85  		int option = getIntegerInput(
86  				"Choose number of account or select 0 for " + zeroOption + ":",
87  				accounts.size());
88  		if (option > 0) {
89  			account = accounts.get(option - 1);
90  		}
91  		return account;
92  	}
93  
94  	private FilePreProcessor chooseFileProcessor(Long id)
95  			throws ClearcheckbookException {
96  		String[] processors = new String[] { "Default",
97  				AMEXFilePreprocessor.class.getName(),
98  				NationwideFilePreprocessor.class.getName() };
99  		for (int i = 0; i < processors.length; i++) {
100 			System.out.println((i) + " " + processors[i]);
101 		}
102 		int option = getIntegerInput("Choose fileProcessor :",
103 				processors.length);
104 		switch (option) {
105 		case 1:
106 			return new AMEXFilePreprocessor(id);
107 		case 2:
108 			return new NationwideFilePreprocessor(id);
109 		default:
110 			return new TransactionFilePreprocessor(id);
111 		}
112 	}
113 
114 	private void exportAccounts() throws ClearcheckbookException {
115 		List<AccountDataType> accounts = fetchAccounts();
116 		String fileName = getFilename(ACCOUNTS_CSV);
117 		helper.exportAccounts(fileName, accounts);
118 		System.out.println("Saved " + accounts.size() + " accounts to "
119 				+ fileName);
120 	}
121 
122 	private void exportTransactions() throws ClearcheckbookException {
123 		List<TransactionDataType> transactions;
124 		AccountDataType account = chooseAccount("all transactions");
125 
126 		if (null == account) {
127 			System.out.println("Fetching all transactions...");
128 			transactions = this.helper.getTransactions();
129 		} else {
130 			System.out.println("Fetching transactions for " + account.getName()
131 					+ "...");
132 			transactions = this.helper.getTransactions(account);
133 		}
134 		System.out.println("Fetched " + transactions.size() + " transactions");
135 		if (transactions.size() > 0) {
136 			String fileName = getFilename(getDefaultFileName(account));
137 			System.out.println("Exporting " + transactions.size()
138 					+ " transactions to file : " + fileName + "...");
139 			this.helper.exportTransactions(fileName, transactions);
140 			System.out.println("...done.");
141 		} else {
142 			System.out.println("Nothing to save.");
143 		}
144 	}
145 
146 	private List<AccountDataType> fetchAccounts()
147 			throws ClearcheckbookException {
148 		System.out.println("Fetching account list...");
149 		List<AccountDataType> accounts = helper.getAccounts();
150 		return accounts;
151 	}
152 
153 	private void getAccountsMenu() throws ClearcheckbookException {
154 		String[] options = new String[] { "List", "Export", "Import" };
155 		for (int i = 0; i < options.length; i++) {
156 			System.out.println(i + " " + options[i]);
157 		}
158 
159 		int option = getIntegerInput("Choose option:", options.length - 1);
160 		switch (option) {
161 		case 0:
162 			listAccounts();
163 			break;
164 		case 1:
165 			exportAccounts();
166 			break;
167 		case 2:
168 			importAccounts();
169 			break;
170 		default:
171 			throw new ClearcheckbookException("Invalid option: " + option);
172 		}
173 	}
174 
175 	private String getDefaultFileName(AccountDataType account) {
176 		String defaultFilename;
177 		if (null == account) {
178 			defaultFilename = ALL_TRANSACTIONS_CSV;
179 		} else {
180 			defaultFilename = "account_" + account.getId() + ".csv";
181 		}
182 		return defaultFilename;
183 	}
184 
185 	private String getFilename(String defaultFilename)
186 			throws ClearcheckbookException {
187 		String fileName = getStringInput("Enter file name [enter for "
188 				+ defaultFilename + "]:");
189 		if (fileName.trim().equals("")) {
190 			fileName = defaultFilename;
191 		}
192 		return fileName;
193 	}
194 
195 	private int getIntegerInput(String question, int maxNumber)
196 			throws ClearcheckbookException {
197 		System.out.print(question);
198 
199 		try {
200 			BufferedReader br = new BufferedReader(new InputStreamReader(
201 					System.in));
202 			int i = Integer.parseInt(br.readLine());
203 			if (i > maxNumber || i < 0) {
204 				System.err.println("Choose number between 0 and " + maxNumber);
205 				return getIntegerInput(question, maxNumber);
206 			}
207 			return i;
208 		} catch (NumberFormatException nfe) {
209 			System.err.println("Invalid Format!");
210 			return getIntegerInput(question, maxNumber);
211 		} catch (IOException e) {
212 			throw new ClearcheckbookException("Failed to get option", e);
213 		}
214 	}
215 
216 	private void getMenu() throws ClearcheckbookException {
217 		String[] options = new String[] { "Accounts", "Transaction", "Quit" };
218 		System.out.println("MAIN MENU");
219 		for (int i = 0; i < options.length; i++) {
220 			System.out.println(i + " " + options[i]);
221 		}
222 
223 		int option = getIntegerInput("Choose option:", options.length - 1);
224 		switch (option) {
225 		case 0:
226 			getAccountsMenu();
227 			break;
228 		case 1:
229 			getTransactionsMenu();
230 			break;
231 		default:
232 			System.out.println("Exiting");
233 			System.exit(0);
234 		}
235 	}
236 
237 	private String getStringInput(String question)
238 			throws ClearcheckbookException {
239 		System.out.print(question);
240 		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
241 		try {
242 			return br.readLine();
243 		} catch (IOException e) {
244 			throw new ClearcheckbookException("Failed to get input", e);
245 		}
246 
247 	}
248 
249 	private void getTransactionsMenu() throws ClearcheckbookException {
250 		String[] options = new String[] { "List", "Export", "Import" };
251 		for (int i = 0; i < options.length; i++) {
252 			System.out.println(i + " " + options[i]);
253 		}
254 
255 		int option = getIntegerInput("Choose option:", options.length - 1);
256 		switch (option) {
257 		case 0:
258 			listTransactions();
259 			break;
260 		case 1:
261 			exportTransactions();
262 			break;
263 		case 2:
264 			importTransactions();
265 			break;
266 		default:
267 			throw new ClearcheckbookException("Invalid option: " + option);
268 		}
269 	}
270 
271 	private void importAccounts() throws ClearcheckbookException {
272 		String fileName = getFilename(ACCOUNTS_CSV);
273 		List<AccountDataType> accounts = helper.importAccounts(fileName);
274 		this.helper.processAccounts(accounts);
275 		System.out.println("Imported " + accounts.size() + " accounts");
276 	}
277 
278 	private void importTransactions() throws ClearcheckbookException {
279 		System.out.println("Choose which account to import to");
280 		AccountDataType account = chooseAccount("no account specified");
281 		Long id = 0L;
282 		if (null != account) {
283 			id = account.getId();
284 		}
285 		String fileName = getFilename(getDefaultFileName(account));
286 
287 		FilePreProcessor preprocessor = chooseFileProcessor(id);
288 
289 		List<TransactionDataType> transactions = helper.importTransactions(
290 				fileName, preprocessor);
291 		this.helper.processTransactions(transactions);
292 		System.out.println("Imported " + transactions.size() + " transactions");
293 	}
294 
295 	private void listAccounts() throws ClearcheckbookException {
296 		List<AccountDataType> accounts = fetchAccounts();
297 		for (Iterator<AccountDataType> iterator = accounts.iterator(); iterator
298 				.hasNext();) {
299 			AccountDataType accountDataType = iterator.next();
300 			System.out.println(accountDataType.getId() + " : "
301 					+ accountDataType.getName() + " "
302 					+ accountDataType.getCurrentBalance());
303 		}
304 	}
305 
306 	private void listTransactions() throws ClearcheckbookException {
307 		List<TransactionDataType> transactions;
308 		AccountDataType account = chooseAccount("all transactions");
309 
310 		if (null == account) {
311 			System.out.println("Fetching all transactions...");
312 			transactions = this.helper.getTransactions();
313 		} else {
314 			System.out.println("Fetching transactions for " + account.getName()
315 					+ "...");
316 			transactions = this.helper.getTransactions(account);
317 		}
318 		System.out.println("Fetched " + transactions.size() + " transactions");
319 		for (Iterator<TransactionDataType> iterator = transactions.iterator(); iterator
320 				.hasNext();) {
321 			TransactionDataType transactionDataType = iterator.next();
322 			System.out.println(transactionDataType.getDate() + " "
323 					+ transactionDataType.getAmount() + " "
324 					+ transactionDataType.getPayee() + " "
325 					+ transactionDataType.getMemo());
326 		}
327 
328 	}
329 
330 }