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.util.Objects;
019import java.util.function.Supplier;
020import java.util.stream.Collector;
021
022import javax.money.CurrencyUnit;
023import javax.money.MonetaryAmount;
024import javax.money.MonetaryOperator;
025import javax.money.convert.ExchangeRateProvider;
026
027import org.javamoney.moneta.convert.ExchangeCurrencyOperator;
028import org.javamoney.moneta.function.MonetarySummaryStatistics;
029
030/**
031 * This singleton class provides access to the predefined monetary functions.
032 * <p>
033 * The class is thread-safe, which is also true for all functions returned by
034 * this class.
035 * <pre>
036 * {@code
037 *      MonetaryAmount money = Money.parse("EUR 2.35");
038 *  MonetaryAmount result = operator.apply(money);
039 * }
040 * </pre>
041 * <p>Or using: </p>
042 * <pre>
043 * {@code
044 *      MonetaryAmount money = Money.parse("EUR 2.35");
045 *  MonetaryAmount result = money.with(operator);
046 * }
047 * </pre>
048 * @see MonetaryAmount#with(MonetaryOperator)
049 * @see MonetaryOperator
050 * @see MonetaryOperator#apply(MonetaryAmount)
051 * @author Werner Keil
052 * @since 1.0.1
053 */
054public final class ConversionOperators {
055
056    private ConversionOperators() {
057    }
058
059        /**
060         * Do exchange of currency, in other words, create the monetary amount with the
061         * same value but with currency different.
062         * <p>
063         * For example, 'EUR 2.35', using the currency 'USD' as exchange parameter, will return 'USD 2.35',
064         * and 'BHD -1.345', using the currency 'USD' as exchange parameter, will return 'BHD -1.345'.
065         * <p>
066         *<pre>
067         *{@code
068         *Currency real = Monetary.getCurrency("BRL");
069         *MonetaryAmount money = Money.parse("EUR 2.355");
070         *MonetaryAmount result = ConversionOperators.exchangeCurrency(real).apply(money);//BRL 2.355
071         *}
072         *</pre>
073         * @param currencyUnit the currency to be used
074         * @return the major part as {@link MonetaryOperator}
075         * @since 1.0.1
076         */
077        public static MonetaryOperator exchange(CurrencyUnit currencyUnit){
078                return new ExchangeCurrencyOperator(Objects.requireNonNull(currencyUnit));
079        }
080        
081        /**
082         * of the summary of the MonetaryAmount
083         * @param currencyUnit
084         *            the target {@link javax.money.CurrencyUnit}
085         * @return the MonetarySummaryStatistics
086         */
087        public static Collector<MonetaryAmount, MonetarySummaryStatistics, MonetarySummaryStatistics> summarizingMonetary(
088                        CurrencyUnit currencyUnit, ExchangeRateProvider provider) {
089
090                Supplier<MonetarySummaryStatistics> supplier = () -> new ExchangeRateMonetarySummaryStatistics(
091                                currencyUnit, provider);
092                return Collector.of(supplier, MonetarySummaryStatistics::accept,
093                                MonetarySummaryStatistics::combine);
094        }
095}