+ throwIfCancelled();
+ }
+ }
+ @NonNull
+ public LedgerAccount ensureAccountExists(String accountName, HashMap<String, LedgerAccount> map,
+ ArrayList<LedgerAccount> createdAccounts) {
+ LedgerAccount acc = map.get(accountName);
+
+ if (acc != null)
+ return acc;
+
+ String parentName = LedgerAccount.extractParentName(accountName);
+ LedgerAccount parentAccount;
+ if (parentName != null) {
+ parentAccount = ensureAccountExists(parentName, map, createdAccounts);
+ }
+ else {
+ parentAccount = null;
+ }
+
+ acc = new LedgerAccount(profile, accountName, parentAccount);
+ createdAccounts.add(acc);
+ return acc;
+ }
+ public void addNumberOfPostings(int number) {
+ expectedPostingsCount += number;
+ }
+ private List<LedgerAccount> retrieveAccountList() throws IOException, HTTPException {
+ HttpURLConnection http = NetworkUtil.prepareConnection(profile, "accounts");
+ http.setAllowUserInteraction(false);
+ switch (http.getResponseCode()) {
+ case 200:
+ break;
+ case 404:
+ return null;
+ default:
+ throw new HTTPException(http.getResponseCode(), http.getResponseMessage());
+ }
+ publishProgress(Progress.indeterminate());
+ SQLiteDatabase db = App.getDatabase();
+ ArrayList<LedgerAccount> list = new ArrayList<>();
+ HashMap<String, LedgerAccount> map = new HashMap<>();
+ HashMap<String, LedgerAccount> currentMap = new HashMap<>();
+ for (LedgerAccount acc : prevAccounts)
+ currentMap.put(acc.getName(), acc);
+ throwIfCancelled();
+ try (InputStream resp = http.getInputStream()) {
+ throwIfCancelled();
+ if (http.getResponseCode() != 200)
+ throw new IOException(String.format("HTTP error %d", http.getResponseCode()));
+
+ AccountListParser parser = new AccountListParser(resp);
+ expectedPostingsCount = 0;
+
+ while (true) {
+ throwIfCancelled();
+ LedgerAccount acc = parser.nextLedgerAccount(this, map);
+ if (acc == null)
+ break;
+ list.add(acc);
+ }
+ throwIfCancelled();
+ }
+
+ // the current account tree may have changed, update the new-to be tree to match
+ for (LedgerAccount acc : list) {
+ LedgerAccount prevData = currentMap.get(acc.getName());
+ if (prevData != null) {
+ acc.setExpanded(prevData.isExpanded());
+ acc.setAmountsExpanded(prevData.amountsExpanded());
+ }
+ }
+
+ return list;
+ }
+ private List<LedgerTransaction> retrieveTransactionList()
+ throws IOException, ParseException, HTTPException {
+ Progress progress = new Progress();
+ progress.setTotal(expectedPostingsCount);
+
+ HttpURLConnection http = NetworkUtil.prepareConnection(profile, "transactions");
+ http.setAllowUserInteraction(false);
+ publishProgress(progress);
+ switch (http.getResponseCode()) {
+ case 200:
+ break;
+ case 404:
+ return null;
+ default:
+ throw new HTTPException(http.getResponseCode(), http.getResponseMessage());
+ }
+ ArrayList<LedgerTransaction> trList = new ArrayList<>();
+ try (InputStream resp = http.getInputStream()) {
+ throwIfCancelled();
+
+ TransactionListParser parser = new TransactionListParser(resp);
+
+ int processedPostings = 0;
+
+ while (true) {
+ throwIfCancelled();
+ ParsedLedgerTransaction parsedTransaction = parser.nextTransaction();
+ throwIfCancelled();
+ if (parsedTransaction == null)
+ break;
+
+ LedgerTransaction transaction = parsedTransaction.asLedgerTransaction();
+ trList.add(transaction);
+
+ progress.setProgress(processedPostings += transaction.getAccounts()
+ .size());
+// Logger.debug("trParser",
+// String.format(Locale.US, "Parsed transaction %d - %s", transaction
+// .getId(),
+// transaction.getDescription()));
+// for (LedgerTransactionAccount acc : transaction.getAccounts()) {
+// Logger.debug("trParser",
+// String.format(Locale.US, " %s", acc.getAccountName()));
+// }
+ publishProgress(progress);
+ }
+
+ throwIfCancelled();
+ }
+
+ // json interface returns transactions if file order and the rest of the machinery
+ // expects them in reverse chronological order
+ Collections.sort(trList, (o1, o2) -> {
+ int res = o2.getDate()
+ .compareTo(o1.getDate());
+ if (res != 0)
+ return res;
+ return Integer.compare(o2.getId(), o1.getId());
+ });
+ return trList;
+ }
+
+ @SuppressLint("DefaultLocale")
+ @Override
+ protected Result doInBackground(Void... params) {
+ Data.backgroundTaskStarted();
+ List<LedgerAccount> accounts;
+ List<LedgerTransaction> transactions;
+ try {
+ accounts = retrieveAccountList();
+ if (accounts == null)
+ transactions = null;
+ else
+ transactions = retrieveTransactionList();
+ if (accounts == null || transactions == null) {
+ accounts = new ArrayList<>();
+ transactions = new ArrayList<>();
+ retrieveTransactionListLegacy(accounts, transactions);