All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javamoney.moneta.spi.base.BaseMonetaryAmount Maven / Gradle / Ivy

Go to download

JSR 354 provides an API for representing, transporting, and performing comprehensive calculations with Money and Currency. This module implements JSR 354.

There is a newer version: 1.4.1
Show newest version
/*
 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU
 * ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS
 * AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
 * THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE
 * BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright
 * (c) 2012-2013, Credit Suisse All rights reserved.
 */
package org.javamoney.moneta.spi.base;

import javax.money.MonetaryAmount;
import javax.money.MonetaryOperator;
import javax.money.MonetaryQuery;

/**
 * Interface defining a monetary amount. The effective format representation of an amount may vary
 * depending on the implementation used. JSR 354 explicitly supports different types of monetary
 * amounts to be implemented and used. Reason behind is that the requirements to an implementation
 * heavily vary for different usage scenarios. E.g. product calculations may require high precision
 * and scale, whereas low latency order and trading systems require high calculation performance for
 * algorithmic operations.
 *
 * Each instance of an amount provides additional meta-data in form of a {@link javax.money.MonetaryContext}.
 * This context contains detailed information on the numeric capabilities, e.g. the supported
 * precision and maximal scale, as well as the common implementation flavor.
 *
 * Also a {@link BaseMonetaryAmount} provides a {@link javax.money.NumberValue}, which allows easily to extract the
 * numeric value, of the amount. And finally {@link #getFactory()} provides a
 * {@link javax.money.MonetaryAmountFactory}, which allows to of instances of {@link BaseMonetaryAmount} based
 * on the same numeric implementation.
 *
 * This JSR additionally recommends to consider the following aspects:
 * 
    *
  • Arithmetic operations should throw an {@link ArithmeticException}, if performing arithmetic * operations between amounts exceeds the capabilities of the numeric representation type used. Any * implicit truncating, that would lead to complete invalid and useless results, should be avoided. * This recommendation does not affect format rounding, as required by the format numeric * representation of a monetary amount. *
  • Monetary amounts should allow numbers as argument for arithmetic operations like division and * multiplication. Adding or subtracting of amounts must only be possible by passing instances of * {@link BaseMonetaryAmount}.
  • *
  • Nevertheless numeric truncation is also explicitly supported when calling * {@link javax.money.NumberValue#numberValue(Class)}, whereas the exact counterpart, * {@link javax.money.NumberValue#numberValueExact(Class)}, works similar to * {@link java.math.BigDecimal#longValueExact()}. *
  • Since implementations are recommended to be immutable, an operation should never change any * format state of an instance. Given an instance, all operations are required to be fully * reproducible.
  • *
  • Finally the result of calling {@link #with(javax.money.MonetaryOperator)} must be of the same type as * type on which {@code with} was called. The {@code with} method also defines additional * interoperability requirements that are important to enable this invariant.
  • *
  • To enable further interoperability a static method {@code from(MonetaryAmount)} is * recommended to be implemented on each implementation class, that allows conversion of a * {@code MonetaryAmount} to a concrete instance. E.g.a class {@code MyMoney extends MonetaryAmount} * would contain the following method: * *
    * *
     * public final class MyMoney implements MonetaryAmount{
     *   ...
     *   public static MyMoney from(MonetaryAmount amount)(...)
     * }
     * 
    * *
  • *
* Implementation specification * Implementations of this interface must be *
    *
  • thread-safe
  • *
* Implementations of this interface should be *
    *
  • final
  • *
  • serializable, hereby writing the numeric value, the {@link javax.money.MonetaryContext} and a serialized * {@link javax.money.CurrencyUnit}.
  • *
* Implementations of this interface must be *
    *
  • thread-safe
  • *
  • immutable
  • *
  • comparable
  • *
  • must implement {@code equals/hashCode}, hereby considering *
      *
    • Implementation type *
    • CurrencyUnit *
    • Numeric value. *
    * This also means that two different implementations types with the same currency and numeric value * are NOT equal.
  • *
* * * @author Anatole Tresch * @author Werner Keil * @version 0.8.2 * @see #with(javax.money.MonetaryOperator) */ public abstract class BaseMonetaryAmount implements MonetaryAmount{ /** * Queries this monetary amount for a value. * * This queries this amount using the specified query strategy object. * * Implementations must ensure that no observable state is altered when this read-only method is * invoked. * * @param the type of the result * @param query the query to invoke, not null * @return the query result, null may be returned (defined by the query) */ public R query(MonetaryQuery query){ return query.queryFrom(this); } /** * Returns an operated object of the same type as this object with the operation made. * Hereby returning an instance of the same type is very important to prevent * uncontrolled mixup of implementations. Switching between implementations is still easily * possible, e.g. by using according {@link javax.money.MonetaryAmountFactory} instances: * * {@code * // converting from Money to MyMoney * Money m = ...; * MonetaryAmountFactory f = Monetary.queryAmountFactory(MyMoney.class); * MyMoney myMoney = f.setAmount(m).of(); * } * * This converts this monetary amount according to the rules of the specified operator. A * typical operator will change the amount and leave the currency unchanged. A more complex * operator might also change the currency. * * Some example code indicating how and why this method is used: * * {@code * MonetaryAmount money = money.with(amountMultipliedBy(2)); * money = money.with(amountRoundedToNearestWholeUnit()); * } * * Hereby also the method signature on the implementation type must return the concrete type, to * enable a fluent API, e.g. * * {@code * public final class MyMoney implements MonetaryAmount{ * ... * public MyMoney with(MonetaryOperator operator){ * ... * } * * ... * } * } * * @param operator the operator to use, not null * @return an object of the same type with the specified conversion made, not null */ public MonetaryAmount with(MonetaryOperator operator){ return operator.apply(this); } /** * Checks if a {@code MonetaryAmount} is negative. * * @return {@code true} if {@link #signum()} < 0. */ public boolean isNegative(){ return signum() < 0; } /** * Checks if a {@code MonetaryAmount} is negative or zero. * * @return {@code true} if {@link #signum()} <= 0. */ public boolean isNegativeOrZero(){ return signum() <= 0; } /** * Checks if a {@code MonetaryAmount} is positive. * * @return {@code true} if {@link #signum()} > 0. */ public boolean isPositive(){ return signum() > 0; } /** * Checks if a {@code MonetaryAmount} is positive or zero. * * @return {@code true} if {@link #signum()} >= 0. */ public boolean isPositiveOrZero(){ return signum() >= 0; } /** * Checks if an {@code MonetaryAmount} is zero. * * @return {@code true} if {@link #signum()} == 0. */ public boolean isZero(){ return signum() == 0; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy