001/* 002 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU 003 * ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS 004 * AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF 005 * THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE 006 * BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright 007 * (c) 2012-2013, Credit Suisse All rights reserved. 008 */ 009package org.javamoney.moneta.spi.base; 010 011import javax.money.MonetaryAmount; 012import javax.money.MonetaryOperator; 013import javax.money.MonetaryQuery; 014 015/** 016 * Interface defining a monetary amount. The effective format representation of an amount may vary 017 * depending on the implementation used. JSR 354 explicitly supports different types of monetary 018 * amounts to be implemented and used. Reason behind is that the requirements to an implementation 019 * heavily vary for different usage scenarios. E.g. product calculations may require high precision 020 * and scale, whereas low latency order and trading systems require high calculation performance for 021 * algorithmic operations. 022 * <p> 023 * Each instance of an amount provides additional meta-data in form of a {@link javax.money.MonetaryContext}. 024 * This context contains detailed information on the numeric capabilities, e.g. the supported 025 * precision and maximal scale, as well as the common implementation flavor. 026 * 027 * Also a {@link BaseMonetaryAmount} provides a {@link javax.money.NumberValue}, which allows easily to extract the 028 * numeric value, of the amount. And finally {@link #getFactory()} provides a 029 * {@link javax.money.MonetaryAmountFactory}, which allows to of instances of {@link BaseMonetaryAmount} based 030 * on the same numeric implementation. 031 * <p> 032 * This JSR additionally recommends to consider the following aspects: 033 * <ul> 034 * <li>Arithmetic operations should throw an {@link ArithmeticException}, if performing arithmetic 035 * operations between amounts exceeds the capabilities of the numeric representation type used. Any 036 * implicit truncating, that would lead to complete invalid and useless results, should be avoided. 037 * This recommendation does not affect format rounding, as required by the format numeric 038 * representation of a monetary amount. 039 * <li>Monetary amounts should allow numbers as argument for arithmetic operations like division and 040 * multiplication. Adding or subtracting of amounts must only be possible by passing instances of 041 * {@link BaseMonetaryAmount}.</li> 042 * <li>Nevertheless numeric truncation is also explicitly supported when calling 043 * {@link javax.money.NumberValue#numberValue(Class)}, whereas the <i>exact</i> counterpart, 044 * {@link javax.money.NumberValue#numberValueExact(Class)}, works similar to 045 * {@link java.math.BigDecimal#longValueExact()}. 046 * <li>Since implementations are recommended to be immutable, an operation should never change any 047 * format state of an instance. Given an instance, all operations are required to be fully 048 * reproducible.</li> 049 * <li>Finally the result of calling {@link #with(javax.money.MonetaryOperator)} must be of the same type as 050 * type on which {@code with} was called. The {@code with} method also defines additional 051 * interoperability requirements that are important to enable this invariant.</li> 052 * <li>To enable further interoperability a static method {@code from(MonetaryAmount)} is 053 * recommended to be implemented on each implementation class, that allows conversion of a 054 * {@code MonetaryAmount} to a concrete instance. E.g.a class {@code MyMoney extends MonetaryAmount} 055 * would contain the following method: 056 * 057 * <blockquote> 058 * <p> 059 * <pre> 060 * public final class MyMoney implements MonetaryAmount{ 061 * ... 062 * public static MyMoney from(MonetaryAmount amount)(...) 063 * } 064 * </pre> 065 * <p> 066 * </blockquote></li> 067 * </ul> 068 * <h4>Implementation specification</h4> 069 * Implementations of this interface must be 070 * <ul> 071 * <li>thread-safe</li> 072 * </ul> 073 * Implementations of this interface should be 074 * <ul> 075 * <li>final</li> 076 * <li>serializable, hereby writing the numeric value, the {@link javax.money.MonetaryContext} and a serialized 077 * {@link javax.money.CurrencyUnit}.</li> 078 * </ul> 079 * Implementations of this interface must be 080 * <ul> 081 * <li>thread-safe</li> 082 * <li>immutable</li> 083 * <li>comparable</li> 084 * <li>must implement {@code equals/hashCode}, hereby considering 085 * <ul> 086 * <li>Implementation type 087 * <li>CurrencyUnit 088 * <li>Numeric value. 089 * </ul> 090 * This also means that two different implementations types with the same currency and numeric value 091 * are NOT equal.</li> 092 * </ul> 093 * <p> 094 * 095 * @author Anatole Tresch 096 * @author Werner Keil 097 * @version 0.8.2 098 * @see #with(javax.money.MonetaryOperator) 099 */ 100public abstract class BaseMonetaryAmount implements MonetaryAmount{ 101 102 /** 103 * Queries this monetary amount for a value. 104 * <p> 105 * This queries this amount using the specified query strategy object. 106 * <p> 107 * Implementations must ensure that no observable state is altered when this read-only method is 108 * invoked. 109 * 110 * @param <R> the type of the result 111 * @param query the query to invoke, not null 112 * @return the query result, null may be returned (defined by the query) 113 */ 114 public <R> R query(MonetaryQuery<R> query){ 115 return query.queryFrom(this); 116 } 117 118 /** 119 * Returns an operated object <b>of the same type</b> as this object with the operation made. 120 * Hereby returning an instance <b>of the same type</b> is very important to prevent 121 * uncontrolled mixup of implementations. Switching between implementations is still easily 122 * possible, e.g. by using according {@link javax.money.MonetaryAmountFactory} instances: <blockquote> 123 * <p> 124 * <pre> 125 * // converting from Money to MyMoney 126 * Money m = ...; 127 * MonetaryAmountFactory<MyMoney> f = Monetary.queryAmountFactory(MyMoney.class); 128 * MyMoney myMoney = f.setAmount(m).of(); 129 * </blockquote> 130 * </pre> 131 * <p> 132 * This converts this monetary amount according to the rules of the specified operator. A 133 * typical operator will change the amount and leave the currency unchanged. A more complex 134 * operator might also change the currency. 135 * <p> 136 * Some example code indicating how and why this method is used: 137 * <p> 138 * <blockquote> 139 * <p> 140 * <pre> 141 * MonetaryAmount money = money.with(amountMultipliedBy(2)); 142 * money = money.with(amountRoundedToNearestWholeUnit()); 143 * </pre> 144 * <p> 145 * </blockquote> 146 * <p> 147 * Hereby also the method signature on the implementation type must return the concrete type, to 148 * enable a fluent API, e.g. 149 * <p> 150 * <blockquote> 151 * <p> 152 * <pre> 153 * public final class MyMoney implements MonetaryAmount{ 154 * ... 155 * public MyMoney with(MonetaryOperator operator){ 156 * ... 157 * } 158 * 159 * ... 160 * } 161 * </pre> 162 * <p> 163 * </blockquote> 164 * 165 * @param operator the operator to use, not null 166 * @return an object of the same type with the specified conversion made, not null 167 */ 168 public MonetaryAmount with(MonetaryOperator operator){ 169 return operator.apply(this); 170 } 171 172 173 /** 174 * Checks if a {@code MonetaryAmount} is negative. 175 * 176 * @return {@code true} if {@link #signum()} < 0. 177 */ 178 public boolean isNegative(){ 179 return signum() < 0; 180 } 181 182 /** 183 * Checks if a {@code MonetaryAmount} is negative or zero. 184 * 185 * @return {@code true} if {@link #signum()} <= 0. 186 */ 187 public boolean isNegativeOrZero(){ 188 return signum() <= 0; 189 } 190 191 /** 192 * Checks if a {@code MonetaryAmount} is positive. 193 * 194 * @return {@code true} if {@link #signum()} > 0. 195 */ 196 public boolean isPositive(){ 197 return signum() > 0; 198 } 199 200 /** 201 * Checks if a {@code MonetaryAmount} is positive or zero. 202 * 203 * @return {@code true} if {@link #signum()} >= 0. 204 */ 205 public boolean isPositiveOrZero(){ 206 return signum() >= 0; 207 } 208 209 /** 210 * Checks if an {@code MonetaryAmount} is zero. 211 * 212 * @return {@code true} if {@link #signum()} == 0. 213 */ 214 public boolean isZero(){ 215 return signum() == 0; 216 } 217 218}