+ catch (Exception e) {
+ Logger.debug("json",
+ String.format(Locale.US, "Error during account list retrieval using API %s",
+ ver.getDescription()));
+ }
+
+ throw new ApiNotSupportedException();
+ }
+
+ throw new RuntimeException("This should never be reached");
+ }
+ private List<LedgerAccount> retrieveAccountListForVersion(API version)
+ 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 = AccountListParser.forApiVersion(version, resp);
+ expectedPostingsCount = 0;
+
+ while (true) {
+ throwIfCancelled();
+ LedgerAccount acc = parser.nextAccount(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 ParseException, HTTPException, IOException, ApiNotSupportedException {
+ final API apiVersion = profile.getApiVersion();
+ if (apiVersion.equals(API.auto)) {
+ return retrieveTransactionListAnyVersion();
+ }
+ else if (apiVersion.equals(API.html)) {
+ Logger.debug("json",
+ "Declining using JSON API for /accounts with configured legacy API version");
+ return null;
+ }
+ else {
+ return retrieveTransactionListForVersion(apiVersion);
+ }
+
+ }
+ private List<LedgerTransaction> retrieveTransactionListAnyVersion()
+ throws ApiNotSupportedException {
+ for (API ver : API.allVersions) {
+ try {
+ return retrieveTransactionListForVersion(ver);
+ }
+ catch (Exception | HTTPException e) {
+ Logger.debug("json",
+ String.format(Locale.US, "Error during account list retrieval using API %s",
+ ver.getDescription()));
+ }
+
+ throw new ApiNotSupportedException();
+ }
+
+ throw new RuntimeException("This should never be reached");
+ }
+ private List<LedgerTransaction> retrieveTransactionListForVersion(API apiVersion)
+ 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 = TransactionListParser.forApiVersion(apiVersion, resp);
+
+ int processedPostings = 0;
+
+ while (true) {
+ throwIfCancelled();
+ LedgerTransaction transaction = parser.nextTransaction();
+ throwIfCancelled();
+ if (transaction == null)
+ break;
+
+ 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();
+ // accounts is null in API-version auto-detection and means
+ // requesting 'html' API version via the JSON classes
+ // this can't work, and the null results in the legacy code below
+ // being called
+ if (accounts == null)
+ transactions = null;
+ else
+ transactions = retrieveTransactionList();
+
+ if (accounts == null || transactions == null) {
+ accounts = new ArrayList<>();
+ transactions = new ArrayList<>();
+ retrieveTransactionListLegacy(accounts, transactions);
+ }
+ mainModel.setAndStoreAccountAndTransactionListFromWeb(accounts, transactions);
+
+ return new Result(accounts, transactions);