/*
* 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: - conversionQuery – the required
ConversionQuery
, not null
Throws: - CurrencyConversionException – If no such rate is available.
- MonetaryException – if one of the currency codes passed is not valid.
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: - conversionQuery – the required
ConversionQuery
, not null
Throws: - MonetaryException – if one of the currency codes passed is not valid.
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: - conversionQuery – the required
ConversionQuery
, not null
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: - base – base
CurrencyUnit
, not null
- term – term
CurrencyUnit
, not null
Throws: - CurrencyConversionException – If no such rate is available.
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: - term – term
CurrencyUnit
, not null
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: - base – the base
CurrencyUnit
- term – the term
CurrencyUnit
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: - MonetaryException – if one of the currency codes passed is not valid.
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: - CurrencyConversionException – If no such rate is available.
- MonetaryException – if one of the currency codes passed is not valid.
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: - rate –
ExchangeRate
, not null
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: - MonetaryException – if one of the currency codes passed is not valid.
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));
}
}