/** * Obtains an instance of {@code BigMoney} from a provider. * <p> * This allows you to create an instance from any class that implements the * provider, such as {@code Money}. * This method simply calls {@link BigMoneyProvider#toBigMoney()} checking for nulls. * * @param moneyProvider the money to convert, not null * @return the new instance, never null */ public static BigMoney of(BigMoneyProvider moneyProvider) { MoneyUtils.checkNotNull(moneyProvider, "BigMoneyProvider must not be null"); BigMoney money = moneyProvider.toBigMoney(); MoneyUtils.checkNotNull(money, "BigMoneyProvider must not return null"); return money; }
/** * Obtains an instance of {@code BigMoney} from a {@code double} using a * well-defined conversion, rounding as necessary. * <p> * This allows you to create an instance with a specific currency and amount. * If the amount has a scale in excess of the scale of the currency then the excess * fractional digits are rounded using the rounding mode. * The result will have a minimum scale of zero. * * @param currency the currency, not null * @param amount the amount of money, not null * @param scale the scale to use, zero or positive * @param roundingMode the rounding mode to use, not null * @return the new instance, never null * @throws ArithmeticException if the rounding fails */ public static BigMoney ofScale(CurrencyUnit currency, BigDecimal amount, int scale, RoundingMode roundingMode) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); amount = amount.setScale(scale, roundingMode); return BigMoney.of(currency, amount); }
/** * Obtains an instance of {@code CurrencyUnit} matching the specified JDK currency. * <p> * This converts the JDK currency instance to a currency unit using the code. * * @param currency the currency, not null * @return the singleton instance, never null * @throws IllegalCurrencyException if the currency is unknown */ public static CurrencyUnit of(Currency currency) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); return of(currency.getCurrencyCode()); }
/** * Obtains an instance of {@code Money} as the total value of an array. * <p> * The array must contain at least one monetary value. * Subsequent amounts are added as though using {@link #plus(Money)}. * All amounts must be in the same currency. * * @param monies the monetary values to total, not empty, no null elements, not null * @return the total, never null * @throws IllegalArgumentException if the array is empty * @throws CurrencyMismatchException if the currencies differ */ public static Money total(Money... monies) { MoneyUtils.checkNotNull(monies, "Money array must not be null"); if (monies.length == 0) { throw new IllegalArgumentException("Money array must not be empty"); } Money total = monies[0]; MoneyUtils.checkNotNull(total, "Money arary must not contain null entries"); for (int i = 1; i < monies.length; i++) { total = total.plus(monies[i]); } return total; }
/** * Returns a copy of this monetary value divided by the specified value * using the specified rounding mode to adjust the scale. * <p> * The result has the same scale as this instance. * For example, 'USD 1.13' divided by '2.5' and rounding down gives 'USD 0.45' * (amount rounded down from 0.452). * <p> * This instance is immutable and unaffected by this method. * * @param valueToDivideBy the scalar value to divide by, not null * @param roundingMode the rounding mode to use, not null * @return the new divided instance, never null * @throws ArithmeticException if dividing by zero * @throws ArithmeticException if the rounding fails */ public BigMoney dividedBy(BigDecimal valueToDivideBy, RoundingMode roundingMode) { MoneyUtils.checkNotNull(valueToDivideBy, "Divisor must not be null"); MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); if (valueToDivideBy.compareTo(BigDecimal.ONE) == 0) { return this; } BigDecimal newAmount = amount.divide(valueToDivideBy, roundingMode); return BigMoney.of(currency, newAmount); }
/** * Obtains an instance of {@code CurrencyUnit} for the specified locale. * <p> * Only the country is used from the locale. * * @param locale the locale, not null * @return the singleton instance, never null * @throws IllegalCurrencyException if the currency is unknown */ public static CurrencyUnit of(Locale locale) { MoneyUtils.checkNotNull(locale, "Locale must not be null"); CurrencyUnit currency = currenciesByCountry.get(locale.getCountry()); if (currency == null) { throw new IllegalCurrencyException("Unknown currency for locale '" + locale + '\''); } return currency; }
/** * Returns a copy of this monetary value with the specified amount. * <p> * The returned instance will have this currency and the new amount. * The scale of the returned instance will be that of the specified BigDecimal. * <p> * This instance is immutable and unaffected by this method. * * @param amount the monetary amount to set in the returned instance, not null * @return the new instance with the input amount set, never null */ public BigMoney withAmount(BigDecimal amount) { MoneyUtils.checkNotNull(amount, "Amount must not be null"); if (this.amount.equals(amount)) { return this; } return BigMoney.of(currency, amount); }
/** * Obtains an instance of {@code CurrencyUnit} for the specified ISO-3166 country code. * <p> * Country codes should generally be in upper case. * This method is case sensitive. * * @param countryCode the country code, typically ISO-3166, not null * @return the singleton instance, never null * @throws IllegalCurrencyException if the currency is unknown */ public static CurrencyUnit ofCountry(String countryCode) { MoneyUtils.checkNotNull(countryCode, "Country code must not be null"); CurrencyUnit currency = currenciesByCountry.get(countryCode); if (currency == null) { throw new IllegalCurrencyException("Unknown currency for country '" + countryCode + '\''); } return currency; }
/** * Obtains an instance of {@code BigMoney} from an amount in major units. * <p> * This allows you to create an instance with a specific currency and amount. * The scale of the money will be zero. * <p> * The amount is a whole number only. Thus you can initialise the value * 'USD 20', but not the value 'USD 20.32'. * For example, {@code ofMajor(USD, 25)} creates the instance {@code USD 25}. * * @param currency the currency, not null * @param amountMajor the amount of money in the major division of the currency * @return the new instance, never null */ public static BigMoney ofMajor(CurrencyUnit currency, long amountMajor) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); return BigMoney.of(currency, BigDecimal.valueOf(amountMajor)); }
/** * Obtains an instance of {@code BigMoney} from a scaled amount. * <p> * This allows you to create an instance with a specific currency, amount and scale. * The amount is defined in terms of the specified scale. * The result will have a minimum scale of zero. * <p> * For example, {@code ofScale(USD, 234, 2)} creates the instance {@code USD 2.34}. * * @param currency the currency, not null * @param unscaledAmount the unscaled amount of money * @param scale the scale to use * @return the new instance, never null */ public static BigMoney ofScale(CurrencyUnit currency, long unscaledAmount, int scale) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); return BigMoney.of(currency, BigDecimal.valueOf(unscaledAmount, scale)); }
/** * Returns a copy of this monetary value with the specified currency. * <p> * The returned instance will have the specified currency and the amount * from this instance. No currency conversion or alteration to the scale occurs. * <p> * This instance is immutable and unaffected by this method. * * @param currency the currency to use, not null * @return the new instance with the input currency set, never null */ public BigMoney withCurrencyUnit(CurrencyUnit currency) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); if (this.currency == currency) { return this; } return new BigMoney(currency, amount); }
/** * Obtains an instance of {@code Money} as the total value of a collection. * <p> * The iterable must provide at least one monetary value. * Subsequent amounts are added as though using {@link #plus(Money)}. * All amounts must be in the same currency. * * @param monies the monetary values to total, not empty, no null elements, not null * @return the total, never null * @throws IllegalArgumentException if the iterable is empty * @throws CurrencyMismatchException if the currencies differ */ public static Money total(Iterable<Money> monies) { MoneyUtils.checkNotNull(monies, "Money iterator must not be null"); Iterator<Money> it = monies.iterator(); if (it.hasNext() == false) { throw new IllegalArgumentException("Money iterator must not be empty"); } Money total = it.next(); MoneyUtils.checkNotNull(total, "Money iterator must not contain null entries"); while (it.hasNext()) { total = total.plus(it.next()); } return total; }
/** * Gets the symbol for this locale from the JDK. * <p> * If this currency doesn't have a JDK equivalent, then the currency code * is returned. * <p> * This method matches the API of {@link Currency}. * * @param locale the locale to get the symbol for, not null * @return the JDK currency instance, never null */ public String getSymbol(Locale locale) { MoneyUtils.checkNotNull(locale, "Locale must not be null"); try { return Currency.getInstance(code).getSymbol(locale); } catch (IllegalArgumentException ex) { return code; } }
/** * Obtains an instance of {@code BigMoney} from a {@code double} using a well-defined conversion. * <p> * This allows you to create an instance with a specific currency and amount. * <p> * The amount is converted via {@link BigDecimal#valueOf(double)} which yields * the most expected answer for most programming scenarios. * Any {@code double} literal in code will be converted to * exactly the same BigDecimal with the same scale. * For example, the literal '1.425d' will be converted to '1.425'. * The scale of the money will be that of the BigDecimal produced, with trailing zeroes stripped, * and with a minimum scale of zero. * * @param currency the currency, not null * @param amount the amount of money, not null * @return the new instance, never null */ public static BigMoney of(CurrencyUnit currency, double amount) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); return BigMoney.of(currency, BigDecimal.valueOf(amount).stripTrailingZeros()); }
/** * Returns a copy of this monetary value multiplied by the specified value. * <p> * No precision is lost in the result. * The result has a scale equal to the sum of the two scales. * For example, 'USD 1.13' multiplied by '2.5' gives 'USD 2.825'. * <p> * This instance is immutable and unaffected by this method. * * @param valueToMultiplyBy the scalar value to multiply by, not null * @return the new multiplied instance, never null */ public BigMoney multipliedBy(BigDecimal valueToMultiplyBy) { MoneyUtils.checkNotNull(valueToMultiplyBy, "Multiplier must not be null"); if (valueToMultiplyBy.compareTo(BigDecimal.ONE) == 0) { return this; } BigDecimal newAmount = amount.multiply(valueToMultiplyBy); return BigMoney.of(currency, newAmount); }
/** * Returns a copy of this monetary value with the amount added. * <p> * This adds the specified amount to this monetary amount, returning a new object. * <p> * No precision is lost in the result. * The scale of the result will be the maximum of the two scales. * For example, 'USD 25.95' plus '3.021' gives 'USD 28.971'. * <p> * This instance is immutable and unaffected by this method. * * @param amountToAdd the monetary value to add, not null * @return the new instance with the input amount added, never null */ public BigMoney plus(BigDecimal amountToAdd) { MoneyUtils.checkNotNull(amountToAdd, "Amount must not be null"); if (amountToAdd.compareTo(BigDecimal.ZERO) == 0) { return this; } BigDecimal newAmount = amount.add(amountToAdd); return BigMoney.of(currency, newAmount); }
/** * Obtains an instance of {@code Money} from a {@code BigDecimal}. * <p> * This allows you to create an instance with a specific currency and amount. * No rounding is performed on the amount, so it must have a scale compatible * with the currency. * * @param currency the currency, not null * @param amount the amount of money, not null * @return the new instance, never null * @throws ArithmeticException if the scale exceeds the currency scale */ public static Money of(CurrencyUnit currency, BigDecimal amount) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); if (amount.scale() > currency.getDecimalPlaces()) { throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency); } return Money.of(currency, amount, RoundingMode.UNNECESSARY); }
/** * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary. * <p> * This allows you to create an instance with a specific currency and amount. * If the amount has a scale in excess of the scale of the currency then the excess * fractional digits are rounded using the rounding mode. * * @param currency the currency, not null * @param amount the amount of money, not null * @param roundingMode the rounding mode to use, not null * @return the new instance, never null * @throws ArithmeticException if the rounding fails */ public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); amount = amount.setScale(currency.getDecimalPlaces(), roundingMode); return new Money(BigMoney.of(currency, amount)); }
/** * Obtains an instance of {@code BigMoney} from a {@code BigDecimal}. * <p> * This allows you to create an instance with a specific currency and amount. * The scale of the money will be that of the {@code BigDecimal}, with * a minimum scale of zero. * * @param currency the currency, not null * @param amount the amount of money, not null * @return the new instance, never null * @throws IllegalArgumentException if an invalid BigDecimal subclass has been used */ public static BigMoney of(CurrencyUnit currency, BigDecimal amount) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); if (amount.getClass() != BigDecimal.class) { BigInteger value = amount.unscaledValue(); if (value == null) { throw new IllegalArgumentException("Illegal BigDecimal subclass"); } if (value.getClass() != BigInteger.class) { value = new BigInteger(value.toString()); } amount = new BigDecimal(value, amount.scale()); } return new BigMoney(currency, amount); }
MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); MoneyUtils.checkNotNull(conversionMultipler, "Multiplier must not be null"); if (this.currency == currency) { if (conversionMultipler.compareTo(BigDecimal.ONE) == 0) {