001/*
002 *  Copyright 2009-2011 Stephen Colebourne
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.joda.money;
017
018/**
019 * Defines operations performed on {@link ExchangeRate}s. Object implementing this interface are contextual objects
020 * operating on "current" ExchangeRate. Some operations modify the underlying ExchageRate and others just perform
021 * operations using the underlying ExchangeRate. The reasoning behind having this can of object is that one can create
022 * such an object with the given settings and then perform serveral operations with the same settings.
023 * 
024 * @author tpasierb
025 */
026public interface ExchangeRateOperations {
027
028    /**
029     * Converts the given {@link BigMoney value in currency} to value in the other currency using the underlying
030     * ExchangeRate. The conversion is possible if either source or target currency of the exchange rate represented by
031     * this object matches the currency of the given {@link BigMoney}.
032     * 
033     * @param toExchange the value in currency to be converted
034     * @return the equivalent in other currency
035     * @throws NullPointerException if the given parameter is <code>null</code>
036     * @throws NotExchangeableException if exchange rate represented by this object cannot be used for conversion of the
037     *             given {@link Money}
038     */
039    BigMoney exchange(BigMoney toExchange);
040
041    /**
042     * Converts the given {@link Money value in currency} to value in the other currency returning an instance of
043     * {@link Money}.
044     * 
045     * @param toExchange the value in currency to be exchanged
046     * @return the equivalent in other currency
047     * @see ExchangeRateOperations#exchange(BigMoney)
048     */
049    Money exchange(Money toExchange);
050
051    /**
052     * Inverts the underlying ExchangeRate. The operation involves swapping currencies and inverting the rate. The
053     * inverted rate can be retrieved using {@link #getExchangeRate()}.
054     * 
055     * @return ExchangeRateOperations this contextual operations object allowing fluent calls
056     */
057    ExchangeRateOperations invert();
058
059    /**
060     * Combines {@link ExchangeRate} represented by this object with the given one. This {@link ExchangeRate} and the
061     * given one have to have a common currency no matter the position "source" or "target".
062     * 
063     * This object's non common currency will become the target currency and the other object's non common currency will
064     * become the source currency of the returned object. The common currency will "disappear".
065     * 
066     * <br>
067     * Example:
068     * 
069     * <pre>
070     * this rate:  1 USD = 3.50 PLN
071     * other rate: 1 EUR = 4.00 PLN
072     * 
073     * this.combine(other) results in 1 USD = 0.8750 EUR
074     * other.combine(this) results in 1 EUR = 1.1429 USD (rounded to 4 decimal places *)
075     * </pre>
076     * 
077     * A special case is when exchange rates for the same sets of currencies are combined no matter the position. In
078     * this case they may or may not differ on the rate field. Combining two such exchange rate will result in
079     * "identity" rate for <code>this</code> rate's target currency.
080     * 
081     * <br>
082     * Example:
083     * 
084     * <pre>
085     * this rate:  1 EUR = 3.22 PLN
086     * other rate: 1 EUR = 3.19 PLN
087     * 
088     * this.combine(other) results in 1 EUR = 1 EUR.
089     * </pre>
090     * 
091     * The resulting ExchangeRate will have the scale and roundingMode of this instance.
092     * 
093     * <pre>
094     * * rounding for this example only, internally scale may be greater
095     * </pre>
096     * 
097     * @param other the exchange rate to be combine with this instance
098     * @return this contextual operations object allowing fluent calls
099     * @throws NullPointerException if the other object is null
100     * @throws NoCommonCurrencyException if objects this and other have no common currency which means that it is
101     *             impossible to create a combination of the two exchange rates
102     */
103    ExchangeRateOperations combine(ExchangeRate other);
104
105    /**
106     * Returns the current ExchangeRate.
107     * 
108     * @return the current ExchangeRate
109     */
110    ExchangeRate getExchangeRate();
111}