/*
 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU
 * ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS
 * AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
 * THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE
 * BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright
 * (c) 2012-2015, Credit Suisse All rights reserved.
 */
package javax.money.spi;

import java.util.*;

import javax.money.CurrencyUnit;
import javax.money.MonetaryException;
import javax.money.convert.*;

SPI (conversion) that implements the functionality provided by the MonetaryConversions singleton accessor. It should be registered as a service using the JDK ServiceLoader. Hereby only one instance can be registered at a time.

This interface is designed to support also contextual behaviour, e.g. in Java EE containers each application may provide its own ExchangeRateProvider instances, e.g. by registering them as CDI beans. An EE container can register an according MonetaryConversionsSingletonSpi that manages the different application contexts transparently. In a SE environment this class is expected to behave like an ordinary singleton, loading its SPIs from the ServiceLoader.

Instances of this class must be thread safe. It is not a requirement that they are serializable.

Only one instance can be registered using the ServiceLoader. When registering multiple instances the MonetaryConversions accessor will not work.

Author:Anatole Tresch, Werner Keil
/** * SPI (conversion) that implements the functionality provided by the * {@code MonetaryConversions} singleton accessor. It should be registered as a * service using the JDK {@code ServiceLoader}. Hereby only one instance can be * registered at a time. * <p> * This interface is designed to support also contextual behaviour, e.g. in Java * EE containers each application may provide its own * {@link ExchangeRateProvider} instances, e.g. by registering them as CDI * beans. An EE container can register an according * {@link MonetaryConversionsSingletonSpi} that manages the different application * contexts transparently. In a SE environment this class is expected to behave * like an ordinary singleton, loading its SPIs from the {@link ServiceLoader}. * <p> * Instances of this class must be thread safe. It is not a requirement that * they are serializable. * <p> * Only one instance can be registered using the {@link ServiceLoader}. When * registering multiple instances the {@link MonetaryConversions} accessor will * not work. * * @author Anatole Tresch * @author Werner Keil */
public interface MonetaryConversionsSingletonSpi {
Get all currently registered provider names.
See Also:
Returns:all currently registered provider names
/** * Get all currently registered provider names. * * @return all currently registered provider names * @see ProviderContext#getProviderName() */
Collection<String> getProviderNames();
Get the default provider chain used. The ordering of the items is the access order/precedence of the providers.
Returns:the default provider chain, not null and not empty.
/** * Get the default provider chain used. The ordering of the items is the * access order/precedence of the providers. * * @return the default provider chain, not {@code null} and not empty. */
List<String> getDefaultProviderChain();
Access an instance of ExchangeRateProvider. By setting ConversionQuery.getCurrencyProviderNames() multiple providers can be selected, that will be included into a compound instance, with the same order as returned by the ConversionQuery.
Params:
  • conversionQuery – the ConversionQuery determining the type of conversion required, not null.
Throws:
See Also:
Returns:an ExchangeRateProvider built up with the given sub providers, never null
/** * Access an instance of {@link ExchangeRateProvider}. By setting {@link javax.money.convert * .ConversionQuery#getCurrencyProviderNames()} multiple providers can be selected, * that will be included into a <i>compound</i> instance, with the same order as returned by the {@link javax * .money.convert.ConversionQuery}. * * @param conversionQuery the {@link javax.money.convert.ConversionQuery} determining the type of conversion * required, not null. * @return an {@link ExchangeRateProvider} built up with the given sub * providers, never {@code null} * @throws MonetaryException if a provider could not be found. * @see #isExchangeRateProviderAvailable(javax.money.convert.ConversionQuery) */
ExchangeRateProvider getExchangeRateProvider(ConversionQuery conversionQuery);
Allows to quickly check, if a ExchangeRateProvider is accessible for the given ConversionQuery.
Params:
  • conversionQuery – the ConversionQuery determining the type of conversion required, not null.
See Also:
Returns:true, if such a conversion is supported, meaning an according ExchangeRateProvider can be accessed.
/** * Allows to quickly check, if a {@link javax.money.convert.ExchangeRateProvider} is accessible for the given * {@link javax.money.convert.ConversionQuery}. * * @param conversionQuery the {@link javax.money.convert.ConversionQuery} determining the type of conversion * required, not null. * @return {@code true}, if such a conversion is supported, meaning an according * {@link ExchangeRateProvider} can be * accessed. * @see #getExchangeRateProvider(ConversionQuery) * @see #getExchangeRateProvider(String...)} */
default boolean isExchangeRateProviderAvailable(ConversionQuery conversionQuery) { try { return getExchangeRateProvider(conversionQuery) != null; } catch (Exception e) { return false; } }
Allows to quickly check, if a CurrencyConversion is accessible for the given ConversionQuery.
Params:
  • conversionQuery – the ConversionQuery determining the type of conversion required, not null.
See Also:
Returns:true, if such a conversion is supported, meaning an according CurrencyConversion can be accessed.
/** * Allows to quickly check, if a {@link javax.money.convert.CurrencyConversion} is accessible for the given * {@link javax.money.convert.ConversionQuery}. * * @param conversionQuery the {@link javax.money.convert.ConversionQuery} determining the type of conversion * required, not null. * @return {@code true}, if such a conversion is supported, meaning an according * {@link CurrencyConversion} can be * accessed. * @see #getConversion(javax.money.convert.ConversionQuery) * @see #getConversion(CurrencyUnit, String...)} */
default boolean isConversionAvailable(ConversionQuery conversionQuery) { try { return getConversion(conversionQuery) != null; } catch (Exception e) { return false; } }
Allows to quickly check, if a CurrencyConversion is accessible for the given ConversionQuery.
Params:
  • termCurrency – the terminating/target currency unit, not null.
  • providers – the provider names defines a corresponding provider chain that must be encapsulated by the resulting CurrencyConversion. By default the provider chain as defined by #getDefaultCurrencyProviderChain will be used.
See Also:
Returns:true, if such a conversion is supported, meaning an according CurrencyConversion can be accessed.
/** * Allows to quickly check, if a {@link javax.money.convert.CurrencyConversion} is accessible for the given * {@link javax.money.convert.ConversionQuery}. * * @param termCurrency the terminating/target currency unit, not null. * @param providers the provider names defines a corresponding * provider chain that must be encapsulated by the resulting {@link javax * .money.convert.CurrencyConversion}. By default the provider * chain as defined by #getDefaultCurrencyProviderChain will be used. * @return {@code true}, if such a conversion is supported, meaning an according * {@link CurrencyConversion} can be * accessed. * @see #getConversion(javax.money.convert.ConversionQuery) * @see #getConversion(CurrencyUnit, String...)} */
default boolean isConversionAvailable(CurrencyUnit termCurrency, String... providers) { return isConversionAvailable( ConversionQueryBuilder.of().setTermCurrency(termCurrency).setProviderNames(providers).build()); }
Access the current registered ExchangeRateProvider instances. If no provider names are passed ALL current registered providers are returned in undefined order.
Params:
  • providers – the provider names of hte providers to be accessed
Throws:
Returns:the list of providers, in the same order as requested.
/** * Access the current registered {@link javax.money.convert.ExchangeRateProvider} instances. If no provider * names are passed ALL current registered providers are returned in undefined order. * * @param providers the provider names of hte providers to be accessed * @return the list of providers, in the same order as requested. * @throws MonetaryException if a provider could not be resolved. */
default List<ExchangeRateProvider> getExchangeRateProviders(String... providers) { List<ExchangeRateProvider> provInstances = new ArrayList<>(); Collection<String> providerNames = Arrays.asList(providers); if (providerNames.isEmpty()) { providerNames = getProviderNames(); } for (String provName : providerNames) { provInstances.add(Optional.ofNullable(getExchangeRateProvider(provName)).orElseThrow( () -> new MonetaryException("Unsupported conversion/rate provider: " + provName))); } return provInstances; }
Access a compound instance of an ExchangeRateProvider based on the given provider chain.
Params:
  • providers – the ConversionQuery provider names defines a corresponding provider chain that must be encapsulated by the resulting ExchangeRateProvider. By default the default provider changes as defined in #getDefaultCurrencyProviderChain will be used.
Throws:
See Also:
Returns:an ExchangeRateProvider built up with the given sub providers, never null.
/** * Access a compound instance of an {@link ExchangeRateProvider} based on the given provider chain. * * @param providers the {@link javax.money.convert.ConversionQuery} provider names defines a corresponding * provider chain that must be * encapsulated by the resulting {@link javax.money.convert.ExchangeRateProvider}. By default * the default * provider changes as defined in #getDefaultCurrencyProviderChain will be used. * @return an {@link ExchangeRateProvider} built up with the given sub * providers, never {@code null}. * @throws MonetaryException if a provider listed could not be found. * @see #getProviderNames() * @see #isExchangeRateProviderAvailable(javax.money.convert.ConversionQuery) */
default ExchangeRateProvider getExchangeRateProvider(String... providers) { return getExchangeRateProvider(ConversionQueryBuilder.of().setProviderNames(providers).build()); }
Access an instance of CurrencyConversion.
Params:
  • conversionQuery – the ConversionQuery determining the type of conversion required, not null.
Throws:
See Also:
Returns:the corresponding conversion, not null.
/** * Access an instance of {@link CurrencyConversion}. * * @param conversionQuery the {@link javax.money.convert.ConversionQuery} determining the type of conversion * required, not null. * @return the corresponding conversion, not null. * @throws javax.money.MonetaryException if no matching conversion could be found. * @see #isConversionAvailable(javax.money.convert.ConversionQuery) */
default CurrencyConversion getConversion(ConversionQuery conversionQuery) { return getExchangeRateProvider(conversionQuery).getCurrencyConversion( Objects.requireNonNull(conversionQuery.getCurrency(), "Terminating Currency is required.") ); }
Access an instance of CurrencyConversion.
Params:
  • termCurrency – the terminating/target currency unit, not null.
  • providers – the ConversionQuery provider names defines a corresponding provider chain that must be encapsulated by the resulting CurrencyConversion. By default the default provider chain as defined by #getDefaultCurrencyProviderChain will be used.
Throws:
See Also:
Returns:the corresponding conversion, not null.
/** * Access an instance of {@link CurrencyConversion}. * * @param termCurrency the terminating/target currency unit, not null. * @param providers the {@link javax.money.convert.ConversionQuery} provider names defines a corresponding * provider chain that must be encapsulated by the resulting {@link javax * .money.convert.CurrencyConversion}. By default the default * provider chain as defined by #getDefaultCurrencyProviderChain will be used. * @return the corresponding conversion, not null. * @throws javax.money.MonetaryException if no matching conversion could be found. * @see #isConversionAvailable(javax.money.convert.ConversionQuery) */
default CurrencyConversion getConversion(CurrencyUnit termCurrency, String... providers) { return getConversion(ConversionQueryBuilder.of().setTermCurrency(termCurrency).setProviderNames(providers).build()); } }