package uk.org.brindy.android.moneytracker; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.util.List; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.util.Log; public class ExpensesDbHelper { // compatible with 1.6, so leave as 1.4 for now private static final String APP_VERSION = "1.4"; private ExpensesMgr expenses; private Disposable disp; private Context mCtx; public ExpensesDbHelper(Context ctx) { this.mCtx = ctx; if (!APP_VERSION.equals(findVersion())) { createFileName(ExpensesMgr.class.getName(), ctx).delete(); createFileName(Disposable.class.getName(), ctx).delete(); // delete the old stuff... File db4oDir = ctx.getDir("db4o", Context.MODE_PRIVATE); new File(db4oDir, "expenses.yap").delete(); db4oDir.delete(); } // load required objects if (null == (expenses = loadObject(ExpensesMgr.class))) { saveObject(expenses = new ExpensesMgr()); } if (null == (disp = loadObject(Disposable.class))) { saveObject(disp = new Disposable()); } } private String findVersion() { File dir = mCtx.getDir("objects", Context.MODE_PRIVATE); File ver = new File(dir, "version.txt"); if (!ver.exists()) { PrintWriter out = null; try { out = new PrintWriter(new FileOutputStream(ver)); out.println(APP_VERSION); out.close(); return APP_VERSION; } catch (IOException ex) { throw new RuntimeException(ex); } finally { if (out != null) { out.close(); } } } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(ver)); return reader.readLine(); } catch (IOException e) { throw new RuntimeException(e); } finally { if (null != reader) { try { reader.close(); } catch (IOException e) { Log.e("MoneyTracker", e.getMessage(), e); } } } } @SuppressWarnings("unchecked") private <T> T loadObject(Class<T> cls) { Context ctx = mCtx; File f = createFileName(cls.getName(), ctx); if (f.exists()) { ObjectInputStream in = null; try { in = new ObjectInputStream(new FileInputStream(f)); return (T) in.readObject(); } catch (Exception ex) { throw new RuntimeException(ex); } finally { if (null != in) { try { in.close(); } catch (IOException e) { Log.e("MoneyTracker", e.getMessage(), e); } } } } return null; } private File createFileName(String name, Context ctx) { File f = new File(ctx.getDir("objects", Context.MODE_PRIVATE), name + ".obj"); return f; } private void saveObject(Object o) { Context ctx = mCtx; File f = createFileName(o.getClass().getName(), ctx); ObjectOutputStream out = null; try { out = new ObjectOutputStream(new FileOutputStream(f)); out.writeObject(o); } catch (Exception e) { throw new RuntimeException(e); } finally { if (null != out) { try { out.close(); } catch (IOException e) { // ignore Log.e("MoneyTracker", e.getMessage(), e); } } } // broadcast to the widget // mCtx.sendBroadcast(new // Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, // null, ctx, MoneyTrackerWidgetProvider.class)); Intent i = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { R.xml.widget_info }); mCtx.sendBroadcast(i); } public long createExpense(Expense expense) { expenses.saveExpense(expense); saveObject(expenses); return expense.getId(); } public boolean deleteExpense(long expenseId) { boolean result = expenses .removeExpense(expenses.findExpense(expenseId)); if (result) { saveObject(expenses); } return result; } public List<Expense> fetchAllExpenses() { return expenses.getAllExpenses(); } public Expense findExpenseById(long expenseId) { return expenses.findExpense(expenseId); } public boolean updateExpense(Expense exp) { expenses.saveExpense(exp); saveObject(expenses); return true; } public void deleteAllExpenses() { expenses.clear(); saveObject(expenses); } public void setDisposable(double disposable) { disp.setValue(disposable); saveObject(disp); } public double getDisposable() { return disp.getValue(); } public double remaining() { return expenses.remaining(getDisposable()); } public void backup(File toFile) throws IOException { ObjectOutputStream out = null; try { out = new ObjectOutputStream(new FileOutputStream(toFile)); out.writeObject(APP_VERSION); out.writeObject(expenses); out.writeObject(disp); } finally { if (null != out) { try { out.close(); } catch (IOException e) { Log.e("MoneyTracker", e.getMessage(), e); } } } } public void restore(File fromFile) throws Exception { ObjectInputStream in = new ObjectInputStream(new FileInputStream( fromFile)); try { String ver = (String) in.readObject(); if (APP_VERSION.equals("ver")) { throw new Exception("Incompatible backup version " + ver); } expenses = (ExpensesMgr) in.readObject(); disp = (Disposable) in.readObject(); saveObject(expenses); saveObject(disp); } catch (IOException ex) { throw new Exception( "Failed to read backup file, it could be corrupt"); } finally { if (in != null) { try { in.close(); } catch (Exception e) { Log.e("MoneyTracker", e.getMessage(), e); } } } } }