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 private static final Comparator<MonetaryAmount> NUMBER_COMPARATOR = new Comparator<MonetaryAmount>() { 037 @Override 038 public int compare(MonetaryAmount o1, MonetaryAmount o2) { 039 return o1.getNumber().compareTo(o2.getNumber()); 040 } 041 }; 042 043 private static final Comparator<MonetaryAmount> CURRENCY_COMPARATOR = new Comparator<MonetaryAmount>() { 044 @Override 045 public int compare(MonetaryAmount o1, MonetaryAmount o2) { 046 return o1.getCurrency().compareTo(o2.getCurrency()); 047 } 048 }; 049 050 /** 051 * Get a comparator for sorting CurrencyUnits ascending. 052 * 053 * @return the Comparator to sort by CurrencyUnit in ascending order, not null. 054 */ 055 public static Comparator<MonetaryAmount> sortCurrencyUnit(){ 056 return CURRENCY_COMPARATOR; 057 } 058 059 /** 060 * comparator to sort the {@link MonetaryAmount} considering the 061 * {@link ExchangeRate} 062 * @param provider the rate provider to be used. 063 * @return the sort of {@link MonetaryAmount} using {@link ExchangeRate} 064 */ 065 public static Comparator<? super MonetaryAmount> sortValuable( 066 final ExchangeRateProvider provider) { 067 return new Comparator<MonetaryAmount>() { 068 @Override 069 public int compare(MonetaryAmount m1, MonetaryAmount m2) { 070 CurrencyConversion conversor = provider.getCurrencyConversion(m1 071 .getCurrency()); 072 return m1.compareTo(conversor.apply(m2)); 073 } 074 }; 075 } 076 077 /** 078 * Descending order of 079 * {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)} 080 * @param provider the rate provider to be used. 081 * @return the Descending order of 082 * {@link MonetaryFunctions#sortValuable(ExchangeRateProvider)} 083 */ 084 public static Comparator<? super MonetaryAmount> sortValuableDesc( 085 final ExchangeRateProvider provider) { 086 return new Comparator<MonetaryAmount>() { 087 @Override 088 public int compare(MonetaryAmount o1, MonetaryAmount o2) { 089 return sortValuable(provider).compare(o1, o2) * -1; 090 } 091 }; 092 } 093 094 /** 095 * Get a comparator for sorting CurrencyUnits descending. 096 * @return the Comparator to sort by CurrencyUnit in descending order, not null. 097 */ 098 public static Comparator<MonetaryAmount> sortCurrencyUnitDesc(){ 099 return new Comparator<MonetaryAmount>() { 100 @Override 101 public int compare(MonetaryAmount o1, MonetaryAmount o2) { 102 return sortCurrencyUnit().compare(o1, o2) * -1; 103 } 104 }; 105 } 106 107 /** 108 * Get a comparator for sorting amount by number value ascending. 109 * @return the Comparator to sort by number in ascending way, not null. 110 */ 111 public static Comparator<MonetaryAmount> sortNumber(){ 112 return NUMBER_COMPARATOR; 113 } 114 115 /** 116 * Get a comparator for sorting amount by number value descending. 117 * @return the Comparator to sort by number in descending way, not null. 118 */ 119 public static Comparator<MonetaryAmount> sortNumberDesc(){ 120 return new Comparator<MonetaryAmount>() { 121 @Override 122 public int compare(MonetaryAmount o1, MonetaryAmount o2) { 123 return sortNumber().compare(o1, o2) * -1; 124 } 125 }; 126 } 127 128 /** 129 * Adds two monetary together 130 * @param a the first operand 131 * @param b the second operand 132 * @return the sum of {@code a} and {@code b} 133 * @throws NullPointerException if a o b be null 134 * @throws MonetaryException if a and b have different currency 135 */ 136 public static MonetaryAmount sum(MonetaryAmount a, MonetaryAmount b){ 137 MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency())); 138 return a.add(b); 139 } 140 141 /** 142 * Returns the smaller of two {@code MonetaryAmount} values. If the arguments 143 * have the same value, the result is that same value. 144 * @param a an argument. 145 * @param b another argument. 146 * @return the smaller of {@code a} and {@code b}. 147 */ 148 static MonetaryAmount min(MonetaryAmount a, MonetaryAmount b) { 149 MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency())); 150 return a.isLessThan(b) ? a : b; 151 } 152 153 /** 154 * Returns the greater of two {@code MonetaryAmount} values. If the 155 * arguments have the same value, the result is that same value. 156 * @param a an argument. 157 * @param b another argument. 158 * @return the larger of {@code a} and {@code b}. 159 */ 160 static MonetaryAmount max(MonetaryAmount a, MonetaryAmount b) { 161 MoneyUtils.checkAmountParameter(Objects.requireNonNull(a), Objects.requireNonNull(b.getCurrency())); 162 return a.isGreaterThan(b) ? a : b; 163 } 164 165}