2 * Copyright © 2021 Damyan Ivanov.
3 * This file is part of MoLe.
4 * MoLe is free software: you can distribute it and/or modify it
5 * under the term of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your opinion), any later version.
9 * MoLe is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License terms for details.
14 * You should have received a copy of the GNU General Public License
15 * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
18 package net.ktnx.mobileledger.backup;
20 import android.util.JsonReader;
21 import android.util.JsonToken;
23 import net.ktnx.mobileledger.App;
24 import net.ktnx.mobileledger.backup.ConfigIO.Keys;
25 import net.ktnx.mobileledger.dao.CurrencyDAO;
26 import net.ktnx.mobileledger.dao.ProfileDAO;
27 import net.ktnx.mobileledger.dao.TemplateHeaderDAO;
28 import net.ktnx.mobileledger.db.Currency;
29 import net.ktnx.mobileledger.db.DB;
30 import net.ktnx.mobileledger.db.Profile;
31 import net.ktnx.mobileledger.db.TemplateAccount;
32 import net.ktnx.mobileledger.db.TemplateHeader;
33 import net.ktnx.mobileledger.db.TemplateWithAccounts;
34 import net.ktnx.mobileledger.model.Data;
35 import net.ktnx.mobileledger.utils.Logger;
37 import java.io.BufferedReader;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.util.ArrayList;
42 import java.util.List;
44 public class RawConfigReader {
45 private final JsonReader r;
46 private List<Currency> commodities;
47 private List<Profile> profiles;
48 private List<TemplateWithAccounts> templates;
49 private String currentProfile;
50 public RawConfigReader(InputStream inputStream) {
51 r = new JsonReader(new BufferedReader(new InputStreamReader(inputStream)));
53 public List<Currency> getCommodities() {
56 public List<Profile> getProfiles() {
59 public List<TemplateWithAccounts> getTemplates() {
62 public String getCurrentProfile() {
63 return currentProfile;
65 public void readConfig() throws IOException {
69 currentProfile = null;
72 String item = r.nextName();
73 if (r.peek() == JsonToken.NULL) {
78 case Keys.COMMODITIES:
79 commodities = readCommodities();
82 profiles = readProfiles();
85 templates = readTemplates();
87 case Keys.CURRENT_PROFILE:
88 currentProfile = r.nextString();
91 throw new RuntimeException("unexpected top-level item " + item);
96 private TemplateAccount readTemplateAccount() throws IOException {
98 TemplateAccount result = new TemplateAccount(0L, 0L, 0L);
99 while (r.peek() != JsonToken.END_OBJECT) {
100 String item = r.nextName();
101 if (r.peek() == JsonToken.NULL) {
107 result.setAccountName(r.nextString());
109 case Keys.NAME_GROUP:
110 result.setAccountNameMatchGroup(r.nextInt());
113 result.setAccountComment(r.nextString());
115 case Keys.COMMENT_GROUP:
116 result.setAccountCommentMatchGroup(r.nextInt());
119 result.setAmount((float) r.nextDouble());
121 case Keys.AMOUNT_GROUP:
122 result.setAmountMatchGroup(r.nextInt());
124 case Keys.NEGATE_AMOUNT:
125 result.setNegateAmount(r.nextBoolean());
128 result.setCurrency(r.nextLong());
130 case Keys.CURRENCY_GROUP:
131 result.setCurrencyMatchGroup(r.nextInt());
135 throw new IllegalStateException("Unexpected template account item: " + item);
142 private TemplateWithAccounts readTemplate(JsonReader r) throws IOException {
145 TemplateHeader t = new TemplateHeader(0L, "", "");
146 List<TemplateAccount> accounts = new ArrayList<>();
148 while (r.peek() != JsonToken.END_OBJECT) {
149 String item = r.nextName();
150 if (r.peek() == JsonToken.NULL) {
156 t.setUuid(r.nextString());
159 t.setName(r.nextString());
162 t.setRegularExpression(r.nextString());
165 t.setTestText(r.nextString());
168 t.setDateYear(r.nextInt());
170 case Keys.DATE_YEAR_GROUP:
171 t.setDateYearMatchGroup(r.nextInt());
173 case Keys.DATE_MONTH:
174 t.setDateMonth(r.nextInt());
176 case Keys.DATE_MONTH_GROUP:
177 t.setDateMonthMatchGroup(r.nextInt());
180 t.setDateDay(r.nextInt());
182 case Keys.DATE_DAY_GROUP:
183 t.setDateDayMatchGroup(r.nextInt());
185 case Keys.TRANSACTION:
186 t.setTransactionDescription(r.nextString());
188 case Keys.TRANSACTION_GROUP:
189 t.setTransactionDescriptionMatchGroup(r.nextInt());
192 t.setTransactionComment(r.nextString());
194 case Keys.COMMENT_GROUP:
195 t.setTransactionCommentMatchGroup(r.nextInt());
197 case Keys.IS_FALLBACK:
198 t.setFallback(r.nextBoolean());
202 while (r.peek() == JsonToken.BEGIN_OBJECT) {
203 accounts.add(readTemplateAccount());
208 throw new RuntimeException("Unknown template header item: " + item);
213 TemplateWithAccounts result = new TemplateWithAccounts();
215 result.accounts = accounts;
218 private List<TemplateWithAccounts> readTemplates() throws IOException {
219 List<TemplateWithAccounts> list = new ArrayList<>();
222 while (r.peek() == JsonToken.BEGIN_OBJECT) {
223 list.add(readTemplate(r));
229 private List<Currency> readCommodities() throws IOException {
230 List<Currency> list = new ArrayList<>();
233 while (r.peek() == JsonToken.BEGIN_OBJECT) {
234 Currency c = new Currency();
237 while (r.peek() != JsonToken.END_OBJECT) {
238 final String item = r.nextName();
239 if (r.peek() == JsonToken.NULL) {
245 c.setName(r.nextString());
248 c.setPosition(r.nextString());
251 c.setHasGap(r.nextBoolean());
254 throw new RuntimeException("Unknown commodity key: " + item);
261 throw new RuntimeException("Missing commodity name");
269 private List<Profile> readProfiles() throws IOException {
270 List<Profile> list = new ArrayList<>();
272 while (r.peek() == JsonToken.BEGIN_OBJECT) {
273 Profile p = new Profile();
275 while (r.peek() != JsonToken.END_OBJECT) {
276 String item = r.nextName();
277 if (r.peek() == JsonToken.NULL) {
284 p.setUuid(r.nextString());
287 p.setName(r.nextString());
290 p.setUrl(r.nextString());
293 p.setUseAuthentication(r.nextBoolean());
296 p.setAuthUser(r.nextString());
299 p.setAuthPassword(r.nextString());
302 p.setApiVersion(r.nextInt());
305 p.setPermitPosting(r.nextBoolean());
307 case Keys.DEFAULT_COMMODITY:
308 p.setDefaultCommodity(r.nextString());
310 case Keys.SHOW_COMMODITY:
311 p.setShowCommodityByDefault(r.nextBoolean());
313 case Keys.SHOW_COMMENTS:
314 p.setShowCommentsByDefault(r.nextBoolean());
316 case Keys.FUTURE_DATES:
317 p.setFutureDates(r.nextInt());
319 case Keys.PREF_ACCOUNT:
320 p.setPreferredAccountsFilter(r.nextString());
323 p.setTheme(r.nextInt());
328 throw new IllegalStateException("Unexpected profile item: " + item);
339 public void restoreAll() {
340 restoreCommodities();
343 restoreCurrentProfile();
345 private void restoreTemplates() {
346 if (templates == null)
349 TemplateHeaderDAO dao = DB.get()
352 for (TemplateWithAccounts t : templates) {
353 if (dao.getTemplateWithAccountsByUuidSync(t.header.getUuid()) == null)
357 private void restoreProfiles() {
358 if (profiles == null)
361 ProfileDAO dao = DB.get()
364 for (Profile p : profiles) {
365 if (dao.getByUuidSync(p.getUuid()) == null)
369 private void restoreCommodities() {
370 if (commodities == null)
373 CurrencyDAO dao = DB.get()
376 for (Currency c : commodities) {
377 if (dao.getByNameSync(c.getName()) == null)
381 private void restoreCurrentProfile() {
382 if (currentProfile == null) {
383 Logger.debug("backup", "Not restoring current profile (not present in backup)");
387 ProfileDAO dao = DB.get()
390 Profile p = dao.getByUuidSync(currentProfile);
393 Logger.debug("backup", "Restoring current profile "+p.getName());
394 Data.postCurrentProfile(p);
395 App.storeStartupProfileAndTheme(p.getId(), p.getTheme());
398 Logger.debug("backup", "Not restoring profile "+currentProfile+": not found in DB");