001/*
002 * Copyright (c) 2012, 2014, Credit Suisse (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.function;
017
018import java.util.Comparator;
019import java.util.Objects;
020
021import javax.money.MonetaryAmount;
022import javax.money.MonetaryException;
023import javax.money.convert.CurrencyConversion;
024import javax.money.convert.ExchangeRate;
025import javax.money.convert.ExchangeRateProvider;
026
027import org.javamoney.moneta.spi.MoneyUtils;
028
029/**
030 * This singleton class provides access to the predefined monetary functions.
031 *
032 * @author otaviojava
033 * @author anatole
034 */
035public final class MonetaryFunctions {
036
037          private static final Comparator<MonetaryAmount> NUMBER_COMPARATOR = new Comparator<MonetaryAmount>() {
038                @Override
039                public int compare(MonetaryAmount o1, MonetaryAmount o2) {
040                    return o1.getNumber().compareTo(o2.getNumber());
041                }
042            };
043
044            private static final Comparator<MonetaryAmount> CURRENCY_COMPARATOR = new Comparator<MonetaryAmount>() {
045                @Override
046                public int compare(MonetaryAmount o1, MonetaryAmount o2) {
047                    return o1.getCurrency().compareTo(o2.getCurrency());
048                }
049            };
050
051            /**
052             * Get a comparator for sorting CurrencyUnits ascending.
053             *
054             * @return the Comparator to sort by CurrencyUnit in ascending order, not null.
055             */
056            public static Comparator<MonetaryAmount> sortCurrencyUnit(){
057                return CURRENCY_COMPARATOR;
058            }
059
060                /**
061                 * comparator to sort the {@link MonetaryAmount} considering the
062                 * {@link ExchangeRate}
063                 * @param provider the rate provider to be used.
064                 * @return the sort of {@link MonetaryAmount} using {@link ExchangeRate}
065                 */
066                public static Comparator<? super MonetaryAmount> sortValuable(
067                    final ExchangeRateProvider provider) {
068                return new Comparator<MonetaryAmount>() {
069                    @Override
070                    public int compare(MonetaryAmount m1, MonetaryAmount m2) {
071                        CurrencyConversion conversor = provider.getCurrencyConversion(m1
072                                .getCurrency());
073                        return m1.compareTo(conversor.apply(m2));
074                    }
075                };
076                }
077
078                /**
079                 * comparator to sort the {@link MonetaryAmount} considering the
080                 * {@link ExchangeRate}
081                 * @param provider the rate provider to be used.
082                 * @return the sort of {@link MonetaryAmount} using {@link ExchangeRate}
083                 * @deprecated call #sortValuable instead of.
084                 */
085                @Deprecated
086                public static Comparator<? super MonetaryAmount> sortValiable(final ExchangeRateProvider provider) {
087                        return sortValuable(provider);
088                }
089
090
091                /**
092                 * Descending order of
093                 * {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)}
094                 * @param provider the rate provider to be used.
095                 * @return the Descending order of
096                 *         {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)}
097                 */
098                public static Comparator<? super MonetaryAmount> sortValuableDesc(
099                    final ExchangeRateProvider provider) {
100                        return new Comparator<MonetaryAmount>() {
101                    @Override
102                    public int compare(MonetaryAmount o1, MonetaryAmount o2) {
103                        return sortValuable(provider).compare(o1, o2) * -1;
104                    }
105                };
106                }
107
108                /**
109                 * Descending order of
110                 * {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)}
111                 * @param provider the rate provider to be used.
112                 * @return the Descending order of
113                 *         {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)}
114                 * @deprecated Use #sortValiableDesc instead of.
115                 */
116                @Deprecated
117                public static Comparator<? super MonetaryAmount> sortValiableDesc(
118                                final ExchangeRateProvider provider) {
119                        return new Comparator<MonetaryAmount>() {
120                                @Override
121                                public int compare(MonetaryAmount o1, MonetaryAmount o2) {
122                                        return sortValuable(provider).compare(o1, o2) * -1;
123                                }
124                        };
125                }
126
127            /**
128             * Get a comparator for sorting CurrencyUnits descending.
129             * @return the Comparator to sort by CurrencyUnit in descending order, not null.
130             */
131            public static Comparator<MonetaryAmount> sortCurrencyUnitDesc(){
132                return new Comparator<MonetaryAmount>() {
133                    @Override
134                    public int compare(MonetaryAmount o1, MonetaryAmount o2) {
135                        return sortCurrencyUnit().compare(o1, o2) * -1;
136                    }
137                };
138            }
139
140            /**
141             * Get a comparator for sorting amount by number value ascending.
142             * @return the Comparator to sort by number in ascending way, not null.
143             */
144            public static Comparator<MonetaryAmount> sortNumber(){
145                return NUMBER_COMPARATOR;
146            }
147
148            /**
149             * Get a comparator for sorting amount by number value descending.
150             * @return the Comparator to sort by number in descending way, not null.
151             */
152            public static Comparator<MonetaryAmount> sortNumberDesc(){
153                return new Comparator<MonetaryAmount>() {
154                    @Override
155                    public int compare(MonetaryAmount o1, MonetaryAmount o2) {
156                        return sortNumber().compare(o1, o2) * -1;
157                    }
158                };
159            }
160
161            /**
162             * Adds two monetary together
163             * @param a the first operand
164             * @param b the second operand
165             * @return the sum of {@code a} and {@code b}
166             * @throws NullPointerException if a o b be null
167             * @throws MonetaryException    if a and b have different currency
168             */
169            public static MonetaryAmount sum(MonetaryAmount a, MonetaryAmount b){
170                MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency()));
171                return a.add(b);
172            }
173
174            /**
175             * Returns the smaller of two {@code MonetaryAmount} values. If the arguments
176             * have the same value, the result is that same value.
177             * @param a an argument.
178             * @param b another argument.
179             * @return the smaller of {@code a} and {@code b}.
180             */
181                static MonetaryAmount min(MonetaryAmount a, MonetaryAmount b) {
182                MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency()));
183                return a.isLessThan(b) ? a : b;
184            }
185
186            /**
187             * Returns the greater of two {@code MonetaryAmount} values. If the
188             * arguments have the same value, the result is that same value.
189             * @param a an argument.
190             * @param b another argument.
191             * @return the larger of {@code a} and {@code b}.
192             */
193                static MonetaryAmount max(MonetaryAmount a, MonetaryAmount b) {
194                MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency()));
195                return a.isGreaterThan(b) ? a : b;
196            }
197
198
199
200}