Hey i have some legacy code i'm working on (It is open source so no problem in me sharing it!). I wanted to refactor some parts in the extractResult
method since it got pretty repetitive. The *.*.*
are extracted from XML, so there is not much to do. I realized that the creation of the Saldos and Values is pretty similar though that's why i extracted the code for its creation into respective methods (createSaldo and createValue). The only thing that doesn't match is the info.reserved
field which is also a Saldo but doesn't take the infos from the same XML as the other Saldos (That is why the keys are different). You can check the old version of the code here. The PR there is also from me, which includes changes for the UPD(). If you want to check the old version of the code take a look at GVSaldoReq.
How would you further refactor this? And thanks for any inputs!
protected void extractResults(HBCIMsgStatus msgstatus, String header, int idx) {
HashMap<String, String> result = msgstatus.getData();
GVRSaldoReq.Info info = new GVRSaldoReq.Info();
info.konto = new Konto();
info.konto.country = result.get(header + ".KTV.KIK.country");
info.konto.blz = result.get(header + ".KTV.KIK.blz");
info.konto.number = result.get(header + ".KTV.number");
info.konto.subnumber = result.get(header + ".KTV.subnumber");
info.konto.bic = result.get(header + ".KTV.bic");
info.konto.iban = result.get(header + ".KTV.iban");
info.konto.type = result.get(header + ".kontobez");
info.konto.curr = result.get(header + ".curr");
passport.fillAccountInfo(info.konto);
Map<String, String> resultHeader = getByPrefix(result, header);
info.ready = createSaldo(getByPrefix(resultHeader, "booked"));
Map<String, String> pendingMap = getByPrefix(resultHeader, "pending");
Optional.ofNullable(pendingMap.get("CreditDebit")).ifPresent(creditDebit ->
info.unready = createSaldo(pendingMap));
info.kredit = createValue(getByPrefix(resultHeader, "kredit"), false);
info.available = createValue(getByPrefix(resultHeader, "curr"), false);
info.used = createValue(getByPrefix(resultHeader, "value"), false);
retrieveReservedBalanceInfoFromUPD().ifPresent(accountDataInfo -> {
Map<String, String> reservedBalanceInfo = getByPrefix(accountDataInfo, "Balance.VOR");
Optional.ofNullable(reservedBalanceInfo.get("Amount")).ifPresent(
amount -> {
amount = amount.replace(".", "").replace(",", ".");
info.reserved = new Saldo();
info.reserved.value = new Value(amount, reservedBalanceInfo.getOrDefault("Currency", "EUR"));
Optional.ofNullable(reservedBalanceInfo.get("Date")).ifPresent(
date -> info.reserved.timestamp = HBCIUtils.string2DateISO(reservedBalanceInfo.get("Date"), "yyyyMMdd")
);
}
);
});
((GVRSaldoReq) (jobResult)).store(info);
}
private Value createValue(Map<String, String> data, boolean negative) {
final var value = data.get("value");
if (value == null) {
return null;
}
final var currency = data.get("curr");
final var valueObj = new Value(value, currency);
if (negative) {
valueObj.setValue(valueObj.getBigDecimalValue().negate());
}
return valueObj;
}
private Saldo createSaldo(Map<String, String> data) {
final Saldo saldo = new Saldo();
saldo.value = createValue(getByPrefix(data, "BTG"), "D".equals(data.get("CreditDebit")));
saldo.timestamp = HBCIUtils.strings2DateTimeISO(data.get("date"), data.get("time"));
return saldo;
}
private static Map<String, String> getByPrefix(Map<String, String> data, String keyPrefix) {
return data.entrySet().stream()
.filter(entry -> entry.getKey().startsWith(keyPrefix + "."))
.collect(Collectors.toMap(entry -> entry.getKey().substring(keyPrefix.length() + 1), Map.Entry::getValue));
}
private Optional<Map<String, String>> retrieveReservedBalanceInfoFromUPD() {
return Optional.ofNullable(passport.getUPD().get("KInfo.accountdata")).map(accountData -> {
final var reservedBalancePattern = Pattern.compile("(Balance\\.VOR\\..*?)=(.*?(?=;))");
final var matcher = reservedBalancePattern.matcher(accountData);
Map<String, String> reservedBalanceInfo = new HashMap<>();
while (matcher.find()) {
final var key = matcher.group(1);
final var value = matcher.group(2);
reservedBalanceInfo.put(key, value);
}
return reservedBalanceInfo;
}
);
}
passport
andjobResult
, where do they come from? \$\endgroup\$