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.async;
20 import android.content.Context;
21 import android.net.Uri;
22 import android.util.JsonReader;
23 import android.util.JsonToken;
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.Misc;
37 import java.io.BufferedReader;
38 import java.io.FileInputStream;
39 import java.io.FileNotFoundException;
40 import java.io.IOException;
41 import java.io.InputStreamReader;
42 import java.util.ArrayList;
43 import java.util.List;
45 public class ConfigReader extends ConfigIO {
46 private final OnDoneListener onDoneListener;
48 public ConfigReader(Context context, Uri uri, OnErrorListener onErrorListener,
49 OnDoneListener onDoneListener) throws FileNotFoundException {
50 super(context, uri, onErrorListener);
52 this.onDoneListener = onDoneListener;
55 protected String getStreamMode() {
59 protected void initStream() {
60 r = new JsonReader(new BufferedReader(
61 new InputStreamReader(new FileInputStream(pfd.getFileDescriptor()))));
64 protected void processStream() throws IOException {
65 List<Currency> commodities = null;
66 List<Profile> profiles = null;
67 List<TemplateWithAccounts> templates = null;
68 String currentProfile = null;
71 String item = r.nextName();
73 case Keys.COMMODITIES:
74 commodities = readCommodities(r);
77 profiles = readProfiles(r);
80 templates = readTemplates(r);
82 case Keys.CURRENT_PROFILE:
83 currentProfile = r.nextString();
86 throw new RuntimeException("unexpected top-level item " + item);
91 restoreCommodities(commodities);
92 restoreProfiles(profiles);
93 restoreTemplates(templates);
95 if (Data.getProfile() == null) {
97 final ProfileDAO dao = DB.get()
99 if (currentProfile != null)
100 p = dao.getByUuidSync(currentProfile);
106 Data.postCurrentProfile(p);
109 if (onDoneListener != null)
110 Misc.onMainThread(onDoneListener::done);
112 private void restoreTemplates(List<TemplateWithAccounts> list) {
116 TemplateHeaderDAO dao = DB.get()
119 for (TemplateWithAccounts t : list) {
120 if (dao.getTemplateWithAccountsByUuidSync(t.header.getUuid()) == null)
124 private void restoreProfiles(List<Profile> list) {
128 ProfileDAO dao = DB.get()
131 for (Profile p : list) {
132 if (dao.getByUuidSync(p.getUuid()) == null)
136 private void restoreCommodities(List<Currency> list) {
140 CurrencyDAO dao = DB.get()
143 for (Currency c : list) {
144 if (dao.getByNameSync(c.getName()) == null)
148 private TemplateAccount readTemplateAccount(JsonReader r) throws IOException {
150 TemplateAccount result = new TemplateAccount(0L, 0L, 0L);
151 while (r.peek() != JsonToken.END_OBJECT) {
152 String item = r.nextName();
155 result.setAccountName(r.nextString());
157 case Keys.NAME_GROUP:
158 result.setAccountNameMatchGroup(r.nextInt());
161 result.setAccountComment(r.nextString());
163 case Keys.COMMENT_GROUP:
164 result.setAccountCommentMatchGroup(r.nextInt());
167 result.setAmount((float) r.nextDouble());
169 case Keys.AMOUNT_GROUP:
170 result.setAmountMatchGroup(r.nextInt());
172 case Keys.NEGATE_AMOUNT:
173 result.setNegateAmount(r.nextBoolean());
176 result.setCurrency(r.nextLong());
178 case Keys.CURRENCY_GROUP:
179 result.setCurrencyMatchGroup(r.nextInt());
183 throw new IllegalStateException("Unexpected template account item: " + item);
190 private TemplateWithAccounts readTemplate(JsonReader r) throws IOException {
193 TemplateHeader t = new TemplateHeader(0L, "", "");
194 List<TemplateAccount> accounts = new ArrayList<>();
196 while (r.peek() != JsonToken.END_OBJECT) {
197 String item = r.nextName();
200 t.setUuid(r.nextString());
203 t.setName(r.nextString());
206 t.setRegularExpression(r.nextString());
209 t.setTestText(r.nextString());
212 t.setDateYear(r.nextInt());
214 case Keys.DATE_YEAR_GROUP:
215 t.setDateYearMatchGroup(r.nextInt());
217 case Keys.DATE_MONTH:
218 t.setDateMonth(r.nextInt());
220 case Keys.DATE_MONTH_GROUP:
221 t.setDateMonthMatchGroup(r.nextInt());
224 t.setDateDay(r.nextInt());
226 case Keys.DATE_DAY_GROUP:
227 t.setDateDayMatchGroup(r.nextInt());
229 case Keys.TRANSACTION:
230 t.setTransactionDescription(r.nextString());
232 case Keys.TRANSACTION_GROUP:
233 t.setTransactionDescriptionMatchGroup(r.nextInt());
236 t.setTransactionComment(r.nextString());
238 case Keys.COMMENT_GROUP:
239 t.setTransactionCommentMatchGroup(r.nextInt());
241 case Keys.IS_FALLBACK:
242 t.setFallback(r.nextBoolean());
246 while (r.peek() == JsonToken.BEGIN_OBJECT) {
247 accounts.add(readTemplateAccount(r));
252 throw new RuntimeException("Unknown template header item: " + item);
257 TemplateWithAccounts result = new TemplateWithAccounts();
259 result.accounts = accounts;
262 private List<TemplateWithAccounts> readTemplates(JsonReader r) throws IOException {
263 List<TemplateWithAccounts> list = new ArrayList<>();
266 while (r.peek() == JsonToken.BEGIN_OBJECT) {
267 list.add(readTemplate(r));
273 private List<Currency> readCommodities(JsonReader r) throws IOException {
274 List<Currency> list = new ArrayList<>();
277 while (r.peek() == JsonToken.BEGIN_OBJECT) {
278 Currency c = new Currency();
281 while (r.peek() != JsonToken.END_OBJECT) {
282 final String item = r.nextName();
285 c.setName(r.nextString());
288 c.setPosition(r.nextString());
291 c.setHasGap(r.nextBoolean());
294 throw new RuntimeException("Unknown commodity key: " + item);
301 throw new RuntimeException("Missing commodity name");
309 private List<Profile> readProfiles(JsonReader r) throws IOException {
310 List<Profile> list = new ArrayList<>();
312 while (r.peek() == JsonToken.BEGIN_OBJECT) {
313 Profile p = new Profile();
315 while (r.peek() != JsonToken.END_OBJECT) {
316 String item = r.nextName();
320 p.setUuid(r.nextString());
323 p.setName(r.nextString());
326 p.setUrl(r.nextString());
329 p.setUseAuthentication(r.nextBoolean());
332 p.setAuthUser(r.nextString());
335 p.setAuthPassword(r.nextString());
338 p.setApiVersion(r.nextInt());
341 p.setPermitPosting(r.nextBoolean());
343 case Keys.DEFAULT_COMMODITY:
344 p.setDefaultCommodity(r.nextString());
346 case Keys.SHOW_COMMODITY:
347 p.setShowCommodityByDefault(r.nextBoolean());
349 case Keys.SHOW_COMMENTS:
350 p.setShowCommentsByDefault(r.nextBoolean());
352 case Keys.FUTURE_DATES:
353 p.setFutureDates(r.nextInt());
355 case Keys.PREF_ACCOUNT:
356 p.setPreferredAccountsFilter(r.nextString());
359 p.setTheme(r.nextInt());
364 throw new IllegalStateException("Unexpected profile item: " + item);
375 abstract static public class OnDoneListener {
376 public abstract void done();