001/**
002 * Copyright (c) 2012, 2015, Anatole Tresch, Werner Keil and others by the @author tag.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005 * use this file except in compliance with the License. You may obtain a copy of
006 * the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013 * License for the specific language governing permissions and limitations under
014 * the License.
015 */
016package org.javamoney.moneta.convert;
017
018import java.math.MathContext;
019import java.util.Objects;
020import java.util.function.Supplier;
021import java.util.stream.Collector;
022
023import javax.money.CurrencyUnit;
024import javax.money.MonetaryAmount;
025import javax.money.MonetaryOperator;
026import javax.money.convert.ExchangeRateProvider;
027
028import org.javamoney.moneta.convert.ExchangeCurrencyOperator;
029import org.javamoney.moneta.function.MonetarySummaryStatistics;
030
031/**
032 * This singleton class provides access to the predefined monetary functions.
033 * <p>
034 * The class is thread-safe, which is also true for all functions returned by
035 * this class.
036 * <pre>
037 * {@code
038 *      MonetaryAmount money = Money.parse("EUR 2.35");
039 *  MonetaryAmount result = operator.apply(money);
040 * }
041 * </pre>
042 * <p>Or using: </p>
043 * <pre>
044 * {@code
045 *      MonetaryAmount money = Money.parse("EUR 2.35");
046 *  MonetaryAmount result = money.with(operator);
047 * }
048 * </pre>
049 * @see {@link MonetaryAmount#with(MonetaryOperator)}
050 * @see {@link MonetaryOperator}
051 * @see {@link MonetaryOperator#apply(MonetaryAmount)}
052 * @author Werner Keil
053 * @since 1.0.1
054 */
055public final class ConversionOperators {
056
057    private static final MathContext DEFAULT_MATH_CONTEXT = MathContext.DECIMAL64;
058
059    private ConversionOperators() {
060    }
061
062        /**
063         * Do exchange of currency, in other words, create the monetary amount with the
064         * same value but with currency different.
065         * <p>
066         * For example, 'EUR 2.35', using the currency 'USD' as exchange parameter, will return 'USD 2.35',
067         * and 'BHD -1.345', using the currency 'USD' as exchange parameter, will return 'BHD -1.345'.
068         * <p>
069         *<pre>
070         *{@code
071         *Currency real = Monetary.getCurrency("BRL");
072         *MonetaryAmount money = Money.parse("EUR 2.355");
073         *MonetaryAmount result = ConversionOperators.exchangeCurrency(real).apply(money);//BRL 2.355
074         *}
075         *</pre>
076         * @param roundingMode rounding to be used
077         * @return the major part as {@link MonetaryOperator}
078         * @since 1.0.1
079         */
080        public static MonetaryOperator exchange(CurrencyUnit currencyUnit){
081                return new ExchangeCurrencyOperator(Objects.requireNonNull(currencyUnit));
082        }
083        
084        /**
085         * of the summary of the MonetaryAmount
086         * @param currencyUnit
087         *            the target {@link javax.money.CurrencyUnit}
088         * @return the MonetarySummaryStatistics
089         */
090        public static Collector<MonetaryAmount, MonetarySummaryStatistics, MonetarySummaryStatistics> summarizingMonetary(
091                        CurrencyUnit currencyUnit, ExchangeRateProvider provider) {
092
093                Supplier<MonetarySummaryStatistics> supplier = () -> new ExchangeRateMonetarySummaryStatistics(
094                                currencyUnit, provider);
095                return Collector.of(supplier, MonetarySummaryStatistics::accept,
096                                MonetarySummaryStatistics::combine);
097        }
098}