All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.money.Monetary Maven / Gradle / Ivy

Go to download

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 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