]> git.ktnx.net Git - mobile-ledger.git/blob - app/src/main/java/net/ktnx/mobileledger/backup/RawConfigReader.java
provide cloud backup functionality
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / backup / RawConfigReader.java
1 /*
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.
8  *
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.
13  *
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/>.
16  */
17
18 package net.ktnx.mobileledger.backup;
19
20 import android.util.JsonReader;
21 import android.util.JsonToken;
22
23 import net.ktnx.mobileledger.backup.ConfigIO.Keys;
24 import net.ktnx.mobileledger.dao.CurrencyDAO;
25 import net.ktnx.mobileledger.dao.ProfileDAO;
26 import net.ktnx.mobileledger.dao.TemplateHeaderDAO;
27 import net.ktnx.mobileledger.db.Currency;
28 import net.ktnx.mobileledger.db.DB;
29 import net.ktnx.mobileledger.db.Profile;
30 import net.ktnx.mobileledger.db.TemplateAccount;
31 import net.ktnx.mobileledger.db.TemplateHeader;
32 import net.ktnx.mobileledger.db.TemplateWithAccounts;
33
34 import java.io.BufferedReader;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.util.ArrayList;
39 import java.util.List;
40
41 public class RawConfigReader {
42     private final JsonReader r;
43     private List<Currency> commodities;
44     private List<Profile> profiles;
45     private List<TemplateWithAccounts> templates;
46     private String currentProfile;
47     public RawConfigReader(InputStream inputStream) {
48         r = new JsonReader(new BufferedReader(new InputStreamReader(inputStream)));
49     }
50     public List<Currency> getCommodities() {
51         return commodities;
52     }
53     public List<Profile> getProfiles() {
54         return profiles;
55     }
56     public List<TemplateWithAccounts> getTemplates() {
57         return templates;
58     }
59     public String getCurrentProfile() {
60         return currentProfile;
61     }
62     public void readConfig() throws IOException {
63         commodities = null;
64         profiles = null;
65         templates = null;
66         currentProfile = null;
67         r.beginObject();
68         while (r.hasNext()) {
69             String item = r.nextName();
70             if (r.peek() == JsonToken.NULL) {
71                 r.nextNull();
72                 continue;
73             }
74             switch (item) {
75                 case Keys.COMMODITIES:
76                     commodities = readCommodities();
77                     break;
78                 case Keys.PROFILES:
79                     profiles = readProfiles();
80                     break;
81                 case Keys.TEMPLATES:
82                     templates = readTemplates();
83                     break;
84                 case Keys.CURRENT_PROFILE:
85                     currentProfile = r.nextString();
86                     break;
87                 default:
88                     throw new RuntimeException("unexpected top-level item " + item);
89             }
90         }
91         r.endObject();
92     }
93     private TemplateAccount readTemplateAccount() throws IOException {
94         r.beginObject();
95         TemplateAccount result = new TemplateAccount(0L, 0L, 0L);
96         while (r.peek() != JsonToken.END_OBJECT) {
97             String item = r.nextName();
98             if (r.peek() == JsonToken.NULL) {
99                 r.nextNull();
100                 continue;
101             }
102             switch (item) {
103                 case Keys.NAME:
104                     result.setAccountName(r.nextString());
105                     break;
106                 case Keys.NAME_GROUP:
107                     result.setAccountNameMatchGroup(r.nextInt());
108                     break;
109                 case Keys.COMMENT:
110                     result.setAccountComment(r.nextString());
111                     break;
112                 case Keys.COMMENT_GROUP:
113                     result.setAccountCommentMatchGroup(r.nextInt());
114                     break;
115                 case Keys.AMOUNT:
116                     result.setAmount((float) r.nextDouble());
117                     break;
118                 case Keys.AMOUNT_GROUP:
119                     result.setAmountMatchGroup(r.nextInt());
120                     break;
121                 case Keys.NEGATE_AMOUNT:
122                     result.setNegateAmount(r.nextBoolean());
123                     break;
124                 case Keys.CURRENCY:
125                     result.setCurrency(r.nextLong());
126                     break;
127                 case Keys.CURRENCY_GROUP:
128                     result.setCurrencyMatchGroup(r.nextInt());
129                     break;
130
131                 default:
132                     throw new IllegalStateException("Unexpected template account item: " + item);
133             }
134         }
135         r.endObject();
136
137         return result;
138     }
139     private TemplateWithAccounts readTemplate(JsonReader r) throws IOException {
140         r.beginObject();
141         String name = null;
142         TemplateHeader t = new TemplateHeader(0L, "", "");
143         List<TemplateAccount> accounts = new ArrayList<>();
144
145         while (r.peek() != JsonToken.END_OBJECT) {
146             String item = r.nextName();
147             if (r.peek() == JsonToken.NULL) {
148                 r.nextNull();
149                 continue;
150             }
151             switch (item) {
152                 case Keys.UUID:
153                     t.setUuid(r.nextString());
154                     break;
155                 case Keys.NAME:
156                     t.setName(r.nextString());
157                     break;
158                 case Keys.REGEX:
159                     t.setRegularExpression(r.nextString());
160                     break;
161                 case Keys.TEST_TEXT:
162                     t.setTestText(r.nextString());
163                     break;
164                 case Keys.DATE_YEAR:
165                     t.setDateYear(r.nextInt());
166                     break;
167                 case Keys.DATE_YEAR_GROUP:
168                     t.setDateYearMatchGroup(r.nextInt());
169                     break;
170                 case Keys.DATE_MONTH:
171                     t.setDateMonth(r.nextInt());
172                     break;
173                 case Keys.DATE_MONTH_GROUP:
174                     t.setDateMonthMatchGroup(r.nextInt());
175                     break;
176                 case Keys.DATE_DAY:
177                     t.setDateDay(r.nextInt());
178                     break;
179                 case Keys.DATE_DAY_GROUP:
180                     t.setDateDayMatchGroup(r.nextInt());
181                     break;
182                 case Keys.TRANSACTION:
183                     t.setTransactionDescription(r.nextString());
184                     break;
185                 case Keys.TRANSACTION_GROUP:
186                     t.setTransactionDescriptionMatchGroup(r.nextInt());
187                     break;
188                 case Keys.COMMENT:
189                     t.setTransactionComment(r.nextString());
190                     break;
191                 case Keys.COMMENT_GROUP:
192                     t.setTransactionCommentMatchGroup(r.nextInt());
193                     break;
194                 case Keys.IS_FALLBACK:
195                     t.setFallback(r.nextBoolean());
196                     break;
197                 case Keys.ACCOUNTS:
198                     r.beginArray();
199                     while (r.peek() == JsonToken.BEGIN_OBJECT) {
200                         accounts.add(readTemplateAccount());
201                     }
202                     r.endArray();
203                     break;
204                 default:
205                     throw new RuntimeException("Unknown template header item: " + item);
206             }
207         }
208         r.endObject();
209
210         TemplateWithAccounts result = new TemplateWithAccounts();
211         result.header = t;
212         result.accounts = accounts;
213         return result;
214     }
215     private List<TemplateWithAccounts> readTemplates() throws IOException {
216         List<TemplateWithAccounts> list = new ArrayList<>();
217
218         r.beginArray();
219         while (r.peek() == JsonToken.BEGIN_OBJECT) {
220             list.add(readTemplate(r));
221         }
222         r.endArray();
223
224         return list;
225     }
226     private List<Currency> readCommodities() throws IOException {
227         List<Currency> list = new ArrayList<>();
228
229         r.beginArray();
230         while (r.peek() == JsonToken.BEGIN_OBJECT) {
231             Currency c = new Currency();
232
233             r.beginObject();
234             while (r.peek() != JsonToken.END_OBJECT) {
235                 final String item = r.nextName();
236                 if (r.peek() == JsonToken.NULL) {
237                     r.nextNull();
238                     continue;
239                 }
240                 switch (item) {
241                     case Keys.NAME:
242                         c.setName(r.nextString());
243                         break;
244                     case Keys.POSITION:
245                         c.setPosition(r.nextString());
246                         break;
247                     case Keys.HAS_GAP:
248                         c.setHasGap(r.nextBoolean());
249                         break;
250                     default:
251                         throw new RuntimeException("Unknown commodity key: " + item);
252                 }
253             }
254             r.endObject();
255
256             if (c.getName()
257                  .isEmpty())
258                 throw new RuntimeException("Missing commodity name");
259
260             list.add(c);
261         }
262         r.endArray();
263
264         return list;
265     }
266     private List<Profile> readProfiles() throws IOException {
267         List<Profile> list = new ArrayList<>();
268         r.beginArray();
269         while (r.peek() == JsonToken.BEGIN_OBJECT) {
270             Profile p = new Profile();
271             r.beginObject();
272             while (r.peek() != JsonToken.END_OBJECT) {
273                 String item = r.nextName();
274                 if (r.peek() == JsonToken.NULL) {
275                     r.nextNull();
276                     continue;
277                 }
278
279                 switch (item) {
280                     case Keys.UUID:
281                         p.setUuid(r.nextString());
282                         break;
283                     case Keys.NAME:
284                         p.setName(r.nextString());
285                         break;
286                     case Keys.URL:
287                         p.setUrl(r.nextString());
288                         break;
289                     case Keys.USE_AUTH:
290                         p.setUseAuthentication(r.nextBoolean());
291                         break;
292                     case Keys.AUTH_USER:
293                         p.setAuthUser(r.nextString());
294                         break;
295                     case Keys.AUTH_PASS:
296                         p.setAuthPassword(r.nextString());
297                         break;
298                     case Keys.API_VER:
299                         p.setApiVersion(r.nextInt());
300                         break;
301                     case Keys.CAN_POST:
302                         p.setPermitPosting(r.nextBoolean());
303                         break;
304                     case Keys.DEFAULT_COMMODITY:
305                         p.setDefaultCommodity(r.nextString());
306                         break;
307                     case Keys.SHOW_COMMODITY:
308                         p.setShowCommodityByDefault(r.nextBoolean());
309                         break;
310                     case Keys.SHOW_COMMENTS:
311                         p.setShowCommentsByDefault(r.nextBoolean());
312                         break;
313                     case Keys.FUTURE_DATES:
314                         p.setFutureDates(r.nextInt());
315                         break;
316                     case Keys.PREF_ACCOUNT:
317                         p.setPreferredAccountsFilter(r.nextString());
318                         break;
319                     case Keys.COLOUR:
320                         p.setTheme(r.nextInt());
321                         break;
322
323
324                     default:
325                         throw new IllegalStateException("Unexpected profile item: " + item);
326                 }
327             }
328             r.endObject();
329
330             list.add(p);
331         }
332         r.endArray();
333
334         return list;
335     }
336     public void restoreAll() {
337         restoreCommodities();
338         restoreProfiles();
339         restoreTemplates();
340     }
341     private void restoreTemplates() {
342         if (templates == null)
343             return;
344
345         TemplateHeaderDAO dao = DB.get()
346                                   .getTemplateDAO();
347
348         for (TemplateWithAccounts t : templates) {
349             if (dao.getTemplateWithAccountsByUuidSync(t.header.getUuid()) == null)
350                 dao.insertSync(t);
351         }
352     }
353     private void restoreProfiles() {
354         if (profiles == null)
355             return;
356
357         ProfileDAO dao = DB.get()
358                            .getProfileDAO();
359
360         for (Profile p : profiles) {
361             if (dao.getByUuidSync(p.getUuid()) == null)
362                 dao.insert(p);
363         }
364     }
365     private void restoreCommodities() {
366         if (commodities == null)
367             return;
368
369         CurrencyDAO dao = DB.get()
370                             .getCurrencyDAO();
371
372         for (Currency c : commodities) {
373             if (dao.getByNameSync(c.getName()) == null)
374                 dao.insert(c);
375         }
376     }
377 }