/*
 * Copyright 2012-2016 Credit Suisse
 * Copyright 2018-2020 Werner Keil, Otavio Santana, Trivadis AG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package javax.money;

import javax.money.spi.*;

import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

Factory singleton for CurrencyUnit, MonetaryAmount and MonetaryRounding instances as provided by the different registered SPI instances.

This class is thread safe.

Author:Anatole Tresch
/** * Factory singleton for {@link CurrencyUnit}, {@link javax.money.MonetaryAmount} and * {@link javax.money.MonetaryRounding} instances as provided by the * different registered SPI instances. * <p> * This class is thread safe. * </p> * * @author Anatole Tresch */
public final class Monetary {
The used MonetaryCurrenciesSingletonSpi instance.
Returns:the used MonetaryCurrenciesSingletonSpi instance, never null
/** * The used {@link javax.money.spi.MonetaryCurrenciesSingletonSpi} instance. * * @return the used {@link javax.money.spi.MonetaryCurrenciesSingletonSpi} instance, * never {@code null} */
private static MonetaryCurrenciesSingletonSpi monetaryCurrenciesSingletonSpi() { try { return Optional.ofNullable(Bootstrap .getService(MonetaryCurrenciesSingletonSpi.class)).orElseGet( DefaultMonetaryCurrenciesSingletonSpi::new); } catch (Exception e) { Logger.getLogger(Monetary.class.getName()) .log(Level.INFO, "Failed to load MonetaryCurrenciesSingletonSpi, using default.", e); return new DefaultMonetaryCurrenciesSingletonSpi(); } }
The used MonetaryAmountsSingletonSpi instance.
/** * The used {@link javax.money.spi.MonetaryAmountsSingletonSpi} instance. */
private static MonetaryAmountsSingletonSpi monetaryAmountsSingletonSpi() { try { return Bootstrap.getService(MonetaryAmountsSingletonSpi.class); } catch (Exception e) { Logger.getLogger(Monetary.class.getName()) .log(Level.SEVERE, "Failed to load MonetaryAmountsSingletonSpi.", e); return null; } }
The used MonetaryAmountsSingletonSpi instance.
/** * The used {@link javax.money.spi.MonetaryAmountsSingletonSpi} instance. */
private static MonetaryAmountsSingletonQuerySpi monetaryAmountsSingletonQuerySpi() { try { return Bootstrap.getService(MonetaryAmountsSingletonQuerySpi.class); } catch (Exception e) { Logger.getLogger(Monetary.class.getName()).log(Level.SEVERE, "Failed to load " + "MonetaryAmountsSingletonQuerySpi, " + "query functionality will not be " + "available.", e); return null; } }
The used MonetaryCurrenciesSingletonSpi instance.
Returns:the used MonetaryCurrenciesSingletonSpi instance, never null
/** * The used {@link javax.money.spi.MonetaryCurrenciesSingletonSpi} instance. * * @return the used {@link javax.money.spi.MonetaryCurrenciesSingletonSpi} instance, * never {@code null} */
private static MonetaryRoundingsSingletonSpi monetaryRoundingsSingletonSpi() { try { return Optional.ofNullable(Bootstrap .getService(MonetaryRoundingsSingletonSpi.class)) .orElseGet(DefaultMonetaryRoundingsSingletonSpi::new); } catch (Exception e) { Logger.getLogger(Monetary.class.getName()) .log(Level.SEVERE, "Failed to load MonetaryCurrenciesSingletonSpi, using default.", e); return new DefaultMonetaryRoundingsSingletonSpi(); } }
Private singletons constructor.
/** * Private singletons constructor. */
private Monetary() { }
Allows to access the names of the current registered providers.
Returns:the set of provider names, never null.
/** * Allows to access the names of the current registered providers. * * @return the set of provider names, never {@code null}. */
public static Set<String> getRoundingProviderNames() { return monetaryRoundingsSingletonSpi() .getProviderNames(); }
Allows to access the default providers chain used if no provider chain was passed explicitly..
Returns:the chained list of provider names, never null.
/** * Allows to access the default providers chain used if no provider chain was passed explicitly.. * * @return the chained list of provider names, never {@code null}. */
public static List<String> getDefaultRoundingProviderChain() { return monetaryRoundingsSingletonSpi() .getDefaultProviderChain(); }
Creates a rounding that can be added as MonetaryOperator to chained calculations. The instance will lookup the concrete MonetaryOperator instance from the Monetary based on the input MonetaryAmount's CurrencyUnit.
Returns:the (shared) default rounding instance.
/** * Creates a rounding that can be added as {@link MonetaryOperator} to * chained calculations. The instance will lookup the concrete * {@link MonetaryOperator} instance from the {@link Monetary} * based on the input {@link MonetaryAmount}'s {@link CurrencyUnit}. * * @return the (shared) default rounding instance. */
public static MonetaryRounding getDefaultRounding() { return monetaryRoundingsSingletonSpi() .getDefaultRounding(); }
Creates an MonetaryOperator for rounding MonetaryAmount instances given a currency.
Params:
  • currencyUnit – The currency, which determines the required scale. As RoundingMode, by default, RoundingMode.HALF_UP is used.
  • providers – the providers and ordering to be used. By default providers and ordering as defined in #getDefaultProviders is used.
Returns:a new instance MonetaryOperator implementing the rounding, never null.
/** * Creates an {@link MonetaryOperator} for rounding {@link MonetaryAmount} * instances given a currency. * * @param currencyUnit The currency, which determines the required scale. As * {@link java.math.RoundingMode}, by default, {@link java.math.RoundingMode#HALF_UP} * is used. * @param providers the providers and ordering to be used. By default providers and ordering as defined in * #getDefaultProviders is used. * @return a new instance {@link MonetaryOperator} implementing the * rounding, never {@code null}. */
public static MonetaryRounding getRounding(CurrencyUnit currencyUnit, String... providers) { return monetaryRoundingsSingletonSpi() .getRounding(currencyUnit, providers); }
Access an MonetaryOperator for custom rounding MonetaryAmount instances.
Params:
  • roundingName – The rounding identifier.
  • providers – the providers and ordering to be used. By default providers and ordering as defined in #getDefaultProviders is used.
Throws:
Returns:the corresponding MonetaryOperator implementing the rounding, never null.
/** * Access an {@link MonetaryOperator} for custom rounding * {@link MonetaryAmount} instances. * * @param roundingName The rounding identifier. * @param providers the providers and ordering to be used. By default providers and ordering as defined in * #getDefaultProviders is used. * @return the corresponding {@link MonetaryOperator} implementing the * rounding, never {@code null}. * @throws IllegalArgumentException if no such rounding is registered using a * {@link javax.money.spi.RoundingProviderSpi} instance. */
public static MonetaryRounding getRounding(String roundingName, String... providers) { return monetaryRoundingsSingletonSpi() .getRounding(roundingName, providers); }
Access a MonetaryRounding using a possibly complex query.
Params:
  • roundingQuery – The RoundingQuery that may contains arbitrary parameters to be evaluated.
Throws:
Returns:the corresponding MonetaryRounding, never null.
/** * Access a {@link MonetaryRounding} using a possibly complex query. * * @param roundingQuery The {@link javax.money.RoundingQuery} that may contains arbitrary parameters to be * evaluated. * @return the corresponding {@link javax.money.MonetaryRounding}, never {@code null}. * @throws IllegalArgumentException if no such rounding is registered using a * {@link javax.money.spi.RoundingProviderSpi} instance. */
public static MonetaryRounding getRounding(RoundingQuery roundingQuery) { return monetaryRoundingsSingletonSpi() .getRounding(roundingQuery); }
Checks if a MonetaryRounding is available given a roundingId.
Params:
  • roundingName – The rounding identifier.
  • providers – the providers and ordering to be used. By default providers and ordering as defined in #getDefaultProviders is used.
Throws:
Returns:true, if a corresponding MonetaryRounding is available.
/** * Checks if a {@link MonetaryRounding} is available given a roundingId. * * @param roundingName The rounding identifier. * @param providers the providers and ordering to be used. By default providers and ordering as defined in * #getDefaultProviders is used. * @return true, if a corresponding {@link javax.money.MonetaryRounding} is available. * @throws IllegalArgumentException if no such rounding is registered using a * {@link javax.money.spi.RoundingProviderSpi} instance. */
public static boolean isRoundingAvailable(String roundingName, String... providers) { return monetaryRoundingsSingletonSpi() .isRoundingAvailable(roundingName, providers); }
Checks if a MonetaryRounding is available given a roundingId.
Params:
  • currencyUnit – The currency, which determines the required scale. As RoundingMode, by default, RoundingMode.HALF_UP is used.
  • providers – the providers and ordering to be used. By default providers and ordering as defined in #getDefaultProviders is used.
Throws:
Returns:true, if a corresponding MonetaryRounding is available.
/** * Checks if a {@link MonetaryRounding} is available given a roundingId. * * @param currencyUnit The currency, which determines the required scale. As {@link java.math.RoundingMode}, * by default, {@link java.math.RoundingMode#HALF_UP} is used. * @param providers the providers and ordering to be used. By default providers and ordering as defined in * #getDefaultProviders is used. * @return true, if a corresponding {@link javax.money.MonetaryRounding} is available. * @throws IllegalArgumentException if no such rounding is registered using a * {@link javax.money.spi.RoundingProviderSpi} instance. */
public static boolean isRoundingAvailable(CurrencyUnit currencyUnit, String... providers) { return monetaryRoundingsSingletonSpi() .isRoundingAvailable(currencyUnit, providers); }
Checks if a MonetaryRounding matching the query is available.
Params:
  • roundingQuery – The RoundingQuery that may contains arbitrary parameters to be evaluated.
Throws:
Returns:true, if a corresponding MonetaryRounding is available.
/** * Checks if a {@link MonetaryRounding} matching the query is available. * * @param roundingQuery The {@link javax.money.RoundingQuery} that may contains arbitrary parameters to be * evaluated. * @return true, if a corresponding {@link javax.money.MonetaryRounding} is available. * @throws IllegalArgumentException if no such rounding is registered using a * {@link javax.money.spi.RoundingProviderSpi} instance. */
public static boolean isRoundingAvailable(RoundingQuery roundingQuery) { return monetaryRoundingsSingletonSpi() .isRoundingAvailable(roundingQuery); }
Access multiple MonetaryRounding instances using a possibly complex query
Params:
  • roundingQuery – The RoundingQuery that may contains arbitrary parameters to be evaluated.
Returns:all MonetaryRounding instances matching the query, never null.
/** * Access multiple {@link MonetaryRounding} instances using a possibly complex query * * @param roundingQuery The {@link javax.money.RoundingQuery} that may contains arbitrary parameters to be * evaluated. * @return all {@link javax.money.MonetaryRounding} instances matching the query, never {@code null}. */
public static Collection<MonetaryRounding> getRoundings(RoundingQuery roundingQuery) { return monetaryRoundingsSingletonSpi() .getRoundings(roundingQuery); }
Allows to access the names of the current defined roundings.
Params:
  • providers – the providers and ordering to be used. By default providers and ordering as defined in #getDefaultProviders is used.
Returns:the set of custom rounding ids, never null.
/** * Allows to access the names of the current defined roundings. * * @param providers the providers and ordering to be used. By default providers and ordering as defined in * #getDefaultProviders is used. * @return the set of custom rounding ids, never {@code null}. */
public static Set<String> getRoundingNames(String... providers) { return monetaryRoundingsSingletonSpi() .getRoundingNames(providers); }
Access an MonetaryAmountFactory for the given MonetaryAmount implementation type.
Params:
Throws:
Returns:the corresponding MonetaryAmountFactory, never null.
/** * Access an {@link MonetaryAmountFactory} for the given {@link MonetaryAmount} implementation * type. * * @param amountType {@link MonetaryAmount} implementation type, nor {@code null}. * @return the corresponding {@link MonetaryAmountFactory}, never {@code null}. * @throws MonetaryException if no {@link MonetaryAmountFactory} targeting the given {@link MonetaryAmount} * implementation class is registered. */
public static <T extends MonetaryAmount> MonetaryAmountFactory<T> getAmountFactory(Class<T> amountType) { MonetaryAmountsSingletonSpi spi = Optional.ofNullable(monetaryAmountsSingletonSpi()) .orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")); MonetaryAmountFactory<T> factory = spi.getAmountFactory(amountType); return Optional.ofNullable(factory).orElseThrow( () -> new MonetaryException("No AmountFactory available for type: " + amountType.getName())); }
Throws:
Returns:the MonetaryAmountFactory corresponding to default amount type, never null.
/** * Access the default {@link MonetaryAmountFactory} as defined by * {@link javax.money.spi.MonetaryAmountsSingletonSpi#getDefaultAmountFactory()}. * * @return the {@link MonetaryAmountFactory} corresponding to default amount type, * never {@code null}. * @throws MonetaryException if no {@link MonetaryAmountFactory} targeting the default amount type * implementation class is registered. */
public static MonetaryAmountFactory<?> getDefaultAmountFactory() { return Optional.ofNullable(monetaryAmountsSingletonSpi()) .orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")) .getDefaultAmountFactory(); }
Access all currently available MonetaryAmount implementation classes that are accessible from this MonetaryAmount singleton.
Returns:all currently available MonetaryAmount implementation classes that have corresponding MonetaryAmountFactory instances provided, never null
/** * Access all currently available {@link MonetaryAmount} implementation classes that are * accessible from this {@link MonetaryAmount} singleton. * * @return all currently available {@link MonetaryAmount} implementation classes that have * corresponding {@link MonetaryAmountFactory} instances provided, never {@code null} */
public static Collection<MonetaryAmountFactory<?>> getAmountFactories() { return Optional.ofNullable(monetaryAmountsSingletonSpi()) .orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")) .getAmountFactories(); }
Access all currently available MonetaryAmount implementation classes that are accessible from this MonetaryAmount singleton.
Returns:all currently available MonetaryAmount implementation classes that have corresponding MonetaryAmountFactory instances provided, never null
/** * Access all currently available {@link MonetaryAmount} implementation classes that are * accessible from this {@link MonetaryAmount} singleton. * * @return all currently available {@link MonetaryAmount} implementation classes that have * corresponding {@link MonetaryAmountFactory} instances provided, never {@code null} */
public static Collection<Class<? extends MonetaryAmount>> getAmountTypes() { return Optional.ofNullable(monetaryAmountsSingletonSpi()) .orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")).getAmountTypes(); }
Access the default MonetaryAmount implementation class that is accessible from this MonetaryAmount singleton.
Returns:all current default MonetaryAmount implementation class, never null
/** * Access the default {@link MonetaryAmount} implementation class that is * accessible from this {@link MonetaryAmount} singleton. * * @return all current default {@link MonetaryAmount} implementation class, never {@code null} */
public static Class<? extends MonetaryAmount> getDefaultAmountType() { return Optional.ofNullable(monetaryAmountsSingletonSpi()) .orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")) .getDefaultAmountType(); }
Executes the query and returns the factory found, if there is only one factory. If multiple factories match the query, one is selected.
Params:
  • query – the factory query, not null.
Returns:the factory found, or null.
/** * Executes the query and returns the factory found, if there is only one factory. * If multiple factories match the query, one is selected. * * @param query the factory query, not null. * @return the factory found, or null. */
@SuppressWarnings("rawtypes") public static MonetaryAmountFactory getAmountFactory(MonetaryAmountFactoryQuery query) { return Optional.ofNullable(monetaryAmountsSingletonQuerySpi()).orElseThrow(() -> new MonetaryException( "No MonetaryAmountsSingletonQuerySpi loaded, query functionality is not available.")) .getAmountFactory(query); }
Returns all factory instances that match the query.
Params:
  • query – the factory query, not null.
Returns:the instances found, never null.
/** * Returns all factory instances that match the query. * * @param query the factory query, not null. * @return the instances found, never null. */
public static Collection<MonetaryAmountFactory<?>> getAmountFactories(MonetaryAmountFactoryQuery query) { return Optional.ofNullable(monetaryAmountsSingletonQuerySpi()).orElseThrow(() -> new MonetaryException( "No MonetaryAmountsSingletonQuerySpi loaded, query functionality is not available.")) .getAmountFactories(query); }
Allows to check if any of the getXXX methods return non empty/non null results of MonetaryAmountFactory.
Params:
  • query – the factory query, not null.
Returns:true, if at least one MonetaryAmountFactory matches the query.
/** * Allows to check if any of the <i>get</i>XXX methods return non empty/non null results of {@link javax.money * .MonetaryAmountFactory}. * * @param query the factory query, not null. * @return true, if at least one {@link MonetaryAmountFactory} matches the query. */
public static boolean isAvailable(MonetaryAmountFactoryQuery query) { return Optional.ofNullable(monetaryAmountsSingletonQuerySpi()).orElseThrow(() -> new MonetaryException( "No MonetaryAmountsSingletonQuerySpi loaded, query functionality is not available.")) .isAvailable(query); }
Access a new instance based on the currency code. Currencies are available as provided by CurrencyProviderSpi instances registered with the Bootstrap.
Params:
  • currencyCode – the ISO currency code, not null.
  • providers – the (optional) specification of providers to consider.
Throws:
Returns:the corresponding CurrencyUnit instance.
/** * Access a new instance based on the currency code. Currencies are * available as provided by {@link CurrencyProviderSpi} instances registered * with the {@link javax.money.spi.Bootstrap}. * * @param currencyCode the ISO currency code, not {@code null}. * @param providers the (optional) specification of providers to consider. * @return the corresponding {@link CurrencyUnit} instance. * @throws UnknownCurrencyException if no such currency exists. */
public static CurrencyUnit getCurrency(String currencyCode, String... providers) { return monetaryCurrenciesSingletonSpi() .getCurrency(currencyCode, providers); }
Access a new instance based on the Locale. Currencies are available as provided by CurrencyProviderSpi instances registered with the Bootstrap.
Params:
  • locale – the target Locale, typically representing an ISO country, not null.
  • providers – the (optional) specification of providers to consider.
Throws:
Returns:the corresponding CurrencyUnit instance.
/** * Access a new instance based on the {@link Locale}. Currencies are * available as provided by {@link CurrencyProviderSpi} instances registered * with the {@link javax.money.spi.Bootstrap}. * * @param locale the target {@link Locale}, typically representing an ISO * country, not {@code null}. * @param providers the (optional) specification of providers to consider. * @return the corresponding {@link CurrencyUnit} instance. * @throws UnknownCurrencyException if no such currency exists. */
public static CurrencyUnit getCurrency(Locale locale, String... providers) { return monetaryCurrenciesSingletonSpi() .getCurrency(locale, providers); }
Access a new instance based on the Locale. Currencies are available as provided by CurrencyProviderSpi instances registered with the Bootstrap.
Params:
  • locale – the target Locale, typically representing an ISO country, not null.
  • providers – the (optional) specification of providers to consider.
Throws:
Returns:the corresponding CurrencyUnit instance.
/** * Access a new instance based on the {@link Locale}. Currencies are * available as provided by {@link CurrencyProviderSpi} instances registered * with the {@link javax.money.spi.Bootstrap}. * * @param locale the target {@link Locale}, typically representing an ISO * country, not {@code null}. * @param providers the (optional) specification of providers to consider. * @return the corresponding {@link CurrencyUnit} instance. * @throws UnknownCurrencyException if no such currency exists. */
public static Set<CurrencyUnit> getCurrencies(Locale locale, String... providers) { return Optional.ofNullable(monetaryCurrenciesSingletonSpi()).orElseThrow( () -> new MonetaryException("No MonetaryCurrenciesSingletonSpi loaded, check your system setup.")) .getCurrencies(locale, providers); }
Allows to check if a CurrencyUnit instance is defined, i.e. accessible from getCurrency(String, String...).
Params:
  • code – the currency code, not null.
  • providers – the (optional) specification of providers to consider.
Returns:true if getCurrency(String, String...) would return a result for the given code.
/** * Allows to check if a {@link CurrencyUnit} instance is defined, i.e. * accessible from {@link Monetary#getCurrency(String, String...)}. * * @param code the currency code, not {@code null}. * @param providers the (optional) specification of providers to consider. * @return {@code true} if {@link Monetary#getCurrency(String, java.lang.String...)} * would return a result for the given code. */
public static boolean isCurrencyAvailable(String code, String... providers) { return monetaryCurrenciesSingletonSpi().isCurrencyAvailable(code, providers); }
Allows to check if a CurrencyUnit instance is defined, i.e. accessible from getCurrency(String, String...).
Params:
  • locale – the target Locale, not null.
  • providers – the (optional) specification of providers to consider.
Returns:true if getCurrencies(Locale, String...) would return a result containing a currency with the given code.
/** * Allows to check if a {@link javax.money.CurrencyUnit} instance is * defined, i.e. accessible from {@link #getCurrency(String, String...)}. * * @param locale the target {@link Locale}, not {@code null}. * @param providers the (optional) specification of providers to consider. * @return {@code true} if {@link #getCurrencies(Locale, String...)} would return a * result containing a currency with the given code. */
public static boolean isCurrencyAvailable(Locale locale, String... providers) { return monetaryCurrenciesSingletonSpi().isCurrencyAvailable(locale, providers); }
Access all currencies known.
Params:
  • providers – the (optional) specification of providers to consider.
Returns:the list of known currencies, never null.
/** * Access all currencies known. * * @param providers the (optional) specification of providers to consider. * @return the list of known currencies, never null. */
public static Collection<CurrencyUnit> getCurrencies(String... providers) { return monetaryCurrenciesSingletonSpi() .getCurrencies(providers); }
Query all currencies matching the given query.
Params:
Returns:the list of known currencies, never null.
/** * Query all currencies matching the given query. * * @param query The {@link javax.money.CurrencyQuery}, not null. * @return the list of known currencies, never null. */
public static CurrencyUnit getCurrency(CurrencyQuery query) { return monetaryCurrenciesSingletonSpi() .getCurrency(query); }
Query all currencies matching the given query.
Params:
Returns:the list of known currencies, never null.
/** * Query all currencies matching the given query. * * @param query The {@link javax.money.CurrencyQuery}, not null. * @return the list of known currencies, never null. */
public static Collection<CurrencyUnit> getCurrencies(CurrencyQuery query) { return Optional.ofNullable(monetaryCurrenciesSingletonSpi()).orElseThrow( () -> new MonetaryException("No MonetaryCurrenciesSingletonSpi loaded, check your system setup.")) .getCurrencies(query); }
Query all currencies matching the given query.
Returns:the list of known currencies, never null.
/** * Query all currencies matching the given query. * * @return the list of known currencies, never null. */
public static Set<String> getCurrencyProviderNames() { return monetaryCurrenciesSingletonSpi() .getProviderNames(); }
Query the list and ordering of provider names modelling the default provider chain to be used, if no provider chain was explicitly set..
Returns:the ordered list provider names, modelling the default provider chain used, never null.
/** * Query the list and ordering of provider names modelling the default provider chain to be used, if no provider * chain was explicitly set.. * * @return the ordered list provider names, modelling the default provider chain used, never null. */
public static List<String> getDefaultCurrencyProviderChain() { return monetaryCurrenciesSingletonSpi() .getDefaultProviderChain(); } }