![JAR search and dependency download from the Maven repository](/logo.png)
javax.money.Monetary Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of money-api Show documentation
Show all versions of money-api Show documentation
JSR 354 provides an API for representing, transporting, and performing comprehensive calculations with Money and Currency.
The newest version!
/*
* 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 {@link CurrencyUnit}, {@link javax.money.MonetaryAmount} and
* {@link javax.money.MonetaryRounding} instances as provided by the
* different registered SPI instances.
*
* This class is thread safe.
*
*
* @author Anatole Tresch
*/
public final class Monetary {
/**
* 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 {@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 {@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 {@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 Monetary() {
}
/**
* Allows to access the names of the current registered providers.
*
* @return the set of provider names, never {@code null}.
*/
public static Set getRoundingProviderNames() {
return monetaryRoundingsSingletonSpi()
.getProviderNames();
}
/**
* 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 getDefaultRoundingProviderChain() {
return monetaryRoundingsSingletonSpi()
.getDefaultProviderChain();
}
/**
* 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 {@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 {@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 {@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 {@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 {@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 {@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 {@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 getRoundings(RoundingQuery roundingQuery) {
return monetaryRoundingsSingletonSpi()
.getRoundings(roundingQuery);
}
/**
* 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 getRoundingNames(String... providers) {
return monetaryRoundingsSingletonSpi()
.getRoundingNames(providers);
}
/**
* 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 MonetaryAmountFactory getAmountFactory(Class amountType) {
MonetaryAmountsSingletonSpi spi = Optional.ofNullable(monetaryAmountsSingletonSpi())
.orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded."));
MonetaryAmountFactory factory = spi.getAmountFactory(amountType);
return Optional.ofNullable(factory).orElseThrow(
() -> new MonetaryException("No AmountFactory available for type: " + amountType.getName()));
}
/**
* 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 {@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> getAmountFactories() {
return Optional.ofNullable(monetaryAmountsSingletonSpi())
.orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded."))
.getAmountFactories();
}
/**
* 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> getAmountTypes() {
return Optional.ofNullable(monetaryAmountsSingletonSpi())
.orElseThrow(() -> new MonetaryException("No MonetaryAmountsSingletonSpi loaded.")).getAmountTypes();
}
/**
* 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.
*
* @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.
*
* @param query the factory query, not null.
* @return the instances found, never null.
*/
public static Collection> 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 {@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 {@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 {@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 {@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 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 {@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 {@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.
*
* @param providers the (optional) specification of providers to consider.
* @return the list of known currencies, never null.
*/
public static Collection getCurrencies(String... providers) {
return monetaryCurrenciesSingletonSpi()
.getCurrencies(providers);
}
/**
* 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.
*
* @param query The {@link javax.money.CurrencyQuery}, not null.
* @return the list of known currencies, never null.
*/
public static Collection 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.
*
* @return the list of known currencies, never null.
*/
public static Set 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..
*
* @return the ordered list provider names, modelling the default provider chain used, never null.
*/
public static List getDefaultCurrencyProviderChain() {
return monetaryCurrenciesSingletonSpi()
.getDefaultProviderChain();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy