/* * Copyright 2015 Qianqian Zhu <zhuqianqian.299@gmail.com> All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.z299studio.pb; import android.os.AsyncTask; import android.os.Environment; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.security.GeneralSecurityException; import java.util.Hashtable; import java.util.List; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVWriter; class ImportExportTask extends AsyncTask<String, Void, String> { interface TaskListener { void onFinish(boolean authenticate, int operation, String result); byte[] saveData(); } static final int OPTION_OVERWRITE = 2; static final int OPTION_KEEPALL = 1; static final int OPTION_IGNORE = 0; private static final int FILE_PB_DATA = 0; private static final int FILE_PB_CSV = 1; private static final int FILE_AW_CSV = 2; private boolean mAuthRequired = false; private static int mOperation; private static int mFileType; private static String mFilePath; private static int mOption; private static String mPassword; private TaskListener mListener; ImportExportTask (TaskListener l, String filePath, String password, int fileType, int operation, int option) { super(); mListener = l; mOption = option; mOperation = operation; mFileType = fileType; mFilePath = filePath; mPassword = password; } ImportExportTask(TaskListener l, String password) { super(); mListener = l; mPassword = password; } private String importPbData() { String result = null; try { byte[] buffer; File file = new File(mFilePath); int size = (int) file.length(); if(size > 0) { buffer = new byte[size]; FileInputStream fis = new FileInputStream(file); fis.read(buffer, 0, size); fis.close(); Application.FileHeader header = Application.FileHeader.parse(buffer); if(header.valid) { AccountManager am = Application.decrypt(new Crypto(), mPassword, header, buffer); process(am); result = mFilePath; } } } catch (GeneralSecurityException e) { mAuthRequired = true; result = null; } catch (Exception e) { result = null; } return result; } private void process(AccountManager am) { AccountManager appAm = Application.getInstance().getAccountManager(); Hashtable<String, Integer> existingCategory = new Hashtable<>(); Hashtable<String, Integer> existingAccounts = new Hashtable<>(); List<AccountManager.Category> newCategories = am.getCategoryList(true, false); List<AccountManager.Account> newAccounts = am.getAllAccounts(false); List<AccountManager.Category> categories = appAm.getCategoryList(true, false); for(AccountManager.Category c : categories) { existingCategory.put(c.mName, c.mId); } for(AccountManager.Category c : newCategories) { if(existingCategory.get(c.mName) == null) { existingCategory.put(c.mName, appAm.addCategory(c.mImgCode, c.mName)); } } AccountManager.Category category; int categoryId; if(mOption != OPTION_KEEPALL) { Integer accId; List<AccountManager.Account> accounts = appAm.getAllAccounts(false); for(AccountManager.Account a : accounts) { existingAccounts.put(a.mProfile, a.mId); } for(AccountManager.Account a: newAccounts) { accId = existingAccounts.get(a.mProfile); if(accId == null) { category = am.getCategory(a.getCategoryId()); if(category!=null) { categoryId = existingCategory.get(category.mName); } else { categoryId = AccountManager.DEFAULT_CATEGORY_ID; } appAm.addAccount(categoryId, a); } else if(mOption == OPTION_OVERWRITE) { AccountManager.Account account = appAm.getAccountById(accId); account.setAccount(a); } } } else { for(AccountManager.Account a : newAccounts) { category = am.getCategory(a.getCategoryId()); if(category==null) { categoryId = AccountManager.DEFAULT_CATEGORY_ID; } else { categoryId = existingCategory.get(category.mName); } appAm.addAccount(categoryId, a); } } } private String importPbCSV() { String result; try { CSVReader csvReader = new CSVReader(new FileReader(mFilePath)); List<String[]> content = csvReader.readAll(); csvReader.close(); AccountManager appAm = Application.getInstance().getAccountManager(); Hashtable<String, Integer> existingCategory = new Hashtable<>(); Hashtable<String, Integer> existingAccounts = new Hashtable<>(); List<AccountManager.Category> categories = appAm.getCategoryList(true, false); for(AccountManager.Category c : categories) { existingCategory.put(c.mName, c.mId); } for(String s : content.get(0)) { if(existingCategory.get(s) == null) { existingCategory.put(s, appAm.addCategory(0, s)); } } String[] line; String names[]; String fields[]; AccountManager.Account account; Integer accId; int categoryId; if(mOption != OPTION_KEEPALL) { List<AccountManager.Account> accounts = appAm.getAllAccounts(false); for(AccountManager.Account a : accounts) { existingAccounts.put(a.mProfile, a.mId); } for(int i = 1; i < content.size(); ++i) { line = content.get(i); names = line[0].split("\t", 2); accId = existingAccounts.get(names[1]); if(accId != null && mOption == OPTION_IGNORE) { continue; } categoryId = existingCategory.get(names[0]); if(accId == null) { account = appAm.newAccount(categoryId); } else { account = appAm.getAccountById(accId); account.setCategory(categoryId); } account.setName(names[1]); account.clearEntries(); for(int j = 1; j < line.length; ++j) { fields = line[j].split("\t", 3); account.addEntry(Integer.parseInt(fields[0]), fields[1], fields[2]); } if(accId == null) { appAm.addAccount(categoryId, account); } else { appAm.setAccount(account); } } } else { for(int i = 1; i < content.size(); ++i) { line = content.get(i); names = line[0].split("\t", 2); categoryId = existingCategory.get(names[0]); account = appAm.newAccount(categoryId); account.setName(names[1]); for(int j = 1; j < line.length; ++j) { fields = line[j].split("\t", 3); account.addEntry(Integer.parseInt(fields[0]), fields[1], fields[2]); } appAm.addAccount(categoryId, account); } } result = mFilePath; } catch (Exception e) { result = null; } return result; } private String importAwCSV() { if(mFilePath == null) { return null; } String result; AccountManager appAm = Application.getInstance().getAccountManager(); int start = mFilePath.lastIndexOf(File.separator)+1; Hashtable<String, Integer> existingAccounts = new Hashtable<>(); int categoryId = -1; try{ CSVReader csvReader = new CSVReader(new FileReader(mFilePath)); List<String[]> content = csvReader.readAll(); csvReader.close(); String categoryName = mFilePath.substring(start, mFilePath.indexOf('.', start)); List<AccountManager.Category> categories = appAm.getCategoryList(true, false); for(AccountManager.Category c : categories) { if(categoryName.equals(c.mName)) { categoryId = c.mId; break; } } if(categoryId == -1) { categoryId = appAm.addCategory(0, categoryName); } AccountManager.Account account; String[] line; String[] fields = content.get(0); if(mOption != OPTION_KEEPALL) { List<AccountManager.Account> accounts = appAm.getAllAccounts(false); for(AccountManager.Account a : accounts) { existingAccounts.put(a.mProfile, a.mId); } Integer accountId; for(int i = 1; i < content.size(); ++i) { line = content.get(i); accountId = existingAccounts.get(line[0]); if(accountId == null) { account = appAm.newAccount(categoryId); account.setName(line[0]); } else if(mOption == OPTION_IGNORE) { continue; } else { account = appAm.getAccountById(accountId); account.clearEntries(); } for(int j = 1; j < line.length; ++j) { if(line[j].length() > 0) { account.addEntry(0, fields[j], line[j]); } } if(accountId != null) { appAm.setAccount(account); } else { appAm.addAccount(categoryId, account); } } } else { for(int i = 1; i < content.size(); ++i) { line = content.get(i); account = appAm.newAccount(categoryId); account.setName(line[0]); for(int j = 1; j < line.length; ++j) { if(line[j].length() > 0) { account.addEntry(0, fields[j], line[j]); } } appAm.addAccount(categoryId, account); } } result = mFilePath; }catch (Exception e) { result = null; } return result; } private String exportData() { String result; byte[] data = mListener.saveData(); try { File file = new File(Environment.getExternalStorageDirectory(), "pbdata"); FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); result = file.getPath(); } catch (Exception ex) { result = null; ex.printStackTrace(); } return result; } private String exportCSV() { String result; try{ AccountManager am = Application.getInstance().getAccountManager(); File file = new File(Environment.getExternalStorageDirectory(), "pb.csv"); FileWriter fw = new FileWriter(file, false); CSVWriter csvWriter = new CSVWriter(fw); csvWriter.writeNext(am.getCategoryNames()); List<AccountManager.Account> accounts = am.getAllAccounts(false); for(AccountManager.Account a: accounts) { csvWriter.writeNext(a.getStringList(am)); } csvWriter.close(); result = file.getPath(); } catch(Exception ex) { result = null; } return result; } @Override protected void onPreExecute() { } @Override protected String doInBackground(String... params) { if(mOperation==ActionDialog.ACTION_EXPORT) { if(mFileType == FILE_PB_DATA) { return exportData(); } else if(mFileType == FILE_PB_CSV) { return exportCSV(); } } else { if(mFileType == FILE_PB_DATA) { return importPbData(); } else if(mFileType == FILE_PB_CSV) { return importPbCSV(); } else if(mFileType == FILE_AW_CSV) { return importAwCSV(); } } return null; } @Override protected void onPostExecute(String result) { if(mListener!=null) { mListener.onFinish(mAuthRequired, mOperation, result); } } }