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
015/**
016 * Strategy for adjusting a monetary amount.
017 * <p>
018 * Adjusters are a key tool for modifying monetary amounts. They match the
019 * strategy design pattern, allowing different types of adjustment to be easily
020 * captured. Examples might be an adjuster that rounds the amount to the nearest
021 * 1000, or one that performs currency conversion.
022 * <p>
023 * There are two equivalent ways of using a {@code MonetaryAdjuster}. The first
024 * is to invoke the method on this interface. The second is to use
025 * {@link MonetaryAmount#with(MonetaryAdjuster)}, whereas implementations of
026 * {@link MonetaryAmount#with(MonetaryAdjuster)} must return the concrete type,
027 * instead of the interface to support a fluent style:
028 * 
029 * <pre>
030 * // these two variants are equivalent
031 * monetary = thisAdjuster.adjustInto(monetary);
032 * monetary = anotherAdjuster.adjustInto(monetary);
033 * 
034 * // second, recommended, approach, using a fluent API
035 * monetary = monetary.with(thisAdjuster).with(anotherAdjuster);
036 * </pre>
037 * 
038 * It is recommended to use the second approach, {@code with(MonetaryAdjuster)},
039 * as it is a lot clearer to read in code.
040 * <h4>Implementation specification</h4>
041 * This interface places no restrictions on the mutability of implementations,
042 * however immutability is strongly recommended.
043 */
044// @FunctionalInterface for Java 9
045public interface MonetaryAdjuster {
046
047        /**
048         * Adjusts the specified monetary object.
049         * <p>
050         * This adjusts the specified monetary object using the logic encapsulated
051         * in the implementing class. Examples might be an adjuster that rounds the
052         * amount to the nearest 1000, or one that performs currency conversion.
053         * <p>
054         * There are two equivalent ways of using a {@code MonetaryAdjuster}. The
055         * first is to invoke the method on this interface. The second is to use
056         * {@link MonetaryAmount#with(MonetaryAdjuster)}:
057         * 
058         * <pre>
059         * // these two lines are equivalent, but the second approach is recommended
060         * monetary = thisAdjuster.adjustInto(monetary);
061         * monetary = monetary.with(thisAdjuster);
062         * </pre>
063         * 
064         * It is recommended to use the second approach,
065         * {@code with(MonetaryAdjuster)}, as it is a lot clearer to read in code.
066         * 
067         * <h4>Implementation specification</h4>
068         * The implementation must take the input object and adjust it. The
069         * implementation defines the logic of the adjustment and is responsible for
070         * documenting that logic. It may use any method on {@code MonetaryAmount}
071         * to determine the result.
072         * <p>
073         * The input object must not be altered. Instead, an adjusted copy of the
074         * original must be returned. This provides equivalent, safe behavior for
075         * immutable and mutable monetary amounts.
076         * <p>
077         * This method may be called from multiple threads in parallel. It must be
078         * thread-safe when invoked.
079         * 
080         * @param amount
081         *            the amount to adjust, not null
082         * @return a monetary amount with the adjustment made, not null
083         * @throws MonetaryException
084         *             if unable to make the adjustment
085         * @throws ArithmeticException
086         *             if numeric overflow occurs
087         */
088        public MonetaryAmount adjustInto(MonetaryAmount amount);
089
090}