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.spi; 017 018import javax.money.convert.ConversionContext; 019import javax.money.convert.ConversionQuery; 020import javax.money.convert.CurrencyConversion; 021import javax.money.convert.ExchangeRate; 022import javax.money.convert.ProviderContext; 023import javax.money.convert.RateType; 024import org.javamoney.moneta.spi.base.BaseExchangeRateProvider; 025 026import javax.money.NumberValue; 027 028import java.math.BigDecimal; 029import java.math.MathContext; 030import java.math.RoundingMode; 031import java.util.Calendar; 032import java.util.Objects; 033import java.util.logging.Logger; 034 035/** 036 * Abstract base class for {@link javax.money.convert.ExchangeRateProvider} implementations. 037 * 038 * @author Anatole Tresch 039 * @author Werner Keil 040 */ 041public abstract class AbstractRateProvider extends BaseExchangeRateProvider { 042 043 /** 044 * The logger used. 045 */ 046 protected final Logger LOGGER = Logger.getLogger(getClass().getName()); 047 048 /** 049 * The {@link javax.money.convert.ConversionContext} of this provider. 050 */ 051 private final ProviderContext providerContext; 052 053 /** 054 * Constructor. 055 * 056 * @param providerContext the {@link ProviderContext}, not null. 057 */ 058 public AbstractRateProvider(ProviderContext providerContext) { 059 this.providerContext = Objects.requireNonNull(providerContext); 060 } 061 062 /* 063 * (non-Javadoc) 064 * 065 * @see org.javamoney.bp.api.convert.spi.ExchangeRateProviderSpi#getExchangeRateType 066 * () 067 */ 068 @Override 069 public ProviderContext getContext() { 070 return providerContext; 071 } 072 073 @Override 074 public abstract ExchangeRate getExchangeRate(ConversionQuery conversionQuery); 075 076 @Override 077 public CurrencyConversion getCurrencyConversion(ConversionQuery conversionQuery) { 078 if (getContext().getRateTypes().size() == 1) { 079 return new LazyBoundCurrencyConversion(conversionQuery, this, ConversionContext 080 .of(getContext().getProviderName(), getContext().getRateTypes().iterator().next())); 081 } 082 return new LazyBoundCurrencyConversion(conversionQuery, this, 083 ConversionContext.of(getContext().getProviderName(), RateType.ANY)); 084 } 085 086 087 /** 088 * A protected helper method to multiply 2 {@link NumberValue} types.<br> 089 * If either of the values is <code>null</code> an {@link ArithmeticException} is thrown. 090 * 091 * @param multiplicand the first value to be multiplied 092 * @param multiplier the second value to be multiplied 093 * @return the result of the multiplication as {@link NumberValue} 094 */ 095 protected static NumberValue multiply(NumberValue multiplicand, NumberValue multiplier) { 096 if (multiplicand==null) { 097 throw new ArithmeticException("The multiplicand cannot be null"); 098 } 099 if (multiplier==null) { 100 throw new ArithmeticException("The multiplier cannot be null"); 101 } 102 return new DefaultNumberValue( 103 multiplicand.numberValueExact(BigDecimal.class).multiply(multiplier.numberValue(BigDecimal.class))); 104 } 105 106 /** 107 * A protected helper method to divide 2 {@link NumberValue} types.<br> 108 * If either of the values is <code>null</code> an {@link ArithmeticException} is thrown. 109 * 110 * @param dividend the first value to be divided 111 * @param divisor the value to be divided by 112 * @return the result of the division as {@link NumberValue} 113 */ 114 protected static NumberValue divide(NumberValue dividend, NumberValue divisor) { 115 if (dividend==null) { 116 throw new ArithmeticException("The dividend cannot be null"); 117 } 118 if (divisor==null) { 119 throw new ArithmeticException("The divisor cannot be null"); 120 } 121 return new DefaultNumberValue( 122 dividend.numberValueExact(BigDecimal.class).divide(divisor.numberValue(BigDecimal.class), 123 RoundingMode.HALF_EVEN)); 124 } 125 126 /** 127 * A protected helper method to divide 2 {@link NumberValue} types.<br> 128 * If either of the values is <code>null</code> an {@link ArithmeticException} is thrown. 129 * 130 * @param dividend the first value to be divided 131 * @param divisor the value to be divided by 132 * @param context the {@link MathContext} to use 133 * @return the result of the division as {@link NumberValue} 134 */ 135 protected static NumberValue divide(NumberValue dividend, NumberValue divisor, MathContext context) { 136 if (dividend==null) { 137 throw new ArithmeticException("The dividend cannot be null"); 138 } 139 if (divisor==null) { 140 throw new ArithmeticException("The divisor cannot be null"); 141 } 142 return new DefaultNumberValue( 143 dividend.numberValueExact(BigDecimal.class).divide(divisor.numberValue(BigDecimal.class), context)); 144 } 145 146 protected String formatLocalDate(Calendar calendar){ 147 return calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH) + 148 "-" + calendar.get(Calendar.DAY_OF_MONTH); 149 } 150}