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.CurrencyUnit; 019import javax.money.MonetaryAmount; 020import javax.money.MonetaryOperator; 021import javax.money.convert.ConversionContext; 022import javax.money.convert.CurrencyConversion; 023import javax.money.convert.CurrencyConversionException; 024import javax.money.convert.ExchangeRate; 025import java.util.Objects; 026 027/** 028 * Abstract base class used for implementing currency conversion. 029 * 030 * @author Anatole Tresch 031 * @author Werner Keil 032 */ 033public abstract class AbstractCurrencyConversion implements CurrencyConversion { 034 035 private CurrencyUnit termCurrency; 036 private ConversionContext conversionContext; 037 038 public AbstractCurrencyConversion(CurrencyUnit termCurrency, ConversionContext conversionContext) { 039 Objects.requireNonNull(termCurrency); 040 Objects.requireNonNull(conversionContext); 041 this.termCurrency = termCurrency; 042 this.conversionContext = conversionContext; 043 } 044 045 /** 046 * Access the terminating {@link CurrencyUnit} of this conversion instance. 047 * 048 * @return the terminating {@link CurrencyUnit} , never {@code null}. 049 */ 050 @Override 051 public CurrencyUnit getCurrency() { 052 return termCurrency; 053 } 054 055 /** 056 * Access the target {@link ConversionContext} of this conversion instance. 057 * 058 * @return the target {@link ConversionContext}. 059 */ 060 @Override 061 public ConversionContext getConversionContext() { 062 return conversionContext; 063 } 064 065 /** 066 * Get the exchange rate type that this {@link MonetaryOperator} instance is 067 * using for conversion. 068 * 069 * @return the {@link ExchangeRate} to be used, or null, if this conversion 070 * is not supported (will lead to a 071 * {@link CurrencyConversionException}. 072 * @see #apply(MonetaryAmount) 073 */ 074 @Override 075 public abstract ExchangeRate getExchangeRate(MonetaryAmount amount); 076 077 /* 078 * (non-Javadoc) 079 * @see javax.money.convert.CurrencyConversion#with(javax.money.convert.ConversionContext) 080 */ 081 public abstract CurrencyConversion with(ConversionContext conversionContext); 082 083 /** 084 * Method that converts the source {@link MonetaryAmount} to an 085 * {@link MonetaryAmount} based on the {@link ExchangeRate} of this 086 * conversion. 087 * 088 * @param amount The source amount 089 * @return The converted amount, never null. 090 * @throws CurrencyConversionException if conversion failed, or the required data is not available. 091 * @see #getExchangeRate(MonetaryAmount) 092 */ 093 @Override 094 public MonetaryAmount apply(MonetaryAmount amount) { 095 if (termCurrency.equals(Objects.requireNonNull(amount).getCurrency())) { 096 return amount; 097 } 098 ExchangeRate rate = getExchangeRate(amount); 099 if (Objects.isNull(rate) || !amount.getCurrency().equals(rate.getBaseCurrency())) { 100 throw new CurrencyConversionException(amount.getCurrency(), 101 Objects.isNull(rate) ? null : rate.getCurrency(), null); 102 } 103 return amount.multiply(rate.getFactor()).getFactory().setCurrency(rate.getCurrency()).create(); 104 } 105 106 107 /* 108 * (non-Javadoc) 109 * 110 * @see java.lang.Object#toString() 111 */ 112 @Override 113 public String toString() { 114 return getClass().getName() + " [MonetaryAmount -> MonetaryAmount" + ']'; 115 } 116 117}