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