Extract parsing functions from BSFormatter to ParsingUtils

Parsing and formatting are 2 different concerns, its better to have 2
classes that handle these.
This commit is contained in:
Justin Carter 2019-09-11 16:07:16 +02:00
parent fe33a80de5
commit 3b46f3584f
No known key found for this signature in database
GPG key ID: 4B8BB0D3F5018030
23 changed files with 164 additions and 136 deletions

View file

@ -35,8 +35,8 @@ import bisq.core.dao.state.model.governance.EvaluatedProposal;
import bisq.core.dao.state.model.governance.Issuance;
import bisq.core.dao.state.model.governance.IssuanceType;
import bisq.core.dao.state.model.governance.ParamChange;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Coin;
@ -924,7 +924,7 @@ public class DaoStateService implements DaoSetupService {
}
public double getParamValueAsPercentDouble(String paramValue) {
return BSFormatter.parsePercentStringToDouble(paramValue);
return ParsingUtils.parsePercentStringToDouble(paramValue);
}
public int getParamValueAsBlock(String paramValue) {

View file

@ -17,7 +17,7 @@
package bisq.core.monetary;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Monetary;
import org.bitcoinj.utils.MonetaryFormat;
@ -89,7 +89,7 @@ public final class Altcoin implements Monetary, Comparable<Altcoin> {
* @throws IllegalArgumentException if you try to specify fractional satoshis, or a value out of range.
*/
public static Altcoin parseAltcoin(final String currencyCode, String input) {
String cleaned = BSFormatter.convertCharsForNumber(input);
String cleaned = ParsingUtils.convertCharsForNumber(input);
try {
long val = new BigDecimal(cleaned).movePointRight(SMALLEST_UNIT_EXPONENT)
.toBigIntegerExact().longValue();

View file

@ -18,7 +18,7 @@
package bisq.core.monetary;
import bisq.core.locale.CurrencyUtil;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Monetary;
@ -58,7 +58,7 @@ public class Price extends MonetaryWrapper implements Comparable<Price> {
* @return The parsed Price.
*/
public static Price parse(String currencyCode, String input) {
String cleaned = BSFormatter.convertCharsForNumber(input);
String cleaned = ParsingUtils.convertCharsForNumber(input);
if (CurrencyUtil.isFiatCurrency(currencyCode))
return new Price(Fiat.parseFiat(currencyCode, cleaned));
else

View file

@ -18,7 +18,7 @@
package bisq.core.monetary;
import bisq.core.locale.CurrencyUtil;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Monetary;
import org.bitcoinj.utils.Fiat;
@ -36,7 +36,7 @@ public class Volume extends MonetaryWrapper implements Comparable<Volume> {
}
public static Volume parse(String input, String currencyCode) {
String cleaned = BSFormatter.convertCharsForNumber(input);
String cleaned = ParsingUtils.convertCharsForNumber(input);
if (CurrencyUtil.isFiatCurrency(currencyCode))
return new Volume(Fiat.parseFiat(currencyCode, cleaned));
else

View file

@ -52,6 +52,7 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@ -66,7 +67,8 @@ public class BSFormatter {
// Input of a group separator (1,123,45) lead to an validation error.
// Note: BtcFormat was intended to be used, but it lead to many problems (automatic format to mBit,
// no way to remove grouping separator). It seems to be not optimal for user input formatting.
protected MonetaryFormat coinFormat;
@Getter
protected MonetaryFormat monetaryFormat;
// protected String currencyCode = CurrencyUtil.getDefaultFiatCurrencyAsCode();
@ -77,7 +79,7 @@ public class BSFormatter {
@Inject
public BSFormatter() {
coinFormat = BisqEnvironment.getParameters().getMonetaryFormat();
monetaryFormat = BisqEnvironment.getParameters().getMonetaryFormat();
}
@ -99,7 +101,7 @@ public class BSFormatter {
}
public String formatCoin(Coin coin, int decimalPlaces, boolean decimalAligned, int maxNumberOfDigits) {
return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, coinFormat);
return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, monetaryFormat);
}
public static String formatCoin(Coin coin,
@ -129,11 +131,11 @@ public class BSFormatter {
}
public String formatCoinWithCode(Coin coin) {
return formatCoinWithCode(coin, coinFormat);
return formatCoinWithCode(coin, monetaryFormat);
}
public String formatCoinWithCode(long value) {
return formatCoinWithCode(Coin.valueOf(value), coinFormat);
return formatCoinWithCode(Coin.valueOf(value), monetaryFormat);
}
public static String formatCoinWithCode(long value, MonetaryFormat coinFormat) {
@ -155,24 +157,6 @@ public class BSFormatter {
}
}
public Coin parseToCoin(String input) {
return parseToCoin(input, coinFormat);
}
public Coin parseToCoin(String input, MonetaryFormat coinFormat) {
if (input != null && input.length() > 0) {
try {
return coinFormat.parse(cleanDoubleInput(input));
} catch (Throwable t) {
log.warn("Exception at parseToBtc: " + t.toString());
return Coin.ZERO;
}
} else {
return Coin.ZERO;
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// FIAT
///////////////////////////////////////////////////////////////////////////////////////////
@ -194,10 +178,10 @@ public class BSFormatter {
}
}
protected static Fiat parseToFiat(String input, String currencyCode) {
private static Fiat parseToFiat(String input, String currencyCode) {
if (input != null && input.length() > 0) {
try {
return Fiat.parseFiat(currencyCode, cleanDoubleInput(input));
return Fiat.parseFiat(currencyCode, ParsingUtils.cleanDoubleInput(input));
} catch (Exception e) {
log.warn("Exception at parseToFiat: " + e.toString());
return Fiat.valueOf(currencyCode, 0);
@ -220,7 +204,7 @@ public class BSFormatter {
public static Fiat parseToFiatWithPrecision(String input, String currencyCode) {
if (input != null && input.length() > 0) {
try {
return parseToFiat(new BigDecimal(cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(),
return parseToFiat(new BigDecimal(ParsingUtils.cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(),
currencyCode);
} catch (Throwable t) {
log.warn("Exception at parseToFiatWithPrecision: " + t.toString());
@ -387,60 +371,6 @@ public class BSFormatter {
return decimalFormat.format(MathUtils.roundDouble(value * 100.0, 2)).replace(",", ".");
}
public static double parseNumberStringToDouble(String input) throws NumberFormatException {
return Double.parseDouble(cleanDoubleInput(input));
}
public static double parsePercentStringToDouble(String percentString) throws NumberFormatException {
String input = percentString.replace("%", "");
input = cleanDoubleInput(input);
double value = Double.parseDouble(input);
return MathUtils.roundDouble(value / 100d, 4);
}
public static long parsePriceStringToLong(BSFormatter bsFormatter,
String currencyCode,
String amount,
int precision) {
if (amount == null || amount.isEmpty())
return 0;
long value = 0;
try {
double amountValue = Double.parseDouble(amount);
amount = BSFormatter.formatRoundedDoubleWithPrecision(amountValue, precision);
value = Price.parse(currencyCode, amount).getValue();
} catch (NumberFormatException ignore) {
// expected NumberFormatException if input is not a number
} catch (Throwable t) {
log.error("parsePriceStringToLong: " + t.toString());
}
return value;
}
public static String convertCharsForNumber(String input) {
// Some languages like finnish use the long dash for the minus
input = input.replace("", "-");
input = StringUtils.deleteWhitespace(input);
return input.replace(",", ".");
}
public static String cleanDoubleInput(String input) {
input = convertCharsForNumber(input);
if (input.equals("."))
input = input.replace(".", "0.");
if (input.equals("-."))
input = input.replace("-.", "-0.");
// don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific
// notation (1.0E-6) which screw up coinFormat.parse
//noinspection ResultOfMethodCallIgnored
// Just called to check if we have a valid double, throws exception otherwise
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(input);
return input;
}
public static String formatDurationAsWords(long durationMillis) {
return formatDurationAsWords(durationMillis, false, true);
}

View file

@ -61,12 +61,12 @@ public class BsqFormatter extends BSFormatter {
GlobalSettings.localeProperty().addListener((observable, oldValue, newValue) -> setFormatter(newValue));
setFormatter(GlobalSettings.getLocale());
btcCoinFormat = super.coinFormat;
btcCoinFormat = super.monetaryFormat;
final String baseCurrencyCode = BisqEnvironment.getBaseCurrencyNetwork().getCurrencyCode();
switch (baseCurrencyCode) {
case "BTC":
coinFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2);
monetaryFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2);
break;
default:
throw new RuntimeException("baseCurrencyCode not defined. baseCurrencyCode=" + baseCurrencyCode);
@ -123,11 +123,11 @@ public class BsqFormatter extends BSFormatter {
}
public String formatBSQSatoshis(long satoshi) {
return super.formatCoin(satoshi, coinFormat);
return super.formatCoin(satoshi, monetaryFormat);
}
public String formatBSQSatoshisWithCode(long satoshi) {
return super.formatCoinWithCode(satoshi, coinFormat);
return super.formatCoinWithCode(satoshi, monetaryFormat);
}
public String formatBTCSatoshis(long satoshi) {
@ -147,7 +147,7 @@ public class BsqFormatter extends BSFormatter {
}
public Coin parseToBTC(String input) {
return super.parseToCoin(input, btcCoinFormat);
return ParsingUtils.parseToCoin(input, btcCoinFormat);
}
public void validateBtcInput(String input) throws ProposalValidationException {
@ -155,12 +155,12 @@ public class BsqFormatter extends BSFormatter {
}
public void validateBsqInput(String input) throws ProposalValidationException {
validateCoinInput(input, this.coinFormat);
validateCoinInput(input, this.monetaryFormat);
}
private void validateCoinInput(String input, MonetaryFormat coinFormat) throws ProposalValidationException {
try {
coinFormat.parse(cleanDoubleInput(input));
coinFormat.parse(ParsingUtils.cleanDoubleInput(input));
} catch (Throwable t) {
throw new ProposalValidationException("Invalid format for a " + coinFormat.code() + " value");
}
@ -172,11 +172,11 @@ public class BsqFormatter extends BSFormatter {
// In case we add a new param old clients will not know that enum and fall back to UNDEFINED.
return Res.get("shared.na");
case BSQ:
return formatCoinWithCode(parseToCoin(value));
return formatCoinWithCode(ParsingUtils.parseToCoin(value, this));
case BTC:
return formatBTCWithCode(parseToBTC(value));
case PERCENT:
return formatToPercentWithSymbol(parsePercentStringToDouble(value));
return formatToPercentWithSymbol(ParsingUtils.parsePercentStringToDouble(value));
case BLOCK:
return Res.get("dao.param.blocks", Integer.parseInt(value));
case ADDRESS:
@ -190,7 +190,7 @@ public class BsqFormatter extends BSFormatter {
public Coin parseParamValueToCoin(Param param, String inputValue) {
switch (param.getParamType()) {
case BSQ:
return parseToCoin(inputValue);
return ParsingUtils.parseToCoin(inputValue, this);
case BTC:
return parseToBTC(inputValue);
default:
@ -216,7 +216,7 @@ public class BsqFormatter extends BSFormatter {
case BTC:
return formatBTC(parseParamValueToCoin(param, inputValue));
case PERCENT:
return formatToPercent(parsePercentStringToDouble(inputValue));
return formatToPercent(ParsingUtils.parsePercentStringToDouble(inputValue));
case BLOCK:
return Integer.toString(parseParamValueToBlocks(param, inputValue));
case ADDRESS:

View file

@ -0,0 +1,83 @@
package bisq.core.util;
import bisq.core.monetary.Price;
import bisq.common.util.MathUtils;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.MonetaryFormat;
import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ParsingUtils {
public static Coin parseToCoin(String input, BSFormatter bsFormatter) {
return parseToCoin(input, bsFormatter.getMonetaryFormat());
}
public static Coin parseToCoin(String input, MonetaryFormat coinFormat) {
if (input != null && input.length() > 0) {
try {
return coinFormat.parse(cleanDoubleInput(input));
} catch (Throwable t) {
log.warn("Exception at parseToBtc: " + t.toString());
return Coin.ZERO;
}
} else {
return Coin.ZERO;
}
}
public static double parseNumberStringToDouble(String input) throws NumberFormatException {
return Double.parseDouble(cleanDoubleInput(input));
}
public static double parsePercentStringToDouble(String percentString) throws NumberFormatException {
String input = percentString.replace("%", "");
input = cleanDoubleInput(input);
double value = Double.parseDouble(input);
return MathUtils.roundDouble(value / 100d, 4);
}
public static long parsePriceStringToLong(String currencyCode, String amount, int precision) {
if (amount == null || amount.isEmpty())
return 0;
long value = 0;
try {
double amountValue = Double.parseDouble(amount);
amount = BSFormatter.formatRoundedDoubleWithPrecision(amountValue, precision);
value = Price.parse(currencyCode, amount).getValue();
} catch (NumberFormatException ignore) {
// expected NumberFormatException if input is not a number
} catch (Throwable t) {
log.error("parsePriceStringToLong: " + t.toString());
}
return value;
}
public static String convertCharsForNumber(String input) {
// Some languages like finnish use the long dash for the minus
input = input.replace("", "-");
input = StringUtils.deleteWhitespace(input);
return input.replace(",", ".");
}
public static String cleanDoubleInput(String input) {
input = convertCharsForNumber(input);
if (input.equals("."))
input = input.replace(".", "0.");
if (input.equals("-."))
input = input.replace("-.", "-0.");
// don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific
// notation (1.0E-6) which screw up coinFormat.parse
//noinspection ResultOfMethodCallIgnored
// Just called to check if we have a valid double, throws exception otherwise
//noinspection ResultOfMethodCallIgnored
Double.parseDouble(input);
return input;
}
}

View file

@ -48,6 +48,7 @@ import bisq.core.provider.price.PriceFeedService;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.InputValidator;
import bisq.common.UserThread;
@ -347,7 +348,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
private void onAddMarketAlert() {
PaymentAccount paymentAccount = paymentAccountsComboBox.getSelectionModel().getSelectedItem();
double percentAsDouble = BSFormatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText());
double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText());
int triggerValue = (int) Math.round(percentAsDouble * 10000);
boolean isBuyOffer = offerTypeRadioButtonsToggleGroup.getSelectedToggle() == buyOffersRadioButton;
MarketAlertFilter marketAlertFilter = new MarketAlertFilter(paymentAccount, triggerValue, isBuyOffer);
@ -510,7 +511,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
marketAlertTriggerFocusListener = (observable, oldValue, newValue) -> {
if (oldValue && !newValue) {
try {
double percentAsDouble = BSFormatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100;
double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100;
marketAlertTriggerInputTextField.setText(BSFormatter.formatRoundedDoubleWithPrecision(percentAsDouble, 2) + "%");
} catch (Throwable ignore) {
}
@ -747,7 +748,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
try {
String inputValue = inputTextField.getText();
if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) {
double priceAsDouble = BSFormatter.parseNumberStringToDouble(inputValue);
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue);
String currencyCode = selectedPriceAlertTradeCurrency;
int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ?
Altcoin.SMALLEST_UNIT_EXPONENT : 2;
@ -755,7 +756,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
// E.g. if input is 5555.5555 it will be rounded to 5555.55 and we use that as the value for comparing
// low and high price...
String stringValue = BSFormatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision);
return BSFormatter.parsePriceStringToLong(formatter, currencyCode, stringValue, precision);
return ParsingUtils.parsePriceStringToLong(currencyCode, stringValue, precision);
} else {
return 0;
}
@ -768,7 +769,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
try {
String inputValue = inputTextField.getText();
if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) {
double priceAsDouble = BSFormatter.parseNumberStringToDouble(inputValue);
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue);
String currencyCode = selectedPriceAlertTradeCurrency;
int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ?
Altcoin.SMALLEST_UNIT_EXPONENT : 2;

View file

@ -38,6 +38,7 @@ import bisq.core.dao.governance.bond.reputation.MyBondedReputation;
import bisq.core.locale.Res;
import bisq.core.user.Preferences;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.HexStringValidator;
import bisq.core.util.validation.IntegerValidator;
@ -170,7 +171,7 @@ public class MyReputationView extends ActivatableView<GridPane, Void> implements
bsqWalletService.addBsqBalanceListener(this);
lockupButton.setOnAction((event) -> {
Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText());
Coin lockupAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
int lockupTime = Integer.parseInt(timeInputTextField.getText());
byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText());
bondingViewUtils.lockupBondForReputation(lockupAmount,

View file

@ -36,6 +36,7 @@ import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.common.app.DevEnv;
@ -273,7 +274,7 @@ public class AssetFeeView extends ActivatableView<GridPane, Void> implements Bsq
}
private Coin getListingFee() {
return bsqFormatter.parseToCoin(feeAmountInputTextField.getText());
return ParsingUtils.parseToCoin(feeAmountInputTextField.getText(), bsqFormatter);
}
private void doPublishFeeTx(Transaction transaction) {

View file

@ -38,6 +38,7 @@ import bisq.core.locale.Res;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.InputValidator;
import bisq.common.app.DevEnv;
@ -273,7 +274,7 @@ public class ProofOfBurnView extends ActivatableView<GridPane, Void> implements
}
private Coin getAmountFee() {
return bsqFormatter.parseToCoin(amountInputTextField.getText());
return ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
}
private void doPublishFeeTx(Transaction transaction, String preImageAsString) {

View file

@ -52,6 +52,7 @@ import bisq.core.dao.state.model.governance.Role;
import bisq.core.locale.Res;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.asset.Asset;
@ -395,13 +396,13 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
"proposalDisplay.requestedBsqTextField must not be null");
return daoFacade.getCompensationProposalWithTransaction(name,
link,
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter));
case REIMBURSEMENT_REQUEST:
checkNotNull(proposalDisplay.requestedBsqTextField,
"proposalDisplay.requestedBsqTextField must not be null");
return daoFacade.getReimbursementProposalWithTransaction(name,
link,
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter));
case CHANGE_PARAM:
checkNotNull(proposalDisplay.paramComboBox,
"proposalDisplay.paramComboBox must no tbe null");

View file

@ -55,6 +55,7 @@ import bisq.core.locale.Res;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.common.UserThread;
import bisq.common.app.DevEnv;
@ -463,7 +464,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
}
private void onVote() {
Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText());
Coin stake = ParsingUtils.parseToCoin(stakeInputTextField.getText(), bsqFormatter);
try {
// We create a dummy tx to get the miningFee for displaying it at the confirmation popup
Tuple2<Coin, Integer> miningFeeAndTxSize = daoFacade.getBlindVoteMiningFeeAndTxSize(stake);

View file

@ -47,6 +47,7 @@ import bisq.core.locale.Res;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.CoinUtil;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.BtcAddressValidator;
import bisq.network.p2p.P2PService;
@ -234,7 +235,7 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
// TODO break up in methods
if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) {
String receiversAddressString = bsqFormatter.getAddressFromBsqAddress(receiversAddressInputTextField.getText()).toString();
Coin receiverAmount = bsqFormatter.parseToCoin(amountInputTextField.getText());
Coin receiverAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
try {
Transaction preparedSendTx = bsqWalletService.getPreparedSendBsqTx(receiversAddressString, receiverAmount);
Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true);

View file

@ -36,6 +36,7 @@ import bisq.core.locale.Res;
import bisq.core.provider.fee.FeeService;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import bisq.common.UserThread;
import bisq.common.app.DevEnv;
@ -232,7 +233,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
walletService.addBalanceListener(balanceListener);
amountTextFieldSubscription = EasyBind.subscribe(amountTextField.textProperty(), t -> {
addressTextField.setAmountAsCoin(formatter.parseToCoin(t));
addressTextField.setAmountAsCoin(ParsingUtils.parseToCoin(t, formatter));
updateQRCode();
});
@ -301,7 +302,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
}
private Coin getAmountAsCoin() {
return formatter.parseToCoin(amountTextField.getText());
return ParsingUtils.parseToCoin(amountTextField.getText(), formatter);
}
@NotNull

View file

@ -41,6 +41,7 @@ import bisq.core.trade.TradeManager;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.CoinUtil;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.BtcAddressValidator;
import bisq.network.p2p.P2PService;
@ -246,7 +247,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
amountListener = (observable, oldValue, newValue) -> {
if (amountTextField.focusedProperty().get()) {
try {
amountAsCoin = formatter.parseToCoin(amountTextField.getText());
amountAsCoin = ParsingUtils.parseToCoin(amountTextField.getText(), formatter);
} catch (Throwable t) {
log.error("Error at amountTextField input. " + t.toString());
}

View file

@ -53,6 +53,7 @@ import bisq.core.provider.price.PriceFeedService;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.BsqFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.InputValidator;
import bisq.network.p2p.P2PService;
@ -316,7 +317,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (marketPrice != null && marketPrice.isRecentExternalPriceAvailable()) {
double marketPriceAsDouble = marketPrice.getPrice();
try {
double priceAsDouble = BSFormatter.parseNumberStringToDouble(price.get());
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(price.get());
double relation = priceAsDouble / marketPriceAsDouble;
final OfferPayload.Direction compareDirection = CurrencyUtil.isCryptoCurrency(currencyCode) ?
OfferPayload.Direction.SELL :
@ -342,7 +343,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (inputIsMarketBasedPrice) {
try {
if (!newValue.isEmpty() && !newValue.equals("-")) {
double percentage = BSFormatter.parsePercentStringToDouble(newValue);
double percentage = ParsingUtils.parsePercentStringToDouble(newValue);
if (percentage >= 1 || percentage <= -1) {
new Popup<>().warning(Res.get("popup.warning.tooLargePercentageValue") + "\n" +
Res.get("popup.warning.examplePercentageValue"))
@ -866,7 +867,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
if (result.isValid) {
double defaultSecurityDeposit = Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount());
String key = "buyerSecurityDepositIsLowerAsDefault";
double depositAsDouble = BSFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get());
double depositAsDouble = ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get());
if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) {
String postfix = dataModel.isBuyOffer() ?
Res.get("createOffer.tooLowSecDeposit.makerIsBuyer") :
@ -906,7 +907,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
public boolean isPriceInRange() {
if (marketPriceMargin.get() != null && !marketPriceMargin.get().isEmpty()) {
if (Math.abs(BSFormatter.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) {
if (Math.abs(ParsingUtils.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) {
displayPriceOutOfRangePopup();
return false;
} else {
@ -1130,7 +1131,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
private void setBuyerSecurityDepositToModel() {
if (buyerSecurityDeposit.get() != null && !buyerSecurityDeposit.get().isEmpty()) {
dataModel.setBuyerSecurityDeposit(BSFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get()));
dataModel.setBuyerSecurityDeposit(ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get()));
} else {
dataModel.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount()));
}

View file

@ -37,6 +37,7 @@ import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.trade.Contract;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import bisq.common.UserThread;
import bisq.common.util.Tuple2;
@ -357,8 +358,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
}
private boolean isPayoutAmountValid() {
Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText());
Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText());
Coin buyerAmount = ParsingUtils.parseToCoin(buyerPayoutAmountInputTextField.getText(), formatter);
Coin sellerAmount = ParsingUtils.parseToCoin(sellerPayoutAmountInputTextField.getText(), formatter);
Contract contract = dispute.getContract();
Coin tradeAmount = contract.getTradeAmount();
Offer offer = new Offer(contract.getOfferPayload());
@ -371,8 +372,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
private void applyCustomAmounts(InputTextField inputTextField) {
Contract contract = dispute.getContract();
Coin buyerAmount = formatter.parseToCoin(buyerPayoutAmountInputTextField.getText());
Coin sellerAmount = formatter.parseToCoin(sellerPayoutAmountInputTextField.getText());
Coin buyerAmount = ParsingUtils.parseToCoin(buyerPayoutAmountInputTextField.getText(), formatter);
Coin sellerAmount = ParsingUtils.parseToCoin(sellerPayoutAmountInputTextField.getText(), formatter);
Offer offer = new Offer(contract.getOfferPayload());
Coin available = contract.getTradeAmount().
add(offer.getBuyerSecurityDeposit())

View file

@ -47,6 +47,7 @@ import bisq.core.provider.fee.FeeService;
import bisq.core.user.BlockChainExplorer;
import bisq.core.user.Preferences;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.IntegerValidator;
import bisq.common.UserThread;
@ -314,7 +315,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
deviationListener = (observable, oldValue, newValue) -> {
try {
double value = BSFormatter.parsePercentStringToDouble(newValue);
double value = ParsingUtils.parsePercentStringToDouble(newValue);
final double maxDeviation = 0.5;
if (value <= maxDeviation) {
preferences.setMaxPriceDistanceInPercent(value);

View file

@ -9,6 +9,7 @@ import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Monetary;
@ -265,7 +266,7 @@ public class DisplayUtils {
*/
public static Coin parseToCoinWith4Decimals(String input, BSFormatter bsFormatter) {
try {
return Coin.valueOf(new BigDecimal(bsFormatter.parseToCoin(BSFormatter.cleanDoubleInput(input)).value).setScale(-scale - 1,
return Coin.valueOf(new BigDecimal(ParsingUtils.parseToCoin(ParsingUtils.cleanDoubleInput(input), bsFormatter).value).setScale(-scale - 1,
BigDecimal.ROUND_HALF_UP).setScale(scale + 1, BigDecimal.ROUND_HALF_UP).toBigInteger().longValue());
} catch (Throwable t) {
if (input != null && input.length() > 0)
@ -275,7 +276,7 @@ public class DisplayUtils {
}
public static boolean hasBtcValidDecimals(String input, BSFormatter bsFormatter) {
return bsFormatter.parseToCoin(input).equals(parseToCoinWith4Decimals(input, bsFormatter));
return ParsingUtils.parseToCoin(input, bsFormatter).equals(parseToCoinWith4Decimals(input, bsFormatter));
}
/**
@ -286,6 +287,6 @@ public class DisplayUtils {
* @return The transformed coin
*/
public static Coin reduceTo4Decimals(Coin coin, BSFormatter bsFormatter) {
return bsFormatter.parseToCoin(bsFormatter.formatCoin(coin));
return ParsingUtils.parseToCoin(bsFormatter.formatCoin(coin), bsFormatter);
}
}

View file

@ -21,6 +21,7 @@ import bisq.core.btc.wallet.Restrictions;
import bisq.core.locale.Res;
import bisq.core.util.BsqFormatter;
import bisq.core.util.CoinUtil;
import bisq.core.util.ParsingUtils;
import org.bitcoinj.core.Coin;
@ -53,7 +54,7 @@ public class BsqValidator extends AltcoinValidator {
public BsqValidator(BsqFormatter bsqFormatter) {
this.bsqFormatter = bsqFormatter;
// Limit to avoid overflows
setMaxValue(bsqFormatter.parseToCoin("10000000"));
setMaxValue(ParsingUtils.parseToCoin("10000000", bsqFormatter));
}
public void setMinValue(@NotNull Coin minValue) {
@ -94,7 +95,7 @@ public class BsqValidator extends AltcoinValidator {
}
private ValidationResult validateIfAboveDust(String input) {
final Coin coin = bsqFormatter.parseToCoin(input);
final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter);
if (Restrictions.isAboveDust(coin))
return new ValidationResult(true);
else
@ -113,7 +114,7 @@ public class BsqValidator extends AltcoinValidator {
private ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
try {
final Coin coin = bsqFormatter.parseToCoin(input);
final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter);
if (maxValue != null && coin.compareTo(maxValue) > 0)
return new ValidationResult(false, Res.get("validation.btc.toLarge", bsqFormatter.formatCoinWithCode(maxValue)));
else
@ -125,7 +126,7 @@ public class BsqValidator extends AltcoinValidator {
private ValidationResult validateIfSufficientAvailableBalance(String input) {
try {
final Coin coin = bsqFormatter.parseToCoin(input);
final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter);
if (availableBalance != null && availableBalance.compareTo(coin) < 0)
return new ValidationResult(false, Res.get("validation.bsq.insufficientBalance",
bsqFormatter.formatCoinWithCode(availableBalance)));
@ -138,7 +139,7 @@ public class BsqValidator extends AltcoinValidator {
private ValidationResult validateIfNotBelowMinValue(String input) {
try {
final Coin coin = bsqFormatter.parseToCoin(input);
final Coin coin = ParsingUtils.parseToCoin(input, bsqFormatter);
if (minValue != null && coin.compareTo(minValue) < 0)
return new ValidationResult(false, Res.get("validation.bsq.amountBelowMinAmount",
bsqFormatter.formatCoinWithCode(minValue)));

View file

@ -18,7 +18,7 @@
package bisq.desktop.util.validation;
import bisq.core.locale.Res;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import bisq.core.util.validation.InputValidator;
/**
@ -30,7 +30,7 @@ import bisq.core.util.validation.InputValidator;
public abstract class NumberValidator extends InputValidator {
protected String cleanInput(String input) {
return BSFormatter.convertCharsForNumber(input);
return ParsingUtils.convertCharsForNumber(input);
}
protected ValidationResult validateIfNumber(String input) {

View file

@ -21,6 +21,7 @@ import bisq.core.btc.wallet.Restrictions;
import bisq.core.locale.Res;
import bisq.core.payment.PaymentAccount;
import bisq.core.util.BSFormatter;
import bisq.core.util.ParsingUtils;
import javax.inject.Inject;
@ -58,7 +59,7 @@ public class SecurityDepositValidator extends NumberValidator {
private ValidationResult validateIfNotTooLowPercentageValue(String input) {
try {
double percentage = BSFormatter.parsePercentStringToDouble(input);
double percentage = ParsingUtils.parsePercentStringToDouble(input);
double minPercentage = Restrictions.getMinBuyerSecurityDepositAsPercent(paymentAccount);
if (percentage < minPercentage)
return new ValidationResult(false,
@ -72,7 +73,7 @@ public class SecurityDepositValidator extends NumberValidator {
private ValidationResult validateIfNotTooHighPercentageValue(String input) {
try {
double percentage = BSFormatter.parsePercentStringToDouble(input);
double percentage = ParsingUtils.parsePercentStringToDouble(input);
double maxPercentage = Restrictions.getMaxBuyerSecurityDepositAsPercent(paymentAccount);
if (percentage > maxPercentage)
return new ValidationResult(false,