/*
 * 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.convert;

import javax.money.*;
import java.util.Objects;

This interface defines access to the exchange rates provided by a provider. The provider and its capabilities can be defined in arbitrary detail by the corresponding ProviderContext. Instances of this class must only provide conversion data for exact one provider, identified by AbstractContext.getProviderName(). When accessing ExchangeRateProvider instances or CurrencyConversion instances from the MonetaryConversions in many cases a chain of providers will be returned. It is the responsibility of the implementation code assembling the chain to establish a well defined coordination mechanism for evaluating the correct result. By default the first provider in the chain that returns a non null result determines the final result of a call. Nevertheless adapting the MonetaryConversionsSingletonSpi allows to implement also alternate strategies, e.g. honoring different priorities of providers as well.

Implementations of this interface are required to be thread save.

Implementations of this class must neither be immutable nor serializable.

Author:Anatole Tresch, Werner Keil
/** * This interface defines access to the exchange rates provided by a provider. * The provider and its capabilities can be defined in arbitrary detail by the * corresponding {@link javax.money.convert.ProviderContext}. * Instances of this class must only provide conversion data for exact one provider, identified by * {@link ProviderContext#getProviderName()}. * * When accessing ExchangeRateProvider instances or {@link javax.money.convert.CurrencyConversion} instances from the * {@link MonetaryConversions} * in many cases a chain of providers will be returned. It is the responsibility of the implementation code assembling * the chain to * establish a well defined coordination mechanism for evaluating the correct result. By default the first provider * in the chain that returns a non null result determines the final result of a call. Nevertheless adapting the * {@link javax.money.spi.MonetaryConversionsSingletonSpi} allows * to implement also alternate strategies, e.g. honoring different priorities of providers as well. * <p> * Implementations of this interface are required to be thread save. * <p> * Implementations of this class must neither be immutable nor serializable. * * @author Anatole Tresch * @author Werner Keil */
public interface ExchangeRateProvider{
Access the ConversionContext for this ExchangeRateProvider. Each instance of ExchangeRateProvider provides conversion data for exact one ConversionContext .
Returns:the exchange rate type, never null.
/** * Access the {@link ConversionContext} for this * {@link ExchangeRateProvider}. Each instance of * {@link ExchangeRateProvider} provides conversion data for exact one * {@link ConversionContext} . * * @return the exchange rate type, never {@code null}. */
ProviderContext getContext();
Access a ExchangeRate using the given currencies. The ExchangeRate may be, depending on the data provider, real-time or deferred. This method should return the rate that is currently valid.
Params:
Throws:
See Also:
Returns:the matching ExchangeRate.
/** * Access a {@link ExchangeRate} using the given currencies. The * {@link ExchangeRate} may be, depending on the data provider, real-time or * deferred. This method should return the rate that is <i>currently</i> * valid. * * @param conversionQuery the required {@link ConversionQuery}, not {@code null} * @return the matching {@link ExchangeRate}. * @throws CurrencyConversionException If no such rate is available. * @throws MonetaryException if one of the currency codes passed is not valid. * @see javax.money.convert.ConversionQueryBuilder */
ExchangeRate getExchangeRate(ConversionQuery conversionQuery);
Access a CurrencyConversion that can be applied as a MonetaryOperator to an amount.
Params:
Throws:
See Also:
Returns:a new instance of a corresponding CurrencyConversion, never null.
/** * Access a {@link CurrencyConversion} that can be applied as a * {@link MonetaryOperator} to an amount. * * @param conversionQuery the required {@link ConversionQuery}, not {@code null} * @return a new instance of a corresponding {@link CurrencyConversion}, * never {@code null}. * @throws MonetaryException if one of the currency codes passed is not valid. * @see javax.money.convert.ConversionQueryBuilder */
CurrencyConversion getCurrencyConversion(ConversionQuery conversionQuery);
Checks if an ExchangeRate between two CurrencyUnit is available from this provider. This method should check, if a given rate is currently defined.
Params:
Returns:true, if such an ExchangeRate is currently defined.
/** * Checks if an {@link ExchangeRate} between two {@link CurrencyUnit} is * available from this provider. This method should check, if a given rate * is <i>currently</i> defined. * * @param conversionQuery the required {@link ConversionQuery}, not {@code null} * @return {@code true}, if such an {@link ExchangeRate} is currently * defined. */
default boolean isAvailable(ConversionQuery conversionQuery){ Objects.requireNonNull(conversionQuery); try{ return conversionQuery.getProviderNames().isEmpty() || conversionQuery.getProviderNames().contains(getContext().getProviderName()); } catch(Exception e){ return false; } }
Access a ExchangeRate using the given currencies. The ExchangeRate may be, depending on the data provider, real-time or deferred. This method should return the rate that is currently valid.
Params:
Throws:
Returns:the matching ExchangeRate.
/** * Access a {@link ExchangeRate} using the given currencies. The * {@link ExchangeRate} may be, depending on the data provider, real-time or * deferred. This method should return the rate that is <i>currently</i> * valid. * * @param base base {@link CurrencyUnit}, not {@code null} * @param term term {@link CurrencyUnit}, not {@code null} * @return the matching {@link ExchangeRate}. * @throws CurrencyConversionException If no such rate is available. */
default ExchangeRate getExchangeRate(CurrencyUnit base, CurrencyUnit term){ Objects.requireNonNull(base, "Base Currency is null"); Objects.requireNonNull(term, "Term Currency is null"); return getExchangeRate(ConversionQueryBuilder.of().setBaseCurrency(base).setTermCurrency(term).build()); }
Access a CurrencyConversion that can be applied as a MonetaryOperator to an amount.
Params:
Returns:a new instance of a corresponding CurrencyConversion, never null.
/** * Access a {@link CurrencyConversion} that can be applied as a * {@link MonetaryOperator} to an amount. * * @param term term {@link CurrencyUnit}, not {@code null} * @return a new instance of a corresponding {@link CurrencyConversion}, * never {@code null}. */
default CurrencyConversion getCurrencyConversion(CurrencyUnit term){ return getCurrencyConversion(ConversionQueryBuilder.of().setTermCurrency(term).build()); }
Checks if an ExchangeRate between two CurrencyUnit is available from this provider. This method should check, if a given rate is currently defined.
Params:
Returns:true, if such an ExchangeRate is currently defined.
/** * Checks if an {@link ExchangeRate} between two {@link CurrencyUnit} is * available from this provider. This method should check, if a given rate * is <i>currently</i> defined. * * @param base the base {@link CurrencyUnit} * @param term the term {@link CurrencyUnit} * @return {@code true}, if such an {@link ExchangeRate} is currently * defined. */
default boolean isAvailable(CurrencyUnit base, CurrencyUnit term){ return isAvailable(ConversionQueryBuilder.of().setBaseCurrency(base).setTermCurrency(term).build()); }
Checks if an ExchangeRate between two CurrencyUnit is available from this provider. This method should check, if a given rate is currently defined.
Params:
  • baseCode – the base currency code
  • termCode – the terminal/target currency code
Throws:
Returns:true, if such an ExchangeRate is currently defined.
/** * Checks if an {@link ExchangeRate} between two {@link CurrencyUnit} is * available from this provider. This method should check, if a given rate * is <i>currently</i> defined. * * @param baseCode the base currency code * @param termCode the terminal/target currency code * @return {@code true}, if such an {@link ExchangeRate} is currently * defined. * @throws MonetaryException if one of the currency codes passed is not valid. */
default boolean isAvailable(String baseCode, String termCode){ return isAvailable(Monetary.getCurrency(baseCode), Monetary.getCurrency(termCode)); }
Access a ExchangeRate using the given currencies. The ExchangeRate may be, depending on the data provider, real-time or deferred. This method should return the rate that is currently valid.
Params:
  • baseCode – base currency code, not null
  • termCode – term/target currency code, not null
Throws:
Returns:the matching ExchangeRate.
/** * Access a {@link ExchangeRate} using the given currencies. The * {@link ExchangeRate} may be, depending on the data provider, real-time or * deferred. This method should return the rate that is <i>currently</i> * valid. * * @param baseCode base currency code, not {@code null} * @param termCode term/target currency code, not {@code null} * @return the matching {@link ExchangeRate}. * @throws CurrencyConversionException If no such rate is available. * @throws MonetaryException if one of the currency codes passed is not valid. */
default ExchangeRate getExchangeRate(String baseCode, String termCode){ return getExchangeRate(Monetary.getCurrency(baseCode), Monetary.getCurrency(termCode)); }
The method reverses the ExchangeRate to a rate mapping from term to base CurrencyUnit. Hereby the factor must not be recalculated as 1/oldFactor, since typically reverse rates are not symmetric in most cases.
Params:
Returns:the matching reversed ExchangeRate, or null, if the rate cannot be reversed.
/** * The method reverses the {@link ExchangeRate} to a rate mapping from term * to base {@link CurrencyUnit}. Hereby the factor must <b>not</b> be * recalculated as {@code 1/oldFactor}, since typically reverse rates are * not symmetric in most cases. * * @param rate {@link ExchangeRate}, not {@code null} * @return the matching reversed {@link ExchangeRate}, or {@code null}, if * the rate cannot be reversed. */
default ExchangeRate getReversed(ExchangeRate rate){ ConversionQuery reverseQuery = rate.getContext().toQueryBuilder().setBaseCurrency(rate.getCurrency()) .setTermCurrency(rate.getBaseCurrency()).build(); if(isAvailable(reverseQuery)){ return getExchangeRate(reverseQuery); } return null; }
Access a CurrencyConversion that can be applied as a MonetaryOperator to an amount.
Params:
  • termCode – terminal/target currency code, not null
Throws:
Returns:a new instance of a corresponding CurrencyConversion, never null.
/** * Access a {@link CurrencyConversion} that can be applied as a * {@link MonetaryOperator} to an amount. * * @param termCode terminal/target currency code, not {@code null} * @return a new instance of a corresponding {@link CurrencyConversion}, * never {@code null}. * @throws MonetaryException if one of the currency codes passed is not valid. */
default CurrencyConversion getCurrencyConversion(String termCode){ return getCurrencyConversion(Monetary.getCurrency(termCode)); } }