X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fasync%2FRetrieveTransactionsTask.java;h=aa47d73d403cc456bf6fca05a7046e8dbd421241;hb=8098a8b37a4331b9faf6cf50a51a0d7aa9677421;hp=85f7665146b556303edfbe8435738b740394e50b;hpb=bcf517d0eae491de46b71a1e0f288852ca3d64df;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java index 85f76651..aa47d73d 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java @@ -1,5 +1,5 @@ /* - * Copyright © 2020 Damyan Ivanov. + * Copyright © 2021 Damyan Ivanov. * This file is part of MoLe. * MoLe is free software: you can distribute it and/or modify it * under the term of the GNU General Public License as published by @@ -24,17 +24,21 @@ import android.os.OperationCanceledException; import androidx.annotation.NonNull; +import com.fasterxml.jackson.databind.RuntimeJsonMappingException; + import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.err.HTTPException; -import net.ktnx.mobileledger.json.v1_15.AccountListParser; -import net.ktnx.mobileledger.json.v1_15.ParsedLedgerTransaction; -import net.ktnx.mobileledger.json.v1_15.TransactionListParser; +import net.ktnx.mobileledger.json.API; +import net.ktnx.mobileledger.json.AccountListParser; +import net.ktnx.mobileledger.json.ApiNotSupportedException; +import net.ktnx.mobileledger.json.TransactionListParser; import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.model.LedgerAccount; import net.ktnx.mobileledger.model.LedgerTransaction; import net.ktnx.mobileledger.model.LedgerTransactionAccount; import net.ktnx.mobileledger.model.MobileLedgerProfile; import net.ktnx.mobileledger.ui.MainModel; +import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.NetworkUtil; import java.io.BufferedReader; @@ -117,9 +121,6 @@ public class RetrieveTransactionsTask extends return null; } } - public MobileLedgerProfile getProfile() { - return profile; - } @Override protected void onProgressUpdate(Progress... values) { super.onProgressUpdate(values); @@ -210,7 +211,7 @@ public class RetrieveTransactionsTask extends else { parentAccount = null; } - lastAccount = new LedgerAccount(profile, accName, parentAccount); + lastAccount = new LedgerAccount(accName, parentAccount); accounts.add(lastAccount); map.put(accName, lastAccount); @@ -374,14 +375,47 @@ public class RetrieveTransactionsTask extends parentAccount = null; } - acc = new LedgerAccount(profile, accountName, parentAccount); + acc = new LedgerAccount(accountName, parentAccount); createdAccounts.add(acc); return acc; } public void addNumberOfPostings(int number) { expectedPostingsCount += number; } - private List retrieveAccountList() throws IOException, HTTPException { + private List retrieveAccountList() + throws IOException, HTTPException, ApiNotSupportedException { + final API apiVersion = profile.getApiVersion(); + if (apiVersion.equals(API.auto)) { + return retrieveAccountListAnyVersion(); + } + else if (apiVersion.equals(API.html)) { + Logger.debug("json", + "Declining using JSON API for /accounts with configured legacy API version"); + return null; + } + else { + return retrieveAccountListForVersion(apiVersion); + } + } + private List retrieveAccountListAnyVersion() + throws HTTPException, ApiNotSupportedException { + for (API ver : API.allVersions) { + try { + return retrieveAccountListForVersion(ver); + } + 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 retrieveAccountListForVersion(API version) + throws IOException, HTTPException { HttpURLConnection http = NetworkUtil.prepareConnection(profile, "accounts"); http.setAllowUserInteraction(false); switch (http.getResponseCode()) { @@ -405,12 +439,12 @@ public class RetrieveTransactionsTask extends if (http.getResponseCode() != 200) throw new IOException(String.format("HTTP error %d", http.getResponseCode())); - AccountListParser parser = new AccountListParser(resp); + AccountListParser parser = AccountListParser.forApiVersion(version, resp); expectedPostingsCount = 0; while (true) { throwIfCancelled(); - LedgerAccount acc = parser.nextLedgerAccount(this, map); + LedgerAccount acc = parser.nextAccount(this, map); if (acc == null) break; list.add(acc); @@ -430,6 +464,39 @@ public class RetrieveTransactionsTask extends return list; } private List 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 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 retrieveTransactionListForVersion(API apiVersion) throws IOException, ParseException, HTTPException { Progress progress = new Progress(); progress.setTotal(expectedPostingsCount); @@ -449,18 +516,17 @@ public class RetrieveTransactionsTask extends try (InputStream resp = http.getInputStream()) { throwIfCancelled(); - TransactionListParser parser = new TransactionListParser(resp); + TransactionListParser parser = TransactionListParser.forApiVersion(apiVersion, resp); int processedPostings = 0; while (true) { throwIfCancelled(); - ParsedLedgerTransaction parsedTransaction = parser.nextTransaction(); + LedgerTransaction transaction = parser.nextTransaction(); throwIfCancelled(); - if (parsedTransaction == null) + if (transaction == null) break; - LedgerTransaction transaction = parsedTransaction.asLedgerTransaction(); trList.add(transaction); progress.setProgress(processedPostings += transaction.getAccounts() @@ -486,7 +552,7 @@ public class RetrieveTransactionsTask extends .compareTo(o1.getDate()); if (res != 0) return res; - return Integer.compare(o2.getId(), o1.getId()); + return Long.compare(o2.getId(), o1.getId()); }); return trList; } @@ -499,10 +565,15 @@ public class RetrieveTransactionsTask extends List 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<>(); @@ -525,6 +596,10 @@ public class RetrieveTransactionsTask extends e.printStackTrace(); return new Result(e.getLocalizedMessage()); } + catch (RuntimeJsonMappingException e) { + e.printStackTrace(); + return new Result(Result.ERR_JSON_PARSER_ERROR); + } catch (ParseException e) { e.printStackTrace(); return new Result("Network error"); @@ -533,6 +608,10 @@ public class RetrieveTransactionsTask extends e.printStackTrace(); return new Result("Operation cancelled"); } + catch (ApiNotSupportedException e) { + e.printStackTrace(); + return new Result("Server version not supported"); + } finally { Data.backgroundTaskFinished(); } @@ -622,6 +701,7 @@ public class RetrieveTransactionsTask extends } public static class Result { + public static String ERR_JSON_PARSER_ERROR = "err_json_parser"; public String error; public List accounts; public List transactions;