aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java
blob: a65a9fb6d65dffa4f51459f46ddfb6b4f4ab0b9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package cgeo.geocaching.utils;

import cgeo.geocaching.DataStore;
import cgeo.geocaching.MainActivity;
import cgeo.geocaching.R;
import cgeo.geocaching.ui.dialog.Dialogs;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.schedulers.Schedulers;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;

import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;

public class DatabaseBackupUtils {

    private DatabaseBackupUtils() {
        // utility class
    }

    /**
     * After confirming to overwrite the existing caches on the devices, restore the database in a new thread, showing a
     * progress window
     *
     * @param activity
     *            calling activity
     */
    public static void restoreDatabase(final Activity activity) {
        if (!hasBackup()) {
            return;
        }
        final int caches = DataStore.getAllCachesCount();
        if (caches == 0) {
            restoreDatabaseInternal(activity);
        }
        else {
            Dialogs.confirm(activity, R.string.init_backup_restore, activity.getString(R.string.restore_confirm_overwrite, activity.getResources().getQuantityString(R.plurals.cache_counts, caches, caches)), new OnClickListener() {

                @Override
                public void onClick(final DialogInterface dialog, final int which) {
                    restoreDatabaseInternal(activity);
                }
            });

        }
    }

    private static void restoreDatabaseInternal(final Activity activity) {
        final Resources res = activity.getResources();
        final ProgressDialog dialog = ProgressDialog.show(activity, res.getString(R.string.init_backup_restore), res.getString(R.string.init_restore_running), true, false);
        final AtomicBoolean restoreSuccessful = new AtomicBoolean(false);
        RxUtils.andThenOnUi(Schedulers.io(), new Action0() {
            @Override
            public void call() {
                restoreSuccessful.set(DataStore.restoreDatabaseInternal());
            }
        }, new Action0() {
            @Override
            public void call() {
                dialog.dismiss();
                final boolean restored = restoreSuccessful.get();
                final String message = restored ? res.getString(R.string.init_restore_success) : res.getString(R.string.init_restore_failed);
                Dialogs.message(activity, R.string.init_backup_restore, message);
                if (activity instanceof MainActivity) {
                    ((MainActivity) activity).updateCacheCounter();
                }
            }
        });
    }

    /**
     * Create a backup after confirming to overwrite the existing backup.
     *
     */
    public static void createBackup(final Activity activity, final Runnable runAfterwards) {
        // avoid overwriting an existing backup with an empty database
        // (can happen directly after reinstalling the app)
        if (DataStore.getAllCachesCount() == 0) {
            Dialogs.message(activity, R.string.init_backup, R.string.init_backup_unnecessary);
            return;
        }
        if (hasBackup()) {
            Dialogs.confirm(activity, R.string.init_backup, activity.getString(R.string.backup_confirm_overwrite, getBackupDateTime()), new OnClickListener() {

                @Override
                public void onClick(final DialogInterface dialog, final int which) {
                    createBackupInternal(activity, runAfterwards);
                }
            });
        }
        else {
            createBackupInternal(activity, runAfterwards);
        }
    }

    private static void createBackupInternal(final Activity activity, final Runnable runAfterwards) {
        final ProgressDialog dialog = ProgressDialog.show(activity,
                activity.getString(R.string.init_backup),
                activity.getString(R.string.init_backup_running), true, false);
        RxUtils.andThenOnUi(Schedulers.io(), new Func0<String>() {
            @Override
            public String call() {
                return DataStore.backupDatabaseInternal();
            }
        }, new Action1<String>() {
            @Override
            public void call(final String backupFileName) {
                dialog.dismiss();
                Dialogs.message(activity,
                        R.string.init_backup_backup,
                        backupFileName != null
                                ? activity.getString(R.string.init_backup_success)
                                + "\n" + backupFileName
                                : activity.getString(R.string.init_backup_failed));
                if (runAfterwards != null) {
                    runAfterwards.run();
                }
            }
        });
    }

    @Nullable
    public static File getRestoreFile() {
        final File fileSourceFile = DataStore.getBackupFileInternal();
        return fileSourceFile.exists() && fileSourceFile.length() > 0 ? fileSourceFile : null;
    }

    public static boolean hasBackup() {
        return getRestoreFile() != null;
    }

    @NonNull
    public static String getBackupDateTime() {
        final File restoreFile = getRestoreFile();
        if (restoreFile == null) {
            return StringUtils.EMPTY;
        }
        return Formatter.formatShortDateTime(restoreFile.lastModified());
    }

}