package com.code44.finance.data.backup; import android.content.Context; import android.database.Cursor; import android.net.Uri; import com.code44.finance.data.Query; import com.code44.finance.data.db.Tables; import com.code44.finance.data.model.Account; import com.code44.finance.data.model.Category; import com.code44.finance.data.model.Currency; import com.code44.finance.data.model.Model; import com.code44.finance.data.model.Tag; import com.code44.finance.data.model.Transaction; import com.code44.finance.data.providers.AccountsProvider; import com.code44.finance.data.providers.CategoriesProvider; import com.code44.finance.data.providers.CurrenciesProvider; import com.code44.finance.data.providers.TagsProvider; import com.code44.finance.data.providers.TransactionsProvider; import com.code44.finance.utils.IOUtils; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; public class BackupDataExporter extends DataExporter { public static final int VERSION = 7; private static final String CHARSET_NAME = "UTF-8"; private final Context context; public BackupDataExporter(OutputStream outputStream, Context context) { super(outputStream); this.context = context; } @Override public void exportData(OutputStream outputStream) throws Exception { final JsonWriter writer = new JsonWriter(new OutputStreamWriter(outputStream, CHARSET_NAME)); writer.setIndent(" "); writer.beginObject(); writeMetaData(writer); writer.name("currencies").beginArray(); writeCurrencies(writer); writer.endArray(); writer.name("categories").beginArray(); writeCategories(writer); writer.endArray(); writer.name("tags").beginArray(); writeTags(writer); writer.endArray(); writer.name("accounts").beginArray(); writeAccounts(writer); writer.endArray(); writer.name("transactions").beginArray(); writeTransactions(writer); writer.endArray(); writer.endObject(); writer.close(); } private void writeMetaData(JsonWriter writer) throws IOException { writer.name("version").value(VERSION); writer.name("timestamp").value(System.currentTimeMillis()); } private void writeCurrencies(JsonWriter writer) throws IOException { final Cursor cursor = getCursor(CurrenciesProvider.uriCurrencies(), Tables.Currencies.PROJECTION); try { if (cursor.moveToFirst()) { final Currency currency = new Currency(); do { currency.updateFrom(cursor, null); writer.beginObject(); writeBaseModel(currency, writer); writer.name("code").value(currency.getCode()); writer.name("symbol").value(currency.getSymbol()); writer.name("symbol_position").value(currency.getSymbolPosition().asInt()); writer.name("decimal_separator").value(currency.getDecimalSeparator().symbol()); writer.name("group_separator").value(currency.getGroupSeparator().symbol()); writer.name("decimal_count").value(currency.getDecimalCount()); writer.name("is_default").value(currency.isDefault()); writer.name("exchange_rate").value(currency.getExchangeRate()); writer.endObject(); } while (cursor.moveToNext()); } } finally { IOUtils.closeQuietly(cursor); } } private void writeCategories(JsonWriter writer) throws IOException { final Cursor cursor = getCursor(CategoriesProvider.uriCategories(), Tables.Categories.PROJECTION); try { if (cursor.moveToFirst()) { final Category category = new Category(); do { category.updateFrom(cursor, null); writer.beginObject(); writeBaseModel(category, writer); writer.name("title").value(category.getTitle()); writer.name("color").value(category.getColor()); writer.name("transaction_type").value(category.getTransactionType().asInt()); writer.name("sort_order").value(category.getSortOrder()); writer.endObject(); } while (cursor.moveToNext()); } } finally { IOUtils.closeQuietly(cursor); } } private void writeTags(JsonWriter writer) throws IOException { final Cursor cursor = getCursor(TagsProvider.uriTags(), Tables.Tags.PROJECTION); try { if (cursor.moveToFirst()) { final Tag tag = new Tag(); do { tag.updateFrom(cursor, null); writer.beginObject(); writeBaseModel(tag, writer); writer.name("title").value(tag.getTitle()); writer.endObject(); } while (cursor.moveToNext()); } } finally { IOUtils.closeQuietly(cursor); } } private void writeAccounts(JsonWriter writer) throws IOException { final Cursor cursor = getCursor(AccountsProvider.uriAccounts(), Tables.Accounts.PROJECTION); try { if (cursor.moveToFirst()) { final Account account = new Account(); do { account.updateFrom(cursor, null); writer.beginObject(); writeBaseModel(account, writer); writer.name("currency_id").value(account.getCurrency().getId()); writer.name("title").value(account.getTitle()); writer.name("note").value(account.getNote()); writer.name("balance").value(account.getBalance()); writer.name("include_in_totals").value(account.includeInTotals()); writer.endObject(); } while (cursor.moveToNext()); } } finally { IOUtils.closeQuietly(cursor); } } private void writeTransactions(JsonWriter writer) throws IOException { final Cursor cursor = Tables.Transactions.getQuery().clearSelection().clearArgs().selection("1=1").from(context, TransactionsProvider.uriTransactions()).execute(); try { if (cursor.moveToFirst()) { final Transaction transaction = new Transaction(); do { transaction.updateFrom(cursor, null); writer.beginObject(); writeBaseModel(transaction, writer); writer.name("account_from_id").value(transaction.getAccountFrom() != null ? transaction.getAccountFrom().getId() : null); writer.name("account_to_id").value(transaction.getAccountTo() != null ? transaction.getAccountTo().getId() : null); writer.name("category_id").value(transaction.getCategory() != null ? transaction.getCategory().getId() : null); writer.name("tag_ids").beginArray(); for (Tag tag : transaction.getTags()) { writer.value(tag.getId()); } writer.endArray(); writer.name("date").value(transaction.getDate()); writer.name("amount").value(transaction.getAmount()); writer.name("exchange_rate").value(transaction.getExchangeRate()); writer.name("note").value(transaction.getNote()); writer.name("transaction_state").value(transaction.getTransactionState().asInt()); writer.name("transaction_type").value(transaction.getTransactionType().asInt()); writer.name("include_in_reports").value(transaction.includeInReports()); writer.endObject(); } while (cursor.moveToNext()); } } finally { IOUtils.closeQuietly(cursor); } } private Cursor getCursor(Uri uri, String... projection) { return Query.create().projection(projection).from(context, uri).execute(); } private void writeBaseModel(Model model, JsonWriter writer) throws IOException { writer.name("id").value(model.getId()); writer.name("model_state").value(model.getModelState().asInt()); writer.name("sync_state").value(model.getSyncState().asInt()); } }