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}