001/*
002 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE
003 * CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT.
004 * PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY. BY
005 * DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF THE
006 * AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE"
007 * BUTTON AT THE BOTTOM OF THIS PAGE.
008 * 
009 * Specification: JSR-354 Money and Currency API ("Specification")
010 * 
011 * Copyright (c) 2012-2013, Credit Suisse All rights reserved.
012 */
013package javax.money;
014
015import java.math.BigDecimal;
016
017/**
018 * Interface defining a monetary amount. The effective internal representation
019 * of an amount may vary depending on the implementation used. JSR 354
020 * explicitly supports different types of MonetaryAmount to be implemented and
021 * used. Reason behind is that the requirements to an implementation heavily
022 * vary for different usage scenarios. E.g. product calculations may require
023 * high precision and scale, whereas low latency order and trading systems
024 * require high calculation performance for algorithmic operations.
025 * <p>
026 * This JSR additionally recommends to consider the following aspects:
027 * <ul>
028 * <li>Arithmetic operations should throw an {@link ArithmeticException}, if
029 * performing arithmetic operations between amounts exceeds the capabilities of
030 * the numeric representation type used. Any implicit truncating, that would
031 * lead to complete invalid and useless results, should be avoided. This
032 * recommendation does not affect internal rounding, as required by the internal
033 * numeric representation of a monetary amount.
034 * <li>Monetary amounts should allow numbers as argument for arithmetic
035 * operations like division and multiplication additionally to a MonetaryAmount.
036 * Adding or subtracting of amounts must only be possible by passing instances
037 * of MonetaryAmount.</li>
038 * <li>Arguments of type {@link Number} should be avoided, since
039 * it does not allow to extract its numeric value in a feasible way.</li>
040 * <li>If the numeric representation of a {@code MonetaryAmount} exceeds the
041 * numeric capabilities of the concrete type {@code T from(MonetaryAmount)}, an
042 * implementation should throw an {@code ArithemticOperationException}.</li>
043 * <li>On the other hand, when the numeric value can not be mapped into the
044 * numeric exchange format defined by this interface, by default also an
045 * {@code ArithmeticException} should be thrown. Never should truncation be
046 * performed implicitly.</li>
047 * <li>Nevertheless truncation may be supported by passing additional parameters
048 * or defining <i>exact</i> methods, similar to {@link BigDecimal#longValueExact()}.
049 * <li>Rounding should never be done automatically, exception internal rounding
050 * implied by the numeric implementation type.</li>
051 * <li>Since implementations are recommended to be immutable, an operation
052 * should never change any internal state of an instance. Given an instance, all
053 * operations are required to be fully reproducible.</li>
054 * <li>Finally the result of calling {@link #with(MonetaryAdjuster)} should be
055 * of the same type as type on which {@code with} was called. The {@code with}
056 * method also defines additional interoperability requirements.</li>
057 * <li>To enable interoperability a static method {@code from(MonetaryAmount)}
058 * is recommended to be implemented, that allows conversion of a
059 * {@code MonetaryAmount} to a concrete type {@code T}:<br/>
060 * 
061 * <pre>
062 * public static T from(MonetaryAmount amount);}
063 * </pre>
064 * 
065 * This is particularly useful when implementing monetary adjusters or queries,
066 * since arithmetic operations are not available on the MonetaryAmount
067 * interface, which is defined for interoperability only.</li>
068 * <li>Finally implementations should not implement a method {@code getAmount()}
069 * . This methid is reserved for future integration into the JDK.</li>
070 * </ul>
071 * <h4>Implementation specification</h4>
072 * Implementations of this interface should be
073 * <ul>
074 * <li>immutable</li>
075 * <li>thread-safe</li>
076 * <li>final</li>
077 * <li>serializable, hereby writing the numeric value and a serialized
078 * {@link CurrencyUnit}.</li>
079 * </ul>
080 * Implementations of this interface must be
081 * <ul>
082 * <li>comparable</li>
083 * <li>must implement {@code equals/hashCode}, hereby considering
084 * <ul>
085 * <li>Implementation type
086 * <li>CurrencyUnit
087 * <li>Numeric value.
088 * </ul>
089 * This also means that two different implementations types with the same
090 * currency and numeric value are NOT equal.</li>
091 * <li>Additionally for the numeric representation of an amount,
092 * <pre>
093 * given w = getAmountWhole()
094 *       n = getFractionNominator()
095 *       d = getFractionDenominator()
096 *       
097 * the following must be always true:
098 * 
099 *       !(w<0 && n>0)  and
100 *       !(w>0 && n<0)  and
101 *       d>0            and
102 *       |n| < d        // || = absolute value
103 * </pre>
104 * </ul>
105 * <p>
106 * Since {@link Number} is not an interface, this type is not extending
107 * {@link Number}.
108 * 
109 * @see #with(MonetaryAdjuster)
110 * @author Anatole Tresch
111 * @author Werner Keil
112 */
113public interface MonetaryAmount {
114
115        /**
116         * Returns the amount’s currency, modelled as {@link CurrencyUnit}.
117         * Implementations may co-variantly change the return type to a more
118         * specific implementation of {@link CurrencyUnit} if desired.
119         * 
120         * @return the currency, never {@code null}
121         */
122        public CurrencyUnit getCurrency();
123
124        /**
125         * Gets the amount in terms of whole units of the currency.
126         * <p>
127         * An amount is defined to consist of an amount of whole currency units plus
128         * a fraction of the unit. This method returns the amount of whole units,
129         * such as the number of complete US dollars represented.
130         * <p>
131         * For example, the amount of '12 dollars and 25 cents' would return 12 from
132         * this method, as there are 12 whole US dollars in the amount.
133         * <p>
134         * Hereby it is always required that
135         * <ul>
136         * <li>{@code !(amountWhole<0 && fractionNumerator > 0) }
137         * <li>{@code !(amountWhole>0 && fractionNumerator < 0) }
138         * </ul>
139         * 
140         * @return the amount's whole number
141         */
142        public long getAmountWhole();
143
144        /**
145         * Gets the numerator of the fractional amount of the currency.
146         * <p>
147         * An amount is defined to consist of an amount of whole currency units plus
148         * a fraction of the unit. This method returns the numerator of the fraction
149         * of the whole currency unit.
150         * <p>
151         * For example, the amount of '12 dollars and 25 cents' would typically
152         * return 25 from this method and 100 from the denominator method.
153         * <p>
154         * Hereby it is always required that
155         * <ul>
156         * <li>{@code fractionNumerator < fractionDenominator}
157         * </ul>
158         * 
159         * @return the fraction numerator
160         */
161        public long getAmountFractionNumerator();
162
163        /**
164         * Gets the denominator of the fractional amount of the currency.
165         * <p>
166         * An amount is defined to consist of an amount of whole currency units plus
167         * a fraction of the unit. This method returns the denominator of the
168         * fraction of the whole currency unit.
169         * <p>
170         * For example, the amount of '12 dollars and 25 cents' would typically
171         * return 100 from this method and 25 from the numerator method.
172         * <p>
173         * Hereby it is always required that
174         * <ul>
175         * <li>{@code fractionDenominator > 0}.
176         * <li>{@code fractionDenominator > abs(fractionNominator)}.
177         * <li>it is recommended that the denominator is a power of 10 (1, 10, 100,
178         * 1000,...).
179         * </ul>
180         * 
181         * @return the fraction denominator
182         */
183        public long getAmountFractionDenominator();
184
185        /**
186         * Queries this monetary amount for a value.
187         * <p>
188         * This queries this amount using the specified query strategy object.
189         * <p>
190         * Implementations must ensure that no observable state is altered when this
191         * read-only method is invoked.
192         * 
193         * @param <R>
194         *            the type of the result
195         * @param adjuster
196         *            the query to invoke, not null
197         * @return the query result, null may be returned (defined by the query)
198         */
199        public <R> R query(MonetaryQuery<R> query);
200
201        /**
202         * Returns an adjusted object <b>of the same type</b> as this object with
203         * the adjustment made.
204         * <p>
205         * This adjusts this monetary amount according to the rules of the specified
206         * adjuster. A typical adjuster will change the amount and leave the
207         * currency unchanged. A more complex adjuster might also change the
208         * currency.
209         * <p>
210         * Some example code indicating how and why this method is used:
211         * 
212         * <pre>
213         * money = money.with(amountMultipliedBy(2));
214         * date = date.with(amountRoundedToNearestWholeUnit());
215         * </pre>
216         * 
217         * Hereby also the method signatur on the implementation type must return
218         * the concrete type, to enable a fluent API, e.g.
219         * 
220         * <pre>
221         * public final class MM implements MonetaryAmount{
222         *   ...
223         *   public MM with(MonetaryAdjuster adjuster){
224         *     ... 
225         *   }
226         *   
227         *   ...
228         * }
229         * </pre>
230         * 
231         * @param adjuster
232         *            the adjuster to use, not null
233         * @return an object of the same type with the specified adjustment made,
234         *         not null
235         */
236        public MonetaryAmount with(MonetaryAdjuster adjuster);
237
238}